atmos/kernel/
woff2_glyf.rs1extern crate alloc;
22
23use alloc::vec::Vec;
24
25pub fn read_255_u16(data: &[u8], pos: &mut usize) -> Option<u16> {
35 const ONE_MORE: u8 = 255;
36 const WORD_CODE: u8 = 253;
37 const LOWEST: u8 = 254;
38 let code = *data.get(*pos)?;
39 *pos += 1;
40 if code == WORD_CODE {
41 let hi = *data.get(*pos)? as u16;
42 let lo = *data.get(*pos + 1)? as u16;
43 *pos += 2;
44 Some((hi << 8) | lo)
45 } else if code == ONE_MORE {
46 let v = *data.get(*pos)? as u16;
47 *pos += 1;
48 Some(v + 253)
49 } else if code == LOWEST {
50 let v = *data.get(*pos)? as u16;
51 *pos += 1;
52 Some(v + 253 * 2)
53 } else {
54 Some(code as u16)
55 }
56}
57
58fn read_u16(d: &[u8], p: &mut usize) -> Option<u16> {
59 let v = u16::from_be_bytes([*d.get(*p)?, *d.get(*p + 1)?]);
60 *p += 2;
61 Some(v)
62}
63
64fn read_i16(d: &[u8], p: &mut usize) -> Option<i16> {
65 read_u16(d, p).map(|v| v as i16)
66}
67
68fn read_u32(d: &[u8], p: &mut usize) -> Option<u32> {
69 let v = u32::from_be_bytes([
70 *d.get(*p)?,
71 *d.get(*p + 1)?,
72 *d.get(*p + 2)?,
73 *d.get(*p + 3)?,
74 ]);
75 *p += 4;
76 Some(v)
77}
78
79fn decode_triplet(flag: u8, g: &[u8], gp: &mut usize) -> Option<(i32, i32)> {
86 let f = flag & 0x7F;
87 if f < 84 {
88 let b0 = *g.get(*gp)? as i32;
90 *gp += 1;
91 let dy = ((f % 12) as i32) * 256 + b0;
92 let dy = if ((f / 12) % 2) == 0 { -dy } else { dy };
93 Some((0, dy))
94 } else if f < 120 {
95 let b0 = *g.get(*gp)? as i32;
97 *gp += 1;
98 let f2 = f - 84;
99 let dx = ((f2 % 12) as i32) * 256 + b0;
100 let dx = if ((f2 / 12) % 2) == 0 { -dx } else { dx };
101 Some((dx, 0))
102 } else if f < 124 {
103 let b0 = *g.get(*gp)? as i32;
105 *gp += 1;
106 let f2 = f - 120;
107 let dx = 1 + ((f2 / 2) as i32) * 16 + (b0 >> 4);
108 let dy = 1 + ((f2 % 2) as i32) * 16 + (b0 & 0x0F);
109 let dx = if (f2 & 0x02) == 0 { -dx } else { dx };
111 let dy = if (f2 & 0x01) == 0 { -dy } else { dy };
112 Some((dx, dy))
113 } else {
114 let f2 = f - 124;
116 if f2 < 4 {
117 let b0 = *g.get(*gp)? as i32;
118 let b1 = *g.get(*gp + 1)? as i32;
119 *gp += 2;
120 let dx = (b0 << 4) | (b1 >> 4);
121 let dy = ((b1 & 0x0F) << 8) | (*g.get(*gp)? as i32);
122 *gp += 1;
123 let dx = if (f2 & 0x02) == 0 { -dx } else { dx };
124 let dy = if (f2 & 0x01) == 0 { -dy } else { dy };
125 Some((dx, dy))
126 } else {
127 let b0 = *g.get(*gp)? as i32;
128 let b1 = *g.get(*gp + 1)? as i32;
129 let b2 = *g.get(*gp + 2)? as i32;
130 let b3 = *g.get(*gp + 3)? as i32;
131 *gp += 4;
132 let dx = (b0 << 8) | b1;
133 let dy = (b2 << 8) | b3;
134 let f3 = f2 - 4;
135 let dx = if (f3 & 0x02) == 0 { -dx } else { dx };
136 let dy = if (f3 & 0x01) == 0 { -dy } else { dy };
137 Some((dx, dy))
138 }
139 }
140}
141
142pub fn reconstruct_glyf(data: &[u8]) -> Option<(Vec<u8>, Vec<u8>, u16)> {
148 let mut p = 0usize;
149 let _version = read_u32(data, &mut p)?;
150 let num_glyphs = read_u16(data, &mut p)? as usize;
151 let index_format = read_u16(data, &mut p)?;
152
153 let n_contour_size = read_u32(data, &mut p)? as usize;
154 let n_points_size = read_u32(data, &mut p)? as usize;
155 let flag_size = read_u32(data, &mut p)? as usize;
156 let glyph_size = read_u32(data, &mut p)? as usize;
157 let composite_size = read_u32(data, &mut p)? as usize;
158 let bbox_size = read_u32(data, &mut p)? as usize;
159 let instruction_size = read_u32(data, &mut p)? as usize;
160
161 let take = |start: usize, len: usize| -> Option<&[u8]> { data.get(start..start + len) };
162 let s0 = p;
163 let n_contour = take(s0, n_contour_size)?;
164 let s1 = s0 + n_contour_size;
165 let n_points = take(s1, n_points_size)?;
166 let s2 = s1 + n_points_size;
167 let flags_s = take(s2, flag_size)?;
168 let s3 = s2 + flag_size;
169 let glyph_s = take(s3, glyph_size)?;
170 let s4 = s3 + glyph_size;
171 let composite_s = take(s4, composite_size)?;
172 let s5 = s4 + composite_size;
173 let bbox_s = take(s5, bbox_size)?;
174 let s6 = s5 + bbox_size;
175 let instr_s = take(s6, instruction_size)?;
176
177 let bitmap_len = num_glyphs.div_ceil(8);
179 let bbox_bitmap = bbox_s.get(..bitmap_len)?;
180 let mut bbox_p = bitmap_len;
181
182 let mut glyf: Vec<u8> = Vec::new();
183 let mut offsets: Vec<u32> = Vec::with_capacity(num_glyphs + 1);
184 offsets.push(0);
185
186 let mut ncp = 0usize; let mut npp = 0usize; let mut fp = 0usize; let mut gp = 0usize; let mut cp = 0usize; let mut ip = 0usize; for gid in 0..num_glyphs {
194 let n_contours = read_i16(n_contour, &mut ncp)?;
195
196 if n_contours == 0 {
197 offsets.push(glyf.len() as u32);
199 continue;
200 }
201
202 let has_bbox = (bbox_bitmap.get(gid / 8)? >> (7 - (gid % 8))) & 1 == 1;
203
204 if n_contours < 0 {
205 let start = cp;
208 loop {
209 let flags = read_u16(composite_s, &mut cp)?;
210 let _glyph_index = read_u16(composite_s, &mut cp)?;
211 if flags & 0x0001 != 0 {
213 cp += 4;
214 } else {
215 cp += 2;
216 }
217 if flags & 0x0008 != 0 {
219 cp += 2;
220 } else if flags & 0x0040 != 0 {
221 cp += 4;
222 } else if flags & 0x0080 != 0 {
223 cp += 8;
224 }
225 if cp > composite_s.len() {
226 return None;
227 }
228 if flags & 0x0020 == 0 {
230 break;
231 }
232 }
233 let body = composite_s.get(start..cp)?;
234
235 if !has_bbox {
237 return None;
238 }
239 let bb = bbox_s.get(bbox_p..bbox_p + 8)?;
240 bbox_p += 8;
241
242 glyf.extend_from_slice(&n_contours.to_be_bytes());
243 glyf.extend_from_slice(bb);
244 glyf.extend_from_slice(body);
245 while glyf.len() % 4 != 0 {
246 glyf.push(0);
247 }
248 offsets.push(glyf.len() as u32);
249 continue;
250 }
251
252 let n_contours = n_contours as usize;
254 let mut end_pts: Vec<u16> = Vec::with_capacity(n_contours);
255 let mut total_points = 0usize;
256 for _ in 0..n_contours {
257 let np = read_255_u16(n_points, &mut npp)? as usize;
258 total_points += np;
259 if total_points == 0 || total_points > u16::MAX as usize + 1 {
260 return None;
261 }
262 end_pts.push((total_points - 1) as u16);
263 }
264
265 let mut xs: Vec<i32> = Vec::with_capacity(total_points);
267 let mut ys: Vec<i32> = Vec::with_capacity(total_points);
268 let mut on_curve: Vec<bool> = Vec::with_capacity(total_points);
269 let mut x = 0i32;
270 let mut y = 0i32;
271 for _ in 0..total_points {
272 let flag = *flags_s.get(fp)?;
273 fp += 1;
274 on_curve.push(flag & 0x80 == 0);
275 let (dx, dy) = decode_triplet(flag, glyph_s, &mut gp)?;
276 x += dx;
277 y += dy;
278 xs.push(x);
279 ys.push(y);
280 }
281
282 let instr_len = read_255_u16(glyph_s, &mut gp)? as usize;
284 let instr = instr_s.get(ip..ip + instr_len)?;
285 ip += instr_len;
286
287 let (x_min, y_min, x_max, y_max) = if has_bbox {
289 let bb = bbox_s.get(bbox_p..bbox_p + 8)?;
290 bbox_p += 8;
291 (
292 i16::from_be_bytes([bb[0], bb[1]]),
293 i16::from_be_bytes([bb[2], bb[3]]),
294 i16::from_be_bytes([bb[4], bb[5]]),
295 i16::from_be_bytes([bb[6], bb[7]]),
296 )
297 } else {
298 let xmin = xs.iter().copied().min().unwrap_or(0);
299 let ymin = ys.iter().copied().min().unwrap_or(0);
300 let xmax = xs.iter().copied().max().unwrap_or(0);
301 let ymax = ys.iter().copied().max().unwrap_or(0);
302 (xmin as i16, ymin as i16, xmax as i16, ymax as i16)
303 };
304
305 glyf.extend_from_slice(&(n_contours as i16).to_be_bytes());
307 glyf.extend_from_slice(&x_min.to_be_bytes());
308 glyf.extend_from_slice(&y_min.to_be_bytes());
309 glyf.extend_from_slice(&x_max.to_be_bytes());
310 glyf.extend_from_slice(&y_max.to_be_bytes());
311 for e in &end_pts {
312 glyf.extend_from_slice(&e.to_be_bytes());
313 }
314 glyf.extend_from_slice(&(instr_len as u16).to_be_bytes());
315 glyf.extend_from_slice(instr);
316
317 for (i, &oc) in on_curve.iter().enumerate() {
320 let _ = i;
321 glyf.push(if oc { 0x01 } else { 0x00 });
322 }
323 let mut prev = 0i32;
324 for &v in &xs {
325 let d = v - prev;
326 prev = v;
327 glyf.extend_from_slice(&(d as i16).to_be_bytes());
328 }
329 let mut prev = 0i32;
330 for &v in &ys {
331 let d = v - prev;
332 prev = v;
333 glyf.extend_from_slice(&(d as i16).to_be_bytes());
334 }
335
336 while glyf.len() % 4 != 0 {
337 glyf.push(0);
338 }
339 offsets.push(glyf.len() as u32);
340 }
341
342 let mut loca: Vec<u8> = Vec::new();
344 if index_format == 0 {
345 for &o in &offsets {
346 if o % 2 != 0 || o / 2 > u16::MAX as u32 {
347 return None;
350 }
351 loca.extend_from_slice(&((o / 2) as u16).to_be_bytes());
352 }
353 } else {
354 for &o in &offsets {
355 loca.extend_from_slice(&o.to_be_bytes());
356 }
357 }
358
359 Some((glyf, loca, index_format))
360}