pub trait RenderDevice {
// Required methods
fn fill_path(
&mut self,
path: &BezPath,
t: Affine,
brush: &Brush<'_>,
rule: FillRule,
aa: AntiAlias,
);
fn stroke_path(
&mut self,
path: &BezPath,
t: Affine,
brush: &Brush<'_>,
stroke: &Stroke,
aa: AntiAlias,
);
fn draw_image(
&mut self,
img: &RasterImage,
t: Affine,
quality: ImageQuality,
alpha: f32,
);
fn push_clip(&mut self, path: &BezPath, rule: FillRule);
fn push_clip_rect(&mut self, rect: Rect);
fn push_layer(
&mut self,
blend: BlendMode,
alpha: f32,
mask: Option<&AlphaMask>,
);
fn pop(&mut self);
// Provided method
fn draw_glyph_lcd(
&mut self,
glyph: &SubpixelBitmap,
origin: (f64, f64),
colour: Color,
) { ... }
}Expand description
The device a page is drawn into: six primitives plus a hard-edged rect clip, all object-safe.
The engine holds one of these per render target — the page, each transparency group, each soft mask, each pattern cell — and never learns which rasterizer is behind it.
Required Methods§
Sourcefn fill_path(
&mut self,
path: &BezPath,
t: Affine,
brush: &Brush<'_>,
rule: FillRule,
aa: AntiAlias,
)
fn fill_path( &mut self, path: &BezPath, t: Affine, brush: &Brush<'_>, rule: FillRule, aa: AntiAlias, )
Fill path (in user space) transformed by t.
Sourcefn stroke_path(
&mut self,
path: &BezPath,
t: Affine,
brush: &Brush<'_>,
stroke: &Stroke,
aa: AntiAlias,
)
fn stroke_path( &mut self, path: &BezPath, t: Affine, brush: &Brush<'_>, stroke: &Stroke, aa: AntiAlias, )
Stroke path (in user space) transformed by t.
The engine has already resolved the stroke’s device width — including
the one-device-pixel minimum — and normalised its dash array to an
even-length, all-positive list, so stroke is always directly usable.
Sourcefn draw_image(
&mut self,
img: &RasterImage,
t: Affine,
quality: ImageQuality,
alpha: f32,
)
fn draw_image( &mut self, img: &RasterImage, t: Affine, quality: ImageQuality, alpha: f32, )
Draw img with its own pixel grid mapped through t, at a
constant alpha.
t maps image pixel (0, 0)’s corner to its device position, so an
identity transform is a texel-for-pixel blit at the origin and a
translation moves it whole pixels — not a unit-square mapping.
Reading t the other way collapses a whole-page image onto a single
pixel, which is silent and total.
An image being reduced has already been box-filtered down to roughly
its device size by crate::stretch::prescale, so t scales it by
less than a pixel in each axis and the two-tap kernel below is running
near 1:1. An image being enlarged arrives at its own resolution, which
is where the two-tap kernel is the right one and quality chooses it.
Sourcefn push_clip(&mut self, path: &BezPath, rule: FillRule)
fn push_clip(&mut self, path: &BezPath, rule: FillRule)
Intersect the clip with path (already in device space).
Sourcefn push_clip_rect(&mut self, rect: Rect)
fn push_clip_rect(&mut self, rect: Rect)
Intersect the clip with an axis-aligned rectangle, hard-edged.
PDFium’s SetClip_PathFill takes a rect fast path that snaps to the
outer integer rect and applies it with no antialiasing at all; re W n
is the commonest clip in the corpus, so routing it through
RenderDevice::push_clip would add a soft pixel along every clipped
edge on a large fraction of the corpus.
Sourcefn push_layer(&mut self, blend: BlendMode, alpha: f32, mask: Option<&AlphaMask>)
fn push_layer(&mut self, blend: BlendMode, alpha: f32, mask: Option<&AlphaMask>)
Begin a layer that will be composited back with blend, scaled by
alpha and masked by mask.
mask, when present, is device-sized and device-aligned. That is an
invariant, not a convention: a mismatched mask is silently ignored by
vello_cpu and merely warned about by tiny-skia, so violating it
fails open, producing unmasked output. Backends assert it.
Provided Methods§
Sourcefn draw_glyph_lcd(
&mut self,
glyph: &SubpixelBitmap,
origin: (f64, f64),
colour: Color,
)
fn draw_glyph_lcd( &mut self, glyph: &SubpixelBitmap, origin: (f64, f64), colour: Color, )
Blit one glyph whose coverage is three values per pixel, one per LCD stripe, each merged into its own destination channel.
The oracle’s ClearType text
(DrawNormalTextHelper’s MergeGammaAdjustRgb arm): for each pixel and
each channel c, dest_c = (dest_c·(255 − a_c) + colour_c·a_c) / 255
where a_c = coverage_c · colour_alpha / 255, and the destination is
left opaque. Three independent alphas is exactly what
RenderDevice::draw_image cannot express — one RGBA pixel carries one
— which is why this is its own primitive rather than a flag on that one.
origin is the device position of the bitmap’s top-left corner, in
whole pixels: both terms of it are integers by construction, so there is
nothing to resample and a backend blits texel for pixel.
Defaulted to grayscale. The default averages each pixel’s three
coverages and draws the result through RenderDevice::draw_image, so
a backend that cannot address channels separately still renders the text
— in grey, without the colour fringes, which is what every other run
of text on the page looks like anyway. That is a visible difference from
the oracle on live-edit text and nothing worse: no glyph goes missing and
no geometry moves. A backend that owns its pixels should override it.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".