The Birdfont Source Code


All Repositories / birdfont.git / commitdiff – RSS feed

Add extrema only if necessary

These changes was commited to the Birdfont repository Fri, 29 Dec 2017 15:54:12 +0000.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git
[Fri, 29 Dec 2017 15:54:12 +0000]

Updated Files

libbirdfont/OpenFontFormat/GlyfData.vala
libbirdfont/Path.vala
libbirdfont/TestCases.vala
--- a/libbirdfont/OpenFontFormat/GlyfData.vala +++ b/libbirdfont/OpenFontFormat/GlyfData.vala @@ -1,5 +1,5 @@ /* - Copyright (C) 2012, 2013, 2014 Johan Mattsson + Copyright (C) 2012, 2013, 2014 2017 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 @@ -16,20 +16,20 @@ namespace BirdFont { - public class CoordinateFlags { + public class CoordinateFlags : GLib.Object { /** TTF coordinate flags. */ - public static const uint8 NONE = 0; - public static const uint8 ON_PATH = 1 << 0; - public static const uint8 X_SHORT_VECTOR = 1 << 1; - public static const uint8 Y_SHORT_VECTOR = 1 << 2; - public static const uint8 REPEAT = 1 << 3; + public const uint8 NONE = 0; + public const uint8 ON_PATH = 1 << 0; + public const uint8 X_SHORT_VECTOR = 1 << 1; + public const uint8 Y_SHORT_VECTOR = 1 << 2; + public const uint8 REPEAT = 1 << 3; // same flag or short vector sign flag - public static const uint8 X_IS_SAME = 1 << 4; - public static const uint8 Y_IS_SAME = 1 << 5; - public static const uint8 X_SHORT_VECTOR_POSITIVE = 1 << 4; - public static const uint8 Y_SHORT_VECTOR_POSITIVE = 1 << 5; + public const uint8 X_IS_SAME = 1 << 4; + public const uint8 Y_IS_SAME = 1 << 5; + public const uint8 X_SHORT_VECTOR_POSITIVE = 1 << 4; + public const uint8 Y_SHORT_VECTOR_POSITIVE = 1 << 5; } @@ -64,17 +64,22 @@ int i = 0; foreach (Path p in all_quadratic.paths) { - if (p.points.size > 0) { - if (likely (!is_empty (p))) { - // Add points at extrema - p.add_extrema (); - qp.add (p); - } else { - warning (@"Path number $i is empty in $(glyph.get_name ())"); - } - i++; + if (p.points.size < 2) { + warning (@"Missing points, $(points.size) points in path."); + continue; } + + if (likely (!is_empty (p))) { + qp.add (p); + } else { + warning (@"Path number $i is empty in $(glyph.get_name ())"); + } + + i++; } + + // Add points at extrema + add_extrema_to_path (qp); points.clear (); paths.clear (); @@ -94,7 +99,137 @@ process_bounding_box (); } } + + public static void add_extrema_to_path (PathList path_list) { + double x0, y0, x1, y1, x2, y2, x3, y3; + double minx, maxx, miny, maxy; + Path path_minx, path_maxx, path_miny, path_maxy; + + path_minx = new Path (); + path_maxx = new Path (); + path_miny = new Path (); + path_maxy = new Path (); + + minx = Glyph.CANVAS_MAX; + miny = Glyph.CANVAS_MAX; + maxx = Glyph.CANVAS_MIN; + maxy = Glyph.CANVAS_MIN; + + x0 = 0; + y0 = 0; + x1 = 0; + y1 = 0; + x2 = 0; + y2 = 0; + x3 = 0; + y3 = 0; + + foreach (Path next_path in path_list.paths) { + if (next_path.points.size < 2) { + warning (@"Missing points, $(next_path.points.size) points in path."); + continue; + } + + next_path.all_of_path ((x, y) => { + if (x < minx) { + x0 = x; + y0 = y; + minx = x; + path_minx = next_path; + } + + if (x > maxx) { + x1 = x; + y1 = y; + maxx = x; + path_maxx = next_path; + } + if (y < miny) { + x2 = x; + y2 = y; + miny = y; + path_miny = next_path; + } + + if (y > maxy) { + x3 = x; + y3 = y; + maxy = y; + path_maxy = next_path; + } + + return true; + }, 3000); + } + + if (!has_extrema (path_minx, x0 + 0.001, true, true)) { + path_minx.insert_new_point_on_path_at (x0 - 0.001, y0); + } + + if (!has_extrema (path_maxx, x1 - 0.001, true, false)) { + path_maxx.insert_new_point_on_path_at (x1 + 0.001, y1); + } + + if (!has_extrema (path_maxy, y2 + 0.001, false, true)) { + path_maxy.insert_new_point_on_path_at (x2, y2 - 0.001); + } + + if (!has_extrema (path_miny, y3 - 0.001, false, false)) { + path_miny.insert_new_point_on_path_at (x3, y3 + 0.001); + } + } + + public static bool has_extrema (Path path, double coordinate, bool x, bool min) { + bool has_extrema = false; + + if (x && min) { + path.all_segments ((start, stop) => { + if (start.x < coordinate) { + has_extrema = true; + return false; + } + + return true; + }); + } + + if (x && !min) { + path.all_segments ((start, stop) => { + if (start.x > coordinate) { + has_extrema = true; + return false; + } + + return true; + }); + } + + if (!x && min) { + path.all_segments ((start, stop) => { + if (start.y < coordinate) { + has_extrema = true; + return false; + } + + return true; + }); + } + + if (!x && !min) { + path.all_segments ((start, stop) => { + if (start.y > coordinate) { + has_extrema = true; + return false; + } + + return true; + }); + } + + return has_extrema; + } + bool is_empty (Path p) { EditPoint? last = null;
--- a/libbirdfont/Path.vala +++ b/libbirdfont/Path.vala @@ -2174,63 +2174,6 @@ find_intersection (p1.x, p1.y, p2.x, p2.y, q1.x, q1.y, q2.x, q2.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.size < 2)) { - warning (@"Missing points, $(points.size) points in path."); - return; - } - - minx = Glyph.CANVAS_MAX; - miny = Glyph.CANVAS_MAX; - maxx = Glyph.CANVAS_MIN; - maxy = Glyph.CANVAS_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 - 0.001, y0); - insert_new_point_on_path_at (x1 + 0.001, y1); - insert_new_point_on_path_at (x2, y2 - 0.001); - insert_new_point_on_path_at (x3, y3 + 0.001); - } - public EditPoint insert_new_point_on_path_at (double x, double y) { EditPoint ep = new EditPoint (); EditPoint prev, next;
--- a/libbirdfont/TestCases.vala +++ b/libbirdfont/TestCases.vala @@ -44,7 +44,6 @@ add (test_preview, "Preview"); add (test_kerning, "Kerning"); add (test_boundaries, "Boundaries"); - add (test_extrema, "Extrema"); add (test_codepages, "Codepages"); add (test_double_quadratic, "Double quadratic"); add (test_raster_path, "Raster path"); @@ -177,23 +176,6 @@ glyph.update_view (); Tool.yield (); } - } - } - - 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.get_all_paths ()) { - p.add_extrema (); } }