1use renderer_core::{BorderRadius, BorderWidths};
10
11use crate::context::use_direction;
12
13pub fn logical_border_widths(
19 top: f32,
20 right: f32,
21 bottom: f32,
22 left: f32,
23 start: Option<f32>,
24 end: Option<f32>,
25) -> BorderWidths {
26 let (mut left, mut right) = (left, right);
27 let rtl = use_direction().is_rtl();
28 if let Some(w) = start {
29 if rtl { right = w } else { left = w }
30 }
31 if let Some(w) = end {
32 if rtl { left = w } else { right = w }
33 }
34 BorderWidths::per_side(top, right, bottom, left)
35}
36
37pub fn logical_border_radius(
43 top_left: f32,
44 top_right: f32,
45 bottom_right: f32,
46 bottom_left: f32,
47 start: Option<f32>,
48 end: Option<f32>,
49) -> BorderRadius {
50 let mut r = BorderRadius {
51 top_left,
52 top_right,
53 bottom_right,
54 bottom_left,
55 };
56 let rtl = use_direction().is_rtl();
57 if let Some(v) = start {
58 if rtl {
59 (r.top_right, r.bottom_right) = (v, v);
60 } else {
61 (r.top_left, r.bottom_left) = (v, v);
62 }
63 }
64 if let Some(v) = end {
65 if rtl {
66 (r.top_left, r.bottom_left) = (v, v);
67 } else {
68 (r.top_right, r.bottom_right) = (v, v);
69 }
70 }
71 r
72}
73
74#[cfg(test)]
75mod tests {
76 use layout_core::Direction;
77
78 use super::*;
79 use crate::context::set_direction;
80
81 #[test]
82 fn a_logical_side_lands_on_the_edge_the_text_comes_from() {
83 set_direction(Direction::Ltr);
84 assert_eq!(
85 logical_border_widths(0.0, 0.0, 0.0, 0.0, Some(2.0), None),
86 BorderWidths::per_side(0.0, 0.0, 0.0, 2.0)
87 );
88 set_direction(Direction::Rtl);
89 assert_eq!(
90 logical_border_widths(0.0, 0.0, 0.0, 0.0, Some(2.0), None),
91 BorderWidths::per_side(0.0, 2.0, 0.0, 0.0)
92 );
93 set_direction(Direction::Ltr);
94 }
95
96 #[test]
97 fn a_physical_side_stays_where_it_was_put() {
98 for direction in [Direction::Ltr, Direction::Rtl] {
99 set_direction(direction);
100 assert_eq!(
101 logical_border_widths(0.0, 0.0, 0.0, 1.0, None, None),
102 BorderWidths::per_side(0.0, 0.0, 0.0, 1.0),
103 "{direction:?}"
104 );
105 }
106 set_direction(Direction::Ltr);
107 }
108
109 #[test]
111 fn a_logical_side_overrides_the_physical_one_it_lands_on() {
112 set_direction(Direction::Ltr);
113 assert_eq!(
114 logical_border_widths(0.0, 0.0, 0.0, 1.0, Some(2.0), None),
115 BorderWidths::per_side(0.0, 0.0, 0.0, 2.0)
116 );
117 set_direction(Direction::Rtl);
118 assert_eq!(
119 logical_border_widths(0.0, 0.0, 0.0, 1.0, Some(2.0), None),
120 BorderWidths::per_side(0.0, 2.0, 0.0, 1.0),
121 "the left keeps what it was given: start went to the other edge"
122 );
123 set_direction(Direction::Ltr);
124 }
125
126 #[test]
127 fn a_logical_radius_rounds_both_corners_of_its_edge() {
128 set_direction(Direction::Ltr);
129 assert_eq!(
130 logical_border_radius(0.0, 0.0, 0.0, 0.0, Some(8.0), None),
131 BorderRadius {
132 top_left: 8.0,
133 top_right: 0.0,
134 bottom_right: 0.0,
135 bottom_left: 8.0,
136 }
137 );
138 set_direction(Direction::Rtl);
139 assert_eq!(
140 logical_border_radius(0.0, 0.0, 0.0, 0.0, Some(8.0), None),
141 BorderRadius {
142 top_left: 0.0,
143 top_right: 8.0,
144 bottom_right: 8.0,
145 bottom_left: 0.0,
146 }
147 );
148 set_direction(Direction::Ltr);
149 }
150}