pdf_interpret/device.rs
1use crate::font::Glyph;
2use crate::soft_mask::SoftMask;
3use crate::{BlendMode, ClipPath, Image};
4use crate::{GlyphDrawMode, Paint, PathDrawMode};
5use kurbo::{Affine, BezPath, Rect, Shape};
6
7/// A trait for a device that can be used to process PDF drawing instructions.
8pub trait Device<'a> {
9 /// Set the properties for future stroking operations.
10 /// Set a soft mask to be used for future drawing instructions.
11 fn set_soft_mask(&mut self, mask: Option<SoftMask<'a>>);
12 /// Set the blend mode that should be used for rendering operations.
13 fn set_blend_mode(&mut self, blend_mode: BlendMode);
14 /// Draw a path.
15 fn draw_path(
16 &mut self,
17 path: &BezPath,
18 transform: Affine,
19 paint: &Paint<'a>,
20 draw_mode: &PathDrawMode,
21 );
22 /// Push a new clip path to the clip stack.
23 fn push_clip_path(&mut self, clip_path: &ClipPath);
24 /// Push a new transparency group to the blend stack.
25 fn push_transparency_group(
26 &mut self,
27 opacity: f32,
28 mask: Option<SoftMask<'a>>,
29 blend_mode: BlendMode,
30 );
31 /// Draw a glyph.
32 fn draw_glyph(
33 &mut self,
34 glyph: &Glyph<'a>,
35 transform: Affine,
36 glyph_transform: Affine,
37 paint: &Paint<'a>,
38 // TODO: Move this into outline glyph.
39 draw_mode: &GlyphDrawMode,
40 );
41 /// Draw an image.
42 fn draw_image(&mut self, image: Image<'a, '_>, transform: Affine);
43 /// Pop the last clip path from the clip stack.
44 fn pop_clip_path(&mut self);
45 /// Pop the last transparency group from the blend stack.
46 fn pop_transparency_group(&mut self);
47 /// Draw a rectangle directly, without going through the general path pipeline.
48 fn draw_rect(
49 &mut self,
50 rect: &Rect,
51 transform: Affine,
52 paint: &Paint<'a>,
53 draw_mode: &PathDrawMode,
54 ) {
55 self.draw_path(&rect.to_path(0.1), transform, paint, draw_mode);
56 }
57 /// Called at the beginning of a marked content sequence (BMC/BDC).
58 ///
59 /// The tag is the marked content tag (e.g. b"P", b"Span"). The mcid is
60 /// the marked content identifier from the properties dict, if present.
61 ///
62 /// `actual_text` is the sequence's `/ActualText` (PDF 32000-1 §14.9.4)
63 /// already decoded from its text-string encoding: the characters the
64 /// producer says this sequence *is*, whatever its glyphs decode to. A
65 /// text extractor must prefer it over the glyphs; a rendering device has
66 /// no use for it and the default implementation ignores it.
67 fn begin_marked_content(
68 &mut self,
69 _tag: &[u8],
70 _mcid: Option<i32>,
71 _actual_text: Option<&str>,
72 ) {
73 }
74 /// Called at the end of a marked content sequence (EMC).
75 fn end_marked_content(&mut self) {}
76 /// Text the page carries at a known place with no glyph drawn for it.
77 ///
78 /// `rect` is where that text sits, already in the device's own coordinate
79 /// system. The one producer today is a form field whose widget has no
80 /// appearance stream to draw: the value is in `/V` and nothing paints it,
81 /// so a device that reads glyphs would never see it (#549). A rendering
82 /// device has nothing to draw either -- synthesising the missing
83 /// appearance is a different job -- and the default implementation
84 /// ignores it.
85 fn draw_placed_text(&mut self, _text: &str, _rect: Rect) {}
86 /// Called when a TJ-array numeric adjustment is encountered between
87 /// substrings. Positive values shift text backward, negative values shift
88 /// it forward (1/1000 em units, per PDF §9.4.3). Text extractors use this
89 /// as a high-confidence word-boundary signal.
90 // ANN[r17/TEX1] Raw TJ offset surfaced so TextExtractionDevice can use it
91 // as the highest-confidence signal in the multi-signal space-detection
92 // consensus. Default is no-op to stay transparent to rendering devices.
93 fn text_adjustment(&mut self, _amount: f32) {}
94}
95
96/// A device that discards all drawing operations.
97pub struct DummyDevice;
98
99impl Device<'_> for DummyDevice {
100 fn set_soft_mask(&mut self, _: Option<SoftMask<'_>>) {}
101 fn set_blend_mode(&mut self, _: BlendMode) {}
102 fn draw_path(&mut self, _: &BezPath, _: Affine, _: &Paint<'_>, _: &PathDrawMode) {}
103 fn push_clip_path(&mut self, _: &ClipPath) {}
104 fn push_transparency_group(&mut self, _: f32, _: Option<SoftMask<'_>>, _: BlendMode) {}
105 fn draw_glyph(
106 &mut self,
107 _: &Glyph<'_>,
108 _: Affine,
109 _: Affine,
110 _: &Paint<'_>,
111 _: &GlyphDrawMode,
112 ) {
113 }
114 fn draw_image(&mut self, _: Image<'_, '_>, _: Affine) {}
115 fn pop_clip_path(&mut self) {}
116 fn pop_transparency_group(&mut self) {}
117}