Commit 051b7d7
Add points at extrema on glyph boundaries
Changed files (11)
modifiedlibbirdfont/Font.valamodifiedlibbirdfont/Glyph.valamodifiedlibbirdfont/MenuTab.valamodifiedlibbirdfont/OpenFontFormat/GlyfData.valamodifiedlibbirdfont/OpenFontFormat/GlyfTable.valamodifiedlibbirdfont/OverView.valamodifiedlibbirdfont/Path.valamodifiedlibbirdfont/SvgFont.valamodifiedlibbirdfont/SvgParser.valamodifiedlibbirdfont/TabBar.valamodifiedlibbirdfont/TestCases.vala
Diff
@@ -329,18 +329,6 @@ public class Font : GLib.Object { return g; }- - // FIXME: DELETE?- public void add_glyph (Glyph glyph) {- GlyphCollection? gc = get_glyph_collection (glyph.get_name ());- GlyphCollection c;- - if (gc == null) {- c = new GlyphCollection (glyph.get_unichar (), glyph.get_name ());- c.insert_glyph (glyph, false);- add_glyph_collection (c);- }- } public void add_glyph_collection (GlyphCollection glyph_collection) { GlyphCollection? gc;@@ -448,7 +436,7 @@ public class Font : GLib.Object { GlyphCollection? gc = null; gc = glyph_cache.get (unicode); - if (gc == null) {+ if (gc == null || ((!)gc).length () == 0) { return null; } @@ -1697,6 +1697,7 @@ public class Glyph : FontDisplay { public void insert_new_point_on_path (double x, double y) { double min, distance; Path? p = null;+ Path path; EditPoint? np = null; EditPoint lep; @@ -1723,10 +1724,12 @@ public class Glyph : FontDisplay { if (p == null) { return; }+ + path = (!) p; lep = new EditPoint ();- ((!)p).get_closest_point_on_path (lep, xt, yt);- ((!)p).insert_new_point_on_path (lep);+ path.get_closest_point_on_path (lep, xt, yt);+ path.insert_new_point_on_path (lep); } /** Merge selected paths. */@@ -212,8 +212,6 @@ public class MenuTab : FontDisplay { MainWindow.get_drawing_tools ().add_new_grid (); KerningTools.update_kerning_classes ();- - select_overview (); }); dialog.signal_save.connect (() => {@@ -228,7 +226,8 @@ public class MenuTab : FontDisplay { } set_suppress_event (false);- + select_overview ();+ return; } @@ -59,12 +59,14 @@ class GlyfData : GLib.Object { Path q; glyph = g;- + foreach (Path p in g.path_list) { if (p.points.length () > 0) { q = p.get_quadratic_points (); if (!is_empty (q)) {+ // Add point at extrema+ q.add_extrema (); paths.append (q); } }@@ -160,7 +160,7 @@ 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;+ g = ((!) gl).copy (); if (g.unichar_code <= 27) { // skip control characters continue;@@ -76,6 +76,7 @@ public class OverView : FontDisplay { bool selected; GlyphCollection? fg; Glyph glyph;+ GlyphCollection glyph_collection; GlyphCanvas canvas; name.append_unichar (character);@@ -87,13 +88,21 @@ public class OverView : FontDisplay { } else { fg = font.get_glyph_collection (name.str); }++ if (fg != null) {+ glyph_collection = (!) fg;+ glyph = glyph_collection.get_current ();+ } else {+ glyph_collection = new GlyphCollection (character, name.str);+ glyph = new Glyph (name.str, character);+ glyph_collection.insert_glyph (glyph, true);+ font.add_glyph_collection (glyph_collection);+ } - glyph = (fg == null) ? new Glyph (name.str, character) : ((!) fg).get_current ();- font.add_glyph (glyph); tabs.add_tab (glyph); canvas = MainWindow.get_glyph_canvas ();- canvas.set_current_glyph (glyph);+ canvas.set_current_glyph (glyph_collection.get_current ()); set_initial_zoom (); }@@ -2480,6 +2480,77 @@ public class Path { public static void find_intersection_handle (EditPointHandle h1, EditPointHandle h2, out double point_x, out double point_y) { find_intersection (h1.parent.x, h1.parent.y, h1.x (), h1.y (), h2.parent.x, h2.parent.y, h2.x (), h2.y (), out point_x, out point_y); }+ + public void add_extrema () {+ double x0, y0, x1, y1, x2, y2, x3, y3;+ double minx, maxx, miny, maxy;+ + if (unlikely (points.length () < 2)) {+ warning ("Missing points");+ return;+ }+ + minx = double.MAX;+ miny = double.MAX;+ maxx = double.MIN;+ maxy = double.MIN;+ + x0 = 0;+ y0 = 0; + x1 = 0;+ y1 = 0; + x2 = 0;+ y2 = 0;+ x3 = 0;+ y3 = 0;+ + all_of_path ((x, y) => {+ if (x < minx) {+ x0 = x;+ y0 = y;+ minx = x;+ }+ + if (x > maxx) {+ x1 = x;+ y1 = y;+ maxx = x;+ }++ if (y < miny) {+ x2 = x;+ y2 = y;+ miny = y;+ }+ + if (y > maxy) {+ x3 = x;+ y3 = y;+ maxy = y;+ }+ + return true;+ });+ + insert_new_point_on_path_at (x0 - 1, y0);+ insert_new_point_on_path_at (x1 + 1, y1);+ insert_new_point_on_path_at (x2, y2 - 1);+ insert_new_point_on_path_at (x3, y3 + 1);+ }+ + void insert_new_point_on_path_at (double x, double y) {+ EditPoint ep = new EditPoint ();+ bool exists;+ + get_closest_point_on_path (ep, x, y);++ exists = ep.get_prev ().data.x == ep.x && ep.get_prev ().data.y == ep.y;+ exists |= ep.get_next ().data.x == ep.x && ep.get_next ().data.y == ep.y;+ + if (!exists) {+ insert_new_point_on_path (ep);+ }+ } } }@@ -231,6 +231,7 @@ class SvgFont : GLib.Object { string glyph_name = ""; string svg = ""; Glyph glyph;+ GlyphCollection glyph_collection; double advance = font_advance; string ligature = ""; SvgParser parser = new SvgParser ();@@ -273,7 +274,10 @@ class SvgFont : GLib.Object { glyph.set_ligature_substitution (ligature); } - font.add_glyph (glyph);+ glyph_collection = new GlyphCollection (unicode_value, glyph_name);+ glyph_collection.insert_glyph (glyph, true);+ + font.add_glyph_collection (glyph_collection); } } @@ -239,6 +239,13 @@ public class SvgParser { return data; } + public void add_path_to_glyph (string d, Glyph g) {+ PathList p = parse_svg_data (d, g);+ foreach (Path path in p.paths) {+ g.add_path (path);+ }+ }+ /** * @param d svg data * @param glyph add paths to this glyph@@ -344,7 +344,14 @@ public class TabBar : GLib.Object { } public Tab get_selected_tab () {- return tabs.nth (get_selected ()).data;+ int s = get_selected ();+ if (0 <= s < tabs.length ()) {+ return tabs.nth (get_selected ()).data;+ }+ + warning ("No tab selected.");+ + return new Tab (new EmptyTab ("Error", "Error"), 30, false); } public uint get_length () {@@ -44,7 +44,8 @@ class TestCases { add (test_preview, "Preview"); add (test_kerning, "Kerning"); add (test_boundaries, "Boundaries");- + add (test_extrema, "Extrema");+ add_bechmark (benchmark_stroke, "Stroke"); } @@ -132,6 +133,23 @@ class TestCases { } } + public static void test_extrema () {+ Glyph g;+ SvgParser parser = new SvgParser ();+ + test_open_next_glyph ();+ g = MainWindow.get_current_glyph ();+ + parser.set_format (SvgFormat.INKSCAPE);+ parser.add_path_to_glyph ("m -163.59375,-250.78125 c -42.43208,51.5679 -78.92929,123.30265 -109.59375,216.03125 l 94.9375,31.375 c 27.9767,-84.600883 60.86301,-146.18598 91.875,-183.875 48.545803,-62.79748 104.513616,-52.47212 139.34375,-5.46875 25.619399,35.30837 51.38402,95.22476 69.625,178.625 l 97.6875,-21.375 c -20.20842,-92.39565 -48.64621,-164.00261 -86.375,-216 -88.811818,-115.9163 -218.868232,-92.82539 -297.5,0.6875 z", g);+ + Toolbox.select_tool_by_name ("full_glyph");+ + foreach (Path p in g.path_list) {+ p.add_extrema ();+ }+ }+ public static void test_freetype () { StringBuilder? data; int error;@@ -606,8 +624,6 @@ class TestCases { Glyph g; Path pn; - f.add_glyph (n);- test_open_next_glyph (); g = MainWindow.get_current_glyph (); foreach (Path p in n.path_list) {