Skip to main content

telar_renderer_core/style/
scale.rs

1use geometry_core::{Point, Rect};
2
3use super::gradient::{Gradient, GradientKind};
4use super::paint::{Paint, Shadow, Stroke};
5use super::shape::{PathStyle, RectStyle};
6use super::{Scale, TextStyle};
7use crate::BorderRadius;
8
9// `Scale` is local to renderer-core, so the orphan rules permit implementing it for these foreign value types here rather than adding arithmetic to the geometry-core crate.
10impl Scale for Point {
11    fn scale(self, sf: f32) -> Self {
12        Point::new(self.x * sf, self.y * sf)
13    }
14}
15
16impl Scale for Rect {
17    fn scale(self, sf: f32) -> Self {
18        Rect::new(self.x * sf, self.y * sf, self.width * sf, self.height * sf)
19    }
20}
21
22impl Scale for Paint {
23    fn scale(self, sf: f32) -> Self {
24        match self {
25            Paint::Solid(_) => self,
26            Paint::Gradient(g) => Paint::Gradient(Gradient {
27                kind: match g.kind {
28                    GradientKind::Linear { start, end } => GradientKind::Linear {
29                        start: start.scale(sf),
30                        end: end.scale(sf),
31                    },
32                    GradientKind::Radial { center, radius } => GradientKind::Radial {
33                        center: center.scale(sf),
34                        radius: radius * sf,
35                    },
36                },
37                stops: g.stops,
38            }),
39        }
40    }
41}
42
43impl Scale for Stroke {
44    fn scale(self, sf: f32) -> Self {
45        Stroke {
46            paint: self.paint.scale(sf),
47            width: self.width * sf,
48            cap: self.cap,
49            join: self.join,
50        }
51    }
52}
53
54impl Scale for Shadow {
55    fn scale(self, sf: f32) -> Self {
56        Shadow {
57            offset_x: self.offset_x * sf,
58            offset_y: self.offset_y * sf,
59            blur_radius: self.blur_radius * sf,
60            spread: self.spread * sf,
61            color: self.color,
62        }
63    }
64}
65
66impl Scale for BorderRadius {
67    fn scale(self, sf: f32) -> Self {
68        BorderRadius {
69            top_left: self.top_left * sf,
70            top_right: self.top_right * sf,
71            bottom_right: self.bottom_right * sf,
72            bottom_left: self.bottom_left * sf,
73        }
74    }
75}
76
77impl Scale for RectStyle {
78    fn scale(self, sf: f32) -> Self {
79        RectStyle {
80            fill: self.fill.map(|p| p.scale(sf)),
81            stroke: self.stroke.map(|s| s.scale(sf)),
82            shadow: self.shadow.map(|s| s.scale(sf)),
83            radius: self.radius.scale(sf),
84        }
85    }
86}
87
88impl Scale for PathStyle {
89    fn scale(self, sf: f32) -> Self {
90        PathStyle {
91            fill: self.fill.map(|p| p.scale(sf)),
92            stroke: self.stroke.map(|s| s.scale(sf)),
93            shadow: self.shadow.map(|s| s.scale(sf)),
94            fill_rule: self.fill_rule,
95        }
96    }
97}
98
99impl Scale for TextStyle {
100    fn scale(self, sf: f32) -> Self {
101        TextStyle {
102            font_size: self.font_size * sf,
103            paint: self.paint.scale(sf),
104            shadow: self.shadow.map(|s| s.scale(sf)),
105            // letter_spacing is a pixel advance, so it scales with font_size; line_height is a unitless multiple and rides along via `..self`.
106            letter_spacing: self.letter_spacing * sf,
107            ..self
108        }
109    }
110}