Commit 12abed3
Move spacing data to font class
Changed files (18)
modifiedlibbirdfont/BirdFont.valamodifiedlibbirdfont/BirdFontFile.valamodifiedlibbirdfont/Font.valamodifiedlibbirdfont/Glyph.valamodifiedlibbirdfont/KerningClasses.valamodifiedlibbirdfont/KerningDisplay.valamodifiedlibbirdfont/KerningList.valamodifiedlibbirdfont/KerningRange.valamodifiedlibbirdfont/KerningTools.valamodifiedlibbirdfont/MenuTab.valamodifiedlibbirdfont/OpenFontFormat/GlyfData.valamodifiedlibbirdfont/OpenFontFormat/KernList.valamodifiedlibbirdfont/Renderer/TextArea.valamodifiedlibbirdfont/Renderer/TextTab.valamodifiedlibbirdfont/SpacingClassTab.valaaddedlibbirdfont/SpacingData.valamodifiedlibbirdfont/SvgFont.valamodifiedlibbirdfont/SvgFontFormatWriter.vala
Diff
@@ -529,7 +529,6 @@ public class BirdFont { MainWindow.get_drawing_tools ().add_new_grid (); } - SpacingClassTab.remove_all_spacing_classes (); KerningTools.update_kerning_classes (); return current_font;@@ -207,7 +207,7 @@ class BirdFontFile : GLib.Object { } public void write_spacing_classes (DataOutputStream os) throws GLib.Error {- SpacingClassTab s = MainWindow.get_spacing_class_tab ();+ SpacingData s = font.get_spacing (); foreach (SpacingClass sc in s.classes) { os.put_string ("<spacing ");@@ -226,29 +226,30 @@ class BirdFontFile : GLib.Object { public void write_kerning (DataOutputStream os) throws GLib.Error { uint num_kerning_pairs; string range;+ KerningClasses classes = font.get_kerning_classes (); - num_kerning_pairs = KerningClasses.get_instance ().classes_first.size;+ num_kerning_pairs = classes.classes_first.size; for (int i = 0; i < num_kerning_pairs; i++) {- range = KerningClasses.get_instance ().classes_first.get (i).get_all_ranges ();+ range = classes.classes_first.get (i).get_all_ranges (); os.put_string ("<kerning "); os.put_string ("left=\""); os.put_string (range); os.put_string ("\" "); - range = KerningClasses.get_instance ().classes_last.get (i).get_all_ranges ();+ range = classes.classes_last.get (i).get_all_ranges (); os.put_string ("right=\""); os.put_string (range); os.put_string ("\" "); os.put_string ("hadjustment=\"");- os.put_string (round (KerningClasses.get_instance ().classes_kerning.get (i).val));+ os.put_string (round (classes.classes_kerning.get (i).val)); os.put_string ("\" />\n"); } - KerningClasses.get_instance ().get_single_position_pairs ((l, r, k) => {+ classes.get_single_position_pairs ((l, r, k) => { try { os.put_string ("<kerning "); os.put_string ("left=\"");@@ -712,7 +713,7 @@ class BirdFontFile : GLib.Object { private void parse_spacing_class (Tag tag) { string first, next;- SpacingClassTab spacing_class_tab = MainWindow.get_spacing_class_tab ();+ SpacingData spacing = font.get_spacing (); first = ""; next = "";@@ -727,7 +728,7 @@ class BirdFontFile : GLib.Object { } } - spacing_class_tab.add_class (first, next);+ spacing.add_class (first, next); } private void parse_kerning (Tag tag) {@@ -765,7 +766,7 @@ class BirdFontFile : GLib.Object { KerningTools.add_unique_class (kerning_range); } - KerningClasses.get_instance ().set_kerning (range_left, range_right, hadjustment);+ font.get_kerning_classes ().set_kerning (range_left, range_right, hadjustment); } catch (MarkupError e) { warning (e.message);@@ -84,7 +84,7 @@ public class Font : GLib.Object { /** File format. */ public FontFormat format = FontFormat.BIRDFONT; - KerningClasses kerning_classes;+ SpacingData spacing; bool read_only = false; @@ -97,6 +97,8 @@ public class Font : GLib.Object { Ligatures ligatures_substitution; public Font () {+ KerningClasses kerning_classes;+ postscript_name = "Typeface"; name = "Typeface"; subfamily = "Regular";@@ -112,8 +114,9 @@ public class Font : GLib.Object { grid_width = new Gee.ArrayList<string> (); - kerning_classes = new KerningClasses ();- + kerning_classes = new KerningClasses (this);+ spacing = new SpacingData (kerning_classes);+ top_limit = 84 ; top_position = 72; xheight_position = 56;@@ -148,9 +151,13 @@ public class Font : GLib.Object { } public KerningClasses get_kerning_classes () {- return kerning_classes;+ return spacing.get_kerning_classes (); }- ++ public SpacingData get_spacing () {+ return spacing;+ }+ public File get_backgrounds_folder () { string fn = @"$(get_name ()) backgrounds"; File f = get_child (BirdFont.get_settings_directory (), fn);@@ -1775,6 +1775,8 @@ public class Glyph : FontDisplay { double box_x1, box_x2, box_y1, box_y2; double marker_x, marker_y; + KerningClasses classes = font.get_kerning_classes ();+ x = 0; box_x1 = path_coordinate_x (0);@@ -1796,7 +1798,7 @@ public class Glyph : FontDisplay { 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);+ kern = classes.get_kerning (last_name, name); } else { kern = 0; }@@ -1829,7 +1831,7 @@ public class Glyph : FontDisplay { 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);+ kern = classes.get_kerning (name, last_name); } else { kern = 0; }@@ -2003,7 +2005,7 @@ public class Glyph : FontDisplay { GlyphCollection gc; Glyph glyph; - foreach (string l in MainWindow.get_spacing_class_tab ()+ foreach (string l in font.get_spacing () .get_all_connections ((!) unichar_code.to_string ())) { if (l != (!) unichar_code.to_string ()) { g = font.get_glyph_collection (l);@@ -2026,7 +2028,7 @@ public class Glyph : FontDisplay { GlyphCollection gc; Glyph glyph; - foreach (string l in MainWindow.get_spacing_class_tab ()+ foreach (string l in font.get_spacing () .get_all_connections ((!) unichar_code.to_string ())) { if (l != (!) unichar_code.to_string ()) { g = font.get_glyph_collection (l);@@ -37,7 +37,11 @@ public class KerningClasses : GLib.Object { /** Ensure that map iterator is not invalidated because of inserts. */ bool protect_map = false; - public KerningClasses () {+ Font font;++ public KerningClasses (Font font) {+ this.font = font;+ classes_first = new Gee.ArrayList<GlyphRange> (); classes_last = new Gee.ArrayList<GlyphRange> (); classes_kerning = new Gee.ArrayList<Kerning> ();@@ -48,8 +52,48 @@ public class KerningClasses : GLib.Object { single_kerning = new HashMap<string, double?> (); } - public static KerningClasses get_instance () {- return BirdFont.get_current_font ().get_kerning_classes ();+ /** Class based gpos kerning. */+ public double get_kerning_for_pair (string a, string b, GlyphRange? gr_left, GlyphRange? gr_right) {+ double k;+ GlyphRange grl, grr;+ try {+ if (gr_left == null) {+ grl = new GlyphRange ();+ grl.parse_ranges (a);+ } else {+ grl = (!) gr_left;+ }++ if (gr_right == null) {+ grr = new GlyphRange ();+ grr.parse_ranges (a);+ } else {+ grr = (!) gr_right;+ }+ + if (gr_left != null && gr_right != null) {+ return get_kerning_for_range (grl, grr);+ }++ if (gr_left != null && gr_right == null) {+ return get_kern_for_range_to_char (grl, b);+ }+ + if (gr_left == null && gr_right != null) {+ return get_kern_for_char_to_range (a, grr);+ }+ + if (gr_left == null && gr_right == null) {+ k = get_kerning (a, b);+ return k;+ } + } catch (MarkupError e) {+ warning (e.message);+ }+ + warning ("no kerning found");+ + return 0; } public void update_space_class (string c) {@@ -86,6 +130,10 @@ public class KerningClasses : GLib.Object { return k; } + private Gee.ArrayList<string> get_spacing_class (string c) {+ return font.get_spacing ().get_all_connections (c);+ }+ public void set_kerning_for_single_glyphs (string le, string ri, double k) { string left = GlyphRange.serialize (le); string right = GlyphRange.serialize (ri);@@ -404,7 +452,6 @@ public class KerningClasses : GLib.Object { } public void all_pairs (KerningIterator kerningIterator) {- Font font = BirdFont.get_current_font (); Gee.ArrayList<Glyph> left_glyphs = new Gee.ArrayList<Glyph> (); Gee.ArrayList<KerningPair> pairs = new Gee.ArrayList<KerningPair> (); double kerning;@@ -512,11 +559,7 @@ public class KerningClasses : GLib.Object { classes_last.remove_at (index); classes_kerning.remove_at (index); }- - private Gee.ArrayList<string> get_spacing_class (string c) {- return MainWindow.get_spacing_class_tab ().get_all_connections (c);- }- + public void delete_kerning_for_pair (string left, string right) { foreach (string l in get_spacing_class (left)) { foreach (string r in get_spacing_class (right)) {@@ -390,14 +390,15 @@ public class KerningDisplay : FontDisplay { double val) { double kern; GlyphRange grl, grr;- KerningClasses classes = KerningClasses.get_instance ();+ KerningClasses classes; string n, f; bool has_kerning; Font font; font = current_font; font.touch ();- + classes = font.get_kerning_classes ();+ kern = get_kerning_for_pair (a, b, gr_left, gr_right); try {@@ -434,48 +435,9 @@ public class KerningDisplay : FontDisplay { } } - /** Class based gpos kerning. */ public static double get_kerning_for_pair (string a, string b, GlyphRange? gr_left, GlyphRange? gr_right) {- double k;- GlyphRange grl, grr;- try {- if (gr_left == null) {- grl = new GlyphRange ();- grl.parse_ranges (a);- } else {- grl = (!) gr_left;- }-- if (gr_right == null) {- grr = new GlyphRange ();- grr.parse_ranges (a);- } else {- grr = (!) gr_right;- }- - if (gr_left != null && gr_right != null) {- return KerningClasses.get_instance ().get_kerning_for_range (grl, grr);- }-- if (gr_left != null && gr_right == null) {- return KerningClasses.get_instance ().get_kern_for_range_to_char (grl, b);- }- - if (gr_left == null && gr_right != null) {- return KerningClasses.get_instance ().get_kern_for_char_to_range (a, grr);- }- - if (gr_left == null && gr_right == null) {- k = KerningClasses.get_instance ().get_kerning (a, b);- return k;- } - } catch (MarkupError e) {- warning (e.message);- }- - warning ("no kerning found");- - return 0;+ KerningClasses k = BirdFont.get_current_font ().get_kerning_classes ();+ return k.get_kerning_for_pair (a, b, gr_left, gr_right); } public void set_current_font (Font f) {@@ -929,7 +891,7 @@ public class KerningDisplay : FontDisplay { /** @return redo state. */ public UndoItem apply_undo (UndoItem ui) {- KerningClasses classes = KerningClasses.get_instance ();+ KerningClasses classes = BirdFont.get_current_font ().get_kerning_classes (); GlyphRange glyph_range_first, glyph_range_next; Font font = current_font; string l, r;@@ -32,7 +32,7 @@ public class KerningList : FontDisplay { } private void update_single_pair_list () {- KerningClasses classes = KerningClasses.get_instance ();+ KerningClasses classes = BirdFont.get_current_font ().get_kerning_classes (); single_pairs.clear (); @@ -44,7 +44,7 @@ public class KerningList : FontDisplay { } public override void draw (WidgetAllocation allocation, Context cr) {- KerningClasses classes = KerningClasses.get_instance ();+ KerningClasses classes = BirdFont.get_current_font ().get_kerning_classes (); int y = 20; int s = 0; bool color = (scroll % 2) == 0;@@ -122,7 +122,7 @@ public class KerningList : FontDisplay { } public override void button_release (int button, double ex, double ey) {- KerningClasses classes = KerningClasses.get_instance ();+ KerningClasses classes = BirdFont.get_current_font ().get_kerning_classes (); int s = 0; int y = 0; string l, r;@@ -166,8 +166,8 @@ public class KerningList : FontDisplay { void delete_kerning (string left, string right) { double kerning = 0; GlyphRange glyph_range_first, glyph_range_next;- KerningClasses classes = KerningClasses.get_instance (); Font font = BirdFont.get_current_font ();+ KerningClasses classes = font.get_kerning_classes (); string l, r; int class_index = -1; @@ -215,7 +215,8 @@ public class KerningList : FontDisplay { } public override void scroll_wheel_down (double x, double y) {- uint pairs = KerningClasses.get_instance ().get_number_of_pairs ();+ KerningClasses classes = BirdFont.get_current_font ().get_kerning_classes ();+ uint pairs = classes.get_number_of_pairs (); scroll += 3; if (scroll > pairs - visible_rows) {@@ -248,7 +249,8 @@ public class KerningList : FontDisplay { } public void update_scrollbar () {- uint rows = KerningClasses.get_instance ().get_number_of_pairs ();+ KerningClasses classes = BirdFont.get_current_font ().get_kerning_classes ();+ uint rows = classes.get_number_of_pairs (); if (rows == 0 || visible_rows == 0) { MainWindow.set_scrollbar_size (0);@@ -260,7 +262,8 @@ public class KerningList : FontDisplay { } public override void scroll_to (double percent) {- uint pairs = KerningClasses.get_instance ().get_number_of_pairs ();+ KerningClasses classes = BirdFont.get_current_font ().get_kerning_classes ();+ uint pairs = classes.get_number_of_pairs (); scroll = (int) (percent * pairs); if (scroll > pairs - visible_rows) {@@ -272,7 +275,7 @@ public class KerningList : FontDisplay { public override void undo () { UndoItem ui;- KerningClasses classes = KerningClasses.get_instance ();+ KerningClasses classes = BirdFont.get_current_font ().get_kerning_classes (); GlyphRange glyph_range_first, glyph_range_next; try {@@ -63,8 +63,10 @@ public class KerningRange : Tool { public void set_ranges (string r) { GlyphRange glyph_range = new GlyphRange ();+ SpacingData spacing = BirdFont.get_current_font ().get_spacing (); string new_range; string ch;+ try { glyph_range.parse_ranges (r); new_range = glyph_range.get_all_ranges ();@@ -72,7 +74,7 @@ public class KerningRange : Tool { for (int i = 0; i < glyph_range.get_length (); i++) { ch = glyph_range.get_char (i); - foreach (string c in MainWindow.get_spacing_class_tab ().get_all_connections (ch)) {+ foreach (string c in spacing.get_all_connections (ch)) { if (!glyph_range.has_character (c) && c != "" && c != "?") { new_range += " " + GlyphRange.serialize (c); }@@ -82,7 +84,7 @@ public class KerningRange : Tool { set_one_range (new_range); malformed = false; } catch (MarkupError e) {- KerningClasses.get_instance ().print_all ();+ warning (@"Failed to add range \"$r\""); warning (e.message); malformed = true; }@@ -162,7 +162,7 @@ public class KerningTools : ToolCollection { } public static void update_kerning_classes () {- KerningClasses k = KerningClasses.get_instance ();+ KerningClasses k = BirdFont.get_current_font ().get_kerning_classes (); KerningRange kr; GlyphRange r; int i;@@ -340,7 +340,8 @@ public class MenuTab : FontDisplay { return; } - KerningClasses.get_instance ().remove_all_pairs ();+ KerningClasses classes = BirdFont.get_current_font ().get_kerning_classes ();+ classes.remove_all_pairs (); KerningTools.update_kerning_classes (); } @@ -252,7 +252,7 @@ public class GlyfData : GLib.Object { if (c > bounding_box_xmax) { bounding_box_xmax = c; }- + last = c; i++; }@@ -32,6 +32,7 @@ public class KernList : GLib.Object { /** @return number of pairs. */ public uint fetch_all_pairs () { PairFormat1 current_pairs = new PairFormat1 ();+ KerningClasses classes; if (pairs.size > 0 || num_pairs > 0) { warning ("Pairs already loaded.");@@ -40,7 +41,8 @@ public class KernList : GLib.Object { num_pairs = 0; pairs.clear (); - KerningClasses.get_instance ().all_pairs ((kp) => {+ classes = BirdFont.get_current_font ().get_kerning_classes ();+ classes.all_pairs ((kp) => { uint16 gid_left, gid_right; KerningPair kerning_pair = kp; int i;@@ -87,7 +87,7 @@ public class TextArea { gr_left = word_with_ligatures.ranges.get (wi - 1); gr_right = word_with_ligatures.ranges.get (wi); - kern = KerningDisplay.get_kerning_for_pair (((!)prev).get_name (), ((!)g).get_name (), gr_left, gr_right);+ kern = font.get_kerning_classes ().get_kerning_for_pair (((!)prev).get_name (), ((!)g).get_name (), gr_left, gr_right); } // process glyph@@ -127,27 +127,78 @@ public class TextArea { ratio = font_size_in_pixels / row_height; cr.save ();- cr.scale (ratio, ratio);+ //cr.scale (ratio, ratio); y = get_row_height () + font.base_line + py; x = px;- + iterate ((glyph, kerning) => {- double center_x = glyph.allocation.width / 2.0;- double center_y = glyph.allocation.height / 2.0;-- cr.save ();+ double lsb = glyph.left_limit;+ glyph.add_help_lines ();- cr.translate (kerning + x - center_x - glyph.get_lsb (), y - center_y + glyph.get_baseline ());- glyph.draw_paths (cr);+ + x += kerning;+ cr.save ();+ cr.new_path ();+ foreach (Path path in glyph.path_list) {+ draw_path (cr, path, lsb, x, y);+ }+ cr.fill (); cr.restore (); - x += glyph.get_width () + kerning;+ x += glyph.get_width (); }); + cr.set_source_rgba (0, 0, 0, 1);+ cr.fill ();+ cr.restore (); } + void draw_path (Context cr, Path path, double lsb, double x, double y) {+ EditPoint e, prev;+ double xb, yb, xc, yc, xd, yd;+ + if (path.points.size > 0) {++ prev = path.points.get (0);+ cr.move_to (prev.x - lsb + x, y - prev.y);+ + for (int i = 1; i < path.points.size; i++) {+ e = path.points.get (i).copy ();+ PenTool.convert_point_segment_type (prev, e, PointType.CUBIC);+ + xb = prev.get_right_handle ().x - lsb + x;+ yb = y - prev.get_right_handle ().y;++ xc = e.get_left_handle ().x - lsb + x;+ yc = y - e.get_left_handle ().y;+ + xd = e.x - lsb + x;+ yd = y - e.y;+ + cr.curve_to (xb, yb, xc, yc, xd, yd);+ cr.line_to (xd, yd);+ + prev = e;+ }+ + // close path+ e = path.points.get (0);+ + xb = prev.get_right_handle ().x - lsb + x;+ yb = y - prev.get_right_handle ().y;++ xc = e.get_left_handle ().x - lsb + x;+ yc = y - e.get_left_handle ().y;+ + xd = e.x - lsb + x;+ yd = y - e.y;+ + cr.curve_to (xb, yb, xc, yc, xd, yd);+ }+ }+ double get_row_height () { return font.top_limit - font.bottom_limit; }@@ -21,6 +21,7 @@ public class TextTab : FontDisplay { TextArea text_area; TextArea text_area2;+ TextArea text_area3; public TextTab () { text_area = new TextArea ();@@ -30,11 +31,16 @@ public class TextTab : FontDisplay { text_area2 = new TextArea (); text_area2.load_font ("testfont.bf"); text_area2.set_text ("Birdfont ÅÄÖ");++ text_area3 = new TextArea ();+ text_area3.load_font ("testfont.bf");+ text_area3.set_text ("TEST 3"); } - public override void draw (WidgetAllocation allocation, Context cr) {+ public override void draw (WidgetAllocation allocation, Context cr) { text_area.draw (cr, 0, 0, 200, 200, 16); text_area2.draw (cr, 0, 100, 200, 200, 16);+ text_area3.draw (cr, 0, 200, 200, 200, 16); } } @@ -18,9 +18,7 @@ namespace BirdFont { public class SpacingClassTab : Table { - public Gee.ArrayList<SpacingClass> classes = new Gee.ArrayList<SpacingClass> (); public static int NEW_CLASS = -1;- Gee.ArrayList<string> connections = new Gee.ArrayList<string> (); Gee.ArrayList<Row> rows = new Gee.ArrayList<Row> (); public SpacingClassTab () {@@ -30,126 +28,47 @@ public class SpacingClassTab : Table { return rows; } - public static void remove_all_spacing_classes () {- if (!is_null (MainWindow.spacing_class_tab)) {- MainWindow.spacing_class_tab.classes.clear ();- }- }-- public Gee.ArrayList<string> get_all_connections (string glyph) {- Gee.ArrayList<string> c = new Gee.ArrayList<string> ();- - connections.clear ();- add_connections (glyph);- - foreach (string t in connections) {- c.add (t);- }- - connections.clear ();- - return c;- }- - public void add_connections (string glyph) {- connections.add (glyph);- - foreach (SpacingClass s in classes) {- if (s.first == glyph) {- if (connections.index_of (s.next) == -1) {- add_connections (s.next);- }- }-- if (s.next == glyph) {- if (connections.index_of (s.first) == -1) {- add_connections (s.first);- }- }- }- - connections.sort ((a, b) => {- return strcmp ((string) a, (string) b);- });- }-- public void add_class (string first, string next) {- SpacingClass s = new SpacingClass (first, next);- s.updated.connect (update_all_rows);- s.updated.connect (update_kerning);- classes.add (s);- update_kerning (s);- }-- public void update_kerning (SpacingClass s) {- Font font = BirdFont.get_current_font ();- GlyphCollection? g;- GlyphCollection gc;- - if (s.next != "?") {- KerningClasses.get_instance ().update_space_class (s.next);- g = font.get_glyph_collection (s.next);- if (g != null) {- gc = (!) g;- gc.get_current ().update_spacing_class ();- }- }- - if (s.first != "?") {- KerningClasses.get_instance ().update_space_class (s.first);- g = font.get_glyph_collection (s.first);- if (g != null) {- gc = (!) g;- gc.get_current ().update_spacing_class ();- }- }- - KerningTools.update_spacing_classes ();- }- public override void selected_row (Row row, int column, bool delete_button) { Font font = BirdFont.get_current_font ();+ SpacingData spacing = font.get_spacing (); if (row.get_index () == -1) {- add_class ("?", "?");+ spacing.add_class ("?", "?"); MainWindow.native_window.hide_text_input (); update_rows (); update_scrollbar (); font.touch ();- } else if (classes.size != 0) {+ } else if (spacing.classes.size != 0) { if (delete_button) {- return_if_fail (0 <= row.get_index () < classes.size);- classes.remove_at (row.get_index ());+ return_if_fail (0 <= row.get_index () < spacing.classes.size);+ spacing.classes.remove_at (row.get_index ()); MainWindow.native_window.hide_text_input (); update_rows (); update_scrollbar (); font.touch (); } else if (column == 0) {- if (!(0 <= row.get_index () < classes.size)) {- warning (@"Index: $(row.get_index ()) classes.size: $(classes.size)");+ if (!(0 <= row.get_index () < spacing.classes.size)) {+ warning (@"Index: $(row.get_index ()) classes.size: $(spacing.classes.size)"); return; }- classes.get (row.get_index ()).set_first ();+ spacing.classes.get (row.get_index ()).set_first (); font.touch (); } else if (column == 2) {- return_if_fail (0 <= row.get_index () < classes.size);- classes.get (row.get_index ()).set_next ();+ return_if_fail (0 <= row.get_index () < spacing.classes.size);+ spacing.classes.get (row.get_index ()).set_next (); font.touch (); } } } - void update_all_rows (SpacingClass s) {- update_rows ();- }- public override void update_rows () { int i = 0;+ SpacingData spacing = BirdFont.get_current_font ().get_spacing (); rows.clear (); rows.add (new Row (t_("New spacing class"), NEW_CLASS, false)); - foreach (SpacingClass c in classes) {+ foreach (SpacingClass c in spacing.classes) { rows.add (new Row.columns_3 (@"$(c.first)", "=", @"$(c.next)", i)); i++; }new file mode 100644@@ -0,0 +1,110 @@+/*+ Copyright (C) 2014 Johan Mattsson++ This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 3 of the + License, or (at your option) any later version.++ This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details.+*/+using Cairo;+using Math;++namespace BirdFont {++public class SpacingData : GLib.Object {+ + public KerningClasses kerning_classes;+ + public Gee.ArrayList<SpacingClass> classes = new Gee.ArrayList<SpacingClass> ();+ Gee.ArrayList<string> connections = new Gee.ArrayList<string> ();++ public SpacingData (KerningClasses kerning) {+ kerning_classes = kerning;+ }++ public KerningClasses get_kerning_classes () {+ return kerning_classes;+ }++ public Gee.ArrayList<string> get_all_connections (string glyph) {+ Gee.ArrayList<string> c = new Gee.ArrayList<string> ();+ + connections.clear ();+ add_connections (glyph);+ + foreach (string t in connections) {+ c.add (t);+ }+ + connections.clear ();+ + return c;+ }+ + public void add_connections (string glyph) {+ connections.add (glyph);+ + foreach (SpacingClass s in classes) {+ if (s.first == glyph) {+ if (connections.index_of (s.next) == -1) {+ add_connections (s.next);+ }+ }++ if (s.next == glyph) {+ if (connections.index_of (s.first) == -1) {+ add_connections (s.first);+ }+ }+ }+ + connections.sort ((a, b) => {+ return strcmp ((string) a, (string) b);+ });+ }++ public void add_class (string first, string next) {+ SpacingClass s = new SpacingClass (first, next);+ s.updated.connect (update_all_rows);+ s.updated.connect (update_kerning);+ classes.add (s);+ update_kerning (s);+ }++ void update_all_rows (SpacingClass s) {+ MainWindow.get_spacing_class_tab ().update_rows ();+ }++ public void update_kerning (SpacingClass s) {+ Font font = BirdFont.get_current_font ();+ GlyphCollection? g;+ GlyphCollection gc;+ + if (s.next != "?") {+ kerning_classes.update_space_class (s.next);+ g = font.get_glyph_collection (s.next);+ if (g != null) {+ gc = (!) g;+ gc.get_current ().update_spacing_class ();+ }+ }+ + if (s.first != "?") {+ kerning_classes.update_space_class (s.first);+ g = font.get_glyph_collection (s.first);+ if (g != null) {+ gc = (!) g;+ gc.get_current ().update_spacing_class ();+ }+ }+ + KerningTools.update_spacing_classes ();+ }+}++}@@ -72,6 +72,7 @@ class SvgFont : GLib.Object { unichar l, r; StringBuilder sl, sr; GlyphRange grr, grl;+ KerningClasses classes = BirdFont.get_current_font ().get_kerning_classes (); foreach (Attribute attr in tag.get_attributes ()) { // left@@ -117,7 +118,7 @@ class SvgFont : GLib.Object { grr = new GlyphRange (); grr.parse_ranges (sr.str); - KerningClasses.get_instance ().set_kerning (grl, grr, -kerning);+ classes.set_kerning (grl, grr, -kerning); } catch (MarkupError e) { warning (e.message); } @@ -49,6 +49,8 @@ class SvgFontFormatWriter : Object { string uni; + KerningClasses classes;+ put ("""<?xml version="1.0" standalone="no"?>"""); put ("""<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >"""); put ("""<svg>""");@@ -86,7 +88,8 @@ class SvgFontFormatWriter : Object { } // FIXME: ligatures- KerningClasses.get_instance ().all_pairs ((kerning) => {+ classes = BirdFont.get_current_font ().get_kerning_classes ();+ classes.all_pairs ((kerning) => { string l, r; foreach (Kerning k in kerning.kerning) {