pub struct GlesCanvas {
pub gl: Arc<Context>,
pub version: GlesVersion,
pub font: Arc<Font>,
pub font_bytes: Arc<Vec<u8>>,
pub font_face: u32,
pub font_registry: Option<Arc<FontRegistry>>,
pub dpi_scale: f32,
pub global_alpha: f32,
pub width: u32,
pub height: u32,
/* private fields */
}Expand description
GPU-accelerated canvas using EGL + GLES2/3.
Renders into a persistent FBO (the “shadow canvas”) so widget
pixels survive across frames — this mirrors the software pixmap
model and is what enables the partial-redraw path on the GPU side.
Self::present blits the FBO onto the default framebuffer; the
caller is responsible for the eglSwapBuffers that follows.
Fields§
§gl: Arc<Context>§version: GlesVersion§font: Arc<Font>Default font loaded from the system via helpers::find_font.
Kept as a fallback for callers that do not route through the
theme registry.
font_bytes: Arc<Vec<u8>>Raw bytes of the default font. Required by rustybuzz for
HarfBuzz shaping (see the text_shaping private module). Kept on the
canvas so the shape pipeline has direct access without a
global lookup.
font_face: u32TTC sub-face index for the default font (0 for non-.ttc files).
font_registry: Option<Arc<FontRegistry>>Optional theme font registry. Populated by the runtime after
theme load; until then it is None and Self::font_for
falls back to Self::font.
dpi_scale: f32§global_alpha: f32§width: u32§height: u32Implementations§
Source§impl GlesCanvas
impl GlesCanvas
pub fn new( gl: Arc<Context>, version: GlesVersion, width: u32, height: u32, ) -> Self
Sourcepub fn sub_canvas(&self, width: u32, height: u32) -> GlesCanvas
pub fn sub_canvas(&self, width: u32, height: u32) -> GlesCanvas
Build a sub-canvas: a separate render target sharing this canvas’s GL
context, font, shader programs, geometry, and uniform locations, but
with its own FBO + color texture sized to width × height. Used to
render content into an off-screen target that can then be composited
back via Self::blit.
The returned canvas inherits the parent’s dpi_scale and global_alpha
(so glyphs render at the same pixel size). Its glyph cache starts empty
— re-rasterising on first use is the cost of not sharing GL textures
across canvases.
pub fn size(&self) -> (u32, u32)
Sourcepub fn clear_gradient_cache(&mut self)
pub fn clear_gradient_cache(&mut self)
Discard all cached gradient LUT textures. Call after a theme change so stale LUTs for old palette colours are freed and rebuilt fresh.
pub fn dpi_scale(&self) -> f32
pub fn set_dpi_scale(&mut self, s: f32)
pub fn global_alpha(&self) -> f32
pub fn set_global_alpha(&mut self, a: f32)
pub fn font(&self) -> &Font
Sourcepub fn set_font_registry(&mut self, registry: Arc<FontRegistry>)
pub fn set_font_registry(&mut self, registry: Arc<FontRegistry>)
Install a theme font registry so Self::font_for can resolve
family+weight+style triples declared by the theme’s fonts block.
Sourcepub fn font_for(&self, family: &str, weight: u16, style: FontStyle) -> Arc<Font>
pub fn font_for(&self, family: &str, weight: u16, style: FontStyle) -> Arc<Font>
Resolve a specific font from the theme registry, falling back to the
canvas’ default Self::font when no registry is installed or the
triple cannot be satisfied.
Sourcepub fn font_for_char(&self, ch: char) -> Arc<Font>
pub fn font_for_char(&self, ch: char) -> Arc<Font>
Pick the right font for ch. Tries the primary Self::font
first; on a miss, delegates to the crate-private system-fonts
fallback chain (lazy load of the relevant Noto pack). Falls
back to the primary (which paints a .notdef box) when no
installed fallback covers the codepoint.
pub fn font_metrics(&self, ch: char, size: f32) -> Metrics
pub fn font_line_metrics(&self, size: f32) -> Option<LineMetrics>
Source§impl GlesCanvas
impl GlesCanvas
pub fn blit(&mut self, src: &GlesCanvas, dest_x: i32, dest_y: i32)
Sourcepub fn blit_fade_bottom(
&mut self,
src: &GlesCanvas,
dest_x: i32,
dest_y: i32,
fade_bottom_px: f32,
)
pub fn blit_fade_bottom( &mut self, src: &GlesCanvas, dest_x: i32, dest_y: i32, fade_bottom_px: f32, )
Blit src into this canvas at ( dest_x, dest_y ), optionally feathering
the last fade_bottom_px source rows so the bottom edge dissolves into
transparency instead of cutting off cleanly. Used by viewports whose
bottom edge is the leading edge of a slide-down animation, where a hard
cut against the underlying layer reads as a knife. With fade_bottom_px == 0.0 this matches Self::blit exactly.
Sourcepub fn borrowed_texture(&self) -> BorrowedGlesTexture
pub fn borrowed_texture(&self) -> BorrowedGlesTexture
Return a borrowed descriptor for the FBO color texture containing the latest rendered pixels.
y_inverted is true: the FBO uses GL’s native lower-left
origin, so row 0 in texture memory is the bottom of the
rendered image. Consumers that follow the same convention flip
during sampling when this flag is set, producing a correctly-
oriented result. The CPU-side counterpart
Self::read_rgba_pixels does the same flip inline so the
byte buffer is top-down.
Sourcepub fn read_rgba_pixels(&self, out: &mut [u8]) -> Result<(), String>
pub fn read_rgba_pixels(&self, out: &mut [u8]) -> Result<(), String>
Read the FBO color attachment into out as tightly packed RGBA8,
top-left row first.
This is a compatibility escape hatch. It forces a GPU→CPU sync and should not be used in steady-state hot paths.
Sourcepub fn present(&mut self)
pub fn present(&mut self)
Blit the FBO color attachment onto the default framebuffer (the EGL
window). Caller is responsible for the eglSwapBuffers that
publishes the result. After present, the FBO is rebound so the next
frame’s draws keep accumulating into the shadow canvas.
The blit always covers the full surface — partial-redraw still saves work upstream (only changed widget pixels are repainted into the FBO), but the FBO→FB0 transfer itself is a single cheap fullscreen op.
Source§impl GlesCanvas
impl GlesCanvas
pub fn set_clip_rects(&mut self, rects: &[Rect])
pub fn clear_clip(&mut self)
Sourcepub fn clip_bounds_snapshot(&self) -> Vec<Rect>
pub fn clip_bounds_snapshot(&self) -> Vec<Rect>
Snapshot of the active scissor as a Vec<Rect> (empty when no
scissor is set).
Sourcepub fn fill(&mut self, color: Color)
pub fn fill(&mut self, color: Color)
Clear to a solid color. Honours the active scissor — if a clip is set, only the clipped region is filled.
Sourcepub fn clear_rects_transparent(&mut self, rects: &[Rect])
pub fn clear_rects_transparent(&mut self, rects: &[Rect])
Zero the pixels inside each rect (alpha+RGB → 0).
Source§impl GlesCanvas
impl GlesCanvas
pub fn fill_rect(&mut self, rect: Rect, color: Color, corners: Corners)
Sourcepub fn fill_linear_gradient_rect(
&mut self,
rect: Rect,
g: &LinearGradient,
corners: Corners,
)
pub fn fill_linear_gradient_rect( &mut self, rect: Rect, g: &LinearGradient, corners: Corners, )
Fill a rectangle with a linear gradient.
Bakes a CPU-side LUT from g.stops and fetches (or creates) the
corresponding cached GPU texture via ensure_lut_texture,
then draws the quad with the gradient shader.
Sourcepub fn fill_radial_gradient_rect(
&mut self,
rect: Rect,
g: &RadialGradient,
corners: Corners,
)
pub fn fill_radial_gradient_rect( &mut self, rect: Rect, g: &RadialGradient, corners: Corners, )
Fill a rectangle with a radial gradient.
g.center is interpreted in box-relative fractions (as declared by
the theme), g.radius is the fractional radial extent. Same cached
LUT strategy as Self::fill_linear_gradient_rect.
Sourcepub fn fill_shadow_outer(
&mut self,
target: Rect,
shadow: &Shadow,
corners: Corners,
)
pub fn fill_shadow_outer( &mut self, target: Rect, shadow: &Shadow, corners: Corners, )
Paint an outer drop shadow behind a rounded rect.
Analytic Gaussian approximation over the shape SDF — see the note
above SHADOW_OUTER_FRAG_SRC. The drawing quad is expanded on each
side by max(blur, 0) + max(spread, 0) + 1 (the + 1 leaves a
single antialias pixel of slack) and offset by shadow.offset so
the fragment shader sees the full falloff region.
Only BlendMode::Normal is honoured today; other modes silently
fall through to Normal because the analytic shader only outputs
over.
Sourcepub fn fill_shadow_inset(
&mut self,
target: Rect,
shadow: &InsetShadow,
corners: Corners,
)
pub fn fill_shadow_inset( &mut self, target: Rect, shadow: &InsetShadow, corners: Corners, )
Paint an inner (inset) shadow inside a rounded rect.
Differences versus Self::fill_shadow_outer:
- The drawing quad matches the target rect exactly — the inset is clipped to the outer SDF by the shader, so no external padding is needed and there is no spatial offset of the geometry.
- The shader carries the per-shadow
offsetas a uniform rather than translating the quad, because the inset is biased inside the shape rather than cast outside it. - The pipeline blend state is switched for the duration of the
draw to honour
InsetShadow::blendand restored afterwards.
Blend modes: Normal stays on the pipeline default
(ONE, ONE_MINUS_SRC_ALPHA). PlusLighter uses (ONE, ONE) —
pure additive on premultiplied inputs, naturally clamped by the
framebuffer to [0, 1], which is exactly the CSS definition.
Multiply uses (DST_COLOR, ZERO) on RGB and (DST_ALPHA, ZERO)
on alpha — a straight multiplicative blend. Screen uses
(ONE_MINUS_DST_COLOR, ONE), the canonical a + b − a·b form.
Overlay cannot be expressed with GL’s fixed-function blend
state alone — it needs to read the destination pixel. This
branch snapshots the current FBO into aux_a via
glCopyTexSubImage2D, then draws through
shadow_inset_overlay_program which samples that snapshot at
gl_FragCoord.xy / canvas_size, computes the per-channel CSS
Overlay formula in-shader, and emits premultiplied
(overlay * mask, mask) — so the usual premul over blend
composes the blended colour on top of the base. One FBO
snapshot per Overlay shadow.
Sourcepub fn stroke_rect(
&mut self,
rect: Rect,
color: Color,
width: f32,
corners: Corners,
)
pub fn stroke_rect( &mut self, rect: Rect, color: Color, width: f32, corners: Corners, )
Stroke a rectangle outline. The stroke is centered on the (rounded) boundary, matching tiny-skia’s stroke_path so software and GPU paths produce the same shape (e.g. a circular focus ring around an icon button stays circular).
The drawing quad is expanded by width / 2 so the outer half of the
stroke — which lies outside the original rect — has fragments to
cover; the SDF in the rect shader then clamps to the ring.
Source§impl GlesCanvas
impl GlesCanvas
pub fn draw_text(&mut self, text: &str, x: f32, y: f32, size: f32, color: Color)
pub fn draw_text_with_font( &mut self, text: &str, x: f32, y: f32, size: f32, color: Color, font: &Arc<Font>, )
pub fn measure_text(&self, text: &str, size: f32) -> f32
pub fn measure_text_with_font( &self, text: &str, size: f32, font: &Arc<Font>, ) -> f32
Source§impl GlesCanvas
impl GlesCanvas
Sourcepub fn draw_image_data(
&mut self,
rgba_data: &[u8],
img_w: u32,
img_h: u32,
dest: Rect,
opacity: f32,
)
pub fn draw_image_data( &mut self, rgba_data: &[u8], img_w: u32, img_h: u32, dest: Rect, opacity: f32, )
Blit RGBA image data scaled to dest rect with opacity.
Defensive: rejects buffers whose declared img_w × img_h × 4 does not
match rgba_data.len(). The mismatch path logs a one-line warning
and returns without uploading or drawing — the same boundary that
the internal upload_rgba_texture helper enforces, raised one
level so the cache key is never seeded with a bogus mapping.
Sourcepub fn draw_external_texture(
&mut self,
texture: Texture,
dest: Rect,
opacity: f32,
)
pub fn draw_external_texture( &mut self, texture: Texture, dest: Rect, opacity: f32, )
Draw an externally-owned GL texture into dest.
The caller owns the texture and is responsible for keeping it valid for the duration of this call. No upload, no caching — used to composite content rendered by another GL producer (web engine, video decoder, …) into the LTK widget tree.
Trait Implementations§
Source§impl Drop for GlesCanvas
Free this canvas’s owned GL resources: FBO, color attachment, aux
FBOs if allocated, and any cached glyph / image textures. Shader
programs and the quad VAO/VBO are shared with sub-canvases and
intentionally NOT deleted here — they leak at process exit, which
is fine for a process-wide GL context.
impl Drop for GlesCanvas
Free this canvas’s owned GL resources: FBO, color attachment, aux FBOs if allocated, and any cached glyph / image textures. Shader programs and the quad VAO/VBO are shared with sub-canvases and intentionally NOT deleted here — they leak at process exit, which is fine for a process-wide GL context.
Auto Trait Implementations§
impl Freeze for GlesCanvas
impl RefUnwindSafe for GlesCanvas
impl Send for GlesCanvas
impl Sync for GlesCanvas
impl Unpin for GlesCanvas
impl UnwindSafe for GlesCanvas
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSync for T
impl<T> DowncastSync for T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more