diff options
| author | Birk Tjelmeland <git@birktj.no> | 2023-04-13 16:05:56 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-13 16:05:56 +0200 |
| commit | d1cd814ef8149cbac6e59c81e074aa59c930eed3 (patch) | |
| tree | 02b9a8afed4d121b34d89669452f91cda19df8e2 /src/export/pdf | |
| parent | 46ce9c94e3f615751989d3cba5aa1599e0ba5913 (diff) | |
Add support for more complex strokes (#505)
Diffstat (limited to 'src/export/pdf')
| -rw-r--r-- | src/export/pdf/page.rs | 60 |
1 files changed, 55 insertions, 5 deletions
diff --git a/src/export/pdf/page.rs b/src/export/pdf/page.rs index 636d42c7..d6ead124 100644 --- a/src/export/pdf/page.rs +++ b/src/export/pdf/page.rs @@ -1,5 +1,7 @@ use ecow::eco_format; -use pdf_writer::types::{ActionType, AnnotationType, ColorSpaceOperand}; +use pdf_writer::types::{ + ActionType, AnnotationType, ColorSpaceOperand, LineCapStyle, LineJoinStyle, +}; use pdf_writer::writers::ColorSpace; use pdf_writer::{Content, Filter, Finish, Name, Rect, Ref, Str}; @@ -7,8 +9,8 @@ use super::{deflate, AbsExt, EmExt, PdfContext, RefExt, D65_GRAY, SRGB}; use crate::doc::{Destination, Frame, FrameItem, GroupItem, Meta, TextItem}; use crate::font::Font; use crate::geom::{ - self, Abs, Color, Em, Geometry, Numeric, Paint, Point, Ratio, Shape, Size, Stroke, - Transform, + self, Abs, Color, Em, Geometry, LineCap, LineJoin, Numeric, Paint, Point, Ratio, + Shape, Size, Stroke, Transform, }; use crate::image::Image; @@ -250,8 +252,17 @@ impl PageContext<'_, '_> { fn set_stroke(&mut self, stroke: &Stroke) { if self.state.stroke.as_ref() != Some(stroke) { + let Stroke { + paint, + thickness, + line_cap, + line_join, + dash_pattern, + miter_limit, + } = stroke; + let f = |c| c as f32 / 255.0; - let Paint::Solid(color) = stroke.paint; + let Paint::Solid(color) = paint; match color { Color::Luma(c) => { self.set_stroke_color_space(D65_GRAY); @@ -267,7 +278,26 @@ impl PageContext<'_, '_> { } } - self.content.set_line_width(stroke.thickness.to_f32()); + self.content.set_line_width(thickness.to_f32()); + if self.state.stroke.as_ref().map(|s| &s.line_cap) != Some(line_cap) { + self.content.set_line_cap(line_cap.into()); + } + if self.state.stroke.as_ref().map(|s| &s.line_join) != Some(line_join) { + self.content.set_line_join(line_join.into()); + } + if self.state.stroke.as_ref().map(|s| &s.dash_pattern) != Some(dash_pattern) { + if let Some(pattern) = dash_pattern { + self.content.set_dash_pattern( + pattern.array.iter().map(|l| l.to_f32()), + pattern.phase.to_f32(), + ); + } else { + self.content.set_dash_pattern([], 0.0); + } + } + if self.state.stroke.as_ref().map(|s| &s.miter_limit) != Some(miter_limit) { + self.content.set_miter_limit(miter_limit.0 as f32); + } self.state.stroke = Some(stroke.clone()); } } @@ -486,3 +516,23 @@ fn write_link(ctx: &mut PageContext, pos: Point, dest: &Destination, size: Size) ctx.links.push((dest.clone(), rect)); } + +impl From<&LineCap> for LineCapStyle { + fn from(line_cap: &LineCap) -> Self { + match line_cap { + LineCap::Butt => LineCapStyle::ButtCap, + LineCap::Round => LineCapStyle::RoundCap, + LineCap::Square => LineCapStyle::ProjectingSquareCap, + } + } +} + +impl From<&LineJoin> for LineJoinStyle { + fn from(line_join: &LineJoin) -> Self { + match line_join { + LineJoin::Miter => LineJoinStyle::MiterJoin, + LineJoin::Round => LineJoinStyle::RoundJoin, + LineJoin::Bevel => LineJoinStyle::BevelJoin, + } + } +} |
