1 | use crate::Rect; |
2 | use skia_bindings as sb; |
3 | use std::{ |
4 | cmp::{max, min}, |
5 | ops::Range, |
6 | }; |
7 | |
8 | pub use sb::skia_textlayout_Affinity as Affinity; |
9 | variant_name!(Affinity::Downstream); |
10 | |
11 | #[repr (i32)] |
12 | #[derive (Debug, Copy, Clone, Hash, PartialEq, Eq, Default)] |
13 | pub enum RectHeightStyle { |
14 | /// Provide tight bounding boxes that fit heights per run. |
15 | #[default] |
16 | Tight, |
17 | // The height of the boxes will be the maximum height of all runs in the |
18 | // line. All rects in the same line will be the same height. |
19 | Max, |
20 | // Extends the top and/or bottom edge of the bounds to fully cover any line |
21 | // spacing. The top edge of each line should be the same as the bottom edge |
22 | // of the line above. There should be no gaps in vertical coverage given any |
23 | // ParagraphStyle line_height. |
24 | // |
25 | // The top and bottom of each rect will cover half of the |
26 | // space above and half of the space below the line. |
27 | IncludeLineSpacingMiddle, |
28 | // The line spacing will be added to the top of the rect. |
29 | IncludeLineSpacingTop, |
30 | // The line spacing will be added to the bottom of the rect. |
31 | IncludeLineSpacingBottom, |
32 | Strut, |
33 | } |
34 | native_transmutable!( |
35 | sb::skia_textlayout_RectHeightStyle, |
36 | RectHeightStyle, |
37 | rect_height_style_layout |
38 | ); |
39 | |
40 | #[repr (i32)] |
41 | #[derive (Debug, Copy, Clone, Hash, PartialEq, Eq, Default)] |
42 | pub enum RectWidthStyle { |
43 | /// Provide tight bounding boxes that fit widths to the runs of each line |
44 | /// independently. |
45 | #[default] |
46 | Tight, |
47 | /// Extends the width of the last rect of each line to match the position of |
48 | /// the widest rect over all the lines. |
49 | Max, |
50 | } |
51 | native_transmutable!( |
52 | sb::skia_textlayout_RectWidthStyle, |
53 | RectWidthStyle, |
54 | rect_width_style_layout |
55 | ); |
56 | |
57 | pub use sb::skia_textlayout_TextAlign as TextAlign; |
58 | variant_name!(TextAlign::End); |
59 | pub use sb::skia_textlayout_TextDirection as TextDirection; |
60 | variant_name!(TextDirection::LTR); |
61 | |
62 | pub use sb::skia_textlayout_PositionWithAffinity as PositionWithAffinity; |
63 | |
64 | #[repr (C)] |
65 | #[derive (Copy, Clone, PartialEq, Debug)] |
66 | pub struct TextBox { |
67 | pub rect: Rect, |
68 | pub direct: TextDirection, |
69 | } |
70 | |
71 | native_transmutable!(sb::skia_textlayout_TextBox, TextBox, text_box_layout); |
72 | |
73 | pub const EMPTY_INDEX: usize = std::usize::MAX; |
74 | |
75 | pub trait RangeExtensions { |
76 | fn width(&self) -> usize; |
77 | fn shift(&mut self, d: isize); |
78 | fn contains(&self, other: &Self) -> bool; |
79 | fn intersects(&self, other: &Self) -> bool; |
80 | #[must_use ] |
81 | fn intersection(&self, other: &Self) -> Self; |
82 | fn empty(&self) -> bool; |
83 | } |
84 | |
85 | impl RangeExtensions for Range<usize> { |
86 | fn width(&self) -> usize { |
87 | self.end - self.start |
88 | } |
89 | |
90 | fn shift(&mut self, d: isize) { |
91 | if d >= 0 { |
92 | let u = d as usize; |
93 | self.start += u; |
94 | self.end += u; |
95 | } else { |
96 | let u = -d as usize; |
97 | self.start -= u; |
98 | self.end -= u; |
99 | } |
100 | } |
101 | |
102 | fn contains(&self, other: &Self) -> bool { |
103 | self.start <= other.start && self.end >= other.end |
104 | } |
105 | |
106 | fn intersects(&self, other: &Self) -> bool { |
107 | max(self.start, other.start) <= min(self.end, other.end) |
108 | } |
109 | |
110 | fn intersection(&self, other: &Self) -> Self { |
111 | Self { |
112 | start: max(self.start, other.start), |
113 | end: min(self.end, other.end), |
114 | } |
115 | } |
116 | |
117 | fn empty(&self) -> bool { |
118 | self.start == EMPTY_INDEX && self.end == EMPTY_INDEX |
119 | } |
120 | } |
121 | |
122 | #[allow (clippy::reversed_empty_ranges)] |
123 | pub const EMPTY_RANGE: Range<usize> = Range { |
124 | start: EMPTY_INDEX, |
125 | end: EMPTY_INDEX, |
126 | }; |
127 | |
128 | pub use sb::skia_textlayout_TextBaseline as TextBaseline; |
129 | variant_name!(TextBaseline::Alphabetic); |
130 | |
131 | pub use sb::skia_textlayout_TextHeightBehavior as TextHeightBehavior; |
132 | variant_name!(TextHeightBehavior::DisableFirstAscent); |
133 | |
134 | // m84: LineMetricStyle is declared but not used in the public API yet. |
135 | |