Commit 86e9a8e
search for glyphs by name, indice and unicode value
Changed files (8)
modifiedlibbirdfont/Font.valamodifiedlibbirdfont/GlyphCollection.valamodifiedlibbirdfont/GlyphTable.valamodifiedlibbirdfont/OpenFontFormatReader.valamodifiedlibbirdfont/OpenFontFormatWriter.valamodifiedlibbirdfont/OverView.valamodifiedlibbirdfont/SvgFont.valamodifiedlibbirdfont/TestCases.vala
Diff
@@ -27,12 +27,11 @@ public enum FontFormat { public class Font : GLib.Object { + /** Table with glyphs sorted by their unicode value. */ GlyphTable glyph_cache = new GlyphTable (); - /** Glyphs that not are tied to a unichar value. */- GlyphTable unassigned_glyphs = new GlyphTable ();-- List<string> glyph_names = new List<string> ();+ /** Table with glyphs sorted by their name. */+ GlyphTable glyph_name = new GlyphTable (); /** Last unassigned index */ int next_unindexed = 0;@@ -174,17 +173,15 @@ public class Font : GLib.Object { } public void print_all () {- stdout.printf ("Assigned:\n"); + stdout.printf ("Unicode:\n"); glyph_cache.for_each((g) => {- stdout.printf (@"$(g.get_name ())\n");+ stdout.printf (@"$(g.get_unicode ())\n"); });-- stdout.printf ("\n");- stdout.printf ("Unssigned:\n"); - unassigned_glyphs.for_each ((g) => {+ + stdout.printf ("Names:\n"); + glyph_name.for_each((g) => { stdout.printf (@"$(g.get_name ())\n"); });- } public bool has_glyph (string n) {@@ -295,28 +292,24 @@ public class Font : GLib.Object { } public void add_glyph_collection (GlyphCollection glyph_collection) {- GlyphCollection? gc = get_cached_glyph_collection (glyph_collection.get_name ());+ GlyphCollection? gc; if (glyph_collection.get_name () == "") { warning ("Refusing to insert glyph with name \"\", null character should be named null."); return; } + gc = glyph_name.get (glyph_collection.get_name ()); if (gc != null) { warning ("glyph has already been added"); return; } - if (glyph_collection.get_current ().is_unassigned ()) {- unassigned_glyphs.insert (glyph_collection);- } else {- glyph_cache.insert (glyph_collection);- }-- if (!has_name (glyph_collection.get_name ())) {- glyph_names.append (glyph_collection.get_name ());- glyph_names.sort (strcmp);+ if (glyph_collection.get_unicode () != "") {+ glyph_name.insert (glyph_collection.get_name (), glyph_collection); }+ + glyph_cache.insert (glyph_collection.get_unicode (), glyph_collection); } public string get_name_for_character (unichar c) {@@ -345,18 +338,13 @@ public class Font : GLib.Object { } public bool has_name (string name) {- foreach (string n in glyph_names) {- if (n == name) {- return true;- }- }- - return false;+ return glyph_name.has_key (name); } - public void delete_glyph (string glyph) {- glyph_names.remove_all (glyph);- glyph_cache.remove (glyph);+ public void delete_glyph (GlyphCollection glyph) {+ glyph_cache.remove (glyph.get_unicode ());+ glyph_name.remove (glyph.get_name ());+ // FIXME: DELETE: glyph_cache.remove (glyph); } /** Obtain all versions and alterntes for this glyph. */@@ -377,20 +365,27 @@ public class Font : GLib.Object { return gc; } - public GlyphCollection? get_cached_glyph_collection (string glyph) {+ /** Get glyph collection by unichar code. */+ public GlyphCollection? get_cached_glyph_collection (string unichar_code) { GlyphCollection? gc = null;- - gc = glyph_cache.get (glyph);+ gc = glyph_cache.get (unichar_code);+ return gc;+ }++ /** Get glyph by unichar code. */ + public Glyph? get_glyph (string glyph) {+ GlyphCollection? gc = get_glyph_collection (glyph); if (gc == null) {- gc = unassigned_glyphs.get (glyph);+ return null; } - return gc;+ return ((!)gc).get_current (); } - public Glyph? get_glyph (string glyph) {- GlyphCollection? gc = get_glyph_collection (glyph);+ public Glyph? get_glyph_by_name (string name) {+ GlyphCollection? gc = null;+ gc = glyph_name.get (name); if (gc == null) { return null;@@ -401,14 +396,12 @@ public class Font : GLib.Object { public Glyph? get_glyph_indice (unichar glyph_indice) { GlyphCollection? gc;- string n; - if (!(0 <= glyph_indice < glyph_names.length ())) {+ if (!(0 <= glyph_indice < glyph_name.length ())) { return null; } - n = glyph_names.nth (glyph_indice).data;- gc = get_glyph_collection (n);+ gc = glyph_name.nth (glyph_indice); if (gc != null) { return ((!) gc).get_current ();@@ -752,11 +745,11 @@ public class Font : GLib.Object { } public uint length () {- return glyph_names.length ();+ return glyph_name.length (); } public bool is_empty () {- return (glyph_names.length () == 0);+ return (glyph_name.length () == 0); } public bool load (string path, bool recent = true) {@@ -770,12 +763,8 @@ public class Font : GLib.Object { grid_width.remove_link (grid_width.first ()); } - while (glyph_names.length () > 0) {- glyph_names.remove_link (glyph_names.first ());- }- glyph_cache.remove_all ();- unassigned_glyphs.remove_all ();+ glyph_name.remove_all (); if (path.has_suffix (".svg")) { font_file = path;@@ -893,13 +882,7 @@ public class Font : GLib.Object { public bool parse_otf_file (string path) throws GLib.Error { otf = new OpenFontFormatReader (); otf_font = true;- otf.parse_index (path);- - foreach (string n in otf.get_all_names ()) {- glyph_names.append (n);- }- return true; } @@ -915,7 +898,7 @@ public class Font : GLib.Object { // empty cache and fill it with new glyphs from disk glyph_cache.remove_all ();- unassigned_glyphs.remove_all ();+ glyph_name.remove_all (); while (background_images.length () > 0) { background_images.remove_link (background_images.first ());@@ -1371,7 +1354,7 @@ public class Font : GLib.Object { if (attr_name == "left_type" && attr_content == "cubic") { type_left = PointType.CURVE; }- + if (attr_name == "right_angle") angle_right = double.parse (attr_content); if (attr_name == "right_length") length_right = double.parse (attr_content); if (attr_name == "left_angle") angle_left = double.parse (attr_content);@@ -1379,6 +1362,15 @@ public class Font : GLib.Object { if (attr_name == "tie_handles") tie_handles = bool.parse (attr_content); }+ + // backward compabtility+ if (type_right == PointType.LINE && length_right != 0) {+ type_right = PointType.CURVE;+ }++ if (type_left == PointType.LINE && length_left != 0) {+ type_left = PointType.CURVE;+ } ep = new EditPoint (x, y); @@ -44,6 +44,12 @@ public class GlyphCollection : GLib.Object { return versions.glyphs.length (); } + public string get_unicode () {+ StringBuilder unicode = new StringBuilder ();+ unicode.append_unichar (get_current ().unichar_code);+ return unicode.str;+ }+ public string get_name () { return get_current ().get_name (); }@@ -32,6 +32,7 @@ class GlyphTable : GLib.Object { while (data.length () > 0) { data.remove_link (data.first ()); }+ build_index (); } public void @for_each (Func<GlyphCollection> func) {@@ -50,6 +51,10 @@ class GlyphTable : GLib.Object { }); } + public bool has_key (string n) {+ return find (n) != null;+ }+ unowned List<Item>? find (string n) { return find_index (n); }@@ -84,23 +89,34 @@ class GlyphTable : GLib.Object { return ((!) d).data.glyph_collection; } - public bool insert (GlyphCollection g) {+ public new GlyphCollection? nth (uint index) {+ unowned List<Item>? d = data.nth (index);+ + if (d == null) {+ return null;+ }+ + return ((!) d).data.glyph_collection;+ }++ public bool insert (string key, GlyphCollection g) { Item item; unowned List<Item>? next; - if (g.get_name () == "") {- warning (@"No proper name for glyph collection. g.get_name (): \"$(g.get_name ())\"");+ if (key == "") {+ warning (@"No proper name key for glyph. \"$(g.get_name ())\""); return false; } - if (find (g.get_name ()) != null) {- warning (@"Table does already contain character \"$(g.get_name ())\".");+ if (find (key) != null) {+ warning (@"Table does already contains a glyph for key \"$key\".");+ stderr.printf ("char: %u\n", (uint) key.get_char (0)); return false; } - next = find_next (g.get_name ());+ next = find_next (key); - item = new Item (g.get_name (), g);+ item = new Item (key, g); if (next == null) { data.append (item);@@ -110,8 +126,9 @@ class GlyphTable : GLib.Object { build_index (); - if (find (g.get_name ()) == null) {- warning (@"Can not find glyph \"$(g.get_name ())\".");+ if (find (key) == null) {+ warning (@"Can not find glyph \"$(key)\".");+ validate_index (); print_all (); return false; }@@ -121,8 +138,10 @@ class GlyphTable : GLib.Object { public void print_all () { int indice = 0;+ + print ("Data:\n"); foreach (Item i in data) {- print (@"$(i.name) indice: $(indice)\n");+ print (@"key: $(i.name) indice: $(indice)\n"); indice++; } @@ -147,7 +166,7 @@ class GlyphTable : GLib.Object { } static int compare (string an, Item b) {- string? bt = b.glyph_collection.get_name ();+ string? bt = b.name; string bn = (!) bt; uint32 ac = 0;@@ -268,7 +287,7 @@ class GlyphTable : GLib.Object { if (((!)next) != data.first () && compare (n, ((!)next).prev.data) == 0) { return ((!)next).prev; // fetch previous since we are searching for the next one }- + return null; } @@ -306,6 +325,7 @@ class GlyphTable : GLib.Object { while (true) { cmp = compare (n, r.data.item.data);+ if (cmp == -1) { break; }@@ -322,6 +342,7 @@ class GlyphTable : GLib.Object { while (true) { cmp = compare (n, r.data.item.data);+ if (cmp == 1) { break; }@@ -122,10 +122,6 @@ class OpenFontFormatReader : Object { public double get_descender () { return directory_table.hhea_table.get_descender (); }-- public unowned List<string> get_all_names () {- return directory_table.post_table.get_all_names ();- } public uint32 get_head_checksum () { return directory_table.head_table.get_adjusted_checksum ();@@ -1351,7 +1351,7 @@ class GlyfTable : Table { uint glyph_header = 12 + ncontours * 2; - printd (@"\next glyf: $(g.name)\n"); + printd (@"next glyf: $(g.name) ($((uint32)g.unichar_code))\n"); printd (@"glyf header length: $(glyph_header)\n"); // instructions should go here @@ -1568,6 +1568,7 @@ class GlyfTable : Table { } foreach (Glyph ug in unassigned_glyphs) { + // FIXME: ligatures // glyphs.append (ug); } @@ -2842,12 +2843,8 @@ class PostTable : Table { id = "post"; glyf_table = g; } - - public unowned List<string> get_all_names () { - return available_names; - } - public int get_gid (string name) { // fixa do fast lookup + public int get_gid (string name) { // FIXME: do fast lookup int i = 0; int j = 0; foreach (string n in names) { @@ -2864,8 +2861,6 @@ class PostTable : Table { } i++; } - - // warn_if_reached (); return -1; } @@ -4733,7 +4728,7 @@ internal static uint16 largest_pow2_exponent (uint16 max) { } void printd (string s) { - //print (s); + // print (s); } } @@ -375,7 +375,7 @@ public class OverView : FontDisplay { } private bool draw_thumbnail (Context cr, string name, double x, double y) {- Glyph? gl = BirdFont.get_current_font ().get_glyph (name);+ Glyph? gl = BirdFont.get_current_font ().get_glyph_by_name (name); Glyph g; double gx, gy;@@ -814,9 +814,9 @@ public class OverView : FontDisplay { if (gc != null) { deleted_glyphs.append ((!) gc);+ f.delete_glyph ((!) gc); }-- f.delete_glyph (g);+ MainWindow.get_tab_bar ().close_by_name (g); set_glyph_range (glyph_range); f.touch ();@@ -220,7 +220,10 @@ class SvgFont : GLib.Object { if (attr_name == "unicode") { unicode_value = get_unichar (attr_content);- glyph_name = attr_content;+ + if (glyph_name == "") {+ glyph_name = attr_content;+ } } // svg data@@ -229,10 +232,7 @@ class SvgFont : GLib.Object { } if (attr_name == "glyph-name") {- // use glyph value as name until ligatures is properly implemented- if (glyph_name == "") {- glyph_name = attr_content;- }+ glyph_name = attr_content; } if (attr_name == "horiz-adv-x") {@@ -706,13 +706,20 @@ class TestCases { gc.append (new GlyphCollection (new Glyph (@"TEST $i", i + 'a'))); } + g = gc.first ().data;+ if (!table.insert (g.get_unicode (), g)) {+ warning (@"Failed to insert $(g.get_name ())");+ return;+ }+ gc.append (g);+ // insert in random order gc_copy = gc.copy (); for (uint i = 0; gc_copy.length () > 0; i++) { int t = (int) ((gc_copy.length () - 1) * Random.next_double ()); g = gc_copy.nth (t).data; - if (!table.insert (g)) {+ if (!table.insert (g.get_name (), g)) { warning (@"Failed to insert $(g.get_name ())"); return; }@@ -726,7 +733,10 @@ class TestCases { } } - return_if_fail (table.length () == gc.length ());+ if (table.length () != gc.length ()) {+ warning ("Table length does not match number of glyphs, $(table.length ()) != $(gc.length ())");+ return;+ } // validate table for (uint i = 0; i > 1000; i++) {@@ -743,7 +753,7 @@ class TestCases { return; } }-+ // remove table.remove ("TEST 0"); table.remove ("TEST 53");