aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjaseg <git@jaseg.de>2021-04-25 15:41:50 +0200
committerjaseg <git@jaseg.de>2021-04-25 15:41:50 +0200
commit6eb2c967a05a698b3da81168bcbcdc8c8368b490 (patch)
tree585b561e6cf03254adc504fd910ed4123240150f
parent1790ef9137b79af448ea6f8e3018ddd4c0f33b05 (diff)
downloadgerbolyze-6eb2c967a05a698b3da81168bcbcdc8c8368b490.tar.gz
gerbolyze-6eb2c967a05a698b3da81168bcbcdc8c8368b490.tar.bz2
gerbolyze-6eb2c967a05a698b3da81168bcbcdc8c8368b490.zip
svg-flatten: Add support for patterned strokes on outline layers
-rw-r--r--svg-flatten/src/svg_doc.cpp68
1 files changed, 33 insertions, 35 deletions
diff --git a/svg-flatten/src/svg_doc.cpp b/svg-flatten/src/svg_doc.cpp
index 6d41aca..bd22058 100644
--- a/svg-flatten/src/svg_doc.cpp
+++ b/svg-flatten/src/svg_doc.cpp
@@ -306,7 +306,7 @@ void gerbolyze::SVGDocument::export_svg_path(xform2d &mat, const RenderSettings
/* Special case: A closed path becomes a number of open paths when it is dashed. */
if (dasharray.empty()) {
- if (rset.outline_mode) {
+ if (rset.outline_mode && stroke_color != GRB_PATTERN_FILL) {
/* In outline mode, manually close polys */
poly.push_back(poly[0]);
*polygon_sink << ApertureToken() << poly;
@@ -321,7 +321,7 @@ void gerbolyze::SVGDocument::export_svg_path(xform2d &mat, const RenderSettings
Paths out;
dash_path(poly_copy, out, dasharray);
- if (rset.outline_mode) {
+ if (rset.outline_mode && stroke_color != GRB_PATTERN_FILL) {
*polygon_sink << ApertureToken(stroke_width) << out;
} else {
offx.AddPaths(out, join_type, end_type);
@@ -333,50 +333,48 @@ void gerbolyze::SVGDocument::export_svg_path(xform2d &mat, const RenderSettings
Paths out;
dash_path(poly, out, dasharray);
- if (rset.outline_mode) {
+ if (rset.outline_mode && stroke_color != GRB_PATTERN_FILL) {
*polygon_sink << ApertureToken(stroke_width) << out;
} else {
offx.AddPaths(out, join_type, end_type);
}
}
- if (!rset.outline_mode) {
- /* Execute clipper offset operation to generate stroke outlines */
- offx.Execute(ptree, 0.5 * stroke_width * clipper_scale);
-
- /* Clip. Note that after the outline, all we have is closed paths as any open path's stroke outline is itself
- * a closed path. */
- if (!clip_path.empty()) {
- Clipper c;
-
- Paths outline_paths;
- PolyTreeToPaths(ptree, outline_paths);
- c.AddPaths(outline_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);
- }
+ /* Execute clipper offset operation to generate stroke outlines */
+ offx.Execute(ptree, 0.5 * stroke_width * clipper_scale);
- /* Call out to pattern tiler for pattern strokes. The stroke's outline becomes the clip here. */
- if (stroke_color == GRB_PATTERN_FILL) {
- string stroke_pattern_id = usvg_id_url(node.attribute("stroke").value());
- Pattern *pattern = lookup_pattern(stroke_pattern_id);
- if (!pattern) {
- cerr << "Warning: Fill pattern with id \"" << stroke_pattern_id << "\" not found." << endl;
+ /* Clip. Note that after the outline, all we have is closed paths as any open path's stroke outline is itself
+ * a closed path. */
+ if (!clip_path.empty()) {
+ Clipper c;
- } else {
- Paths clip;
- PolyTreeToPaths(ptree, clip);
- pattern->tile(local_xf, rset, clip);
- }
+ Paths outline_paths;
+ PolyTreeToPaths(ptree, outline_paths);
+ c.AddPaths(outline_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);
+ }
- } else {
- Paths s_polys;
- dehole_polytree(ptree, s_polys);
+ /* Call out to pattern tiler for pattern strokes. The stroke's outline becomes the clip here. */
+ if (stroke_color == GRB_PATTERN_FILL) {
+ string stroke_pattern_id = usvg_id_url(node.attribute("stroke").value());
+ Pattern *pattern = lookup_pattern(stroke_pattern_id);
+ if (!pattern) {
+ cerr << "Warning: Fill pattern with id \"" << stroke_pattern_id << "\" not found." << endl;
- *polygon_sink << ApertureToken() << (stroke_color == GRB_DARK ? GRB_POL_DARK : GRB_POL_CLEAR) << s_polys;
+ } else {
+ Paths clip;
+ PolyTreeToPaths(ptree, clip);
+ pattern->tile(local_xf, rset, clip);
}
+
+ } else if (!rset.outline_mode) {
+ Paths s_polys;
+ dehole_polytree(ptree, s_polys);
+
+ *polygon_sink << ApertureToken() << (stroke_color == GRB_DARK ? GRB_POL_DARK : GRB_POL_CLEAR) << s_polys;
}
}
*polygon_sink << ApertureToken();