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}