Commit 902267d
revert "parse ligatures from svg font" since it broke Firefox support This reverts commit a76d9a8e1fd33f29ad36b3d3bf0976499b41d283. Conflicts: libbirdfont/Context.vala libbirdfont/Font.vala libbirdfont/Glyph.vala libbirdfont/SvgFont.vala
Changed files (8)
addedlibbirdfont/Context.valamodifiedlibbirdfont/Font.valamodifiedlibbirdfont/Glyph.valamodifiedlibbirdfont/GlyphSequence.valadeletedlibbirdfont/KerningDisplay.valamodifiedlibbirdfont/MenuTab.valamodifiedlibbirdfont/OpenFontFormatWriter.valamodifiedlibbirdfont/SvgFont.vala
Diff
new file mode 100644@@ -0,0 +1,335 @@+/*+ Copyright (C) 2012 Johan Mattsson++ This program is free software: you can redistribute it and/or modify+ it under the terms of the GNU General Public License as published by+ the Free Software Foundation, either version 3 of the License, or+ (at your option) any later version.++ This program 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 General Public License for more details.++ You should have received a copy of the GNU General Public License+ along with this program. If not, see <http://www.gnu.org/licenses/>.+*/++using Cairo;++namespace BirdFont {++/** Kerning context. */+public class ContextDisplay : FontDisplay {++ List <GlyphSequence> row;+ int active_handle = -1;+ int selected_handle = -1;+ + double begin_handle_x = 0;+ double begin_handle_y = 0;+ + double last_handle_x = 0;+/*+<<<<<<< HEAD+ public KerningDisplay () {+ GlyphSequence w = new GlyphSequence ();+ row = new List <GlyphSequence> ();+=======+*/+ public ContextDisplay () {+ GlyphSequence w = new GlyphSequence ();+ row = new List <GlyphSequence> ();+//>>>>>>> parent of a76d9a8... parse ligatures from svg font+ row.append (w);+ }++ public override string get_name () {+ return "Kerning";+ }+ + public override void draw (Allocation allocation, Context cr) {+ Glyph glyph;+ double x, y, w, kern, alpha;+ double x2;+ int i, wi;+ Glyph? prev;+ Font font = BirdFont.get_current_font ();+ GlyphSequence word_with_ligatures;+ + i = 0;+ + // bg color+ cr.save ();+ cr.set_source_rgba (1, 1, 1, 1);+ cr.rectangle (0, 0, allocation.width, allocation.height);+ cr.fill ();+ cr.restore ();+ + alpha = 1;+ y = 100;+ x = 20;+ w = 0;+ prev = null;+ + foreach (GlyphSequence word in row) {+ wi = 0;+ word_with_ligatures = word.process_ligatures ();+ foreach (Glyph? g in word_with_ligatures.glyph) {+ if (g == null) {+ continue;+ }+ + if (prev == null) {+ kern = 0;+ } else {+ kern = font.get_kerning_by_name (((!)prev).get_name (), ((!)g).get_name ());+ }+ + // draw glyph + if (g == null) {+ w = 50;+ alpha = 1;+ } else {+ alpha = 0;+ glyph = (!) g;+ Svg.draw_svg_path (cr, glyph.get_svg_data (), x + kern, y);+ w = glyph.get_width ();+ }++ // handle+ if (active_handle == i) {+ //x2 = x + kern;+ x2 = x + kern / 2.0;+ + cr.save ();+ cr.set_source_rgba (153/255.0, 153/255.0, 173/255.0, 1);+ cr.move_to (x2 - 5, y + 20);+ cr.line_to (x2 + 0, y + 20 - 5);+ cr.line_to (x2 + 5, y + 20);+ cr.fill ();+ + cr.set_font_size (10);+ cr.show_text (((!)g).get_name ());+ cr.restore ();+ } + + x += w + kern;+ + // caption+ if (g == null || ((!)g).is_empty ()) {+ cr.save ();+ cr.set_source_rgba (153/255.0, 153/255.0, 153/255.0, alpha);+ cr.move_to (x - w / 2.0 - 5, y + 20);+ cr.set_font_size (10);+ cr.show_text ("?"); // ?+ cr.restore ();+ }+ + prev = g;+ + wi++;+ i++;+ }+ + if (y > allocation.height && i > 10) {+ row.remove (word);+ }+ + y += MainWindow.get_current_glyph ().get_height () + 20;+ x = 20; + }+ }+ + private void set_kerning (int handle, double val) {+ string a, b;+ Font font;+ int wi = 0;+ double kern;+ GlyphSequence word_with_ligatures;+ + font = BirdFont.get_current_font ();++ font.touch ();++ a = "";+ b = "";++ foreach (GlyphSequence word in row) {+ word_with_ligatures = word.process_ligatures ();+ foreach (Glyph? g in word_with_ligatures.glyph) {+ + if (g == null) {+ continue;+ }+ + b = ((!) g).get_name ();+ + if (handle == wi) {+ kern = font.get_kerning_by_name (a, b) + val;+ font.set_kerning_by_name (a, b, kern);+ }+ + wi++;+ + a = b;+ }+ }+ + + }++ public override void selected_canvas () {+ Glyph g;+ GlyphSequence w;+ unowned List<GlyphSequence>? r;+ StringBuilder s = new StringBuilder ();+ bool append_char = false;+ Font font = BirdFont.get_current_font ();+ + KeyBindings.singleton.set_require_modifier (true);+ + g = MainWindow.get_current_glyph ();+ s.append_unichar (g.get_unichar ());++ r = row;+ return_if_fail (r != null);++ if (row.length () == 0) {+ append_char = true;+ }+ + if (append_char) {+ w = new GlyphSequence ();+ row.append (w);+ w.glyph.prepend (font.get_glyph (s.str));+ } + }+ + public override void key_press (uint keyval) {+ unichar c = (unichar) keyval;+ Glyph? g;+ Font f = BirdFont.get_current_font ();+ string name;+ + if (KeyBindings.modifier == NONE || KeyBindings.modifier == SHIFT) {+ + if (keyval == Key.BACK_SPACE && row.length () > 0) { + row.first ().data.glyph.remove_link (row.first ().data.glyph.last ());+ }+ + if (row.length () == 0 || c == Key.ENTER) {+ row.prepend (new GlyphSequence ());+ }+ + if (!is_modifier_key (c) && c.validate ()) {+ name = f.get_name_for_character (c);+ g = f.get_glyph_by_name (name);+ row.first ().data.glyph.append (g);+ }+ }+ + MainWindow.get_glyph_canvas ().redraw ();+ }+ + public override void motion_notify (double ex, double ey) {+ double k, y;+ + if (selected_handle == -1) {+ set_active_handle (ex, ey);+ } else {+ y = 1;+ + if (Math.fabs (ey - begin_handle_y) > 20) {+ y = ((Math.fabs (ey - begin_handle_y) / 100) + 1);+ }+ + k = (ex - last_handle_x) / y; // y-axis is variable precision+ set_kerning (selected_handle, k);+ MainWindow.get_glyph_canvas ().redraw ();+ }+ + last_handle_x = ex;+ }+ + public void set_active_handle (double ex, double ey) {+ double y = 100;+ double x = 20;+ double w = 0;+ double d, kern;+ double min = double.MAX;+ int i = 0;+ int row_index = 0;+ int col_index = 0;+ Glyph glyph = new Glyph.no_lines ("");+ Font font = BirdFont.get_current_font ();+ + Glyph? prev = null;+ string gl_name = "";+ GlyphSequence word_with_ligatures;+ + foreach (GlyphSequence word in row) {+ col_index = 0;+ + word_with_ligatures = word.process_ligatures ();+ foreach (Glyph? g in word_with_ligatures.glyph) {+ // draw glyph++ if (g == null) {+ w = 50; + } else {+ glyph = (!) g;+ w = glyph.get_width ();+ }+ + gl_name = glyph.get_name ();+ + if (prev == null) {+ kern = 0;+ } else {+ kern = font.get_kerning_by_name (((!)prev).get_name (), gl_name);+ }+ + d = Math.pow (x + kern - ex, 2) + Math.pow (y - ey, 2);+ + if (d < min) {+ min = d;+ + if (active_handle != i - row_index) {+ active_handle = i - row_index;+ MainWindow.get_glyph_canvas ().redraw ();+ }++ if (col_index == word.glyph.length () || col_index == 0) {+ active_handle = -1;+ }+ }+ + prev = g;+ x += w + kern;+ i++;+ col_index++;+ }+ + row_index++;+ y += MainWindow.get_current_glyph ().get_height () + 20;+ x = 20;+ }+ }+ + public override void button_release (int button, double ex, double ey) {+ set_active_handle (ex, ey);+ selected_handle = -1;+ }+ + public override void button_press (uint button, double ex, double ey) {+ set_active_handle (ex, ey);+ selected_handle = active_handle;+ begin_handle_x = ex;+ begin_handle_y = ey;+ last_handle_x = ex;+ }++}++}@@ -29,13 +29,13 @@ public enum FontFormat { public class Font : GLib.Object { /** Table with glyphs sorted by their unicode value. */- GlyphTable glyph_unicode = new GlyphTable ();+ GlyphTable glyph_cache = new GlyphTable (); /** Table with glyphs sorted by their name. */ GlyphTable glyph_name = new GlyphTable (); - /** Ligatures */- GlyphTable ligature = new GlyphTable ();+ /** Last unassigned index */+ int next_unindexed = 0; public List <string> background_images = new List <string> (); public string background_scale = "1";@@ -175,7 +175,7 @@ public class Font : GLib.Object { public void print_all () { stdout.printf ("Unicode:\n"); - glyph_unicode.for_each((g) => {+ glyph_cache.for_each((g) => { stdout.printf (@"$(g.get_unicode ())\n"); }); @@ -197,7 +197,7 @@ public class Font : GLib.Object { } ret = new Glyph ("nonmarkingreturn", '\r');-+ ret.set_unassigned (false); ret.left_limit = 0; ret.right_limit = 0; ret.remove_empty_paths ();@@ -215,7 +215,7 @@ public class Font : GLib.Object { } n = new Glyph ("null", '\0');- + n.set_unassigned (false); n.left_limit = 0; n.right_limit = 0; n.remove_empty_paths ();@@ -237,7 +237,7 @@ public class Font : GLib.Object { } n = new Glyph ("space", ' ');-+ n.set_unassigned (false); n.left_limit = 0; n.right_limit = 27; n.remove_empty_paths ();@@ -261,6 +261,7 @@ public class Font : GLib.Object { p = new Path (); i = new Path (); + g.set_unassigned (true); g.left_limit = -33; g.right_limit = 33; @@ -306,10 +307,10 @@ public class Font : GLib.Object { } if (glyph_collection.get_unicode () != "") {- glyph_unicode.insert (glyph_collection.get_unicode (), glyph_collection);+ glyph_name.insert (glyph_collection.get_name (), glyph_collection); } - 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) {@@ -342,13 +343,19 @@ public class Font : GLib.Object { } public void delete_glyph (GlyphCollection glyph) {- glyph_unicode.remove (glyph.get_unicode ());+ glyph_cache.remove (glyph.get_unicode ()); glyph_name.remove (glyph.get_name ());+/*+<<<<<<< HEAD } // FIXME: order if ligature substitution is important public GlyphCollection? get_ligature (uint indice) { return ligature.nth (indice);+=======+*/+ // FIXME: DELETE: glyph_cache.remove (glyph);+//>>>>>>> parent of a76d9a8... parse ligatures from svg font } /** Obtain all versions and alterntes for this glyph. */@@ -372,7 +379,7 @@ public class Font : GLib.Object { /** Get glyph collection by unichar code. */ public GlyphCollection? get_cached_glyph_collection (string unichar_code) { GlyphCollection? gc = null;- gc = glyph_unicode.get (unichar_code);+ gc = glyph_cache.get (unichar_code); return gc; } @@ -397,7 +404,11 @@ public class Font : GLib.Object { public Glyph? get_glyph (string unicode) { GlyphCollection? gc = null;- gc = glyph_unicode.get (unicode);+//<<<<<<< HEAD+// gc = glyph_unicode.get (unicode);+//=======+ gc = glyph_cache.get (name);+//>>>>>>> parent of a76d9a8... parse ligatures from svg font if (gc == null) { return null;@@ -426,19 +437,6 @@ public class Font : GLib.Object { background_images.append (file); } - public string get_name_from_unicode (string unicode) {- string v = "";- Glyph? g = get_glyph (unicode);- - if (g != null) {- v = ((!)g).get_name ();- } else {- warning (@"no name for \"$unicode\"");- }- - return v;- }- /** Obtain kerning for pair with name a and b. * @param a name of left glyph kerning pair * @param b name of right glyph kerning pair@@ -636,7 +634,7 @@ public class Font : GLib.Object { os.put_string ("\n"); } - glyph_unicode.for_each ((gc) => {+ glyph_cache.for_each ((gc) => { bool selected; if (is_null (gc)) {@@ -654,7 +652,7 @@ public class Font : GLib.Object { } }); - glyph_unicode.for_each ((gc) => {+ glyph_cache.for_each ((gc) => { Glyph glyph; try {@@ -682,7 +680,7 @@ public class Font : GLib.Object { } }); - glyph_unicode.for_each ((gc) => {+ glyph_cache.for_each ((gc) => { GlyphBackgroundImage bg; try {@@ -828,7 +826,7 @@ public class Font : GLib.Object { grid_width.remove_link (grid_width.first ()); } - glyph_unicode.remove_all ();+ glyph_cache.remove_all (); glyph_name.remove_all (); if (path.has_suffix (".svg")) {@@ -955,16 +953,38 @@ public class Font : GLib.Object { if (gcl != null) { warning (@"glyph \"$(g.get_name ())\" does already exist");- return; }- + + if (g.is_unassigned ()) {+ gc = new GlyphCollection (g);+ +/* +<<<<<<< HEAD gc = new GlyphCollection (g); add_glyph_collection (gc); if (g.is_ligature ()) { liga = g.get_ligature_string (); ligature.insert (liga, gc);+=======+*/+ if (g.name == "") {+ warning ("refusing to insert glyph without name");+ g.name = @"($(++next_unindexed))";+ return;+ }+ + add_glyph_collection ((!) gc);+ } else if (gcl == null) {+ gc = new GlyphCollection (g);+ add_glyph_collection ((!) gc);+ } else {+ stderr.printf (@"Glyph collection does already have an entry for $(g.get_name ()) char $((uint64) g.unichar_code).\n");+//>>>>>>> parent of a76d9a8... parse ligatures from svg font }+ + // take xheight from appropriate lower case letter+ // xheight_position = estimate_xheight (); } public bool parse_otf_file (string path) throws GLib.Error {@@ -985,7 +1005,7 @@ public class Font : GLib.Object { font_file = path; // empty cache and fill it with new glyphs from disk- glyph_unicode.remove_all ();+ glyph_cache.remove_all (); glyph_name.remove_all (); while (background_images.length () > 0) {@@ -75,6 +75,7 @@ public class Glyph : FontDisplay { bool xheight_lines_visible = false; bool margin_boundries_visible = false; + bool unassigned = false; public unichar unichar_code = 0; List<Glyph> undo_list = new List<Glyph> ();@@ -83,10 +84,14 @@ public class Glyph : FontDisplay { string glyph_sequence = ""; bool open = true;- +/*+<<<<<<< HEAD bool ligature = false; string substitution = ""; +=======+>>>>>>> parent of a76d9a8... parse ligatures from svg font+*/ public Glyph (string name, unichar unichar_code = 0) { this.name = name; this.unichar_code = unichar_code;@@ -105,6 +110,8 @@ public class Glyph : FontDisplay { path_list.append (new Path ()); }+/*+<<<<<<< HEAD public string get_ligature_string () { return substitution;@@ -141,7 +148,9 @@ public class Glyph : FontDisplay { public bool is_ligature () { return ligature; }-+=======+>>>>>>> parent of a76d9a8... parse ligatures from svg font+*/ public void select_all_paths () { clear_active_paths (); @@ -205,6 +214,14 @@ public class Glyph : FontDisplay { return 0; }+ + 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) {@@ -1475,10 +1492,14 @@ public class Glyph : FontDisplay { if (background_image != null) { g.background_image = ((!) background_image).copy (); }- + /* +<<<<<<< HEAD g.ligature = ligature; g.substitution = substitution; +=======+>>>>>>> parent of a76d9a8... parse ligatures from svg font+*/ return g; } @@ -30,7 +30,7 @@ public class GlyphSequence { */ public GlyphSequence process_ligatures () { GlyphSequence ligatures = new GlyphSequence ();- Font font = BirdFont.get_current_font ();+/* // FIXME Font font = BirdFont.get_current_font (); Glyph liga; GlyphCollection? gc; @@ -51,7 +51,7 @@ public class GlyphSequence { ligatures.replace (liga.get_ligature (), liga); i++; }- + */ return ligatures; } deleted file mode 100644@@ -1,328 +0,0 @@-/*- Copyright (C) 2012 Johan Mattsson-- This program is free software: you can redistribute it and/or modify- it under the terms of the GNU General Public License as published by- the Free Software Foundation, either version 3 of the License, or- (at your option) any later version.-- This program 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 General Public License for more details.-- You should have received a copy of the GNU General Public License- along with this program. If not, see <http://www.gnu.org/licenses/>.-*/--using Cairo;--namespace BirdFont {--/** Kerning context. */-public class KerningDisplay : FontDisplay {-- List <GlyphSequence> row;- int active_handle = -1;- int selected_handle = -1;- - double begin_handle_x = 0;- double begin_handle_y = 0;- - double last_handle_x = 0;- - public KerningDisplay () {- GlyphSequence w = new GlyphSequence ();- row = new List <GlyphSequence> ();- row.append (w);- }-- public override string get_name () {- return "Kerning";- }- - public override void draw (Allocation allocation, Context cr) {- Glyph glyph;- double x, y, w, kern, alpha;- double x2;- int i, wi;- Glyph? prev;- Font font = BirdFont.get_current_font ();- GlyphSequence word_with_ligatures;- - i = 0;- - // bg color- cr.save ();- cr.set_source_rgba (1, 1, 1, 1);- cr.rectangle (0, 0, allocation.width, allocation.height);- cr.fill ();- cr.restore ();- - alpha = 1;- y = 100;- x = 20;- w = 0;- prev = null;- - foreach (GlyphSequence word in row) {- wi = 0;- word_with_ligatures = word.process_ligatures ();- foreach (Glyph? g in word_with_ligatures.glyph) {- if (g == null) {- continue;- }- - if (prev == null) {- kern = 0;- } else {- kern = font.get_kerning_by_name (((!)prev).get_name (), ((!)g).get_name ());- }- - // draw glyph - if (g == null) {- w = 50;- alpha = 1;- } else {- alpha = 0;- glyph = (!) g;- Svg.draw_svg_path (cr, glyph.get_svg_data (), x + kern, y);- w = glyph.get_width ();- }-- // handle- if (active_handle == i) {- //x2 = x + kern;- x2 = x + kern / 2.0;- - cr.save ();- cr.set_source_rgba (153/255.0, 153/255.0, 173/255.0, 1);- cr.move_to (x2 - 5, y + 20);- cr.line_to (x2 + 0, y + 20 - 5);- cr.line_to (x2 + 5, y + 20);- cr.fill ();- - cr.set_font_size (10);- cr.show_text (((!)g).get_name ());- cr.restore ();- } - - x += w + kern;- - // caption- if (g == null || ((!)g).is_empty ()) {- cr.save ();- cr.set_source_rgba (153/255.0, 153/255.0, 153/255.0, alpha);- cr.move_to (x - w / 2.0 - 5, y + 20);- cr.set_font_size (10);- cr.show_text ("?"); // ?- cr.restore ();- }- - prev = g;- - wi++;- i++;- }- - if (y > allocation.height && i > 10) {- row.remove (word);- }- - y += MainWindow.get_current_glyph ().get_height () + 20;- x = 20; - }- }- - private void set_kerning (int handle, double val) {- string a, b;- Font font;- int wi = 0;- double kern;- GlyphSequence word_with_ligatures;- - font = BirdFont.get_current_font ();-- font.touch ();-- a = "";- b = "";-- foreach (GlyphSequence word in row) {- word_with_ligatures = word.process_ligatures ();- foreach (Glyph? g in word_with_ligatures.glyph) {- - if (g == null) {- continue;- }- - b = ((!) g).get_name ();- - if (handle == wi) {- kern = font.get_kerning_by_name (a, b) + val;- font.set_kerning_by_name (a, b, kern);- }- - wi++;- - a = b;- }- }- - - }-- public override void selected_canvas () {- Glyph g;- GlyphSequence w;- unowned List<GlyphSequence>? r;- StringBuilder s = new StringBuilder ();- bool append_char = false;- Font font = BirdFont.get_current_font ();- - KeyBindings.singleton.set_require_modifier (true);- - g = MainWindow.get_current_glyph ();- s.append_unichar (g.get_unichar ());-- r = row;- return_if_fail (r != null);-- if (row.length () == 0) {- append_char = true;- }- - if (append_char) {- w = new GlyphSequence ();- row.append (w);- w.glyph.prepend (font.get_glyph (s.str));- } - }- - public override void key_press (uint keyval) {- unichar c = (unichar) keyval;- Glyph? g;- Font f = BirdFont.get_current_font ();- string name;- - if (KeyBindings.modifier == NONE || KeyBindings.modifier == SHIFT) {- - if (keyval == Key.BACK_SPACE && row.length () > 0) { - row.first ().data.glyph.remove_link (row.first ().data.glyph.last ());- }- - if (row.length () == 0 || c == Key.ENTER) {- row.prepend (new GlyphSequence ());- }- - if (!is_modifier_key (c) && c.validate ()) {- name = f.get_name_for_character (c);- g = f.get_glyph_by_name (name);- row.first ().data.glyph.append (g);- }- }- - MainWindow.get_glyph_canvas ().redraw ();- }- - public override void motion_notify (double ex, double ey) {- double k, y;- - if (selected_handle == -1) {- set_active_handle (ex, ey);- } else {- y = 1;- - if (Math.fabs (ey - begin_handle_y) > 20) {- y = ((Math.fabs (ey - begin_handle_y) / 100) + 1);- }- - k = (ex - last_handle_x) / y; // y-axis is variable precision- set_kerning (selected_handle, k);- MainWindow.get_glyph_canvas ().redraw ();- }- - last_handle_x = ex;- }- - public void set_active_handle (double ex, double ey) {- double y = 100;- double x = 20;- double w = 0;- double d, kern;- double min = double.MAX;- int i = 0;- int row_index = 0;- int col_index = 0;- Glyph glyph = new Glyph.no_lines ("");- Font font = BirdFont.get_current_font ();- - Glyph? prev = null;- string gl_name = "";- GlyphSequence word_with_ligatures;- - foreach (GlyphSequence word in row) {- col_index = 0;- - word_with_ligatures = word.process_ligatures ();- foreach (Glyph? g in word_with_ligatures.glyph) {- // draw glyph-- if (g == null) {- w = 50; - } else {- glyph = (!) g;- w = glyph.get_width ();- }- - gl_name = glyph.get_name ();- - if (prev == null) {- kern = 0;- } else {- kern = font.get_kerning_by_name (((!)prev).get_name (), gl_name);- }- - d = Math.pow (x + kern - ex, 2) + Math.pow (y - ey, 2);- - if (d < min) {- min = d;- - if (active_handle != i - row_index) {- active_handle = i - row_index;- MainWindow.get_glyph_canvas ().redraw ();- }-- if (col_index == word.glyph.length () || col_index == 0) {- active_handle = -1;- }- }- - prev = g;- x += w + kern;- i++;- col_index++;- }- - row_index++;- y += MainWindow.get_current_glyph ().get_height () + 20;- x = 20;- }- }- - public override void button_release (int button, double ex, double ey) {- set_active_handle (ex, ey);- selected_handle = -1;- }- - public override void button_press (uint button, double ex, double ey) {- set_active_handle (ex, ey);- selected_handle = active_handle;- begin_handle_x = ex;- begin_handle_y = ey;- last_handle_x = ex;- }--}--}@@ -408,7 +408,7 @@ c.append (""" } public static void show_kerning_context () {- MainWindow.get_tab_bar ().add_unique_tab (new KerningDisplay (), 85, false);+ MainWindow.get_tab_bar ().add_unique_tab (new ContextDisplay (), 85, false); } public static void preview () {@@ -759,6 +759,11 @@ class GlyfTable : Table { while (gl != glyphs.first ()) { g = (!) gl.data; + + if (!g.is_unassigned ()) { + break; + } + gl = gl.prev; } @@ -840,6 +845,10 @@ class GlyfTable : Table { glyph.name = name; + if (character == 0) { + glyph.set_unassigned (true); + } + if (character == 0 && name != "") { stderr.printf (@"Got null character\n"); stderr.printf (@"gid: $index\n"); @@ -1551,7 +1560,11 @@ class GlyfTable : Table { g.remove_empty_paths (); - glyphs.append (g); + if (!g.is_unassigned ()) { + glyphs.append (g); + } else { + unassigned_glyphs.append (g); + } } foreach (Glyph ug in unassigned_glyphs) { @@ -1796,7 +1809,9 @@ class CmapSubtableWindowsUnicode : CmapSubtable { uint32 first_assigned = 1; foreach (Glyph g in glyf_table.glyphs) { - glyph_range.add_single (g.unichar_code); + if (!g.is_unassigned ()) { + glyph_range.add_single (g.unichar_code); + } } // glyph_range.print_all (); @@ -93,7 +93,6 @@ class SvgFont : GLib.Object { StringBuilder sl, sr; string attr_name = ""; string attr_content;- string ln, rn; for (Xml.Attr* prop = node->properties; prop != null; prop = prop->next) { attr_name = prop->name;@@ -123,52 +122,22 @@ class SvgFont : GLib.Object { } } - // , is used as separator- if (left == ",") {- left = ",";- }-- if (right == ",") {- right = ",";- } - // TODO: ranges for u1 & u2 + g1 & g2- - // u1 + u2 or g2+ // TODO: ranges and sequences for u1 & u2 + g1 & g2 foreach (string lk in left.split (",")) {- l = get_unichar (lk);- sl = new StringBuilder ();- sl.append_unichar (l);- ln = font.get_name_from_unicode (sl.str);- - foreach (string rk in right.split (",")) {- r = get_unichar (rk);- sr = new StringBuilder ();- sr.append_unichar (r);- rn = font.get_name_from_unicode (sr.str);- font.set_kerning_by_name (ln, rn, -kerning);- }-- foreach (string rk in right_name.split (",")) {- font.set_kerning_by_name (ln, rk, -kerning);- }- }-- // g1 + u2 or g2- foreach (string lk in left_name.split (",")) { foreach (string rk in right.split (",")) {+ l = get_unichar (lk); r = get_unichar (rk);+ + sl = new StringBuilder ();+ sl.append_unichar (l);+ sr = new StringBuilder (); sr.append_unichar (r);- rn = font.get_name_from_unicode (sr.str);- font.set_kerning_by_name (lk, rn, -kerning);- }-- foreach (string rk in right_name.split (",")) {- font.set_kerning_by_name (lk, rk, -kerning);+ + font.set_kerning (sl.str, sr.str, -kerning); } }- } void parse_font_limits (Xml.Node* node) {@@ -227,18 +196,14 @@ class SvgFont : GLib.Object { /** Obtain unichar value from either a character, a hex representation of * a character or series of characters (f, m or ffi). */- unichar get_unichar (string val) {+ static unichar get_unichar (string val) { string v = val; unichar unicode_value;-+ if (val == "&") { return '&'; }-- if (val == ",") {- return ',';- }-+ // TODO: parse ligatures if (v.has_prefix ("&")) { // parse hex value@@ -247,27 +212,19 @@ class SvgFont : GLib.Object { v = v.replace (";", ""); unicode_value = Font.to_unichar (v); } else {+ // obtain unicode value - // don't assign ligatures to any code point- if (is_ligature (val)) {+ if (v.char_count () > 1) {+ warning ("font contains ligatures"); return '\0'; } - // obtain unicode value unicode_value = v.get_char (0); } return unicode_value; } - bool is_ligature (string v) {- if (v.has_prefix ("&")) {- return false;- }- - return v.char_count () > 1; - }- void parse_glyph (Xml.Node* node) { string attr_name = ""; string attr_content;@@ -276,7 +233,6 @@ class SvgFont : GLib.Object { string svg = ""; Glyph glyph; double advance = font_advance;- string ligature = ""; for (Xml.Attr* prop = node->properties; prop != null; prop = prop->next) { attr_name = prop->name;@@ -288,10 +244,6 @@ class SvgFont : GLib.Object { if (glyph_name == "") { glyph_name = attr_content; }- - if (is_ligature (attr_content)) {- ligature = attr_content;- } } // svg data@@ -307,16 +259,27 @@ class SvgFont : GLib.Object { advance = double.parse (attr_content); } }- ++/* +<<<<<<< HEAD glyph = new Glyph (glyph_name, unicode_value); ImportSvg.parse_svg_data (svg, glyph, true, units); glyph.right_limit = glyph.left_limit + advance * units; if (ligature != "") { glyph.set_ligature_substitution (ligature);+=======+*/+ // FIXME: this code will ignore characters that are mapped several glyphs+ if (unicode_value != '\0') {+ glyph = new Glyph (glyph_name, unicode_value);+ ImportSvg.parse_svg_data (svg, glyph, true, units); + glyph.right_limit = glyph.left_limit + advance * units;+ font.add_glyph_callback (glyph);+ } else {+ warning ("ignoring glyph");+//>>>>>>> parent of a76d9a8... parse ligatures from svg font }- - font.add_glyph_callback (glyph); } }