Skip to main content

rustmotion_core/traits/
painter.rs

1//! `Painter` trait — replaces the old `Widget::render`. A component implements
2//! `Painter` to draw its **content** onto a Skia canvas. Box decorations
3//! (background, border, shadow) are handled generically by the paint pass.
4//!
5//! Layout is computed by taffy from the component's `CssStyle`; the resulting
6//! [`BoxLayout`] is passed in.
7
8use skia_safe::Canvas;
9
10use crate::engine::animator::AnimatedProperties;
11use crate::engine::box_tree::AvailableSpace;
12use crate::engine::layout_pass::BoxLayout;
13
14/// Frame-level info passed into every paint call.
15#[derive(Debug, Clone, Copy)]
16pub struct PaintCtx {
17    /// Seconds since this *scene* started. What animation progress, reveals
18    /// and every timed effect are expressed in.
19    pub time: f64,
20    /// Seconds since the start of the scenario (of the view, in a `world`
21    /// view). Only the audio-reactive painters need it — the audio analysis is
22    /// indexed on that timeline, not on each scene's own.
23    pub scenario_time: f64,
24    pub scene_duration: f64,
25    pub frame_index: u32,
26    pub fps: u32,
27    pub video_width: u32,
28    pub video_height: u32,
29    /// Stagger offset accumulated by parent containers (seconds).
30    pub stagger_offset: f64,
31}
32
33/// Available space hint passed to `intrinsic_size` (proxy for taffy's enum).
34#[derive(Debug, Clone, Copy)]
35pub struct AvailableSize {
36    pub width: AvailableSpace,
37    pub height: AvailableSpace,
38}
39
40#[derive(Debug, Clone, Copy)]
41pub struct MeasureCtx {
42    pub video_width: u32,
43    pub video_height: u32,
44}
45
46/// Component paint contract.
47pub trait Painter {
48    /// Paint the component's *content* into the canvas. The canvas is
49    /// already translated to the content-box origin and clipped if
50    /// `overflow: hidden` was set. Generic decorations (bg, border,
51    /// shadow) are already painted by the engine.
52    ///
53    /// `props` carries the per-component animation state at the current
54    /// frame. Outer paint properties (transform / opacity / filter) have
55    /// already been applied to the canvas by the engine via CSS overrides;
56    /// `props` exposes the *internal-only* fields (`draw_progress`,
57    /// `stroke_width`, `char_animation`, `visible_chars*`, `font_size`,
58    /// `color`, `border_radius`, etc.) that components use to drive their
59    /// own painting.
60    fn paint_content(
61        &self,
62        canvas: &Canvas,
63        layout: &BoxLayout,
64        props: &AnimatedProperties,
65        ctx: &PaintCtx,
66    );
67
68    /// Optional intrinsic measurement for leaves like `text`, `image`,
69    /// `codeblock`. Return `None` to let taffy compute the size from the
70    /// CSS style alone. `available` mirrors taffy's `AvailableSpace`.
71    fn intrinsic_size(&self, _available: AvailableSize, _ctx: &MeasureCtx) -> Option<(f32, f32)> {
72        None
73    }
74}