Skip to main content

fret_core/
vector_path.rs

1use crate::{Point, Px, Rect, ids::PathId, scene::DashPatternV1};
2
3#[derive(Debug, Clone, Copy, PartialEq)]
4pub enum PathCommand {
5    MoveTo(Point),
6    LineTo(Point),
7    QuadTo {
8        ctrl: Point,
9        to: Point,
10    },
11    CubicTo {
12        ctrl1: Point,
13        ctrl2: Point,
14        to: Point,
15    },
16    Close,
17}
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
20pub enum FillRule {
21    #[default]
22    NonZero,
23    EvenOdd,
24}
25
26#[derive(Debug, Clone, Copy, PartialEq)]
27pub struct FillStyle {
28    pub rule: FillRule,
29}
30
31impl Default for FillStyle {
32    fn default() -> Self {
33        Self {
34            rule: FillRule::NonZero,
35        }
36    }
37}
38
39#[derive(Debug, Clone, Copy, PartialEq)]
40pub struct StrokeStyle {
41    pub width: Px,
42}
43
44impl Default for StrokeStyle {
45    fn default() -> Self {
46        Self { width: Px(1.0) }
47    }
48}
49
50#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
51pub enum StrokeJoinV1 {
52    #[default]
53    Miter,
54    Bevel,
55    Round,
56}
57
58#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
59pub enum StrokeCapV1 {
60    #[default]
61    Butt,
62    Square,
63    Round,
64}
65
66#[derive(Debug, Clone, Copy, PartialEq)]
67pub struct StrokeStyleV2 {
68    pub width: Px,
69    pub join: StrokeJoinV1,
70    pub cap: StrokeCapV1,
71    /// Only meaningful when `join == StrokeJoinV1::Miter`.
72    ///
73    /// v2 contract: callers should treat this as a portability knob; renderers may clamp.
74    pub miter_limit: f32,
75    /// Optional dash pattern (dash/gap/phase), compatible with ADR 0271.
76    pub dash: Option<DashPatternV1>,
77}
78
79impl Default for StrokeStyleV2 {
80    fn default() -> Self {
81        Self {
82            width: Px(1.0),
83            join: StrokeJoinV1::Miter,
84            cap: StrokeCapV1::Butt,
85            miter_limit: 4.0,
86            dash: None,
87        }
88    }
89}
90
91#[derive(Debug, Clone, Copy, PartialEq)]
92pub enum PathStyle {
93    Fill(FillStyle),
94    Stroke(StrokeStyle),
95    StrokeV2(StrokeStyleV2),
96}
97
98#[derive(Debug, Clone, Copy, PartialEq)]
99pub struct PathConstraints {
100    /// Window/device scale factor used for tessellation and caching.
101    pub scale_factor: f32,
102}
103
104impl Default for PathConstraints {
105    fn default() -> Self {
106        Self { scale_factor: 1.0 }
107    }
108}
109
110#[derive(Debug, Default, Clone, Copy, PartialEq)]
111pub struct PathMetrics {
112    pub bounds: Rect,
113}
114
115pub trait PathService {
116    fn prepare(
117        &mut self,
118        commands: &[PathCommand],
119        style: PathStyle,
120        constraints: PathConstraints,
121    ) -> (PathId, PathMetrics);
122
123    fn measure(
124        &mut self,
125        commands: &[PathCommand],
126        style: PathStyle,
127        constraints: PathConstraints,
128    ) -> PathMetrics {
129        let (id, metrics) = self.prepare(commands, style, constraints);
130        self.release(id);
131        metrics
132    }
133
134    fn release(&mut self, path: PathId);
135}