cranpose_text/
shaped_glyphs.rs1use std::ops::{Deref, Range};
2
3use crate::glyph_id::GlyphId;
4
5const UNSAFE_TO_BREAK: u32 = 1 << 31;
9
10#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
14pub struct ShapedGlyph {
15 id: u32,
16 pub cluster: u32,
18 pub advance: i32,
20}
21
22#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
25pub struct GlyphOffset {
26 pub x: i32,
28 pub y: i32,
30}
31
32#[derive(Clone, Copy)]
35pub(crate) enum BreakBefore {
36 Safe,
37 Unsafe,
38}
39
40#[derive(Clone, Debug, Default, PartialEq)]
43pub struct ShapedGlyphs {
44 glyphs: Vec<ShapedGlyph>,
45 offsets: Vec<GlyphOffset>,
48}
49
50impl ShapedGlyph {
51 pub(crate) fn new(id: GlyphId, cluster: u32, advance: i32, before: BreakBefore) -> Self {
52 let flag = match before {
53 BreakBefore::Safe => 0,
54 BreakBefore::Unsafe => UNSAFE_TO_BREAK,
55 };
56 Self {
57 id: id.0 | flag,
58 cluster,
59 advance,
60 }
61 }
62
63 pub(crate) fn in_cluster(self, cluster: u32) -> Self {
65 Self { cluster, ..self }
66 }
67
68 pub fn id(&self) -> GlyphId {
70 GlyphId(self.id & !UNSAFE_TO_BREAK)
71 }
72
73 pub fn unsafe_to_break(&self) -> bool {
76 self.id & UNSAFE_TO_BREAK != 0
77 }
78
79 pub fn text_offset(&self) -> usize {
81 usize::try_from(self.cluster).unwrap_or(usize::MAX)
82 }
83}
84
85impl ShapedGlyphs {
86 pub fn offset(&self, index: usize) -> GlyphOffset {
88 self.offsets.get(index).copied().unwrap_or_default()
89 }
90
91 pub(crate) fn offsets(&self) -> &[GlyphOffset] {
94 &self.offsets
95 }
96
97 pub(crate) fn glyphs_mut(&mut self) -> &mut [ShapedGlyph] {
98 &mut self.glyphs
99 }
100
101 pub(crate) fn push(&mut self, glyph: ShapedGlyph, offset: GlyphOffset) {
103 if offset != GlyphOffset::default() {
104 self.offsets
105 .resize(self.glyphs.len(), GlyphOffset::default());
106 self.offsets.push(offset);
107 }
108 self.glyphs.push(glyph);
109 }
110
111 pub(crate) fn extend_from_slice(&mut self, glyphs: &[ShapedGlyph], offsets: &[GlyphOffset]) {
114 self.add_offsets(offsets);
115 self.glyphs.extend_from_slice(glyphs);
116 }
117
118 pub(crate) fn extend(
121 &mut self,
122 glyphs: impl Iterator<Item = ShapedGlyph>,
123 offsets: &[GlyphOffset],
124 ) {
125 self.add_offsets(offsets);
126 self.glyphs.extend(glyphs);
127 }
128
129 pub(crate) fn extend_from_word(
133 &mut self,
134 glyphs: &[ShapedGlyph],
135 offsets: &[GlyphOffset],
136 start: u32,
137 ) {
138 self.add_offsets(offsets);
139 self.glyphs.extend(
140 glyphs
141 .iter()
142 .map(|glyph| glyph.in_cluster(glyph.cluster + start)),
143 );
144 }
145
146 fn add_offsets(&mut self, offsets: &[GlyphOffset]) {
148 if !offsets.is_empty() {
149 self.offsets
150 .resize(self.glyphs.len(), GlyphOffset::default());
151 self.offsets.extend_from_slice(offsets);
152 }
153 }
154
155 pub(crate) fn truncate(&mut self, len: usize) {
156 self.glyphs.truncate(len);
157 self.offsets.truncate(len);
158 }
159
160 pub(crate) fn clear(&mut self) {
161 self.glyphs.clear();
162 self.offsets.clear();
163 }
164
165 pub(crate) fn reserve(&mut self, additional: usize) {
166 self.glyphs.reserve(additional);
167 }
168
169 pub(crate) fn capacity(&self) -> usize {
170 self.glyphs.capacity()
171 }
172
173 pub(crate) fn reverse(&mut self, range: Range<usize>) {
175 if self.offsets.len() > range.start {
176 let len = self.offsets.len().max(range.end);
177 self.offsets.resize(len, GlyphOffset::default());
178 self.offsets[range.clone()].reverse();
179 }
180 self.glyphs[range].reverse();
181 }
182}
183
184impl Deref for ShapedGlyphs {
185 type Target = [ShapedGlyph];
186
187 fn deref(&self) -> &[ShapedGlyph] {
188 &self.glyphs
189 }
190}