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::{BorderWidths, 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 BorderWidths {
78    fn scale(self, sf: f32) -> Self {
79        match self {
80            // Uniform carries no number of its own: it defers to the stroke, which scales itself.
81            BorderWidths::Uniform => self,
82            BorderWidths::PerSide {
83                top,
84                right,
85                bottom,
86                left,
87            } => BorderWidths::PerSide {
88                top: top * sf,
89                right: right * sf,
90                bottom: bottom * sf,
91                left: left * sf,
92            },
93        }
94    }
95}
96
97impl Scale for RectStyle {
98    fn scale(self, sf: f32) -> Self {
99        RectStyle {
100            fill: self.fill.map(|p| p.scale(sf)),
101            stroke: self.stroke.map(|s| s.scale(sf)),
102            shadow: self.shadow.map(|s| s.scale(sf)),
103            radius: self.radius.scale(sf),
104            border_widths: self.border_widths.scale(sf),
105        }
106    }
107}
108
109impl Scale for PathStyle {
110    fn scale(self, sf: f32) -> Self {
111        PathStyle {
112            fill: self.fill.map(|p| p.scale(sf)),
113            stroke: self.stroke.map(|s| s.scale(sf)),
114            shadow: self.shadow.map(|s| s.scale(sf)),
115            fill_rule: self.fill_rule,
116        }
117    }
118}
119
120impl Scale for TextStyle {
121    fn scale(self, sf: f32) -> Self {
122        TextStyle {
123            font_size: self.font_size * sf,
124            paint: self.paint.scale(sf),
125            shadow: self.shadow.map(|s| s.scale(sf)),
126            // letter_spacing is a pixel advance, so it scales with font_size; line_height is a unitless multiple and rides along via `..self`.
127            letter_spacing: self.letter_spacing * sf,
128            ..self
129        }
130    }
131}