ttf_view/tables/cmap/
mod.rs1use crate::types::{Offset32, Tag, tags, uint16, uint32};
2use std::mem::ManuallyDrop;
3
4mod codepoint;
5mod glyph_id;
6
7pub use codepoint::*;
8pub use glyph_id::*;
9
10pub mod format0;
11pub mod format2;
12pub mod format4;
13pub mod format6;
14pub mod format8;
15
16pub mod format10;
17pub mod format12;
18pub mod format13;
19pub mod format14;
20
21#[repr(C)]
22#[non_exhaustive]
23pub struct CmapTableRepr {
24 pub version: uint16,
25 pub num_tables: uint16,
26 encoding_records: [EncodingRecordRepr; 0],
27}
28#[repr(C)]
29pub struct EncodingRecordRepr {
30 pub platform_id: uint16,
31 pub encoding_id: uint16,
32 pub subtable_offset: Offset32,
33}
34
35impl super::Table for CmapTableRepr {
36 const TAG: Tag = tags::cmap;
37 type Handle<'a> = &'a Self;
38}
39
40impl CmapTableRepr {
41 pub const fn encodings(&self) -> &[EncodingRecordRepr] {
42 unsafe {
43 std::slice::from_raw_parts(self.encoding_records.as_ptr(), self.num_tables.get() as _)
44 }
45 }
46}
47impl EncodingRecordRepr {
48 pub const fn subtable<'a>(&'a self, cmap: &'a CmapTableRepr) -> &'a CmapSubtableRepr {
49 unsafe { &*std::ptr::from_ref(cmap).byte_add(self.subtable_offset.get() as _).cast() }
50 }
51}
52
53#[repr(C)]
54#[non_exhaustive]
55pub struct CmapSubtableRepr {
56 meta: SubtableMeta,
57}
58
59#[repr(C)]
78union SubtableMeta {
79 short: ManuallyDrop<ShortMeta>,
80 long: ManuallyDrop<LongMeta>,
81 len_only: ManuallyDrop<LenOnlyMeta>,
82}
83
84#[repr(C)]
85#[non_exhaustive]
86struct ShortMeta {
87 format: uint16,
88 length: uint16,
89 language: uint16,
90 data: [u8; 0],
91}
92#[repr(C)]
93#[non_exhaustive]
94struct LongMeta {
95 format: uint16,
96 reserved: uint16,
97 length: uint32,
98 language: uint32,
99 data: [u8; 0],
100}
101#[repr(C)]
102#[non_exhaustive]
103struct LenOnlyMeta {
104 format: uint16,
105 length: uint32,
106 data: [u8; 0],
107}
108
109impl CmapSubtableRepr {
110 pub const fn format(&self) -> u16 {
111 unsafe { self.meta.short.format.get() }
112 }
113 pub const fn length(&self) -> Option<u32> {
114 Some(match self.format() {
115 0 | 2 | 4 | 6 => unsafe { self.meta.short.length.get() as _ },
116 8 | 10 | 12 | 13 => unsafe { self.meta.long.length.get() },
117 14 => unsafe { self.meta.len_only.length.get() },
118 _ => return None,
119 })
120 }
121 pub const fn language(&self) -> Option<u32> {
122 Some(match self.format() {
123 0 | 2 | 4 | 6 => unsafe { self.meta.short.language.get() as _ },
124 8 | 10 | 12 | 13 => unsafe { self.meta.long.language.get() },
125 _ => return None,
126 })
127 }
128 pub const fn data_ptr(&self) -> Option<&u8> {
129 Some(match self.format() {
130 0 | 2 | 4 | 6 => unsafe { &*self.meta.short.data.as_ptr() },
131 8 | 10 | 12 | 13 => unsafe { &*self.meta.long.data.as_ptr() },
132 14 => unsafe { &*self.meta.len_only.data.as_ptr() },
133 _ => return None,
134 })
135 }
136 pub const fn data(&self) -> Option<&[u8]> {
137 match self.format() {
138 0 | 2 | 4 | 6 => unsafe {
139 let size = self.meta.short.length.get() as usize - size_of::<ShortMeta>();
140 Some(std::slice::from_raw_parts(self.meta.short.data.as_ptr(), size))
141 },
142 8 | 10 | 12 | 13 => unsafe {
143 let size = self.meta.long.length.get() as usize - size_of::<LongMeta>();
144 Some(std::slice::from_raw_parts(self.meta.long.data.as_ptr(), size))
145 },
146 14 => unsafe {
147 let size = self.meta.len_only.length.get() as usize - size_of::<LenOnlyMeta>();
148 Some(std::slice::from_raw_parts(self.meta.len_only.data.as_ptr(), size))
149 },
150 _ => None,
151 }
152 }
153}