The Birdfont Source Code


All Repositories / birdfont.git / commitdiff – RSS feed

Check if a point is inside of a path with curves.

These changes was commited to the Birdfont repository Sun, 12 Apr 2015 16:47:49 +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, 12 Apr 2015 16:47:49 +0000]

Updated Files

libbirdfont/Path.vala
libbirdfont/StrokeTool.vala
libbirdfont/SvgParser.vala
--- a/libbirdfont/Path.vala +++ b/libbirdfont/Path.vala @@ -2122,8 +2122,13 @@ public static int counters (PathList pl, Path path) { int inside_count = 0; bool inside; + PathList lines = new PathList (); foreach (Path p in pl.paths) { + lines.add (SvgParser.get_lines (path)); + } + + foreach (Path p in lines.paths) { if (p.points.size > 1 && p != path && path.boundaries_intersecting (p)) {
--- a/libbirdfont/StrokeTool.vala +++ b/libbirdfont/StrokeTool.vala @@ -19,7 +19,7 @@ public class StrokeTool : Tool { - static bool stroke_selected = false; + public static bool stroke_selected = false; static int iterations = 0; public StrokeTool (string tooltip) { @@ -1082,7 +1082,7 @@ && is_flat (x1, y1, x2, y2, x3, y3, tolerance); } - static bool is_flat (double x1, double y1, double x2, double y2, double x3, double y3, double tolerance = 0.01) { + public static bool is_flat (double x1, double y1, double x2, double y2, double x3, double y3, double tolerance = 0.01) { double ds = Path.distance (x1, x3, y1, y3); double d1 = Path.distance (x1, x2, y1, y2); double d2 = Path.distance (x2, x3, y2, y3);
--- a/libbirdfont/SvgParser.vala +++ b/libbirdfont/SvgParser.vala @@ -468,27 +468,96 @@ } } - /** Check if a point is inside using the even odd fill rule. */ + public static void create_lines_for_segment (Path path, EditPoint start, EditPoint end) { + double x1, x2, x3; + double y1, y2, y3; + double step_start, step, step_end; + + path.add (start.x, start.y); + + step_start = 0; + step = 0.5; + step_end = 1; + + while (true) { + Path.get_point_for_step (start, end, step_start, out x1, out y1); + Path.get_point_for_step (start, end, step, out x2, out y2); + Path.get_point_for_step (start, end, step_end, out x3, out y3); + + if (!StrokeTool.is_flat (x1, y1, x2, y2, x3, y3, 1) + && step_end - step / 2.0 > step_start + && step_end - step / 2.0 > 0.1 + && step > 0.05) { + + step /= 2.0; + + if (step < 0.05) { + step = 0.05; + } else { + step_end = step_start + 2 * step; + } + } else { + path.add (x3, y3); + + if (step_end + step < 1) { + step_start = step_end; + step_end += step; + } else { + break; + } + } + } + } + + // FIXME: cache lines in path + public static Path get_lines (Path p) { + EditPoint start; + Path path = new Path (); + + if (p.points.size == 0) { + return path; + } + + // create a set of straight lines + start = p.points.get (p.points.size - 1); + + foreach (EditPoint end in p.points) { + create_lines_for_segment (path, start, end); + start = end; + } + + if (StrokeTool.stroke_selected) { // FIXME: DELETE + ((!) BirdFont.get_current_font ().get_glyph ("b")).add_path (path); + path.recalculate_linear_handles (); + } + + return path; + } + + /** Check if a point is inside using the even odd fill rule. + * The path should only have straight lines. + */ public static bool is_inside (EditPoint point, Path path) { EditPoint prev; bool inside = false; + Path lines = path; - if (path.points.size == 0) { + if (path.points.size <= 1) { return false; } - + prev = path.get_last_point (); - - foreach (EditPoint p in path.points) { - if (p.x == point.x && point.y == p.y) { + + foreach (EditPoint start in path.points) { + if (start.x == point.x && point.y == start.y) { inside = true; break; - } else if ((p.y > point.y) != (prev.y > point.y) - && point.x < (prev.x - p.x) * (point.y - p.y) / (prev.y - p.y) + p.x) { + } else if ((start.y > point.y) != (prev.y > point.y) + && point.x < (prev.x - start.x) * (point.y - start.y) / (prev.y - start.y) + start.x) { inside = !inside; } - prev = p; + prev = start; } return inside;