The Birdfont Source Code


All Repositories / birdfont.git / commitdiff – RSS feed

Remove compiled python code and update merge code

These changes was commited to the Birdfont repository Sun, 02 Aug 2015 06:45:28 +0000.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git
[Sun, 02 Aug 2015 06:45:28 +0000]

Updated Files

libbirdfont/Intersection.vala
libbirdfont/Menu.vala
libbirdfont/Path.vala
libbirdfont/StrokeTool.vala
scripts/release.sh
--- a/libbirdfont/Intersection.vala +++ b/libbirdfont/Intersection.vala @@ -49,8 +49,8 @@ if (p == other_path) { return path; } - - warning ("Wrong intersection."); + + warning (@"Wrong intersection."); return new Path (); }
--- a/libbirdfont/Menu.vala +++ b/libbirdfont/Menu.vala @@ -232,7 +232,10 @@ // FIXME: overview MenuItem merge_paths = add_menu_item (t_("Merge Paths"), "merge_paths", "Glyph"); merge_paths.action.connect (() => { - StrokeTool.merge_selected_paths (); + Task t = new Task (); + t.task.connect (merge_selected_paths); + MainWindow.native_window.run_background_thread (t); + show_menu = false; }); edit_menu.items.add (merge_paths); @@ -490,8 +493,12 @@ add_tool_key_bindings (); load_key_bindings (); + } + + void merge_selected_paths () { + StrokeTool.merge_selected_paths (); } } }
--- a/libbirdfont/Path.vala +++ b/libbirdfont/Path.vala @@ -850,7 +850,10 @@ Path flat = new Path (); all_of_path ((x, y, t) => { - flat.add (x, y); + EditPoint ep = flat.add (x, y); + ep.type = PointType.LINE_QUADRATIC; + ep.get_right_handle ().type = PointType.LINE_QUADRATIC; + ep.get_left_handle ().type = PointType.LINE_QUADRATIC; return true; }, steps); // FIXME: g.view_zoom @@ -1381,7 +1384,8 @@ * Don't look for a point in the segment skip_previous to skip_next. */ public void get_closest_point_on_path (EditPoint edit_point, double x, double y, - EditPoint? skip_previous = null, EditPoint? skip_next = null) { + EditPoint? skip_previous = null, EditPoint? skip_next = null, + int steps = -1) { return_if_fail (points.size >= 1); double min = double.MAX; @@ -1440,16 +1444,10 @@ break; } - if (skip_previous != null && skip_next != null) { - EditPoint? si, sp; - si = i; - sp = prev; - - if (skip_previous == sp && skip_next == si) { - continue; - } + if (skip_previous == prev && skip_next == i) { + continue; } - + all_of (prev, i, (cx, cy, t) => { n = pow (x - cx, 2) + pow (y - cy, 2); @@ -1468,7 +1466,7 @@ } return true; - }); + }, steps); first = false; } @@ -1494,6 +1492,10 @@ edit_point.next = next_point; edit_point.set_position (ox, oy); + + edit_point.type = previous.type; + edit_point.get_left_handle ().type = previous.get_right_handle ().type; + edit_point.get_right_handle ().type = next.get_left_handle ().type; } public static bool all_of (EditPoint start, EditPoint stop,
--- a/libbirdfont/StrokeTool.vala +++ b/libbirdfont/StrokeTool.vala @@ -101,36 +101,202 @@ return m; } - public static PathList merge_selected_paths () { - PathList flat = new PathList (); - PathList o = new PathList (); + public static void merge_selected_paths () { Glyph g = MainWindow.get_current_glyph (); + PathList o = new PathList (); + PathList r; + PathList new_paths = new PathList (); g.store_undo_state (); + + foreach (Path p in g.active_paths) { + p.close (); + o.add (p); + } + + for (int i = 0; i < o.paths.size; i++) { + for (int j = 0; j < o.paths.size; j++) { + Path p1, p2; + + p1 = o.paths.get (i); + p2 = o.paths.get (j); + + if (i == j) { + continue; + } + + r = merge_selected (p1, p2); + + remove_merged_curve_parts (r); + + // FIXME: delete + print (@"Merge result $(r.paths.size) ($i, $j)\n"); + if (r.paths.size > 0) { + foreach (Path p in r.paths) { + foreach (EditPoint ep in p.points) { + ep.flags &= uint.MAX ^ + (EditPoint.INTERSECTION + | EditPoint.COPIED + | EditPoint.NEW_CORNER + | EditPoint.SELF_INTERSECTION); + } + p.update_region_boundaries (); + } + + new_paths.append (r); + /*o.paths.remove (p1); + o.paths.remove (p2); + */ + i = 0; + j = 0; + } + + //FIXME: delete + print (@"Remaining $(o.paths.size)\n"); + foreach (Path p in o.paths) { + print (@"p.points.size $(p.points.size)\n"); + } + } + } + + //o.append (new_paths); foreach (Path p in g.active_paths) { + g.delete_path (p); + } + + g.clear_active_paths (); + + remove_merged_curve_parts (new_paths); + + foreach (Path p in new_paths.paths) { + g.add_path (p); + g.add_active_path (null, p); + } + + GlyphCanvas.redraw (); + } + + static void remove_merged_curve_parts (PathList r) { + Gee.ArrayList<Path> remove = new Gee.ArrayList<Path> (); + PathList flat = new PathList (); + + print (@"remove_merged_curve_parts: $(r.paths.size)\n"); + + foreach (Path p in r.paths) { + p.update_region_boundaries (); + flat.add (p.flatten ()); + } + + foreach (Path p in r.paths) { + PathList pl = get_insides (flat, p); + + int counters = 0; + int clockwise = 0; + + foreach (Path i in pl.paths) { + if (i.is_clockwise ()) { + clockwise++; + } else { + counters++; + } + } + + print (@"clockwise $clockwise counters $counters pl.size $(pl.paths.size)\n"); + + if (p.is_clockwise ()) { + int c = clockwise - counters; + if (c % 2 == 0) { + //remove.add (p); + break; + } + } else { + int c = clockwise - counters; + if (c % 2 == 1) { + //remove.add (p); + break; + } + } + } + + foreach (Path p in remove) { + r.paths.remove (p); + remove_merged_curve_parts (r); + return; + } + } + + public static PathList merge_selected (Path path1, Path path2) { + PathList flat = new PathList (); + PathList o = new PathList (); + PathList pl = new PathList (); + PathList r = new PathList (); + + pl.add (path1); + pl.add (path2); + + if (!path1.boundaries_intersecting (path2)) { + return r; + } + + foreach (Path p in pl.paths) { if (p.stroke == 0) { - o.add (p.copy ()); + o.add (p); flat.add (p.copy ().flatten (50)); } } flat = merge (flat); + foreach (Path p in flat.paths) { + ((!) BirdFont.get_current_font ().get_glyph_by_name ("b")).add_path (p); + } + + bool has_split_point = false; foreach (Path p in flat.paths) { foreach (EditPoint ep in p.points) { if ((ep.flags & EditPoint.SPLIT_POINT) > 0) { foreach (Path pp in o.paths) { EditPoint lep = new EditPoint (); - pp.get_closest_point_on_path (lep, ep.x, ep.y); + pp.get_closest_point_on_path (lep, ep.x, ep.y, null, null); + + if (Path.distance_to_point (lep, (!) lep.prev) < 0.1 + || Path.distance_to_point (lep, (!) lep.next) < 0.1) { + // FIXME: find a better solution + continue; + } if (Path.distance_to_point (ep, lep) < 0.1) { - // self intersection EditPoint lep2 = new EditPoint (); pp.get_closest_point_on_path (lep2, ep.x, ep.y, lep.prev, lep.next); - if (Path.distance_to_point (ep, lep2) < 0.01 - && Path.distance_to_point (lep, lep2) < 0.01) { + if (lep.prev != null) { + lep.get_left_handle ().type = lep.get_prev ().get_right_handle ().type; + } else { + lep.get_left_handle ().type = pp.get_last_point ().get_right_handle ().type; + } + + if (lep.next != null) { + lep.get_right_handle ().type = lep.get_next ().get_left_handle ().type; + } else { + lep.get_left_handle ().type = pp.get_first_point ().get_right_handle ().type; + } + + if (lep2.prev != null) { + lep2.get_left_handle ().type = lep2.get_prev ().get_right_handle ().type; + } else { + lep2.get_left_handle ().type = pp.get_first_point ().get_right_handle ().type; + } + + if (lep2.next != null) { + lep2.get_right_handle ().type = lep2.get_next ().get_left_handle ().type; + } else { + lep2.get_left_handle ().type = pp.get_last_point ().get_right_handle ().type; + } + + // self intersection + if (Path.distance_to_point (ep, lep2) < 0.1 + && Path.distance_to_point (ep, lep) < 0.1) { pp.insert_new_point_on_path (lep); pp.insert_new_point_on_path (lep2); @@ -140,17 +306,31 @@ lep.tie_handles = false; lep.reflective_point = false; lep2.tie_handles = false; - lep2.reflective_point = false; + lep2.reflective_point = false; + + // FIXME: DELETE + lep2.color = Color.magenta (); + lep.color = Color.magenta (); } else { pp.insert_new_point_on_path (lep); lep.flags |= EditPoint.INTERSECTION; lep.tie_handles = false; lep.reflective_point = false; + + // FIXME: DELETE + lep2.color = Color.pink (); + lep.color = Color.pink (); } + + has_split_point = true; } } } } + } + + if (!has_split_point) { + return r; } // remove double intersection points @@ -159,8 +339,8 @@ foreach (EditPoint ep in pp.points) { if (((prev.flags & EditPoint.SELF_INTERSECTION) > 0 || (prev.flags & EditPoint.INTERSECTION) > 0) && ((ep.flags & EditPoint.SELF_INTERSECTION) > 0 || (ep.flags & EditPoint.INTERSECTION) > 0) - && fabs (ep.x - prev.x) < 0.1 - && fabs (ep.y - prev.y) < 0.1) { + && fabs (ep.x - prev.x) < 0.2 + && fabs (ep.y - prev.y) < 0.2) { prev.deleted = true; } @@ -172,94 +352,35 @@ pp.remove_deleted_points (); } - o = merge_curves (o, flat); - - // FIXME: remove split points - - foreach (Path p in g.active_paths) { - g.delete_path (p); - } - - g.clear_active_paths (); - foreach (Path p in o.paths) { foreach (EditPoint ep in p.points) { - ep.flags &= uint.MAX ^ - (EditPoint.INTERSECTION - | EditPoint.COPIED - | EditPoint.NEW_CORNER - | EditPoint.SELF_INTERSECTION); - ep.flags = 0; + ep.flags &= uint.MAX ^ EditPoint.COPIED; } - p.update_region_boundaries (); - - g.add_path (p); - g.add_active_path (null, p); } - - GlyphCanvas.redraw (); - - return o; - } - - static PathList merge_curves (PathList pl, PathList flat) { - PathList r = new PathList (); - - if (pl.paths.size != 2) { - warning ("FIXME: more than two paths"); - return pl; + + foreach (Path p in o.paths) { + ((!) BirdFont.get_current_font ().get_glyph_by_name ("a")).add_path (p); } - r = merge_paths_with_curves (pl.paths.get (0), pl.paths.get (1)); - remove_curves_inside (r); + return_val_if_fail (o.paths.size == 2, r); + + Path p1, p2; - return r; - } - - static void remove_curves_inside (PathList r) { - PathList flat = new PathList (); - Gee.ArrayList<Path> remove = new Gee.ArrayList<Path> (); - int c; + p1 = o.paths.get (0); + p2 = o.paths.get (1); - foreach (Path p in r.paths) { - p.update_region_boundaries (); - Path f = p.flatten (50); - flat.add (f); - } + r = merge_paths_with_curves (p1, p2); - foreach (Path p in r.paths) { - c = counters (flat, p); - bool cp = Path.is_counter (flat, p); - - if (c > 1) { - if (c % 2 != 0) { // path is always inside the outline in flat - if (!p.is_clockwise ()) { - remove.add (p); - } - } else { - if (p.is_clockwise ()) { - remove.add (p); - } - } - } + print (@"Result $(r.paths.size)\n"); + if (r.paths.size > 0) { + o.paths.remove (p1); + o.paths.remove (p2); + o.append (r); } + + // FIXME: remove split points - foreach (Path p in r.paths) { - bool inter = true; - foreach (EditPoint ep in p.points) { - if ((ep.flags & EditPoint.INTERSECTION) == 0) { - inter = false; - } - } - - if (inter) { - remove.add (p); - } - } - - foreach (Path p in remove) { - r.paths.remove (p); - } + return r; } static PathList merge_paths_with_curves (Path path1, Path path2) { @@ -276,9 +397,10 @@ flat1 = path1.flatten (); flat2 = path2.flatten (); - return_val_if_fail (path1.points.size > 1, r); - return_val_if_fail (path2.points.size > 1, r); - + if (path1.points.size <= 1 || path2.points.size <= 1) { + return r; + } + // reset copied points foreach (EditPoint n in path2.points) { n.flags &= uint.MAX ^ EditPoint.COPIED; @@ -383,13 +505,13 @@ find_parts = true; new_start = inter; current = new_start.path; - break; } } if (new_path.points.size > 0) { new_path.close (); new_path.recalculate_linear_handles (); + new_path.update_region_boundaries (); r.add (new_path); } @@ -420,6 +542,7 @@ previous = ep1; + print (@"INTERSECTION: $(ep1.x), $(ep1.y)\n"); new_start = intersections.get_point (ep1, out other); current = new_start.get_other_path (current); i = index_of (current, new_start.get_point (current)); @@ -436,7 +559,7 @@ Path.get_point_for_step (ep1, ep2, 0.5, out px, out py); - // FIXME: for merging outline with counters + // FIXME: merging outline with counters bool inside = (current == path1 && flat2.is_over_coordinate (px, py)) || (current == path2 && flat1.is_over_coordinate (px, py)); @@ -468,6 +591,7 @@ if ((ep1.flags & EditPoint.SELF_INTERSECTION) > 0) { bool other; + print ("SELF_INTERSECTION:\n"); new_start = intersections.get_point (ep1, out other); i = index_of (current, other ? new_start.point : new_start.other_point); @@ -1774,7 +1898,6 @@ c = counters (r, p); if (c % 2 == 0) { - if (!p.is_clockwise ()) { remove.add (p); } @@ -1789,6 +1912,32 @@ r.paths.remove (p); } } + + public static PathList get_insides (PathList pl, Path path) { + bool inside = false; + PathList insides = new PathList (); + + foreach (Path p in pl.paths) { + if (p.points.size > 1 + && p != path + && path.boundaries_intersecting (p)) { + + inside = true; + foreach (EditPoint ep in path.points) { + if (!is_inside (ep, p)) { + inside = false; + break; + } + } + + if (inside) { + insides.add (path); + } + } + } + + return insides; + } public static int counters (PathList pl, Path path) { int inside_count = 0; @@ -1879,6 +2028,14 @@ EditPoint intersection_point, other_intersection_point; bool path1_direction, path2_direction; + if (path1.points.size == 0) { + return false; + } + + if (path2.points.size == 0) { + return false; + } + error = false; merged_paths = new PathList (); intersections = new IntersectionList ();
--- a/scripts/release.sh +++ b/scripts/release.sh @@ -46,6 +46,7 @@ cd birdfont-$version python3 ./scripts/complete_translations.py -t 93 -i + rm -rf ./scripts/__pycache__ cd .. tar -cf birdfont-$version.tar birdfont-$version