rpdfium_render/renderdevicedriver_iface.rs
1// Derived from PDFium's core/fxge/cfx_renderdevice.h
2// Original: Copyright 2014 The PDFium Authors
3// Licensed under BSD-3-Clause / Apache-2.0
4// See pdfium-upstream/LICENSE for the original license.
5
6//! Render backend trait defining the interface for 2D rendering engines.
7
8use rpdfium_core::Matrix;
9use rpdfium_graphics::{Bitmap, BlendMode, ClipPath, FillRule, PathOp};
10
11use crate::color_convert::RgbaColor;
12use crate::image::DecodedImage;
13use crate::stroke::StrokeStyle;
14
15/// Trait for a 2D rendering backend.
16///
17/// Implementations provide the actual drawing operations (fill, stroke, clip,
18/// compositing) using a concrete rendering library (e.g., tiny-skia).
19pub trait RenderBackend: Send {
20 /// The surface type used by this backend.
21 type Surface;
22
23 /// Create a new rendering surface with the given dimensions and background.
24 fn create_surface(&self, width: u32, height: u32, bg: &RgbaColor) -> Self::Surface;
25
26 /// Fill a path with the given color and transform.
27 fn fill_path(
28 &mut self,
29 surface: &mut Self::Surface,
30 ops: &[PathOp],
31 fill_rule: FillRule,
32 color: &RgbaColor,
33 transform: &Matrix,
34 );
35
36 /// Fill a path with anti-aliasing forced off.
37 ///
38 /// Used by shading subdivision where upstream PDFium uses `full_cover = true`
39 /// to avoid visible seams between adjacent sub-patches.
40 fn fill_path_no_aa(
41 &mut self,
42 surface: &mut Self::Surface,
43 ops: &[PathOp],
44 fill_rule: FillRule,
45 color: &RgbaColor,
46 transform: &Matrix,
47 ) {
48 // Default: fall back to normal (AA-enabled) fill.
49 self.fill_path(surface, ops, fill_rule, color, transform);
50 }
51
52 /// Stroke a path with the given style, color, and transform.
53 fn stroke_path(
54 &mut self,
55 surface: &mut Self::Surface,
56 ops: &[PathOp],
57 style: &StrokeStyle,
58 color: &RgbaColor,
59 transform: &Matrix,
60 );
61
62 /// Draw a decoded image with the given transform.
63 ///
64 /// When `interpolate` is true, the backend should use bilinear (or higher)
65 /// filtering instead of nearest-neighbor. This matches PDFium's auto-bilinear
66 /// heuristic for upscaled images (see `CStretchEngine::UseInterpolateBilinear`).
67 fn draw_image(
68 &mut self,
69 surface: &mut Self::Surface,
70 image: &DecodedImage,
71 transform: &Matrix,
72 interpolate: bool,
73 );
74
75 /// Push a clipping region onto the clip stack.
76 fn push_clip(&mut self, surface: &mut Self::Surface, clip: &ClipPath, transform: &Matrix);
77
78 /// Pop the most recent clipping region.
79 fn pop_clip(&mut self, surface: &mut Self::Surface);
80
81 /// Begin a transparency group with the given blend mode, opacity, and
82 /// transparency group attributes.
83 fn push_group(
84 &mut self,
85 surface: &mut Self::Surface,
86 blend_mode: BlendMode,
87 opacity: f32,
88 isolated: bool,
89 knockout: bool,
90 );
91
92 /// End the current transparency group, compositing it onto the surface below.
93 fn pop_group(&mut self, surface: &mut Self::Surface);
94
95 /// Set a soft mask on the topmost group entry.
96 ///
97 /// The mask is provided as a single-channel alpha buffer (one byte per pixel,
98 /// row-major, same dimensions as the surface). Implementations store it so
99 /// that `pop_group` can apply the mask during compositing.
100 fn set_group_mask(&mut self, _alpha_data: Vec<u8>, _width: u32, _height: u32) {
101 // Default: ignore mask (backends that don't support soft masks).
102 }
103
104 /// Return the dimensions `(width, height)` of the given surface.
105 fn surface_dimensions(&self, surface: &Self::Surface) -> (u32, u32);
106
107 /// Draw the content of `src` over `dst` using normal (SourceOver) blending.
108 ///
109 /// This is used to composite rendered content (on a transparent backdrop)
110 /// onto a background-color surface.
111 fn composite_over(&mut self, dst: &mut Self::Surface, src: &Self::Surface);
112
113 /// Draw a pre-rasterized alpha bitmap at the given position with the given color.
114 ///
115 /// The alpha data is a row-major single-channel bitmap. Each pixel in the output
116 /// should be colored with `color` modulated by the alpha value.
117 #[allow(clippy::too_many_arguments)]
118 fn draw_alpha_bitmap(
119 &mut self,
120 _surface: &mut Self::Surface,
121 _alpha: &[u8],
122 _width: u32,
123 _height: u32,
124 _bearing_x: i32,
125 _bearing_y: i32,
126 _color: &RgbaColor,
127 _transform: &Matrix,
128 ) {
129 // Default: no-op (backends that don't support alpha bitmaps fall back to outline rendering)
130 }
131
132 /// Set whether anti-aliasing is enabled for subsequent fill/stroke operations.
133 ///
134 /// Backends may ignore this hint. The default implementation is a no-op.
135 fn set_antialiasing(&mut self, _enabled: bool) {}
136
137 /// Return the raw pixel data of the surface as premultiplied RGBA bytes.
138 fn surface_pixels(&self, surface: &Self::Surface) -> Vec<u8>;
139
140 /// Finish rendering and return the final bitmap.
141 fn finish(self, surface: Self::Surface) -> Bitmap;
142}