1use super::geometry::{Bounds, BoundsBuilder, Transform};
4use super::path_builder::{PathBuilder, TransformSink};
5use super::path_data::PathData;
6use super::raster::HeapStorage;
7use super::segment::Segment;
8use super::stroke::stroke_with_storage;
9use super::style::{Fill, Style};
10
11use crate::lib::Vec;
12use core::borrow::Borrow;
13
14#[derive(Default)]
16pub struct Scratch {
17 pub(super) inner: Inner,
18 pub(super) render: HeapStorage,
19}
20
21impl Scratch {
22 pub fn new() -> Self {
24 Self::default()
25 }
26
27 pub fn apply<'a>(
29 &mut self,
30 data: impl PathData,
31 style: impl Into<Style<'a>>,
32 transform: Option<Transform>,
33 sink: &mut impl PathBuilder,
34 ) -> Fill {
35 self.inner.apply(data, &style.into(), transform, sink)
36 }
37
38 pub fn bounds<'a>(
40 &mut self,
41 data: impl PathData,
42 style: impl Into<Style<'a>>,
43 transform: Option<Transform>,
44 ) -> Bounds {
45 let style = style.into();
46 let mut bounds = BoundsBuilder::new();
47 self.apply(data, style, transform, &mut bounds);
48 bounds.build()
49 }
50}
51
52#[derive(Default)]
53pub(super) struct Inner {
54 pub segments: Vec<Segment>,
55}
56
57impl Inner {
58 pub fn apply(
59 &mut self,
60 data: impl PathData,
61 style: &Style,
62 transform: Option<Transform>,
63 sink: &mut impl PathBuilder,
64 ) -> Fill {
65 match style {
66 Style::Fill(fill) => {
67 if let Some(transform) = transform {
68 let mut transform_sink = TransformSink { sink, transform };
69 data.copy_to(&mut transform_sink);
70 *fill
71 } else {
72 data.copy_to(sink);
73 *fill
74 }
75 }
76 Style::Stroke(stroke) => {
77 if let Some(transform) = transform {
78 if stroke.scale {
79 let mut transform_sink = TransformSink { sink, transform };
80 stroke_with_storage(
81 data.commands(),
82 stroke,
83 &mut transform_sink,
84 &mut self.segments,
85 );
86 } else {
87 stroke_with_storage(
88 data.commands()
89 .map(|cmd| cmd.borrow().transform(&transform)),
90 stroke,
91 sink,
92 &mut self.segments,
93 );
94 }
95 } else {
96 stroke_with_storage(data.commands(), stroke, sink, &mut self.segments);
97 }
98 Fill::NonZero
99 }
100 }
101 }
102}