The Birdfont Source Code


All Repositories / birdfont.git / commit – RSS feed

Better SVG import (fix the fill property problem)

These changes was commited to the Birdfont repository Fri, 13 Mar 2015 13:34:42 +0000.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git
author Johan Mattsson <johan.mattsson.m@gmail.com>
Fri, 13 Mar 2015 13:34:42 +0000 (14:34 +0100)
committer Johan Mattsson <johan.mattsson.m@gmail.com>
Fri, 13 Mar 2015 13:37:53 +0000 (14:37 +0100)
commit 51e0b9fc0a6ef8bad77177d53bd1672e543a60e7
tree 7f0ce03771494217a58be17c6a8522bfdf6c3593
parent aa91bb94fc25bd7612136cd15a1dd2789d408b3a
Better SVG import (fix the fill property problem)
Conver SVG paths that uses the even odd rule to paths using the non-zero rule.

libbirdfont/SvgParser.vala
--- a/libbirdfont/SvgParser.vala +++ b/libbirdfont/SvgParser.vala @@ -444,11 +444,41 @@ private void parse_path (Tag tag, Layer pl) { Glyph glyph = MainWindow.get_current_glyph (); PathList path_list = new PathList (); - + int inside_count; + bool inside; + foreach (Attribute attr in tag.get_attributes ()) { if (attr.get_name () == "d") { path_list = parse_svg_data (attr.get_content (), glyph); pl.paths.append (path_list); + } + } + + // assume the even odd rule is applied and convert the path + // to a path using the non-zero rule + foreach (Path p1 in pl.paths.paths) { + inside_count = 0; + + foreach (Path p2 in pl.paths.paths) { + if (p1 != p2) { + inside = true; + + foreach (EditPoint ep in p1.points) { + if (!is_inside (ep, p2)) { + inside = false; + } + } + + if (inside) { + inside_count++; + } + } + } + + if (inside_count % 2 == 0) { + p1.force_direction (Direction.CLOCKWISE); + } else { + p1.force_direction (Direction.COUNTER_CLOCKWISE); } } @@ -458,7 +488,30 @@ } } } - + + /** Check if a point is inside using the even odd fill rule. */ + bool is_inside (EditPoint point, Path path) { + EditPoint prev; + bool inside = false; + + if (path.points.size == 0) { + return false; + } + + prev = path.points.get (path.points.size - 1); + + foreach (EditPoint p in path.points) { + 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) { + inside = !inside; + } + + prev = p; + } + + return inside; + } + /** Add space as separator to svg data. * @param d svg data */