Commit 34aa2c1
Reorganize unassigned glyphs
Changed files (25)
modifiedbirdfont-autotrace/AutoTrace.valamodifiedbirdfont/GtkWindow.valamodifiedlibbirdfont/BirdFont.valamodifiedlibbirdfont/BirdFontFile.valamodifiedlibbirdfont/ClipTool.valamodifiedlibbirdfont/Font.valamodifiedlibbirdfont/Glyph.valamodifiedlibbirdfont/GlyphCanvas.valamodifiedlibbirdfont/GlyphCollection.valamodifiedlibbirdfont/MainWindow.valamodifiedlibbirdfont/MenuTab.valamodifiedlibbirdfont/OpenFontFormat/CmapSubtableFormat0.valamodifiedlibbirdfont/OpenFontFormat/CmapSubtableFormat12.valamodifiedlibbirdfont/OpenFontFormat/CmapSubtableFormat4.valamodifiedlibbirdfont/OpenFontFormat/CodePageBits.valamodifiedlibbirdfont/OpenFontFormat/GlyfTable.valamodifiedlibbirdfont/OpenFontFormat/HmtxTable.valamodifiedlibbirdfont/OpenFontFormat/PostTable.valamodifiedlibbirdfont/OpenFontFormat/UnicodeRangeBits.valamodifiedlibbirdfont/OverView.valamodifiedlibbirdfont/Tab.valamodifiedlibbirdfont/TabBar.valamodifiedlibbirdfont/TabContent.valamodifiedlibbirdfont/TestCases.valamodifiedlibbirdfont/VersionList.vala
Diff
@@ -124,7 +124,7 @@ class AutoTrace { g = new Glyph.no_lines (""); GlyphCanvas.current_display = g;- BirdFont.current_glyph = g;+ BirdFont.current_glyph_collection = new GlyphCollection.with_glyph ('\0', ""); h = bg.get_img ().get_height (); @@ -104,7 +104,6 @@ public class GtkWindow : Gtk.Window, NativeWindow { string uri = ""; string html = ""; FontDisplay fd = tab.get_display ();- MainWindow.glyph_canvas.set_current_glyph (fd); scrollbar.set_visible (fd.has_scrollbar ()); @@ -36,7 +36,7 @@ public static int run_import (string[] arg) { Preferences.load (); BirdFont.args = new Argument (""); BirdFont.current_font = new Font ();- BirdFont.current_glyph = new Glyph ("");+ BirdFont.current_glyph_collection = new GlyphCollection.with_glyph ('\0', ""); MainWindow.init (); if (arg.length < 3) {@@ -150,7 +150,7 @@ static bool import_svg_file (Font font, File svg_file) { } canvas = MainWindow.get_glyph_canvas ();- canvas.set_current_glyph (glyph);+ canvas.set_current_glyph_collection (glyph_collection); stdout.printf (t_("Adding")); stdout.printf (" ");@@ -210,7 +210,7 @@ public static int run_export (string[] arg) { } BirdFont.current_font = BirdFont.new_font ();- BirdFont.current_glyph = new Glyph ("null", '\0');+ BirdFont.current_glyph_collection = new GlyphCollection.with_glyph ( '\0', "null"); main_window = new MainWindow (); // FIXME: create a option for this and structure the log messages@@ -271,7 +271,7 @@ public static int run_export (string[] arg) { Preferences.load (); BirdFont.args = new Argument ("");- BirdFont.current_glyph = new Glyph ("");+ BirdFont.current_glyph_collection = new GlyphCollection.with_glyph ('\0', ""); file_name = build_absoulute_path (file_name); @@ -364,7 +364,7 @@ public class BirdFont { public static DataOutputStream? logstream = null; public static Font current_font;- public static Glyph current_glyph;+ public static GlyphCollection current_glyph_collection; public BirdFont () { }@@ -422,7 +422,7 @@ public class BirdFont { current_font = new Font (); current_font.set_name (""); current_font.initialised = false;- current_glyph = new Glyph ("");+ current_glyph_collection = new GlyphCollection.with_glyph ('\0', ""); experimental = args.has_argument ("--test"); show_coordinates = args.has_argument ("--show-coordinates") || experimental;@@ -313,7 +313,7 @@ class BirdFontFile : GLib.Object { public void write_glyph_collection_start (GlyphCollection gc, DataOutputStream os) throws GLib.Error { os.put_string ("<collection "); - if (gc.get_current ().is_unassigned ()) {+ if (gc.is_unassigned ()) { os.put_string (@"name=\"$(gc.get_current ().get_name ())\""); } else { os.put_string (@"unicode=\"$(Font.to_hex (gc.get_current ().unichar_code))\"");@@ -1044,7 +1044,7 @@ class BirdFontFile : GLib.Object { } glyph.version_id = (has_id) ? id : (int) gc.length () + 1;- glyph.set_unassigned (unassigned);+ gc.set_unassigned (unassigned); gc.insert_glyph (glyph, selected || selected_id == id); } @@ -153,6 +153,7 @@ public class ClipTool : Tool { Gee.ArrayList<Path> paths = new Gee.ArrayList<Path> (); Path new_path; Glyph glyph;+ GlyphCollection glyph_collection; OverView o; if (overview) {@@ -176,6 +177,10 @@ public class ClipTool : Tool { s.append ("\n"); } + s.append ("BF name: ");+ s.append (@"$(gc.get_name ())");+ s.append ("\n"); + s.append ("BF unassigned: "); s.append (@"$(gc.is_unassigned ())"); s.append ("\n");@@ -198,6 +203,7 @@ public class ClipTool : Tool { } } else { glyph = MainWindow.get_current_glyph ();+ glyph_collection = MainWindow.get_current_glyph_collection (); s.append ("\n"); s.append ("<!-- BirdFontClipboard\n");@@ -205,9 +211,13 @@ public class ClipTool : Tool { s.append ("BF glyph: "); s.append (@"$(Font.to_hex (glyph.unichar_code))"); s.append ("\n");++ s.append ("BF name: ");+ s.append (@"$(glyph_collection.get_name ())");+ s.append ("\n"); s.append ("BF unassigned: ");- s.append (@"$(glyph.is_unassigned ())");+ s.append (@"$(glyph_collection.is_unassigned ())"); s.append ("\n"); s.append ("BF left: ");@@ -288,12 +298,12 @@ public class ClipTool : Tool { } static void import_birdfont_clipboard (string data, bool paste_guide_lines, bool overview) {- Gee.ArrayList<Glyph> glyphs = new Gee.ArrayList<Glyph> ();+ Gee.ArrayList<GlyphCollection> glyphs = new Gee.ArrayList<GlyphCollection> (); Glyph glyph = new Glyph ("null", '\0'); string[] items = data.split ("\nBF "); unichar c; Glyph destination;- GlyphCollection gc;+ GlyphCollection glyph_collection = new GlyphCollection ('\0', ""); OverView o; foreach (string p in items) {@@ -301,16 +311,26 @@ public class ClipTool : Tool { p = p.replace ("glyph: ", ""); p = p.replace ("\n", ""); c = Font.to_unichar (p);+ glyph_collection = new GlyphCollection (c, (!) c.to_string ());+ glyphs.add (glyph_collection);+ glyph = new Glyph ((!) c.to_string (), c);- glyphs.add (glyph);+ glyph_collection.add_glyph (glyph); } if (p.has_prefix ("unassigned:")) { p = p.replace ("unassigned: ", ""); p = p.replace ("\n", "");- glyph.set_unassigned (bool.parse (p)); // FIXME: move to gc+ glyph_collection.set_unassigned (bool.parse (p)); }- ++ if (p.has_prefix ("name:")) {+ p = p.replace ("name: ", "");+ p = p.replace ("\n", "");+ glyph_collection.set_name (p);+ glyph.name = p;+ }+ if (p.has_prefix ("path:")) { p = p.replace ("path: ", ""); p = p.replace ("\n", "");@@ -333,7 +353,7 @@ public class ClipTool : Tool { if (!overview) { return_if_fail (glyphs.size > 0); destination = MainWindow.get_current_glyph ();- glyph = glyphs.get (0);+ glyph = glyphs.get (0).get_current (); foreach (Path p in glyph.path_list) { destination.add_path (p);@@ -349,9 +369,7 @@ public class ClipTool : Tool { } else { o = MainWindow.get_overview (); o.copied_glyphs.clear ();- foreach (Glyph g in glyphs) { - gc = new GlyphCollection (g.unichar_code, g.name);- gc.add_glyph (g);+ foreach (GlyphCollection gc in glyphs) { o.copied_glyphs.add (gc); } o.paste ();@@ -267,79 +267,94 @@ public class Font : GLib.Object { return get_glyph (n) != null; } - public Glyph get_nonmarking_return () {- Glyph ret;+ public GlyphCollection get_nonmarking_return () {+ Glyph g;+ GlyphCollection gc; if (has_glyph ("nonmarkingreturn")) {- return (!) get_glyph ("nonmarkingreturn");+ return (!) get_glyph_collection ("nonmarkingreturn"); }- - ret = new Glyph ("nonmarkingreturn", '\r');- ret.set_unassigned (false);- ret.left_limit = 0;- ret.right_limit = 0;- ret.remove_empty_paths (); - assert (ret.path_list.size == 0);+ gc = new GlyphCollection ('\r', "nonmarkingreturn");+ + g = new Glyph ("nonmarkingreturn", '\r');+ g.left_limit = 0;+ g.right_limit = 0;+ g.remove_empty_paths ();+ + gc.set_unassigned (false);+ gc.add_glyph (g); - return ret;+ return gc; } - public Glyph get_null_character () {+ public GlyphCollection get_null_character () { Glyph n;+ GlyphCollection gc; if (has_glyph ("null")) {- return (!) get_glyph ("null");+ return (!) get_glyph_collection ("null"); } + gc = new GlyphCollection ('\0', "null"); n = new Glyph ("null", '\0');- n.set_unassigned (false);+ + gc.add_glyph (n);+ gc.set_unassigned (false);+ n.left_limit = 0; n.right_limit = 0; n.remove_empty_paths (); assert (n.path_list.size == 0); - return n;+ return gc; } - public Glyph get_space () {+ public GlyphCollection get_space () { Glyph n;+ GlyphCollection gc; if (has_glyph (" ")) {- return (!) get_glyph (" ");+ return (!) get_glyph_collection (" "); } if (has_glyph ("space")) {- return (!) get_glyph ("space");+ return (!) get_glyph_collection ("space"); }- + + gc = new GlyphCollection (' ', "space");+ n = new Glyph ("space", ' ');- n.set_unassigned (false); n.left_limit = 0; n.right_limit = 27; n.remove_empty_paths (); - assert (n.path_list.size == 0);+ gc.add_glyph (n);+ gc.set_unassigned (false); - return n; + return gc; } - public Glyph get_not_def_character () {+ public GlyphCollection get_not_def_character () { Glyph g;+ GlyphCollection gc; Path p; Path i; if (has_glyph (".notdef")) {- return (!) get_glyph (".notdef");+ return (!) get_glyph_collection (".notdef"); } + gc = new GlyphCollection ('\0', ".notdef"); g = new Glyph (".notdef", 0); p = new Path (); i = new Path (); - g.set_unassigned (true);+ gc.set_unassigned (true);+ gc.add_glyph (g);+ g.left_limit = -33; g.right_limit = 33; @@ -359,7 +374,7 @@ public class Font : GLib.Object { g.add_path (i); g.add_path (p); - return g;+ return gc; } public void add_glyph_collection (GlyphCollection glyph_collection) {@@ -377,7 +392,7 @@ public class Font : GLib.Object { } // FIXME: move unassinged- if (glyph_collection.get_unicode () != "" || glyph_collection.get_current ().is_unassigned ()) {+ if (glyph_collection.get_unicode () != "" || glyph_collection.is_unassigned ()) { glyph_name.insert (glyph_collection.get_name (), glyph_collection); } @@ -64,7 +64,6 @@ public class Glyph : FontDisplay { public WidgetAllocation allocation = new WidgetAllocation (); - bool unassigned = false; public unichar unichar_code = 0; // FIXME: name and unichar should be moved to to glyph collection public string name; @@ -210,16 +209,6 @@ public class Glyph : FontDisplay { return active_paths.get (active_paths.size - 1); } - // It looks like this can be remove but firefox refuses to load- // the generated font if it is removed. See the revert 6bbf and a76d.- public void set_unassigned (bool u) {- unassigned = u;- }- - public bool is_unassigned () {- return unassigned;- }- public void boundaries (out double x1, out double y1, out double x2, out double y2) { if (path_list.size == 0) { x1 = 0;@@ -1845,7 +1834,7 @@ public class Glyph : FontDisplay { for (int i = pos + 1; i < glyph_sequence.char_count (); i++) { c = glyph_sequence.get_char (i); name = font.get_name_for_character (c); - juxtaposed = (font.has_glyph (name)) ? (!) font.get_glyph (name) : font.get_space ();+ juxtaposed = (font.has_glyph (name)) ? (!) font.get_glyph (name) : font.get_space ().get_current (); if (font.has_glyph (last_name) && font.has_glyph (name)) { kern = KerningClasses.get_instance ().get_kerning (last_name, name);@@ -1878,7 +1867,7 @@ public class Glyph : FontDisplay { for (int i = pos - 1; i >= 0; i--) { c = glyph_sequence.get_char (i); name = font.get_name_for_character (c); - juxtaposed = (font.has_glyph (name)) ? (!) font.get_glyph (name) : font.get_space ();+ juxtaposed = (font.has_glyph (name)) ? (!) font.get_glyph (name) : font.get_space ().get_current (); if (font.has_glyph (last_name) && font.has_glyph (name)) { kern = KerningClasses.get_instance ().get_kerning (name, last_name);@@ -51,19 +51,19 @@ public class GlyphCanvas : GLib.Object { } } - public void set_current_glyph (FontDisplay fd) { - if (fd is Glyph) { - Glyph g = (Glyph) fd; - - BirdFont.current_glyph = g; - BirdFont.current_glyph.resized (allocation); - } - + internal static void set_display (FontDisplay fd) { current_display = fd; + } + + public void set_current_glyph_collection (GlyphCollection gc) { + Glyph g = gc.get_current (); + + BirdFont.current_glyph_collection = gc; + g.resized (allocation); - fd.selected_canvas (); + current_display.selected_canvas (); - fd.redraw_area.connect ((x, y, w, h) => { + current_display.redraw_area.connect ((x, y, w, h) => { signal_redraw_area ((int)x, (int)y, (int)w, (int)h); }); @@ -75,7 +75,7 @@ public class GlyphCanvas : GLib.Object { } public static Glyph get_current_glyph () { - return BirdFont.current_glyph; + return MainWindow.get_current_glyph (); } public FontDisplay get_current_display () { @@ -29,6 +29,16 @@ public class GlyphCollection : GLib.Object { versions = new VersionList (null, this); } + public GlyphCollection.with_glyph (unichar unicode_character, string name) {+ Glyph g;+ + this.unicode_character = unicode_character;+ this.name = name;+ + g = new Glyph (name, unicode_character);+ versions = new VersionList (g, this);+ }+ public void set_unassigned (bool a) { unassigned = a; }@@ -76,6 +86,10 @@ public class GlyphCollection : GLib.Object { return name; } + public void set_name (string n) {+ name = n;+ }+ public int get_selected_id () { return versions.get_current ().version_id; }@@ -98,14 +98,23 @@ public class MainWindow : GLib.Object { public static GlyphCanvas get_glyph_canvas () { return glyph_canvas; } - - public static Glyph get_current_glyph () { - if (unlikely (is_null (BirdFont.current_glyph))) { + + public static GlyphCollection get_current_glyph_collection () { + if (unlikely (is_null (BirdFont.current_glyph_collection))) { + GlyphCollection gc; + warning ("No default glyph have been set yet.\n"); - return new Glyph ("no_glyph_created"); + gc = new GlyphCollection ('\0', ""); + gc.add_glyph (new Glyph ("", '\0')); + + return gc; } - return BirdFont.current_glyph; + return BirdFont.current_glyph_collection; + } + + public static Glyph get_current_glyph () { + return get_current_glyph_collection ().get_current (); } public static Toolbox get_toolbox () { @@ -477,7 +477,7 @@ public class MenuTab : FontDisplay { glyph_collection = new GlyphCollection ('\0', ligature_name); glyph = new Glyph (ligature_name, '\0');- glyph.set_unassigned (true);+ glyph_collection.set_unassigned (true); glyph_collection.insert_glyph (glyph, true); font.add_glyph_collection (glyph_collection);@@ -36,8 +36,8 @@ public class CmapSubtableFormat0 : GLib.Object { uint8 get_gid_for_unichar (unichar c, GlyfTable glyf_table) { uint32 indice = 0;- foreach (Glyph g in glyf_table.glyphs) {- if (g.unichar_code == c) {+ foreach (GlyphCollection g in glyf_table.glyphs) {+ if (g.get_unicode_character () == c) { return (indice <= uint8.MAX) ? (uint8) indice : 0; } indice++;@@ -27,9 +27,9 @@ public class CmapSubtableFormat12 : GLib.Object { uint32 first_assigned = 1; uint32 indice; - foreach (Glyph g in glyf_table.glyphs) {- if (!g.is_unassigned () && g.unichar_code < 0xFFFFFFFF) {- glyph_range.add_single (g.unichar_code);+ foreach (GlyphCollection g in glyf_table.glyphs) {+ if (!g.is_unassigned () && g.get_unicode_character () < 0xFFFFFFFF) {+ glyph_range.add_single (g.get_unicode_character ()); } } @@ -190,9 +190,9 @@ public class CmapSubtableFormat4 : GLib.Object { uint32 indice; uint32 first_assigned = 1; - foreach (Glyph g in glyf_table.glyphs) {- if (!g.is_unassigned () && g.unichar_code < 0xFFFF) {- glyph_range.add_single (g.unichar_code);+ foreach (GlyphCollection g in glyf_table.glyphs) {+ if (!g.is_unassigned () && g.get_unicode_character () < 0xFFFF) {+ glyph_range.add_single (g.get_unicode_character ()); } } @@ -34,16 +34,16 @@ public class CodePageBits : GLib.Object { public void get_pages (Font font, out uint32 p0, out uint32 p1) { uint32 indice;- Glyph? gl;- Glyph g;+ GlyphCollection? gl;+ GlyphCollection g; p0 = 0; p1 = 0; - for (indice = 0; (gl = font.get_glyph_indice (indice)) != null; indice++) { + for (indice = 0; (gl = font.get_glyph_collection_indice (indice)) != null; indice++) { g = (!) gl; - if (default_range.has_char (g.get_unichar ())) {+ if (default_range.has_char (g.get_unicode_character ())) { set_bit (0, ref p0, ref p1); } else { set_bits_for_glyph (g, ref p0, ref p1);@@ -51,11 +51,11 @@ public class CodePageBits : GLib.Object { } } - void set_bits_for_glyph (Glyph g, ref uint32 p0, ref uint32 p1) {+ void set_bits_for_glyph (GlyphCollection g, ref uint32 p0, ref uint32 p1) { Gee.ArrayList<int> bits; if (!g.is_unassigned ()) {- bits = get_bits (g.get_unichar ());+ bits = get_bits (g.get_unicode_character ()); foreach (int bit in bits) { set_bit (bit, ref p0, ref p1);@@ -45,7 +45,7 @@ public class GlyfTable : Table { // ttf font. notdef is the firs glyph followed by null and nonmarkingreturn. // after that will all assigned glyphs appear in sorted (unicode) order, all // remaining unassigned glyphs will be added in the last section of the file. - public Gee.ArrayList<Glyph> glyphs;+ public Gee.ArrayList<GlyphCollection> glyphs; uint16 max_points = 0; uint16 max_contours = 0;@@ -54,14 +54,14 @@ public class GlyfTable : Table { id = "glyf"; loca_table = l; location_offsets = new Gee.ArrayList<uint32> ();- glyphs = new Gee.ArrayList<Glyph> ();+ glyphs = new Gee.ArrayList<GlyphCollection> (); } public int get_gid (string name) { int i = 0; - foreach (Glyph g in glyphs) {- if (g.name == name) {+ foreach (GlyphCollection g in glyphs) {+ if (g.get_name () == name) { return i; } i++;@@ -85,23 +85,24 @@ public class GlyfTable : Table { public uint16 get_last_char () requires (glyphs.size > 0) {- Glyph g = glyphs.get (glyphs.size - 1);+ GlyphCollection gc = glyphs.get (glyphs.size - 1); for (int i = glyphs.size - 1; i >= 0; i--) {- g = glyphs.get (i);+ gc = glyphs.get (i); - if (!g.is_unassigned ()) {+ if (!gc.is_unassigned ()) { break; } } - return (uint16) g.unichar_code; + return (uint16) gc.get_unicode_character (); } public void process () throws GLib.Error { FontData fd = new FontData (); uint last_len = 0; uint num_glyphs;+ Glyph g; create_glyph_table (); @@ -111,7 +112,8 @@ public class GlyfTable : Table { warning ("No glyphs in glyf table."); } - foreach (Glyph g in glyphs) {+ foreach (GlyphCollection gc in glyphs) {+ g = gc.get_current (); // set values for loca table assert (fd.length () % 4 == 0); location_offsets.add (fd.length ());@@ -134,13 +136,14 @@ public class GlyfTable : Table { // necessary in order to have glyphs sorted according to ttf specification public void create_glyph_table () {- Glyph? gl; Glyph g;+ GlyphCollection gc;+ GlyphCollection? gcn; Font font = OpenFontFormatWriter.get_current_font (); uint32 indice; Gee.ArrayList<Glyph> unassigned_glyphs; - // add notdef. character at index zero + other special chars first+ // add notdef character and other special chars first glyphs.add (font.get_not_def_character ()); glyphs.add (font.get_null_character ()); glyphs.add (font.get_nonmarking_return ());@@ -153,8 +156,9 @@ public class GlyfTable : Table { } // add glyphs, first all assigned then the unassigned ones- for (indice = 0; (gl = font.get_glyph_indice (indice)) != null; indice++) { - g = ((!) gl).copy ();+ for (indice = 0; (gcn = font.get_glyph_collection_indice (indice)) != null; indice++) { + gc = (!) gcn;+ g = gc.get_current ().copy (); if (g.unichar_code <= 27) { // skip control characters continue;@@ -170,8 +174,8 @@ public class GlyfTable : Table { g.remove_empty_paths (); - if (!g.is_unassigned ()) {- glyphs.add (g);+ if (!gc.is_unassigned ()) {+ glyphs.add (gc); } else { printd ("Adding unassigned glyph."); unassigned_glyphs.add (g);@@ -337,7 +341,10 @@ public class GlyfTable : Table { } Glyph parse_index (int index, FontData dis, LocaTable loca, HmtxTable hmtx_table, HeadTable head_table, PostTable post_table) throws GLib.Error {++// FIXME: DELETE done by freetype Glyph glyph = new Glyph ("");+/* double xmin, xmax; double units_per_em = head_table.get_units_per_em (); unichar character = 0;@@ -379,7 +386,7 @@ public class GlyfTable : Table { stderr.printf (@"char: $((uint) character)\n"); stderr.printf (@"name: $(name)\n"); }- +*/ return glyph; } @@ -110,6 +110,8 @@ public class HmtxTable : Table { double xmax; double ymax; + Glyph g;+ if (advance_width != null) { warning ("advance_width is set"); delete advance_width;@@ -118,7 +120,8 @@ public class HmtxTable : Table { // advance and lsb nmetrics = 0;- foreach (Glyph g in glyf_table.glyphs) {+ foreach (GlyphCollection gc in glyf_table.glyphs) {+ g = gc.get_current (); g.boundaries (out xmin, out ymin, out xmax, out ymax); xmax = Math.rint (xmax * HeadTable.UNITS);@@ -1186,6 +1186,7 @@ public class PostTable : Table { FontData fd = new FontData (); string n; int name_index;+ GlyphCollection gc; Glyph g; fd.add_fixed (0x00020000); // Version@@ -1214,7 +1215,8 @@ public class PostTable : Table { add_standard_names (); for (int i = 1; i < glyf_table.glyphs.size; i++) {- g = glyf_table.glyphs.get (i);+ gc = glyf_table.glyphs.get (i);+ g = gc.get_current (); name_index = get_standard_index (g.unichar_code); if (name_index != 0) {@@ -24,8 +24,8 @@ public class UnicodeRangeBits : GLib.Object { public void get_ranges (Font font, out uint32 r0, out uint32 r1, out uint32 r2, out uint32 r3) { uint32 indice;- Glyph? gl;- Glyph g;+ GlyphCollection? gl;+ GlyphCollection g; int bit; r0 = 0;@@ -33,10 +33,10 @@ public class UnicodeRangeBits : GLib.Object { r2 = 0; r3 = 0; - for (indice = 0; (gl = font.get_glyph_indice (indice)) != null; indice++) { + for (indice = 0; (gl = font.get_glyph_collection_indice (indice)) != null; indice++) { g = (!) gl; if (!g.is_unassigned ()) {- bit = get_bit (g.get_unichar ());+ bit = get_bit (g.get_unicode_character ()); if (likely (bit >= 0)) { set_bit (bit, ref r0, ref r1, ref r2, ref r3); } else {@@ -72,8 +72,8 @@ public class OverView : FontDisplay { if (!selected) { canvas = MainWindow.get_glyph_canvas ();- tabs.add_tab (g);- canvas.set_current_glyph (g);+ tabs.add_tab (g, true, glyph_collection);+ canvas.set_current_glyph_collection (glyph_collection); set_initial_zoom (); } });@@ -93,12 +93,12 @@ public class OverView : FontDisplay { glyph_collection = add_character_to_font (character); glyph = glyph_collection.get_current ();- tabs.add_tab (glyph);+ tabs.add_tab (glyph, true, glyph_collection); selected_items.add (glyph_collection); canvas = MainWindow.get_glyph_canvas ();- canvas.set_current_glyph (glyph_collection.get_current ());+ canvas.set_current_glyph_collection (glyph_collection); set_initial_zoom (); }@@ -18,20 +18,30 @@ public class Tab : GLib.Object { bool always_open; double width; - FontDisplay display; string label;+ FontDisplay display;+ GlyphCollection glyph_collection; public Tab (FontDisplay glyph, double tab_width, bool always_open) { width = tab_width; display = glyph; this.always_open = always_open; label = display.get_label ();+ glyph_collection = new GlyphCollection.with_glyph ('\0', ""); } public bool has_close_button () { return !always_open; } + public GlyphCollection get_glyph_collection () {+ return glyph_collection;+ }++ public void set_glyph_collection (GlyphCollection gc) {+ glyph_collection = gc;+ }+ public void set_display (FontDisplay fd) { display = fd; }@@ -255,6 +255,7 @@ public class TabBar : GLib.Object { Tab t; EmptyTab empty_tab_canvas; Tab empty_tab;+ GlyphCollection gc; if (MenuTab.suppress_event) { warn_if_test ("Event suppressed");@@ -267,7 +268,8 @@ public class TabBar : GLib.Object { if (tabs.size == 1) { empty_tab_canvas = new EmptyTab ("", "");- MainWindow.get_glyph_canvas ().set_current_glyph (empty_tab_canvas);+ gc = new GlyphCollection.with_glyph('\0', "");+ MainWindow.get_glyph_canvas ().set_current_glyph_collection (gc); empty_tab = new Tab (empty_tab_canvas, 0, false); signal_tab_selected (empty_tab); }@@ -470,6 +472,12 @@ public class TabBar : GLib.Object { Tab t; t = tabs.get (index);+ + GlyphCanvas.set_display (t.get_display ());+ + MainWindow.get_glyph_canvas ()+ .set_current_glyph_collection (t.get_glyph_collection ());+ signal_tab_selected (t); } @@ -536,10 +544,11 @@ public class TabBar : GLib.Object { } } - public void add_tab (FontDisplay display_item, bool signal_selected = true) {+ public void add_tab (FontDisplay display_item, bool signal_selected = true, GlyphCollection? gc = null) { double tab_width = -1; bool always_open = false; int s = (tabs.size == 0) ? 0 : selected + 1;+ Tab t; if (MenuTab.suppress_event) { warn_if_test ("Event suppressed");@@ -550,8 +559,19 @@ public class TabBar : GLib.Object { tab_width = 9 * display_item.get_label ().char_count (); tab_width += 36; }+ + t = new Tab (display_item, tab_width, always_open);+ tabs.insert (s,t);+ + if (gc != null) {+ t.set_glyph_collection ((!) gc);+ }++ GlyphCanvas.set_display (t.get_display ());++ MainWindow.get_glyph_canvas ()+ .set_current_glyph_collection (t.get_glyph_collection ()); - tabs.insert (s, new Tab (display_item, tab_width, always_open)); select_tab (s, signal_selected); } @@ -67,7 +67,7 @@ public class TabContent : GLib.Object { cr.restore (); } else { GlyphCanvas.set_allocation (allocation);- BirdFont.current_glyph.resized (allocation);+ MainWindow.get_current_glyph ().resized (allocation); GlyphCanvas.current_display.draw (allocation, cr); } }@@ -31,7 +31,6 @@ class TestCases { add (test_drawing, "Pen tool"); add (test_delete_points, "Delete edit points"); add (test_convert_to_quadratic_bezier_path, "Convert to quadratic path");- add (test_notdef, "Notdef"); add (test_over_path, "Over path"); add (test_export, "Export"); add (test_background_coordinates, "Background coordinates");@@ -629,22 +628,6 @@ class TestCases { } - public static void test_notdef () {- Font f = BirdFont.get_current_font ();- Glyph n = f.get_not_def_character ();- Glyph g;- Path pn;- - test_open_next_glyph ();- g = MainWindow.get_current_glyph ();- foreach (Path p in n.path_list) {- pn = p.copy ().get_quadratic_points ();- g.path_list.add (pn);- pn.move (50, 0);- g.path_list.add (p.copy ());- }- }- public static void test_convert_to_quadratic_bezier_path () { Glyph g; Path p, p1;@@ -98,7 +98,7 @@ public class VersionList : DropMenu { } public Glyph get_current () {- Glyph gl;+ Glyph? gl = null; foreach (Glyph g in glyphs) { if (g.version_id == current_version_id) {@@ -106,15 +106,19 @@ public class VersionList : DropMenu { } } - warning (@"Can not find current glyph for id $current_version_id");- - if (glyphs.size > 0) {+ if (unlikely (glyphs.size > 0)) {+ warning (@"Can not find current glyph for id $current_version_id"); gl = glyphs.get (glyphs.size - 1);- set_selected_version (gl.version_id);- return gl;+ set_selected_version (((!) gl).version_id);+ return (!) gl;+ }+ + if (unlikely (glyphs.size == 0 && current_version_id == -1)) {+ warning (@"No glyphs added to collection");+ gl = new Glyph ("", '\0'); } - return new Glyph ("");+ return (!) gl; } public void add_new_version () {@@ -131,7 +135,7 @@ public class VersionList : DropMenu { private void set_selected_item (MenuAction ma) { int i = ma.index;- Glyph current_glyph = MainWindow.get_current_glyph ();+ Glyph current_glyph; Glyph g; return_if_fail (0 <= i < glyphs.size);@@ -145,9 +149,12 @@ public class VersionList : DropMenu { ma.set_selected (true); reload_all_open_glyphs ();-- g.set_allocation (current_glyph.allocation);- g.set_default_zoom ();+ + if (!is_null (BirdFont.current_glyph_collection)) {+ current_glyph = MainWindow.get_current_glyph ();+ g.set_allocation (current_glyph.allocation);+ g.set_default_zoom ();+ } } /** Reload a glyph when a new version is selected. Updates the path