1use zpdf_core::{Matrix, Point, Rect};
2
3#[derive(Debug, Clone)]
4pub struct DisplayList {
5 pub page_rect: Rect,
6 pub commands: Vec<RenderCommand>,
7}
8
9impl DisplayList {
10 pub fn new(page_rect: Rect) -> Self {
11 Self {
12 page_rect,
13 commands: Vec::new(),
14 }
15 }
16
17 pub fn push(&mut self, cmd: RenderCommand) {
18 self.commands.push(cmd);
19 }
20}
21
22#[derive(Debug, Clone)]
23pub enum RenderCommand {
24 FillPath {
25 path: Path,
26 rule: FillRule,
27 paint: Paint,
28 alpha: f32,
29 },
30 StrokePath {
31 path: Path,
32 style: StrokeStyle,
33 paint: Paint,
34 alpha: f32,
35 },
36 DrawGlyphRun(GlyphRun),
37 DrawImage(ImageDraw),
38 PushClip {
39 path: Path,
40 rule: FillRule,
41 },
42 PushClipStroke {
46 path: Path,
47 style: StrokeStyle,
48 },
49 PopClip,
50 PushBlendGroup {
51 blend_mode: BlendMode,
52 isolated: bool,
53 knockout: bool,
54 bounds: Rect,
55 alpha: f32,
58 mask: Option<SoftMask>,
60 },
61 PopBlendGroup,
62}
63
64#[derive(Debug, Clone)]
68pub struct SoftMask {
69 pub kind: SoftMaskKind,
70 pub commands: std::sync::Arc<DisplayList>,
73 pub offset: (f32, f32),
78 pub backdrop_luma: f32,
81 pub transfer: Option<std::sync::Arc<[u8; 256]>>,
83}
84
85#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
86pub enum SoftMaskKind {
87 Luminosity,
89 Alpha,
91}
92
93#[derive(Debug, Clone)]
96pub struct Path {
97 pub elements: Vec<PathElement>,
98}
99
100impl Path {
101 pub fn new() -> Self {
102 Self {
103 elements: Vec::new(),
104 }
105 }
106
107 pub fn move_to(&mut self, p: Point) {
108 self.elements.push(PathElement::MoveTo(p));
109 }
110
111 pub fn line_to(&mut self, p: Point) {
112 self.elements.push(PathElement::LineTo(p));
113 }
114
115 pub fn curve_to(&mut self, c1: Point, c2: Point, end: Point) {
116 self.elements.push(PathElement::CurveTo(c1, c2, end));
117 }
118
119 pub fn close(&mut self) {
120 self.elements.push(PathElement::Close);
121 }
122
123 pub fn rect(&mut self, r: Rect) {
124 self.move_to(Point::new(r.x0, r.y0));
125 self.line_to(Point::new(r.x1, r.y0));
126 self.line_to(Point::new(r.x1, r.y1));
127 self.line_to(Point::new(r.x0, r.y1));
128 self.close();
129 }
130
131 pub fn is_empty(&self) -> bool {
132 self.elements.is_empty()
133 }
134}
135
136impl Default for Path {
137 fn default() -> Self {
138 Self::new()
139 }
140}
141
142#[derive(Debug, Clone, Copy)]
143pub enum PathElement {
144 MoveTo(Point),
145 LineTo(Point),
146 CurveTo(Point, Point, Point),
147 Close,
148}
149
150#[derive(Debug, Clone, Copy, PartialEq, Eq)]
151pub enum FillRule {
152 NonZero,
153 EvenOdd,
154}
155
156#[derive(Debug, Clone)]
159pub struct StrokeStyle {
160 pub width: f32,
161 pub cap: LineCap,
162 pub join: LineJoin,
163 pub miter_limit: f32,
164 pub dash: Option<DashPattern>,
165}
166
167impl Default for StrokeStyle {
168 fn default() -> Self {
169 Self {
170 width: 1.0,
171 cap: LineCap::Butt,
172 join: LineJoin::Miter,
173 miter_limit: 10.0,
174 dash: None,
175 }
176 }
177}
178
179#[derive(Debug, Clone, Copy, PartialEq, Eq)]
180pub enum LineCap {
181 Butt,
182 Round,
183 Square,
184}
185
186#[derive(Debug, Clone, Copy, PartialEq, Eq)]
187pub enum LineJoin {
188 Miter,
189 Round,
190 Bevel,
191}
192
193#[derive(Debug, Clone)]
194pub struct DashPattern {
195 pub array: Vec<f32>,
196 pub phase: f32,
197}
198
199#[derive(Debug, Clone, Copy)]
202pub struct Color {
203 pub r: f32,
204 pub g: f32,
205 pub b: f32,
206 pub a: f32,
207}
208
209impl Color {
210 pub fn rgb(r: f32, g: f32, b: f32) -> Self {
211 Self { r, g, b, a: 1.0 }
212 }
213
214 pub fn rgba(r: f32, g: f32, b: f32, a: f32) -> Self {
215 Self { r, g, b, a }
216 }
217
218 pub fn gray(v: f32) -> Self {
219 Self::rgb(v, v, v)
220 }
221
222 pub fn black() -> Self {
223 Self::gray(0.0)
224 }
225
226 pub fn white() -> Self {
227 Self::gray(1.0)
228 }
229}
230
231#[derive(Debug, Clone)]
232pub enum Paint {
233 Solid(Color),
234 Pattern(u32),
235 Shading(u32),
236}
237
238pub type FontId = u32;
241pub type ImageId = u32;
242
243#[derive(Debug, Clone)]
244pub struct GlyphRun {
245 pub font_id: FontId,
246 pub font_size: f32,
247 pub glyphs: Vec<PositionedGlyph>,
248 pub paint: Paint,
249 pub alpha: f32,
250 pub transform: Matrix,
251 pub h_scale: f32,
255}
256
257#[derive(Debug, Clone, Copy)]
258pub struct PositionedGlyph {
259 pub glyph_id: u16,
260 pub x: f32,
261 pub y: f32,
262 pub advance: f32,
263}
264
265#[derive(Debug, Clone)]
268pub struct ImageDraw {
269 pub image_id: ImageId,
270 pub transform: Matrix,
271 pub alpha: f32,
272}
273
274#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
277pub enum BlendMode {
278 #[default]
279 Normal,
280 Multiply,
281 Screen,
282 Overlay,
283 Darken,
284 Lighten,
285 ColorDodge,
286 ColorBurn,
287 HardLight,
288 SoftLight,
289 Difference,
290 Exclusion,
291 Hue,
292 Saturation,
293 Color,
294 Luminosity,
295}