1use crate::CacheKey;
2use crate::color::Color;
3use crate::pattern::Pattern;
4use crate::util::hash128;
5use crate::x_object::ImageXObject;
6use kurbo::{BezPath, Cap, Join};
7use smallvec::{SmallVec, smallvec};
8
9#[derive(Debug, Clone)]
11pub struct ClipPath {
12 pub path: BezPath,
14 pub fill: FillRule,
16}
17
18impl CacheKey for ClipPath {
19 fn cache_key(&self) -> u128 {
20 hash128(&(&self.path.to_svg(), &self.fill))
21 }
22}
23
24pub struct StencilImage<'a, 'b> {
26 pub(crate) paint: Paint<'a>,
27 pub(crate) image_xobject: ImageXObject<'b>,
28}
29
30impl<'a, 'b> StencilImage<'a, 'b> {
31 pub fn with_stencil(&self, func: impl FnOnce(LumaData, &Paint<'a>)) {
33 if let Some(luma) = self
34 .image_xobject
35 .decoded_object()
36 .and_then(|d| d.luma_data)
37 {
38 func(luma, &self.paint);
39 }
40 }
41}
42
43impl CacheKey for StencilImage<'_, '_> {
44 fn cache_key(&self) -> u128 {
45 self.image_xobject.cache_key()
46 }
47}
48
49pub struct RasterImage<'a>(pub(crate) ImageXObject<'a>);
51
52impl RasterImage<'_> {
53 pub fn with_rgba(&self, func: impl FnOnce(RgbData, Option<LumaData>)) {
55 let decoded = self.0.decoded_object();
56
57 if let Some(decoded) = decoded
58 && let Some(rgb) = decoded.rgb_data
59 {
60 func(rgb, decoded.luma_data)
61 }
62 }
63}
64
65impl CacheKey for RasterImage<'_> {
66 fn cache_key(&self) -> u128 {
67 self.0.cache_key()
68 }
69}
70
71pub enum Image<'a, 'b> {
73 Stencil(StencilImage<'a, 'b>),
75 Raster(RasterImage<'b>),
77}
78
79impl CacheKey for Image<'_, '_> {
80 fn cache_key(&self) -> u128 {
81 match self {
82 Image::Stencil(i) => i.cache_key(),
83 Image::Raster(i) => i.cache_key(),
84 }
85 }
86}
87
88#[derive(Clone)]
90pub struct RgbData {
91 pub data: Vec<u8>,
93 pub width: u32,
95 pub height: u32,
97 pub interpolate: bool,
99}
100
101#[derive(Clone)]
103pub struct LumaData {
104 pub data: Vec<u8>,
106 pub width: u32,
108 pub height: u32,
110 pub interpolate: bool,
112}
113
114#[derive(Clone, Debug)]
116pub enum Paint<'a> {
117 Color(Color),
119 Pattern(Box<Pattern<'a>>),
121}
122
123impl CacheKey for Paint<'_> {
124 fn cache_key(&self) -> u128 {
125 match self {
126 Paint::Color(c) => {
127 hash128(&c.to_rgba().to_rgba8())
130 }
131 Paint::Pattern(p) => p.cache_key(),
132 }
133 }
134}
135
136#[derive(Clone, Debug)]
138pub enum PathDrawMode {
139 Fill(FillRule),
141 Stroke(StrokeProps),
143}
144
145#[derive(Clone, Debug)]
147pub enum GlyphDrawMode {
148 Fill,
150 Stroke(StrokeProps),
152}
153
154#[derive(Clone, Debug)]
156pub struct StrokeProps {
157 pub line_width: f32,
159 pub line_cap: Cap,
161 pub line_join: Join,
163 pub miter_limit: f32,
165 pub dash_array: SmallVec<[f32; 4]>,
167 pub dash_offset: f32,
169}
170
171impl Default for StrokeProps {
172 fn default() -> Self {
173 Self {
174 line_width: 1.0,
175 line_cap: Cap::Butt,
176 line_join: Join::Miter,
177 miter_limit: 10.0,
178 dash_array: smallvec![],
179 dash_offset: 0.0,
180 }
181 }
182}
183
184#[derive(Clone, Debug, Copy, Hash, PartialEq, Eq)]
186pub enum FillRule {
187 NonZero,
189 EvenOdd,
191}