skia_safe/modules/paragraph/
dart_types.rs1use crate::Rect;
2use skia_bindings as sb;
3use std::{
4 cmp::{max, min},
5 ops::Range,
6};
7
8pub use sb::skia_textlayout_Affinity as Affinity;
9variant_name!(Affinity::Downstream);
10
11#[repr(i32)]
12#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Default)]
13pub enum RectHeightStyle {
14 #[default]
16 Tight,
17 Max,
20 IncludeLineSpacingMiddle,
28 IncludeLineSpacingTop,
30 IncludeLineSpacingBottom,
32 Strut,
33}
34native_transmutable!(sb::skia_textlayout_RectHeightStyle, RectHeightStyle);
35
36#[repr(i32)]
37#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Default)]
38pub enum RectWidthStyle {
39 #[default]
42 Tight,
43 Max,
46}
47native_transmutable!(sb::skia_textlayout_RectWidthStyle, RectWidthStyle);
48
49pub use sb::skia_textlayout_TextAlign as TextAlign;
50variant_name!(TextAlign::End);
51pub use sb::skia_textlayout_TextDirection as TextDirection;
52variant_name!(TextDirection::LTR);
53
54pub use sb::skia_textlayout_PositionWithAffinity as PositionWithAffinity;
55
56#[repr(C)]
57#[derive(Copy, Clone, PartialEq, Debug)]
58pub struct TextBox {
59 pub rect: Rect,
60 pub direct: TextDirection,
61}
62
63native_transmutable!(sb::skia_textlayout_TextBox, TextBox);
64
65pub const EMPTY_INDEX: usize = usize::MAX;
66
67pub trait RangeExtensions {
68 fn width(&self) -> usize;
69 fn shift(&mut self, d: isize);
70 fn contains(&self, other: &Self) -> bool;
71 fn intersects(&self, other: &Self) -> bool;
72 #[must_use]
73 fn intersection(&self, other: &Self) -> Self;
74 fn empty(&self) -> bool;
75}
76
77impl RangeExtensions for Range<usize> {
78 fn width(&self) -> usize {
79 self.end - self.start
80 }
81
82 fn shift(&mut self, d: isize) {
83 if d >= 0 {
84 let u = d as usize;
85 self.start += u;
86 self.end += u;
87 } else {
88 let u = -d as usize;
89 self.start -= u;
90 self.end -= u;
91 }
92 }
93
94 fn contains(&self, other: &Self) -> bool {
95 self.start <= other.start && self.end >= other.end
96 }
97
98 fn intersects(&self, other: &Self) -> bool {
99 max(self.start, other.start) <= min(self.end, other.end)
100 }
101
102 fn intersection(&self, other: &Self) -> Self {
103 Self {
104 start: max(self.start, other.start),
105 end: min(self.end, other.end),
106 }
107 }
108
109 fn empty(&self) -> bool {
110 self.start == EMPTY_INDEX && self.end == EMPTY_INDEX
111 }
112}
113
114#[allow(clippy::reversed_empty_ranges)]
115pub const EMPTY_RANGE: Range<usize> = Range {
116 start: EMPTY_INDEX,
117 end: EMPTY_INDEX,
118};
119
120pub use sb::skia_textlayout_TextBaseline as TextBaseline;
121variant_name!(TextBaseline::Alphabetic);
122
123pub use sb::skia_textlayout_TextHeightBehavior as TextHeightBehavior;
124variant_name!(TextHeightBehavior::DisableFirstAscent);
125
126