Skip to main content

rpic_core/
ir.rs

1//! Intermediate representation: the placed-primitive tree produced by the
2//! evaluator and consumed by the render backends. All coordinates are absolute,
3//! in pic units (inches), y pointing up.
4
5use crate::geom::{Bbox, Point};
6
7/// A fully evaluated drawing.
8#[derive(Debug, Clone, PartialEq)]
9pub struct Drawing {
10    pub shapes: Vec<Shape>,
11    pub bbox: Bbox,
12    pub anims: Vec<Anim>,
13}
14
15/// A resolved animation entry. `shape` indexes into [`Drawing::shapes`]; the
16/// SVG backend gives that shape the id `s{shape}` so the player can target it.
17#[derive(Debug, Clone, PartialEq)]
18pub struct Anim {
19    pub shape: usize,
20    pub effect: String,
21    /// Absolute start time in seconds.
22    pub start: f64,
23    pub duration: f64,
24}
25
26/// Line dash style.
27#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
28pub enum Dash {
29    #[default]
30    Solid,
31    Dashed,
32    Dotted,
33}
34
35/// Fill specification.
36#[derive(Debug, Clone, PartialEq)]
37pub enum Fill {
38    /// Gray level, pic convention: 0 = black, 1 = white.
39    Gray(f64),
40    /// A named/explicit color.
41    Color(String),
42}
43
44/// Visual style shared by all shapes.
45#[derive(Debug, Clone, PartialEq)]
46pub struct Style {
47    /// Stroke color (CSS), or `None` to use the default.
48    pub stroke: Option<String>,
49    pub fill: Option<Fill>,
50    pub dash: Dash,
51    /// Stroke thickness in points; `None` = backend default.
52    pub thick: Option<f64>,
53    /// Invisible (used by `move` and `invis`): geometry counts, nothing drawn.
54    pub invis: bool,
55}
56
57impl Default for Style {
58    fn default() -> Self {
59        Style {
60            stroke: None,
61            fill: None,
62            dash: Dash::Solid,
63            thick: None,
64            invis: false,
65        }
66    }
67}
68
69/// Which ends of a path carry an arrowhead.
70#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
71pub enum Arrowheads {
72    #[default]
73    None,
74    Start,
75    End,
76    Both,
77}
78
79/// A line of attached text with placement hints.
80#[derive(Debug, Clone, PartialEq)]
81pub struct TextLine {
82    pub s: String,
83    /// horizontal: -1 = ljust, 0 = center, +1 = rjust.
84    pub halign: i8,
85    /// vertical: +1 = above, 0 = center, -1 = below.
86    pub valign: i8,
87}
88
89/// A placed drawing primitive.
90#[derive(Debug, Clone, PartialEq)]
91pub enum Shape {
92    Box {
93        c: Point,
94        w: f64,
95        h: f64,
96        rad: f64,
97        style: Style,
98        text: Vec<TextLine>,
99    },
100    Circle {
101        c: Point,
102        r: f64,
103        style: Style,
104        text: Vec<TextLine>,
105    },
106    Ellipse {
107        c: Point,
108        w: f64,
109        h: f64,
110        style: Style,
111        text: Vec<TextLine>,
112    },
113    /// Straight polyline (line / arrow / move).
114    Path {
115        pts: Vec<Point>,
116        arrows: Arrowheads,
117        style: Style,
118        text: Vec<TextLine>,
119    },
120    Spline {
121        pts: Vec<Point>,
122        arrows: Arrowheads,
123        style: Style,
124        text: Vec<TextLine>,
125    },
126    Arc {
127        c: Point,
128        r: f64,
129        /// start and end angles in radians.
130        a0: f64,
131        a1: f64,
132        cw: bool,
133        arrows: Arrowheads,
134        style: Style,
135        text: Vec<TextLine>,
136    },
137    Text {
138        at: Point,
139        text: Vec<TextLine>,
140    },
141}