Commit bc1ef84
parse and add glyph that don't exixt in cmap
Changed files (5)
modifiedsrc/Font.valamodifiedsrc/Glyph.valamodifiedsrc/GlyphRange.valamodifiedsrc/OpenFontFormatWriter.valamodifiedsrc/OverView.vala
Diff
@@ -23,6 +23,10 @@ namespace Supplement { class Font : GLib.Object { HashTable <string, GlyphCollection> glyph_cache = new HashTable <string, GlyphCollection> (str_hash, str_equal);+ + /** Glyphs that not are tied to a unichar value. */+ HashTable <string, GlyphCollection> unassigned_glyphs = new HashTable <string, GlyphCollection> (str_hash, str_equal);+ public HashTable <string, Kerning> kerning = new HashTable <string, Kerning> (str_hash, str_equal); public List <string> background_images = new List <string> ();@@ -75,6 +79,10 @@ class Font : GLib.Object { return f; } + public uint get_length () {+ return glyph_cache.get_keys ().length ();+ }+ /** Retuns true if the current font has be modified */ public bool is_modified () { return modified;@@ -248,6 +256,8 @@ class Font : GLib.Object { gr.sort (); + gr.unassigned = unassigned_glyphs.get_keys ();+ return gr; } @@ -275,7 +285,17 @@ class Font : GLib.Object { /** Obtain all versions and alterntes for this glyph. */ public GlyphCollection? get_glyph_collection (string glyph) {- return glyph_cache.lookup (glyph);+ GlyphCollection? gc = glyph_cache.lookup (glyph);+ + if (gc == null) {+ gc = unassigned_glyphs.lookup (glyph);+ + if (gc == null) { + return null;+ }+ }+ + return gc; } public Glyph? get_glyph_from_unichar (unichar glyph) {@@ -285,7 +305,7 @@ class Font : GLib.Object { } public Glyph? get_glyph (string glyph) {- unowned GlyphCollection? gc = glyph_cache.lookup (glyph);+ GlyphCollection? gc = get_glyph_collection (glyph); if (gc == null) { return null;@@ -296,14 +316,25 @@ class Font : GLib.Object { public Glyph? get_glyph_indice (unichar glyph_indice) { List<unowned GlyphCollection> gl;+ unowned GlyphCollection gc; - if (glyph_indice >= glyph_cache.size ()) {+ if (glyph_indice >= glyph_cache.size () + unassigned_glyphs.size ()) { return null; } - gl = glyph_cache.get_values ();- - return gl.nth (glyph_indice).data.get_current ();+ if (glyph_indice >= glyph_cache.size ()) {+ gl = unassigned_glyphs.get_values ();+ glyph_indice -= glyph_cache.size ();+ + return null;+ } else {+ gl = glyph_cache.get_values ();+ }+ + gc = gl.nth (glyph_indice).data;+ return ((!) gc).get_current ();++ return null; } public void add_background_image (string file) {@@ -558,18 +589,21 @@ class Font : GLib.Object { glyph_cache.remove_all (); - print (@"Adding $(otf.get_glyphs ().length ()) to font.");+ print (@"Adding $(otf.get_glyphs ().length ()) glyphs to font.\n"); foreach (Glyph g in otf.get_glyphs ()) { gc = get_glyph_collection (g.get_name ());- - if (gc == null) {+ + if (g.is_unassigned ()) {+ gc = new GlyphCollection ();+ unassigned_glyphs.insert (@"($(++unindexed)) $(g.get_name ())", (!) gc); + } else if (gc == null) { gc = new GlyphCollection (); glyph_cache.insert (g.get_name (), (!) gc); } else { stderr.printf (@"Glyph collection does already have an entry for $(g.get_name ()) char $((uint64) g.unichar_code).\n"); gc = new GlyphCollection ();- glyph_cache.insert (@"$(++unindexed) $(g.get_name ())", (!) gc);+ unassigned_glyphs.insert (@"($(++unindexed))", (!) gc); } ((!)gc).insert_glyph (g, true);@@ -584,6 +618,8 @@ class Font : GLib.Object { // take xheight from appropriate lower case letter xheight_position = estimate_xheight (); + print (@"Num chars $(get_length ()).\n");+ return true; // Fixa } @@ -84,6 +84,7 @@ class Glyph : FontDisplay { bool xheight_lines_visible = false; // blue lines bool margin_boundries_visible = false; // red lines + bool unassigned = false; public unichar unichar_code = 0; bool editable = true;@@ -113,6 +114,14 @@ class Glyph : FontDisplay { path_list.append (new Path ()); }+ + public void set_unassigned (bool u) {+ unassigned = u;+ }+ + public bool is_unassigned () {+ return unassigned;+ } public void boundries (out double x1, out double y1, out double x2, out double y2) { if (path_list.length () == 0) {@@ -20,8 +20,9 @@ namespace Supplement { class GlyphRange { List<UniRange> ranges;- List<unichar> index_start;++ public List<unowned string> unassigned; unichar len = 0; @@ -91,7 +92,7 @@ class GlyphRange { } public unichar get_length () {- return len;+ return len + unassigned.length (); } public void add_range (unichar start, unichar stop) {@@ -116,19 +117,15 @@ class GlyphRange { } }- - public unichar get_unichar (unichar index) {- return get_char (index).get_char (0);- }- + public string get_char (unichar index) { int i = 0; unichar next = 0;+ foreach (unichar s in index_start) { StringBuilder sbt = new StringBuilder (); if (!s.validate () && s >= index) {- sbt.append_unichar (s); break; } else if (s >= index) {@@ -140,12 +137,16 @@ class GlyphRange { i++; } - if (unlikely(index == 0)) {- return "\0".dup();- }-- if (!unlikely(0 <= i < ranges.length ())) {- return "\0".dup();+ if (index == 0 || !(0 <= i < ranges.length ())) {+ if (index > ranges.length ()) {+ i = (int) (index - ranges.length ());+ + if (i >= unassigned.length ()) {+ return "\0".dup();+ }+ + return unassigned.nth (i).data.dup();+ } } UniRange u = ranges.nth_data (i);@@ -642,6 +642,10 @@ class GlyfTable : Table { glyph.right_limit = hmtx_table.get_advance (i) - hmtx_table.get_lsb (i); } + if (character == 0 && i != 0) { + glyph.set_unassigned (true); + } + glyphs.append (glyph); } catch (Error e) { @@ -1275,7 +1279,6 @@ class CmapSubtableWindowsUnicode : CmapSubtable { table.insert (indice, character); } - indice++; j++; } while (character != end_char[i]); @@ -1306,7 +1309,7 @@ class CmapSubtableWindowsUnicode : CmapSubtable { if (c == 0) { s = new StringBuilder (); s.append_unichar (c); - warning (@"No characte in cmap for index $i. Last avalable char is $(s.str) Got $(s.str), ($((uint32)c))"); + warning (@"No entry in cmap for index $i. Last avalable char is $(s.str) Got $(s.str), ($((uint32)c))"); err++; return false; } else { @@ -64,11 +64,13 @@ class OverView : FontDisplay { Toolbox tools = MainWindow.get_toolbox (); bool selected = tabs.select_char (s); unichar new_char = s.get_char (0);+ Font f = Supplement.get_current_font (); stdout.printf ("Open '%s' character: %u (%s)\n", s, new_char, Font.to_hex (new_char));- + + if (f.get_glyph_collection (s) == null) print ("NO GLYPH \n");+ if (!selected) {- Font f = Supplement.get_current_font (); GlyphCollection? fg = f.get_glyph_collection (s); Glyph g = (fg == null) ? new Glyph (s, new_char) : ((!) fg).get_current (); ZoomTool z = (ZoomTool) tools.get_tool ("zoom_tool");@@ -734,6 +736,7 @@ class OverView : FontDisplay { selected++; x += nail_width; }+ selected--; if (current == selected && !menu_action) {@@ -756,12 +759,15 @@ class OverView : FontDisplay { } public void set_glyph_range (GlyphRange range) {- string c = glyph_range.get_char (selected); + string c = glyph_range.get_char (selected); bool done = false; unichar i; unichar len;+ glyph_range = range; + // Todo: optimized search when full range is selected.+ // scroll to the selected character if (c == "") { print (@"No glyph.. \"$c\" move to a\n");@@ -774,6 +780,11 @@ class OverView : FontDisplay { scroll_top (); + // Skip scroll if this is a unassigned character+ if (c.char_count () > 1) {+ return;+ }+ while (true) { for (i = first_visible; i < first_visible + items_per_row * (rows + 1); i++) { if (range.get_char (i) == c) {@@ -785,7 +796,7 @@ class OverView : FontDisplay { if (done) break; if (at_bottom ()) break;- + scroll_rows (rows); }