summaryrefslogtreecommitdiff
path: root/src/export/render.rs
diff options
context:
space:
mode:
authorBirk Tjelmeland <git@birktj.no>2023-04-13 16:05:56 +0200
committerGitHub <noreply@github.com>2023-04-13 16:05:56 +0200
commitd1cd814ef8149cbac6e59c81e074aa59c930eed3 (patch)
tree02b9a8afed4d121b34d89669452f91cda19df8e2 /src/export/render.rs
parent46ce9c94e3f615751989d3cba5aa1599e0ba5913 (diff)
Add support for more complex strokes (#505)
Diffstat (limited to 'src/export/render.rs')
-rw-r--r--src/export/render.rs54
1 files changed, 51 insertions, 3 deletions
diff --git a/src/export/render.rs b/src/export/render.rs
index 8cee3aa6..f3c72ba0 100644
--- a/src/export/render.rs
+++ b/src/export/render.rs
@@ -11,7 +11,8 @@ use usvg::{FitTo, NodeExt};
use crate::doc::{Frame, FrameItem, GroupItem, Meta, TextItem};
use crate::geom::{
- self, Abs, Color, Geometry, Paint, PathItem, Shape, Size, Stroke, Transform,
+ self, Abs, Color, Geometry, LineCap, LineJoin, Paint, PathItem, Shape, Size, Stroke,
+ Transform,
};
use crate::image::{DecodedImage, Image};
@@ -392,9 +393,36 @@ fn render_shape(
canvas.fill_path(&path, &paint, rule, ts, mask);
}
- if let Some(Stroke { paint, thickness }) = &shape.stroke {
+ if let Some(Stroke {
+ paint,
+ thickness,
+ line_cap,
+ line_join,
+ dash_pattern,
+ miter_limit,
+ }) = &shape.stroke
+ {
+ let dash = dash_pattern.as_ref().and_then(|pattern| {
+ // tiny-skia only allows dash patterns with an even number of elements,
+ // while pdf allows any number.
+ let len = if pattern.array.len() % 2 == 1 {
+ pattern.array.len() * 2
+ } else {
+ pattern.array.len()
+ };
+ let dash_array =
+ pattern.array.iter().map(|l| l.to_f32()).cycle().take(len).collect();
+
+ sk::StrokeDash::new(dash_array, pattern.phase.to_f32())
+ });
let paint = paint.into();
- let stroke = sk::Stroke { width: thickness.to_f32(), ..Default::default() };
+ let stroke = sk::Stroke {
+ width: thickness.to_f32(),
+ line_cap: line_cap.into(),
+ line_join: line_join.into(),
+ dash,
+ miter_limit: miter_limit.0 as f32,
+ };
canvas.stroke_path(&path, &paint, &stroke, ts, mask);
}
@@ -525,6 +553,26 @@ impl From<Color> for sk::Color {
}
}
+impl From<&LineCap> for sk::LineCap {
+ fn from(line_cap: &LineCap) -> Self {
+ match line_cap {
+ LineCap::Butt => sk::LineCap::Butt,
+ LineCap::Round => sk::LineCap::Round,
+ LineCap::Square => sk::LineCap::Square,
+ }
+ }
+}
+
+impl From<&LineJoin> for sk::LineJoin {
+ fn from(line_join: &LineJoin) -> Self {
+ match line_join {
+ LineJoin::Miter => sk::LineJoin::Miter,
+ LineJoin::Round => sk::LineJoin::Round,
+ LineJoin::Bevel => sk::LineJoin::Bevel,
+ }
+ }
+}
+
/// Allows to build tiny-skia paths from glyph outlines.
struct WrappedPathBuilder(sk::PathBuilder);