pineal_render/canvas.rs
1//! El trait `Canvas` que todos los painters consumen.
2//!
3//! Mantenemos el set mínimo: line / polyline / rect (fill+stroke) /
4//! triangle strip. Cualquier visualización compleja (curvas
5//! bezier, gradients) se descompone en estos primitivos por el
6//! painter — el backend no necesita entender la semántica.
7//!
8//! Convención: coordenadas en píxeles del viewport, origen
9//! arriba-izquierda, +Y hacia abajo. La proyección de datos→pixel
10//! la hace el painter via las escalas de `pineal-core`.
11
12use crate::{Color, Point, Rect};
13
14#[derive(Debug, Clone, Copy)]
15pub struct StrokeStyle {
16 pub width: f32,
17 pub color: Color,
18}
19
20impl StrokeStyle {
21 pub const fn new(width: f32, color: Color) -> Self {
22 Self { width, color }
23 }
24}
25
26pub trait Canvas {
27 /// Clip subsiguiente al rect dado. Stack-discipline:
28 /// `push_clip` + draw + `pop_clip`.
29 fn push_clip(&mut self, rect: Rect);
30 fn pop_clip(&mut self);
31
32 /// Rectángulo relleno (sin stroke).
33 fn fill_rect(&mut self, rect: Rect, color: Color);
34
35 /// Rectángulo sólo stroke (sin fill).
36 fn stroke_rect(&mut self, rect: Rect, stroke: StrokeStyle);
37
38 /// Línea de a→b.
39 fn stroke_line(&mut self, a: Point, b: Point, stroke: StrokeStyle);
40
41 /// Polilínea sobre coords interleaved `[x0,y0,x1,y1,…]`.
42 /// El backend la rendea como un solo draw call cuando puede.
43 fn stroke_polyline(&mut self, coords: &[f32], stroke: StrokeStyle);
44
45 /// Triangle strip rellenado, con un color por vértice
46 /// (longitudes deben coincidir: `coords.len()/2 == colors.len()`).
47 /// Es lo que usa el phosphor trail y los ribbons Sankey.
48 fn fill_triangle_strip(&mut self, coords: &[f32], colors: &[Color]);
49
50 /// Glyph de texto sencillo. El layout va a un text-cache
51 /// dentro del backend; por ahora un trazo simple.
52 fn draw_text(&mut self, p: Point, text: &str, color: Color, size_px: f32);
53}