aboutsummaryrefslogtreecommitdiff
path: root/svg-flatten/src/svg_doc.cpp
diff options
context:
space:
mode:
authorjaseg <git-bigdata-wsl-arch@jaseg.de>2021-02-17 18:33:31 +0100
committerjaseg <git-bigdata-wsl-arch@jaseg.de>2021-02-17 18:33:31 +0100
commitf9c5c00f513e6c6be70b033782976fd109eb4ac9 (patch)
tree2ecfeff36cd18cb3feb51a5383ff49cc1f73dce3 /svg-flatten/src/svg_doc.cpp
parent901efc75c6fb7d31a4549f876f8b780f2728ae28 (diff)
downloadgerbolyze-f9c5c00f513e6c6be70b033782976fd109eb4ac9.tar.gz
gerbolyze-f9c5c00f513e6c6be70b033782976fd109eb4ac9.tar.bz2
gerbolyze-f9c5c00f513e6c6be70b033782976fd109eb4ac9.zip
svg-flatten: Fix fill-rule handling for filled open paths
Diffstat (limited to 'svg-flatten/src/svg_doc.cpp')
-rw-r--r--svg-flatten/src/svg_doc.cpp28
1 files changed, 15 insertions, 13 deletions
diff --git a/svg-flatten/src/svg_doc.cpp b/svg-flatten/src/svg_doc.cpp
index 0ae9b68..f387bcc 100644
--- a/svg-flatten/src/svg_doc.cpp
+++ b/svg-flatten/src/svg_doc.cpp
@@ -234,29 +234,32 @@ void gerbolyze::SVGDocument::export_svg_path(const RenderSettings &rset, const p
cairo_save(cr);
apply_cairo_transform_from_svg(cr, node.attribute("transform").value());
+ PolyTree ptree_stroke;
+ PolyTree ptree_fill;
PolyTree ptree;
- load_svg_path(cr, node, ptree);
+ load_svg_path(cr, node, ptree_stroke, ptree_fill);
double _y = 0;
cairo_user_to_device_distance(cr, &stroke_width, &_y);
cairo_restore (cr);
- Paths open_paths, closed_paths;
- OpenPathsFromPolyTree(ptree, open_paths);
- ClosedPathsFromPolyTree(ptree, closed_paths);
+ Paths open_paths, closed_paths, fill_paths;
+ OpenPathsFromPolyTree(ptree_stroke, open_paths);
+ ClosedPathsFromPolyTree(ptree_stroke, closed_paths);
+ PolyTreeToPaths(ptree_fill, fill_paths);
/* Skip filling for transparent fills */
if (fill_color) {
/* Clip paths. Consider all paths closed for filling. */
if (!clip_path.empty()) {
Clipper c;
- c.AddPaths(open_paths, ptSubject, /* closed */ false);
- c.AddPaths(closed_paths, ptSubject, /* closed */ true);
+ c.AddPaths(fill_paths, ptSubject, /* closed */ true);
c.AddPaths(clip_path, ptClip, /* closed */ true);
c.StrictlySimple(true);
/* fill rules are nonzero since both subject and clip have already been normalized by clipper. */
c.Execute(ctIntersection, ptree, pftNonZero, pftNonZero);
+ PolyTreeToPaths(ptree, fill_paths);
}
/* Call out to pattern tiler for pattern fills. The path becomes the clip here. */
@@ -267,16 +270,14 @@ void gerbolyze::SVGDocument::export_svg_path(const RenderSettings &rset, const p
cerr << "Warning: Fill pattern with id \"" << fill_pattern_id << "\" not found." << endl;
} else {
- Paths clip;
- PolyTreeToPaths(ptree, clip);
- pattern->tile(rset, clip);
+ pattern->tile(rset, fill_paths);
}
} else { /* solid fill */
Paths f_polys;
/* Important for gerber spec compliance and also for reliable rendering results irrespective of board house
* and gerber viewer. */
- dehole_polytree(ptree, f_polys);
+ dehole_polytree(ptree_fill, f_polys);
/* Export SVG */
cairo_save(cr);
@@ -475,15 +476,16 @@ void gerbolyze::SVGDocument::load_clips() {
* rendering, and the only way a group might stay is if it affects rasterization (e.g. through mask, clipPath).
*/
for (const auto &child : node.children("path")) {
- PolyTree ptree;
+ PolyTree ptree_stroke; /* discarded */
+ PolyTree ptree_fill;
cairo_save(cr);
/* TODO: we currently only support clipPathUnits="userSpaceOnUse", not "objectBoundingBox". */
apply_cairo_transform_from_svg(cr, child.attribute("transform").value());
- load_svg_path(cr, child, ptree);
+ load_svg_path(cr, child, ptree_stroke, ptree_fill);
cairo_restore (cr);
Paths paths;
- PolyTreeToPaths(ptree, paths);
+ PolyTreeToPaths(ptree_fill, paths);
c.AddPaths(paths, ptSubject, /* closed */ false);
}