Composite modes on the GLES canvas: Canvas::set_composite_mode and CompositeMode, completing the blend state the previous commit already applies
CI / build + test (push) Canceled after 0s
CI / cargo audit (push) Canceled after 0s

A canvas only composited source-over. A host that draws Porter-Duff modes, as Android's Canvas does with an xfermode, had to read the pixels back, combine them on the CPU and upload them again, which on the GLES backend meant a glReadPixels and a fresh texture for every such draw.
The new `CompositeMode` in types.rs, exported from the crate root, names the Porter-Duff operators (Clear, Src, Dst, SrcOver, DstOver, SrcIn, DstIn, SrcOut, DstOut, SrcAtop, DstAtop, Xor) and the separable modes with an exact premultiplied form (Plus, Multiply, Screen); SrcOver is the default. Darken and Lighten are left out, since GL can only approximate them where alpha is below one.
`Canvas::set_composite_mode` sets how the following draws, blits included, combine with the canvas. On a GLES canvas it stores the mode, which `activate_target` turns into the blend function before every draw: each canvas carries its own, because the GL blend state is global and canvases share one context. A sub-canvas starts in SrcOver and does not inherit its parent's mode. A software canvas ignores the call and keeps compositing source-over. The field, its initialisation and `apply_composite` landed with the previous commit; this one adds the type and the public entry point they use, without which that commit does not build.
The inset shadow, which switches the blend for one draw, now restores the canvas's mode instead of always going back to source-over.
This commit is contained in:
2026-10-19 22:16:17 +02:00
parent 20dc21448e
commit 1a39c43762
3 changed files with 34 additions and 2 deletions
+9
View File
@@ -497,6 +497,15 @@ impl Canvas
}
}
/// How the following draws, blits included, combine with the canvas. GPU canvases only; a software canvas always composites src-over.
pub fn set_composite_mode( &mut self, mode: crate::types::CompositeMode )
{
if let Canvas::Gles( c ) = self
{
c.set_composite_mode( mode );
}
}
/// Shared font handle. Exposed so widgets that need raw face
/// access (e.g. `Text` for ascent/descent) do not have to go
/// through wrappers for every metric they read.