ttf_view/tables/glyf/
mod.rs1use crate::{
2 tables::{Table, TableDirectory, TableError, cmap::GlyphId, loca::Loca},
3 types::{Tag, int16, tags},
4};
5use std::{ops::Range, ptr::NonNull};
6
7mod composite;
8mod simple;
9
10pub use composite::*;
11pub use simple::*;
12
13impl<'a> Table<'a> for Glyf<'a> {
14 const TAG: Tag = tags::glyf;
15 fn new_in(dir: &'a TableDirectory) -> Result<Self, TableError> {
16 let rec = dir.table_record(Self::TAG).ok_or(TableError::NotFound)?;
17
18 let loca = dir.loca().map_err(|_| TableError::Dependency(tags::loca))?;
19
20 let req_len = loca.iter_raw().last().ok_or(TableError::Malformed(&"no glyphs"))?;
21 if rec.length.get() < req_len {
22 return Err(TableError::InvalidLen);
23 }
24
25 let ptr = NonNull::from_ref(rec.raw_as::<()>().unwrap()).cast::<u8>();
26 Ok(Self { ptr, loca })
27 }
28}
29
30#[derive(Copy)]
31#[derive_const(Clone)]
32pub struct Glyf<'a> {
33 ptr: NonNull<u8>,
34 loca: Loca<'a>,
35}
36
37impl<'a> Glyf<'a> {
38 pub fn glyph_as_bytes(&self, glyph_id: GlyphId) -> Option<&'a [u8]> {
39 let Range { start, end } = self.loca.range(glyph_id)?;
40 if start == end {
41 return Some(&[]);
42 }
43 let ptr = self.ptr.as_ptr().cast_const();
44 Some(unsafe { std::slice::from_raw_parts(ptr.byte_add(start as _), (end - start) as _) })
45 }
46}
47
48#[repr(C)]
49pub struct Glyph {
50 _exhaustive_but_dont_instantiate: (),
51 pub number_of_contours: int16,
52 pub x_min: int16,
53 pub y_min: int16,
54 pub x_max: int16,
55 pub y_max: int16,
56 }
58
59impl Glyph {
60 pub const fn is_simple(&self) -> bool {
61 self.number_of_contours.get() >= 0
62 }
63 pub const fn is_composite(&self) -> bool {
64 !self.is_simple()
65 }
66
67 pub const fn as_simple(&self) -> Option<&SimpleGlyph> {
68 if self.is_simple() {
69 Some(unsafe { std::mem::transmute::<&Self, &SimpleGlyph>(self) })
70 } else {
71 None
72 }
73 }
74 pub const fn as_composite(&self) -> Option<&CompositeGlyph> {
75 if self.is_composite() {
76 Some(unsafe { std::mem::transmute::<&Self, &CompositeGlyph>(self) })
77 } else {
78 None
79 }
80 }
81}