1 // THIS FILE IS AUTOGENERATED.
2 // Any changes to this file will be overwritten.
3 // For more information about how codegen works, see font-codegen/README.md
4 
5 #[allow(unused_imports)]
6 use crate::codegen_prelude::*;
7 
8 /// [cmap](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#overview)
9 #[derive(Debug, Clone, Copy)]
10 #[doc(hidden)]
11 pub struct CmapMarker {
12     encoding_records_byte_len: usize,
13 }
14 
15 impl CmapMarker {
version_byte_range(&self) -> Range<usize>16     fn version_byte_range(&self) -> Range<usize> {
17         let start = 0;
18         start..start + u16::RAW_BYTE_LEN
19     }
num_tables_byte_range(&self) -> Range<usize>20     fn num_tables_byte_range(&self) -> Range<usize> {
21         let start = self.version_byte_range().end;
22         start..start + u16::RAW_BYTE_LEN
23     }
encoding_records_byte_range(&self) -> Range<usize>24     fn encoding_records_byte_range(&self) -> Range<usize> {
25         let start = self.num_tables_byte_range().end;
26         start..start + self.encoding_records_byte_len
27     }
28 }
29 
30 impl TopLevelTable for Cmap<'_> {
31     /// `cmap`
32     const TAG: Tag = Tag::new(b"cmap");
33 }
34 
35 impl<'a> FontRead<'a> for Cmap<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>36     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
37         let mut cursor = data.cursor();
38         cursor.advance::<u16>();
39         let num_tables: u16 = cursor.read()?;
40         let encoding_records_byte_len = num_tables as usize * EncodingRecord::RAW_BYTE_LEN;
41         cursor.advance_by(encoding_records_byte_len);
42         cursor.finish(CmapMarker {
43             encoding_records_byte_len,
44         })
45     }
46 }
47 
48 /// [cmap](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#overview)
49 pub type Cmap<'a> = TableRef<'a, CmapMarker>;
50 
51 impl<'a> Cmap<'a> {
52     /// Table version number (0).
version(&self) -> u1653     pub fn version(&self) -> u16 {
54         let range = self.shape.version_byte_range();
55         self.data.read_at(range.start).unwrap()
56     }
57 
58     /// Number of encoding tables that follow.
num_tables(&self) -> u1659     pub fn num_tables(&self) -> u16 {
60         let range = self.shape.num_tables_byte_range();
61         self.data.read_at(range.start).unwrap()
62     }
63 
encoding_records(&self) -> &'a [EncodingRecord]64     pub fn encoding_records(&self) -> &'a [EncodingRecord] {
65         let range = self.shape.encoding_records_byte_range();
66         self.data.read_array(range).unwrap()
67     }
68 }
69 
70 #[cfg(feature = "traversal")]
71 impl<'a> SomeTable<'a> for Cmap<'a> {
type_name(&self) -> &str72     fn type_name(&self) -> &str {
73         "Cmap"
74     }
get_field(&self, idx: usize) -> Option<Field<'a>>75     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
76         match idx {
77             0usize => Some(Field::new("version", self.version())),
78             1usize => Some(Field::new("num_tables", self.num_tables())),
79             2usize => Some(Field::new(
80                 "encoding_records",
81                 traversal::FieldType::array_of_records(
82                     stringify!(EncodingRecord),
83                     self.encoding_records(),
84                     self.offset_data(),
85                 ),
86             )),
87             _ => None,
88         }
89     }
90 }
91 
92 #[cfg(feature = "traversal")]
93 impl<'a> std::fmt::Debug for Cmap<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result94     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95         (self as &dyn SomeTable<'a>).fmt(f)
96     }
97 }
98 
99 /// [Encoding Record](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#encoding-records-and-encodings)
100 #[derive(Clone, Debug)]
101 #[repr(C)]
102 #[repr(packed)]
103 pub struct EncodingRecord {
104     /// Platform ID.
105     pub platform_id: BigEndian<PlatformId>,
106     /// Platform-specific encoding ID.
107     pub encoding_id: BigEndian<u16>,
108     /// Byte offset from beginning of the [`Cmap`] table to the subtable for this
109     /// encoding.
110     pub subtable_offset: BigEndian<Offset32>,
111 }
112 
113 impl EncodingRecord {
114     /// Platform ID.
platform_id(&self) -> PlatformId115     pub fn platform_id(&self) -> PlatformId {
116         self.platform_id.get()
117     }
118 
119     /// Platform-specific encoding ID.
encoding_id(&self) -> u16120     pub fn encoding_id(&self) -> u16 {
121         self.encoding_id.get()
122     }
123 
124     /// Byte offset from beginning of the [`Cmap`] table to the subtable for this
125     /// encoding.
subtable_offset(&self) -> Offset32126     pub fn subtable_offset(&self) -> Offset32 {
127         self.subtable_offset.get()
128     }
129 
130     /// Byte offset from beginning of the [`Cmap`] table to the subtable for this
131     /// encoding.
132     ///
133     /// The `data` argument should be retrieved from the parent table
134     /// By calling its `offset_data` method.
subtable<'a>(&self, data: FontData<'a>) -> Result<CmapSubtable<'a>, ReadError>135     pub fn subtable<'a>(&self, data: FontData<'a>) -> Result<CmapSubtable<'a>, ReadError> {
136         self.subtable_offset().resolve(data)
137     }
138 }
139 
140 impl FixedSize for EncodingRecord {
141     const RAW_BYTE_LEN: usize =
142         PlatformId::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN;
143 }
144 
145 impl sealed::Sealed for EncodingRecord {}
146 
147 /// SAFETY: see the [`FromBytes`] trait documentation.
148 unsafe impl FromBytes for EncodingRecord {
this_trait_should_only_be_implemented_in_generated_code()149     fn this_trait_should_only_be_implemented_in_generated_code() {}
150 }
151 
152 #[cfg(feature = "traversal")]
153 impl<'a> SomeRecord<'a> for EncodingRecord {
traverse(self, data: FontData<'a>) -> RecordResolver<'a>154     fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
155         RecordResolver {
156             name: "EncodingRecord",
157             get_field: Box::new(move |idx, _data| match idx {
158                 0usize => Some(Field::new("platform_id", self.platform_id())),
159                 1usize => Some(Field::new("encoding_id", self.encoding_id())),
160                 2usize => Some(Field::new(
161                     "subtable_offset",
162                     FieldType::offset(self.subtable_offset(), self.subtable(_data)),
163                 )),
164                 _ => None,
165             }),
166             data,
167         }
168     }
169 }
170 
171 /// <https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#platform-ids>
172 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
173 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
174 #[repr(u16)]
175 #[allow(clippy::manual_non_exhaustive)]
176 pub enum PlatformId {
177     #[default]
178     Unicode = 0,
179     Macintosh = 1,
180     ISO = 2,
181     Windows = 3,
182     Custom = 4,
183     #[doc(hidden)]
184     /// If font data is malformed we will map unknown values to this variant
185     Unknown,
186 }
187 
188 impl PlatformId {
189     /// Create from a raw scalar.
190     ///
191     /// This will never fail; unknown values will be mapped to the `Unknown` variant
new(raw: u16) -> Self192     pub fn new(raw: u16) -> Self {
193         match raw {
194             0 => Self::Unicode,
195             1 => Self::Macintosh,
196             2 => Self::ISO,
197             3 => Self::Windows,
198             4 => Self::Custom,
199             _ => Self::Unknown,
200         }
201     }
202 }
203 
204 impl font_types::Scalar for PlatformId {
205     type Raw = <u16 as font_types::Scalar>::Raw;
to_raw(self) -> Self::Raw206     fn to_raw(self) -> Self::Raw {
207         (self as u16).to_raw()
208     }
from_raw(raw: Self::Raw) -> Self209     fn from_raw(raw: Self::Raw) -> Self {
210         let t = <u16>::from_raw(raw);
211         Self::new(t)
212     }
213 }
214 
215 #[cfg(feature = "traversal")]
216 impl<'a> From<PlatformId> for FieldType<'a> {
from(src: PlatformId) -> FieldType<'a>217     fn from(src: PlatformId) -> FieldType<'a> {
218         (src as u16).into()
219     }
220 }
221 
222 /// The different cmap subtable formats.
223 #[derive(Clone)]
224 pub enum CmapSubtable<'a> {
225     Format0(Cmap0<'a>),
226     Format2(Cmap2<'a>),
227     Format4(Cmap4<'a>),
228     Format6(Cmap6<'a>),
229     Format8(Cmap8<'a>),
230     Format10(Cmap10<'a>),
231     Format12(Cmap12<'a>),
232     Format13(Cmap13<'a>),
233     Format14(Cmap14<'a>),
234 }
235 
236 impl<'a> CmapSubtable<'a> {
237     /// Format number is set to 0.
format(&self) -> u16238     pub fn format(&self) -> u16 {
239         match self {
240             Self::Format0(item) => item.format(),
241             Self::Format2(item) => item.format(),
242             Self::Format4(item) => item.format(),
243             Self::Format6(item) => item.format(),
244             Self::Format8(item) => item.format(),
245             Self::Format10(item) => item.format(),
246             Self::Format12(item) => item.format(),
247             Self::Format13(item) => item.format(),
248             Self::Format14(item) => item.format(),
249         }
250     }
251 }
252 
253 impl<'a> FontRead<'a> for CmapSubtable<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>254     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
255         let format: u16 = data.read_at(0usize)?;
256         match format {
257             Cmap0Marker::FORMAT => Ok(Self::Format0(FontRead::read(data)?)),
258             Cmap2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)),
259             Cmap4Marker::FORMAT => Ok(Self::Format4(FontRead::read(data)?)),
260             Cmap6Marker::FORMAT => Ok(Self::Format6(FontRead::read(data)?)),
261             Cmap8Marker::FORMAT => Ok(Self::Format8(FontRead::read(data)?)),
262             Cmap10Marker::FORMAT => Ok(Self::Format10(FontRead::read(data)?)),
263             Cmap12Marker::FORMAT => Ok(Self::Format12(FontRead::read(data)?)),
264             Cmap13Marker::FORMAT => Ok(Self::Format13(FontRead::read(data)?)),
265             Cmap14Marker::FORMAT => Ok(Self::Format14(FontRead::read(data)?)),
266             other => Err(ReadError::InvalidFormat(other.into())),
267         }
268     }
269 }
270 
271 #[cfg(feature = "traversal")]
272 impl<'a> CmapSubtable<'a> {
dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a>273     fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> {
274         match self {
275             Self::Format0(table) => table,
276             Self::Format2(table) => table,
277             Self::Format4(table) => table,
278             Self::Format6(table) => table,
279             Self::Format8(table) => table,
280             Self::Format10(table) => table,
281             Self::Format12(table) => table,
282             Self::Format13(table) => table,
283             Self::Format14(table) => table,
284         }
285     }
286 }
287 
288 #[cfg(feature = "traversal")]
289 impl<'a> std::fmt::Debug for CmapSubtable<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result290     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
291         self.dyn_inner().fmt(f)
292     }
293 }
294 
295 #[cfg(feature = "traversal")]
296 impl<'a> SomeTable<'a> for CmapSubtable<'a> {
type_name(&self) -> &str297     fn type_name(&self) -> &str {
298         self.dyn_inner().type_name()
299     }
get_field(&self, idx: usize) -> Option<Field<'a>>300     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
301         self.dyn_inner().get_field(idx)
302     }
303 }
304 
305 impl Format<u16> for Cmap0Marker {
306     const FORMAT: u16 = 0;
307 }
308 
309 /// [cmap Format 0](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-0-byte-encoding-table): Byte encoding table
310 #[derive(Debug, Clone, Copy)]
311 #[doc(hidden)]
312 pub struct Cmap0Marker {
313     glyph_id_array_byte_len: usize,
314 }
315 
316 impl Cmap0Marker {
format_byte_range(&self) -> Range<usize>317     fn format_byte_range(&self) -> Range<usize> {
318         let start = 0;
319         start..start + u16::RAW_BYTE_LEN
320     }
length_byte_range(&self) -> Range<usize>321     fn length_byte_range(&self) -> Range<usize> {
322         let start = self.format_byte_range().end;
323         start..start + u16::RAW_BYTE_LEN
324     }
language_byte_range(&self) -> Range<usize>325     fn language_byte_range(&self) -> Range<usize> {
326         let start = self.length_byte_range().end;
327         start..start + u16::RAW_BYTE_LEN
328     }
glyph_id_array_byte_range(&self) -> Range<usize>329     fn glyph_id_array_byte_range(&self) -> Range<usize> {
330         let start = self.language_byte_range().end;
331         start..start + self.glyph_id_array_byte_len
332     }
333 }
334 
335 impl<'a> FontRead<'a> for Cmap0<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>336     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
337         let mut cursor = data.cursor();
338         cursor.advance::<u16>();
339         cursor.advance::<u16>();
340         cursor.advance::<u16>();
341         let glyph_id_array_byte_len = 256_usize * u8::RAW_BYTE_LEN;
342         cursor.advance_by(glyph_id_array_byte_len);
343         cursor.finish(Cmap0Marker {
344             glyph_id_array_byte_len,
345         })
346     }
347 }
348 
349 /// [cmap Format 0](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-0-byte-encoding-table): Byte encoding table
350 pub type Cmap0<'a> = TableRef<'a, Cmap0Marker>;
351 
352 impl<'a> Cmap0<'a> {
353     /// Format number is set to 0.
format(&self) -> u16354     pub fn format(&self) -> u16 {
355         let range = self.shape.format_byte_range();
356         self.data.read_at(range.start).unwrap()
357     }
358 
359     /// This is the length in bytes of the subtable.
length(&self) -> u16360     pub fn length(&self) -> u16 {
361         let range = self.shape.length_byte_range();
362         self.data.read_at(range.start).unwrap()
363     }
364 
365     /// For requirements on use of the language field, see “Use of
366     /// the language field in 'cmap' subtables” in this document.
language(&self) -> u16367     pub fn language(&self) -> u16 {
368         let range = self.shape.language_byte_range();
369         self.data.read_at(range.start).unwrap()
370     }
371 
372     /// An array that maps character codes to glyph index values.
glyph_id_array(&self) -> &'a [u8]373     pub fn glyph_id_array(&self) -> &'a [u8] {
374         let range = self.shape.glyph_id_array_byte_range();
375         self.data.read_array(range).unwrap()
376     }
377 }
378 
379 #[cfg(feature = "traversal")]
380 impl<'a> SomeTable<'a> for Cmap0<'a> {
type_name(&self) -> &str381     fn type_name(&self) -> &str {
382         "Cmap0"
383     }
get_field(&self, idx: usize) -> Option<Field<'a>>384     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
385         match idx {
386             0usize => Some(Field::new("format", self.format())),
387             1usize => Some(Field::new("length", self.length())),
388             2usize => Some(Field::new("language", self.language())),
389             3usize => Some(Field::new("glyph_id_array", self.glyph_id_array())),
390             _ => None,
391         }
392     }
393 }
394 
395 #[cfg(feature = "traversal")]
396 impl<'a> std::fmt::Debug for Cmap0<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result397     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
398         (self as &dyn SomeTable<'a>).fmt(f)
399     }
400 }
401 
402 impl Format<u16> for Cmap2Marker {
403     const FORMAT: u16 = 2;
404 }
405 
406 /// [cmap Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-2-high-byte-mapping-through-table): High-byte mapping through table
407 #[derive(Debug, Clone, Copy)]
408 #[doc(hidden)]
409 pub struct Cmap2Marker {
410     sub_header_keys_byte_len: usize,
411 }
412 
413 impl Cmap2Marker {
format_byte_range(&self) -> Range<usize>414     fn format_byte_range(&self) -> Range<usize> {
415         let start = 0;
416         start..start + u16::RAW_BYTE_LEN
417     }
length_byte_range(&self) -> Range<usize>418     fn length_byte_range(&self) -> Range<usize> {
419         let start = self.format_byte_range().end;
420         start..start + u16::RAW_BYTE_LEN
421     }
language_byte_range(&self) -> Range<usize>422     fn language_byte_range(&self) -> Range<usize> {
423         let start = self.length_byte_range().end;
424         start..start + u16::RAW_BYTE_LEN
425     }
sub_header_keys_byte_range(&self) -> Range<usize>426     fn sub_header_keys_byte_range(&self) -> Range<usize> {
427         let start = self.language_byte_range().end;
428         start..start + self.sub_header_keys_byte_len
429     }
430 }
431 
432 impl<'a> FontRead<'a> for Cmap2<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>433     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
434         let mut cursor = data.cursor();
435         cursor.advance::<u16>();
436         cursor.advance::<u16>();
437         cursor.advance::<u16>();
438         let sub_header_keys_byte_len = 256_usize * u16::RAW_BYTE_LEN;
439         cursor.advance_by(sub_header_keys_byte_len);
440         cursor.finish(Cmap2Marker {
441             sub_header_keys_byte_len,
442         })
443     }
444 }
445 
446 /// [cmap Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-2-high-byte-mapping-through-table): High-byte mapping through table
447 pub type Cmap2<'a> = TableRef<'a, Cmap2Marker>;
448 
449 impl<'a> Cmap2<'a> {
450     /// Format number is set to 2.
format(&self) -> u16451     pub fn format(&self) -> u16 {
452         let range = self.shape.format_byte_range();
453         self.data.read_at(range.start).unwrap()
454     }
455 
456     /// This is the length in bytes of the subtable.
length(&self) -> u16457     pub fn length(&self) -> u16 {
458         let range = self.shape.length_byte_range();
459         self.data.read_at(range.start).unwrap()
460     }
461 
462     /// For requirements on use of the language field, see “Use of
463     /// the language field in 'cmap' subtables” in this document.
language(&self) -> u16464     pub fn language(&self) -> u16 {
465         let range = self.shape.language_byte_range();
466         self.data.read_at(range.start).unwrap()
467     }
468 
469     /// Array that maps high bytes to subHeaders: value is subHeader
470     /// index × 8.
sub_header_keys(&self) -> &'a [BigEndian<u16>]471     pub fn sub_header_keys(&self) -> &'a [BigEndian<u16>] {
472         let range = self.shape.sub_header_keys_byte_range();
473         self.data.read_array(range).unwrap()
474     }
475 }
476 
477 #[cfg(feature = "traversal")]
478 impl<'a> SomeTable<'a> for Cmap2<'a> {
type_name(&self) -> &str479     fn type_name(&self) -> &str {
480         "Cmap2"
481     }
get_field(&self, idx: usize) -> Option<Field<'a>>482     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
483         match idx {
484             0usize => Some(Field::new("format", self.format())),
485             1usize => Some(Field::new("length", self.length())),
486             2usize => Some(Field::new("language", self.language())),
487             3usize => Some(Field::new("sub_header_keys", self.sub_header_keys())),
488             _ => None,
489         }
490     }
491 }
492 
493 #[cfg(feature = "traversal")]
494 impl<'a> std::fmt::Debug for Cmap2<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result495     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
496         (self as &dyn SomeTable<'a>).fmt(f)
497     }
498 }
499 
500 /// Part of [Cmap2]
501 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
502 #[repr(C)]
503 #[repr(packed)]
504 pub struct SubHeader {
505     /// First valid low byte for this SubHeader.
506     pub first_code: BigEndian<u16>,
507     /// Number of valid low bytes for this SubHeader.
508     pub entry_count: BigEndian<u16>,
509     /// See text below.
510     pub id_delta: BigEndian<i16>,
511     /// See text below.
512     pub id_range_offset: BigEndian<u16>,
513 }
514 
515 impl SubHeader {
516     /// First valid low byte for this SubHeader.
first_code(&self) -> u16517     pub fn first_code(&self) -> u16 {
518         self.first_code.get()
519     }
520 
521     /// Number of valid low bytes for this SubHeader.
entry_count(&self) -> u16522     pub fn entry_count(&self) -> u16 {
523         self.entry_count.get()
524     }
525 
526     /// See text below.
id_delta(&self) -> i16527     pub fn id_delta(&self) -> i16 {
528         self.id_delta.get()
529     }
530 
531     /// See text below.
id_range_offset(&self) -> u16532     pub fn id_range_offset(&self) -> u16 {
533         self.id_range_offset.get()
534     }
535 }
536 
537 impl FixedSize for SubHeader {
538     const RAW_BYTE_LEN: usize =
539         u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + i16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN;
540 }
541 
542 impl sealed::Sealed for SubHeader {}
543 
544 /// SAFETY: see the [`FromBytes`] trait documentation.
545 unsafe impl FromBytes for SubHeader {
this_trait_should_only_be_implemented_in_generated_code()546     fn this_trait_should_only_be_implemented_in_generated_code() {}
547 }
548 
549 #[cfg(feature = "traversal")]
550 impl<'a> SomeRecord<'a> for SubHeader {
traverse(self, data: FontData<'a>) -> RecordResolver<'a>551     fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
552         RecordResolver {
553             name: "SubHeader",
554             get_field: Box::new(move |idx, _data| match idx {
555                 0usize => Some(Field::new("first_code", self.first_code())),
556                 1usize => Some(Field::new("entry_count", self.entry_count())),
557                 2usize => Some(Field::new("id_delta", self.id_delta())),
558                 3usize => Some(Field::new("id_range_offset", self.id_range_offset())),
559                 _ => None,
560             }),
561             data,
562         }
563     }
564 }
565 
566 impl Format<u16> for Cmap4Marker {
567     const FORMAT: u16 = 4;
568 }
569 
570 /// [cmap Format 4](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-4-segment-mapping-to-delta-values): Segment mapping to delta values
571 #[derive(Debug, Clone, Copy)]
572 #[doc(hidden)]
573 pub struct Cmap4Marker {
574     end_code_byte_len: usize,
575     start_code_byte_len: usize,
576     id_delta_byte_len: usize,
577     id_range_offsets_byte_len: usize,
578     glyph_id_array_byte_len: usize,
579 }
580 
581 impl Cmap4Marker {
format_byte_range(&self) -> Range<usize>582     fn format_byte_range(&self) -> Range<usize> {
583         let start = 0;
584         start..start + u16::RAW_BYTE_LEN
585     }
length_byte_range(&self) -> Range<usize>586     fn length_byte_range(&self) -> Range<usize> {
587         let start = self.format_byte_range().end;
588         start..start + u16::RAW_BYTE_LEN
589     }
language_byte_range(&self) -> Range<usize>590     fn language_byte_range(&self) -> Range<usize> {
591         let start = self.length_byte_range().end;
592         start..start + u16::RAW_BYTE_LEN
593     }
seg_count_x2_byte_range(&self) -> Range<usize>594     fn seg_count_x2_byte_range(&self) -> Range<usize> {
595         let start = self.language_byte_range().end;
596         start..start + u16::RAW_BYTE_LEN
597     }
search_range_byte_range(&self) -> Range<usize>598     fn search_range_byte_range(&self) -> Range<usize> {
599         let start = self.seg_count_x2_byte_range().end;
600         start..start + u16::RAW_BYTE_LEN
601     }
entry_selector_byte_range(&self) -> Range<usize>602     fn entry_selector_byte_range(&self) -> Range<usize> {
603         let start = self.search_range_byte_range().end;
604         start..start + u16::RAW_BYTE_LEN
605     }
range_shift_byte_range(&self) -> Range<usize>606     fn range_shift_byte_range(&self) -> Range<usize> {
607         let start = self.entry_selector_byte_range().end;
608         start..start + u16::RAW_BYTE_LEN
609     }
end_code_byte_range(&self) -> Range<usize>610     fn end_code_byte_range(&self) -> Range<usize> {
611         let start = self.range_shift_byte_range().end;
612         start..start + self.end_code_byte_len
613     }
reserved_pad_byte_range(&self) -> Range<usize>614     fn reserved_pad_byte_range(&self) -> Range<usize> {
615         let start = self.end_code_byte_range().end;
616         start..start + u16::RAW_BYTE_LEN
617     }
start_code_byte_range(&self) -> Range<usize>618     fn start_code_byte_range(&self) -> Range<usize> {
619         let start = self.reserved_pad_byte_range().end;
620         start..start + self.start_code_byte_len
621     }
id_delta_byte_range(&self) -> Range<usize>622     fn id_delta_byte_range(&self) -> Range<usize> {
623         let start = self.start_code_byte_range().end;
624         start..start + self.id_delta_byte_len
625     }
id_range_offsets_byte_range(&self) -> Range<usize>626     fn id_range_offsets_byte_range(&self) -> Range<usize> {
627         let start = self.id_delta_byte_range().end;
628         start..start + self.id_range_offsets_byte_len
629     }
glyph_id_array_byte_range(&self) -> Range<usize>630     fn glyph_id_array_byte_range(&self) -> Range<usize> {
631         let start = self.id_range_offsets_byte_range().end;
632         start..start + self.glyph_id_array_byte_len
633     }
634 }
635 
636 impl<'a> FontRead<'a> for Cmap4<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>637     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
638         let mut cursor = data.cursor();
639         cursor.advance::<u16>();
640         cursor.advance::<u16>();
641         cursor.advance::<u16>();
642         let seg_count_x2: u16 = cursor.read()?;
643         cursor.advance::<u16>();
644         cursor.advance::<u16>();
645         cursor.advance::<u16>();
646         let end_code_byte_len = transforms::half(seg_count_x2) * u16::RAW_BYTE_LEN;
647         cursor.advance_by(end_code_byte_len);
648         cursor.advance::<u16>();
649         let start_code_byte_len = transforms::half(seg_count_x2) * u16::RAW_BYTE_LEN;
650         cursor.advance_by(start_code_byte_len);
651         let id_delta_byte_len = transforms::half(seg_count_x2) * i16::RAW_BYTE_LEN;
652         cursor.advance_by(id_delta_byte_len);
653         let id_range_offsets_byte_len = transforms::half(seg_count_x2) * u16::RAW_BYTE_LEN;
654         cursor.advance_by(id_range_offsets_byte_len);
655         let glyph_id_array_byte_len =
656             cursor.remaining_bytes() / u16::RAW_BYTE_LEN * u16::RAW_BYTE_LEN;
657         cursor.advance_by(glyph_id_array_byte_len);
658         cursor.finish(Cmap4Marker {
659             end_code_byte_len,
660             start_code_byte_len,
661             id_delta_byte_len,
662             id_range_offsets_byte_len,
663             glyph_id_array_byte_len,
664         })
665     }
666 }
667 
668 /// [cmap Format 4](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-4-segment-mapping-to-delta-values): Segment mapping to delta values
669 pub type Cmap4<'a> = TableRef<'a, Cmap4Marker>;
670 
671 impl<'a> Cmap4<'a> {
672     /// Format number is set to 4.
format(&self) -> u16673     pub fn format(&self) -> u16 {
674         let range = self.shape.format_byte_range();
675         self.data.read_at(range.start).unwrap()
676     }
677 
678     /// This is the length in bytes of the subtable.
length(&self) -> u16679     pub fn length(&self) -> u16 {
680         let range = self.shape.length_byte_range();
681         self.data.read_at(range.start).unwrap()
682     }
683 
684     /// For requirements on use of the language field, see “Use of
685     /// the language field in 'cmap' subtables” in this document.
language(&self) -> u16686     pub fn language(&self) -> u16 {
687         let range = self.shape.language_byte_range();
688         self.data.read_at(range.start).unwrap()
689     }
690 
691     /// 2 × segCount.
seg_count_x2(&self) -> u16692     pub fn seg_count_x2(&self) -> u16 {
693         let range = self.shape.seg_count_x2_byte_range();
694         self.data.read_at(range.start).unwrap()
695     }
696 
697     /// Maximum power of 2 less than or equal to segCount, times 2
698     /// ((2**floor(log2(segCount))) * 2, where “**” is an
699     /// exponentiation operator)
search_range(&self) -> u16700     pub fn search_range(&self) -> u16 {
701         let range = self.shape.search_range_byte_range();
702         self.data.read_at(range.start).unwrap()
703     }
704 
705     /// Log2 of the maximum power of 2 less than or equal to numTables
706     /// (log2(searchRange/2), which is equal to floor(log2(segCount)))
entry_selector(&self) -> u16707     pub fn entry_selector(&self) -> u16 {
708         let range = self.shape.entry_selector_byte_range();
709         self.data.read_at(range.start).unwrap()
710     }
711 
712     /// segCount times 2, minus searchRange ((segCount * 2) -
713     /// searchRange)
range_shift(&self) -> u16714     pub fn range_shift(&self) -> u16 {
715         let range = self.shape.range_shift_byte_range();
716         self.data.read_at(range.start).unwrap()
717     }
718 
719     /// End characterCode for each segment, last=0xFFFF.
end_code(&self) -> &'a [BigEndian<u16>]720     pub fn end_code(&self) -> &'a [BigEndian<u16>] {
721         let range = self.shape.end_code_byte_range();
722         self.data.read_array(range).unwrap()
723     }
724 
725     /// Start character code for each segment.
start_code(&self) -> &'a [BigEndian<u16>]726     pub fn start_code(&self) -> &'a [BigEndian<u16>] {
727         let range = self.shape.start_code_byte_range();
728         self.data.read_array(range).unwrap()
729     }
730 
731     /// Delta for all character codes in segment.
id_delta(&self) -> &'a [BigEndian<i16>]732     pub fn id_delta(&self) -> &'a [BigEndian<i16>] {
733         let range = self.shape.id_delta_byte_range();
734         self.data.read_array(range).unwrap()
735     }
736 
737     /// Offsets into glyphIdArray or 0
id_range_offsets(&self) -> &'a [BigEndian<u16>]738     pub fn id_range_offsets(&self) -> &'a [BigEndian<u16>] {
739         let range = self.shape.id_range_offsets_byte_range();
740         self.data.read_array(range).unwrap()
741     }
742 
743     /// Glyph index array (arbitrary length)
glyph_id_array(&self) -> &'a [BigEndian<u16>]744     pub fn glyph_id_array(&self) -> &'a [BigEndian<u16>] {
745         let range = self.shape.glyph_id_array_byte_range();
746         self.data.read_array(range).unwrap()
747     }
748 }
749 
750 #[cfg(feature = "traversal")]
751 impl<'a> SomeTable<'a> for Cmap4<'a> {
type_name(&self) -> &str752     fn type_name(&self) -> &str {
753         "Cmap4"
754     }
get_field(&self, idx: usize) -> Option<Field<'a>>755     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
756         match idx {
757             0usize => Some(Field::new("format", self.format())),
758             1usize => Some(Field::new("length", self.length())),
759             2usize => Some(Field::new("language", self.language())),
760             3usize => Some(Field::new("seg_count_x2", self.seg_count_x2())),
761             4usize => Some(Field::new("search_range", self.search_range())),
762             5usize => Some(Field::new("entry_selector", self.entry_selector())),
763             6usize => Some(Field::new("range_shift", self.range_shift())),
764             7usize => Some(Field::new("end_code", self.end_code())),
765             8usize => Some(Field::new("start_code", self.start_code())),
766             9usize => Some(Field::new("id_delta", self.id_delta())),
767             10usize => Some(Field::new("id_range_offsets", self.id_range_offsets())),
768             11usize => Some(Field::new("glyph_id_array", self.glyph_id_array())),
769             _ => None,
770         }
771     }
772 }
773 
774 #[cfg(feature = "traversal")]
775 impl<'a> std::fmt::Debug for Cmap4<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result776     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
777         (self as &dyn SomeTable<'a>).fmt(f)
778     }
779 }
780 
781 impl Format<u16> for Cmap6Marker {
782     const FORMAT: u16 = 6;
783 }
784 
785 /// [cmap Format 6](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-6-trimmed-table-mapping): Trimmed table mapping
786 #[derive(Debug, Clone, Copy)]
787 #[doc(hidden)]
788 pub struct Cmap6Marker {
789     glyph_id_array_byte_len: usize,
790 }
791 
792 impl Cmap6Marker {
format_byte_range(&self) -> Range<usize>793     fn format_byte_range(&self) -> Range<usize> {
794         let start = 0;
795         start..start + u16::RAW_BYTE_LEN
796     }
length_byte_range(&self) -> Range<usize>797     fn length_byte_range(&self) -> Range<usize> {
798         let start = self.format_byte_range().end;
799         start..start + u16::RAW_BYTE_LEN
800     }
language_byte_range(&self) -> Range<usize>801     fn language_byte_range(&self) -> Range<usize> {
802         let start = self.length_byte_range().end;
803         start..start + u16::RAW_BYTE_LEN
804     }
first_code_byte_range(&self) -> Range<usize>805     fn first_code_byte_range(&self) -> Range<usize> {
806         let start = self.language_byte_range().end;
807         start..start + u16::RAW_BYTE_LEN
808     }
entry_count_byte_range(&self) -> Range<usize>809     fn entry_count_byte_range(&self) -> Range<usize> {
810         let start = self.first_code_byte_range().end;
811         start..start + u16::RAW_BYTE_LEN
812     }
glyph_id_array_byte_range(&self) -> Range<usize>813     fn glyph_id_array_byte_range(&self) -> Range<usize> {
814         let start = self.entry_count_byte_range().end;
815         start..start + self.glyph_id_array_byte_len
816     }
817 }
818 
819 impl<'a> FontRead<'a> for Cmap6<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>820     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
821         let mut cursor = data.cursor();
822         cursor.advance::<u16>();
823         cursor.advance::<u16>();
824         cursor.advance::<u16>();
825         cursor.advance::<u16>();
826         let entry_count: u16 = cursor.read()?;
827         let glyph_id_array_byte_len = entry_count as usize * u16::RAW_BYTE_LEN;
828         cursor.advance_by(glyph_id_array_byte_len);
829         cursor.finish(Cmap6Marker {
830             glyph_id_array_byte_len,
831         })
832     }
833 }
834 
835 /// [cmap Format 6](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-6-trimmed-table-mapping): Trimmed table mapping
836 pub type Cmap6<'a> = TableRef<'a, Cmap6Marker>;
837 
838 impl<'a> Cmap6<'a> {
839     /// Format number is set to 6.
format(&self) -> u16840     pub fn format(&self) -> u16 {
841         let range = self.shape.format_byte_range();
842         self.data.read_at(range.start).unwrap()
843     }
844 
845     /// This is the length in bytes of the subtable.
length(&self) -> u16846     pub fn length(&self) -> u16 {
847         let range = self.shape.length_byte_range();
848         self.data.read_at(range.start).unwrap()
849     }
850 
851     /// For requirements on use of the language field, see “Use of
852     /// the language field in 'cmap' subtables” in this document.
language(&self) -> u16853     pub fn language(&self) -> u16 {
854         let range = self.shape.language_byte_range();
855         self.data.read_at(range.start).unwrap()
856     }
857 
858     /// First character code of subrange.
first_code(&self) -> u16859     pub fn first_code(&self) -> u16 {
860         let range = self.shape.first_code_byte_range();
861         self.data.read_at(range.start).unwrap()
862     }
863 
864     /// Number of character codes in subrange.
entry_count(&self) -> u16865     pub fn entry_count(&self) -> u16 {
866         let range = self.shape.entry_count_byte_range();
867         self.data.read_at(range.start).unwrap()
868     }
869 
870     /// Array of glyph index values for character codes in the range.
glyph_id_array(&self) -> &'a [BigEndian<u16>]871     pub fn glyph_id_array(&self) -> &'a [BigEndian<u16>] {
872         let range = self.shape.glyph_id_array_byte_range();
873         self.data.read_array(range).unwrap()
874     }
875 }
876 
877 #[cfg(feature = "traversal")]
878 impl<'a> SomeTable<'a> for Cmap6<'a> {
type_name(&self) -> &str879     fn type_name(&self) -> &str {
880         "Cmap6"
881     }
get_field(&self, idx: usize) -> Option<Field<'a>>882     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
883         match idx {
884             0usize => Some(Field::new("format", self.format())),
885             1usize => Some(Field::new("length", self.length())),
886             2usize => Some(Field::new("language", self.language())),
887             3usize => Some(Field::new("first_code", self.first_code())),
888             4usize => Some(Field::new("entry_count", self.entry_count())),
889             5usize => Some(Field::new("glyph_id_array", self.glyph_id_array())),
890             _ => None,
891         }
892     }
893 }
894 
895 #[cfg(feature = "traversal")]
896 impl<'a> std::fmt::Debug for Cmap6<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result897     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
898         (self as &dyn SomeTable<'a>).fmt(f)
899     }
900 }
901 
902 impl Format<u16> for Cmap8Marker {
903     const FORMAT: u16 = 8;
904 }
905 
906 /// [cmap Format 8](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-8-mixed-16-bit-and-32-bit-coverage): mixed 16-bit and 32-bit coverage
907 #[derive(Debug, Clone, Copy)]
908 #[doc(hidden)]
909 pub struct Cmap8Marker {
910     is32_byte_len: usize,
911     groups_byte_len: usize,
912 }
913 
914 impl Cmap8Marker {
format_byte_range(&self) -> Range<usize>915     fn format_byte_range(&self) -> Range<usize> {
916         let start = 0;
917         start..start + u16::RAW_BYTE_LEN
918     }
reserved_byte_range(&self) -> Range<usize>919     fn reserved_byte_range(&self) -> Range<usize> {
920         let start = self.format_byte_range().end;
921         start..start + u16::RAW_BYTE_LEN
922     }
length_byte_range(&self) -> Range<usize>923     fn length_byte_range(&self) -> Range<usize> {
924         let start = self.reserved_byte_range().end;
925         start..start + u32::RAW_BYTE_LEN
926     }
language_byte_range(&self) -> Range<usize>927     fn language_byte_range(&self) -> Range<usize> {
928         let start = self.length_byte_range().end;
929         start..start + u32::RAW_BYTE_LEN
930     }
is32_byte_range(&self) -> Range<usize>931     fn is32_byte_range(&self) -> Range<usize> {
932         let start = self.language_byte_range().end;
933         start..start + self.is32_byte_len
934     }
num_groups_byte_range(&self) -> Range<usize>935     fn num_groups_byte_range(&self) -> Range<usize> {
936         let start = self.is32_byte_range().end;
937         start..start + u32::RAW_BYTE_LEN
938     }
groups_byte_range(&self) -> Range<usize>939     fn groups_byte_range(&self) -> Range<usize> {
940         let start = self.num_groups_byte_range().end;
941         start..start + self.groups_byte_len
942     }
943 }
944 
945 impl<'a> FontRead<'a> for Cmap8<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>946     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
947         let mut cursor = data.cursor();
948         cursor.advance::<u16>();
949         cursor.advance::<u16>();
950         cursor.advance::<u32>();
951         cursor.advance::<u32>();
952         let is32_byte_len = 8192_usize * u8::RAW_BYTE_LEN;
953         cursor.advance_by(is32_byte_len);
954         let num_groups: u32 = cursor.read()?;
955         let groups_byte_len = num_groups as usize * SequentialMapGroup::RAW_BYTE_LEN;
956         cursor.advance_by(groups_byte_len);
957         cursor.finish(Cmap8Marker {
958             is32_byte_len,
959             groups_byte_len,
960         })
961     }
962 }
963 
964 /// [cmap Format 8](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-8-mixed-16-bit-and-32-bit-coverage): mixed 16-bit and 32-bit coverage
965 pub type Cmap8<'a> = TableRef<'a, Cmap8Marker>;
966 
967 impl<'a> Cmap8<'a> {
968     /// Subtable format; set to 8.
format(&self) -> u16969     pub fn format(&self) -> u16 {
970         let range = self.shape.format_byte_range();
971         self.data.read_at(range.start).unwrap()
972     }
973 
974     /// Byte length of this subtable (including the header)
length(&self) -> u32975     pub fn length(&self) -> u32 {
976         let range = self.shape.length_byte_range();
977         self.data.read_at(range.start).unwrap()
978     }
979 
980     /// For requirements on use of the language field, see “Use of
981     /// the language field in 'cmap' subtables” in this document.
language(&self) -> u32982     pub fn language(&self) -> u32 {
983         let range = self.shape.language_byte_range();
984         self.data.read_at(range.start).unwrap()
985     }
986 
987     /// Tightly packed array of bits (8K bytes total) indicating
988     /// whether the particular 16-bit (index) value is the start of a
989     /// 32-bit character code
is32(&self) -> &'a [u8]990     pub fn is32(&self) -> &'a [u8] {
991         let range = self.shape.is32_byte_range();
992         self.data.read_array(range).unwrap()
993     }
994 
995     /// Number of groupings which follow
num_groups(&self) -> u32996     pub fn num_groups(&self) -> u32 {
997         let range = self.shape.num_groups_byte_range();
998         self.data.read_at(range.start).unwrap()
999     }
1000 
1001     /// Array of SequentialMapGroup records.
groups(&self) -> &'a [SequentialMapGroup]1002     pub fn groups(&self) -> &'a [SequentialMapGroup] {
1003         let range = self.shape.groups_byte_range();
1004         self.data.read_array(range).unwrap()
1005     }
1006 }
1007 
1008 #[cfg(feature = "traversal")]
1009 impl<'a> SomeTable<'a> for Cmap8<'a> {
type_name(&self) -> &str1010     fn type_name(&self) -> &str {
1011         "Cmap8"
1012     }
get_field(&self, idx: usize) -> Option<Field<'a>>1013     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1014         match idx {
1015             0usize => Some(Field::new("format", self.format())),
1016             1usize => Some(Field::new("length", self.length())),
1017             2usize => Some(Field::new("language", self.language())),
1018             3usize => Some(Field::new("is32", self.is32())),
1019             4usize => Some(Field::new("num_groups", self.num_groups())),
1020             5usize => Some(Field::new(
1021                 "groups",
1022                 traversal::FieldType::array_of_records(
1023                     stringify!(SequentialMapGroup),
1024                     self.groups(),
1025                     self.offset_data(),
1026                 ),
1027             )),
1028             _ => None,
1029         }
1030     }
1031 }
1032 
1033 #[cfg(feature = "traversal")]
1034 impl<'a> std::fmt::Debug for Cmap8<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1035     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1036         (self as &dyn SomeTable<'a>).fmt(f)
1037     }
1038 }
1039 
1040 /// Used in [Cmap8] and [Cmap12]
1041 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1042 #[repr(C)]
1043 #[repr(packed)]
1044 pub struct SequentialMapGroup {
1045     /// First character code in this group; note that if this group is
1046     /// for one or more 16-bit character codes (which is determined
1047     /// from the is32 array), this 32-bit value will have the high
1048     /// 16-bits set to zero
1049     pub start_char_code: BigEndian<u32>,
1050     /// Last character code in this group; same condition as listed
1051     /// above for the startCharCode
1052     pub end_char_code: BigEndian<u32>,
1053     /// Glyph index corresponding to the starting character code
1054     pub start_glyph_id: BigEndian<u32>,
1055 }
1056 
1057 impl SequentialMapGroup {
1058     /// First character code in this group; note that if this group is
1059     /// for one or more 16-bit character codes (which is determined
1060     /// from the is32 array), this 32-bit value will have the high
1061     /// 16-bits set to zero
start_char_code(&self) -> u321062     pub fn start_char_code(&self) -> u32 {
1063         self.start_char_code.get()
1064     }
1065 
1066     /// Last character code in this group; same condition as listed
1067     /// above for the startCharCode
end_char_code(&self) -> u321068     pub fn end_char_code(&self) -> u32 {
1069         self.end_char_code.get()
1070     }
1071 
1072     /// Glyph index corresponding to the starting character code
start_glyph_id(&self) -> u321073     pub fn start_glyph_id(&self) -> u32 {
1074         self.start_glyph_id.get()
1075     }
1076 }
1077 
1078 impl FixedSize for SequentialMapGroup {
1079     const RAW_BYTE_LEN: usize = u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN;
1080 }
1081 
1082 impl sealed::Sealed for SequentialMapGroup {}
1083 
1084 /// SAFETY: see the [`FromBytes`] trait documentation.
1085 unsafe impl FromBytes for SequentialMapGroup {
this_trait_should_only_be_implemented_in_generated_code()1086     fn this_trait_should_only_be_implemented_in_generated_code() {}
1087 }
1088 
1089 #[cfg(feature = "traversal")]
1090 impl<'a> SomeRecord<'a> for SequentialMapGroup {
traverse(self, data: FontData<'a>) -> RecordResolver<'a>1091     fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
1092         RecordResolver {
1093             name: "SequentialMapGroup",
1094             get_field: Box::new(move |idx, _data| match idx {
1095                 0usize => Some(Field::new("start_char_code", self.start_char_code())),
1096                 1usize => Some(Field::new("end_char_code", self.end_char_code())),
1097                 2usize => Some(Field::new("start_glyph_id", self.start_glyph_id())),
1098                 _ => None,
1099             }),
1100             data,
1101         }
1102     }
1103 }
1104 
1105 impl Format<u16> for Cmap10Marker {
1106     const FORMAT: u16 = 10;
1107 }
1108 
1109 /// [cmap Format 10](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-10-trimmed-array): Tr
1110 #[derive(Debug, Clone, Copy)]
1111 #[doc(hidden)]
1112 pub struct Cmap10Marker {
1113     glyph_id_array_byte_len: usize,
1114 }
1115 
1116 impl Cmap10Marker {
format_byte_range(&self) -> Range<usize>1117     fn format_byte_range(&self) -> Range<usize> {
1118         let start = 0;
1119         start..start + u16::RAW_BYTE_LEN
1120     }
reserved_byte_range(&self) -> Range<usize>1121     fn reserved_byte_range(&self) -> Range<usize> {
1122         let start = self.format_byte_range().end;
1123         start..start + u16::RAW_BYTE_LEN
1124     }
length_byte_range(&self) -> Range<usize>1125     fn length_byte_range(&self) -> Range<usize> {
1126         let start = self.reserved_byte_range().end;
1127         start..start + u32::RAW_BYTE_LEN
1128     }
language_byte_range(&self) -> Range<usize>1129     fn language_byte_range(&self) -> Range<usize> {
1130         let start = self.length_byte_range().end;
1131         start..start + u32::RAW_BYTE_LEN
1132     }
start_char_code_byte_range(&self) -> Range<usize>1133     fn start_char_code_byte_range(&self) -> Range<usize> {
1134         let start = self.language_byte_range().end;
1135         start..start + u32::RAW_BYTE_LEN
1136     }
num_chars_byte_range(&self) -> Range<usize>1137     fn num_chars_byte_range(&self) -> Range<usize> {
1138         let start = self.start_char_code_byte_range().end;
1139         start..start + u32::RAW_BYTE_LEN
1140     }
glyph_id_array_byte_range(&self) -> Range<usize>1141     fn glyph_id_array_byte_range(&self) -> Range<usize> {
1142         let start = self.num_chars_byte_range().end;
1143         start..start + self.glyph_id_array_byte_len
1144     }
1145 }
1146 
1147 impl<'a> FontRead<'a> for Cmap10<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>1148     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1149         let mut cursor = data.cursor();
1150         cursor.advance::<u16>();
1151         cursor.advance::<u16>();
1152         cursor.advance::<u32>();
1153         cursor.advance::<u32>();
1154         cursor.advance::<u32>();
1155         cursor.advance::<u32>();
1156         let glyph_id_array_byte_len =
1157             cursor.remaining_bytes() / u16::RAW_BYTE_LEN * u16::RAW_BYTE_LEN;
1158         cursor.advance_by(glyph_id_array_byte_len);
1159         cursor.finish(Cmap10Marker {
1160             glyph_id_array_byte_len,
1161         })
1162     }
1163 }
1164 
1165 /// [cmap Format 10](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-10-trimmed-array): Tr
1166 pub type Cmap10<'a> = TableRef<'a, Cmap10Marker>;
1167 
1168 impl<'a> Cmap10<'a> {
1169     /// Subtable format; set to 10.
format(&self) -> u161170     pub fn format(&self) -> u16 {
1171         let range = self.shape.format_byte_range();
1172         self.data.read_at(range.start).unwrap()
1173     }
1174 
1175     /// Byte length of this subtable (including the header)
length(&self) -> u321176     pub fn length(&self) -> u32 {
1177         let range = self.shape.length_byte_range();
1178         self.data.read_at(range.start).unwrap()
1179     }
1180 
1181     /// For requirements on use of the language field, see “Use of
1182     /// the language field in 'cmap' subtables” in this document.
language(&self) -> u321183     pub fn language(&self) -> u32 {
1184         let range = self.shape.language_byte_range();
1185         self.data.read_at(range.start).unwrap()
1186     }
1187 
1188     /// First character code covered
start_char_code(&self) -> u321189     pub fn start_char_code(&self) -> u32 {
1190         let range = self.shape.start_char_code_byte_range();
1191         self.data.read_at(range.start).unwrap()
1192     }
1193 
1194     /// Number of character codes covered
num_chars(&self) -> u321195     pub fn num_chars(&self) -> u32 {
1196         let range = self.shape.num_chars_byte_range();
1197         self.data.read_at(range.start).unwrap()
1198     }
1199 
1200     /// Array of glyph indices for the character codes covered
glyph_id_array(&self) -> &'a [BigEndian<u16>]1201     pub fn glyph_id_array(&self) -> &'a [BigEndian<u16>] {
1202         let range = self.shape.glyph_id_array_byte_range();
1203         self.data.read_array(range).unwrap()
1204     }
1205 }
1206 
1207 #[cfg(feature = "traversal")]
1208 impl<'a> SomeTable<'a> for Cmap10<'a> {
type_name(&self) -> &str1209     fn type_name(&self) -> &str {
1210         "Cmap10"
1211     }
get_field(&self, idx: usize) -> Option<Field<'a>>1212     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1213         match idx {
1214             0usize => Some(Field::new("format", self.format())),
1215             1usize => Some(Field::new("length", self.length())),
1216             2usize => Some(Field::new("language", self.language())),
1217             3usize => Some(Field::new("start_char_code", self.start_char_code())),
1218             4usize => Some(Field::new("num_chars", self.num_chars())),
1219             5usize => Some(Field::new("glyph_id_array", self.glyph_id_array())),
1220             _ => None,
1221         }
1222     }
1223 }
1224 
1225 #[cfg(feature = "traversal")]
1226 impl<'a> std::fmt::Debug for Cmap10<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1227     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1228         (self as &dyn SomeTable<'a>).fmt(f)
1229     }
1230 }
1231 
1232 impl Format<u16> for Cmap12Marker {
1233     const FORMAT: u16 = 12;
1234 }
1235 
1236 /// [cmap Format 12](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-12-segmented-coverage): Segmented coverage
1237 #[derive(Debug, Clone, Copy)]
1238 #[doc(hidden)]
1239 pub struct Cmap12Marker {
1240     groups_byte_len: usize,
1241 }
1242 
1243 impl Cmap12Marker {
format_byte_range(&self) -> Range<usize>1244     fn format_byte_range(&self) -> Range<usize> {
1245         let start = 0;
1246         start..start + u16::RAW_BYTE_LEN
1247     }
reserved_byte_range(&self) -> Range<usize>1248     fn reserved_byte_range(&self) -> Range<usize> {
1249         let start = self.format_byte_range().end;
1250         start..start + u16::RAW_BYTE_LEN
1251     }
length_byte_range(&self) -> Range<usize>1252     fn length_byte_range(&self) -> Range<usize> {
1253         let start = self.reserved_byte_range().end;
1254         start..start + u32::RAW_BYTE_LEN
1255     }
language_byte_range(&self) -> Range<usize>1256     fn language_byte_range(&self) -> Range<usize> {
1257         let start = self.length_byte_range().end;
1258         start..start + u32::RAW_BYTE_LEN
1259     }
num_groups_byte_range(&self) -> Range<usize>1260     fn num_groups_byte_range(&self) -> Range<usize> {
1261         let start = self.language_byte_range().end;
1262         start..start + u32::RAW_BYTE_LEN
1263     }
groups_byte_range(&self) -> Range<usize>1264     fn groups_byte_range(&self) -> Range<usize> {
1265         let start = self.num_groups_byte_range().end;
1266         start..start + self.groups_byte_len
1267     }
1268 }
1269 
1270 impl<'a> FontRead<'a> for Cmap12<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>1271     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1272         let mut cursor = data.cursor();
1273         cursor.advance::<u16>();
1274         cursor.advance::<u16>();
1275         cursor.advance::<u32>();
1276         cursor.advance::<u32>();
1277         let num_groups: u32 = cursor.read()?;
1278         let groups_byte_len = num_groups as usize * SequentialMapGroup::RAW_BYTE_LEN;
1279         cursor.advance_by(groups_byte_len);
1280         cursor.finish(Cmap12Marker { groups_byte_len })
1281     }
1282 }
1283 
1284 /// [cmap Format 12](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-12-segmented-coverage): Segmented coverage
1285 pub type Cmap12<'a> = TableRef<'a, Cmap12Marker>;
1286 
1287 impl<'a> Cmap12<'a> {
1288     /// Subtable format; set to 12.
format(&self) -> u161289     pub fn format(&self) -> u16 {
1290         let range = self.shape.format_byte_range();
1291         self.data.read_at(range.start).unwrap()
1292     }
1293 
1294     /// Byte length of this subtable (including the header)
length(&self) -> u321295     pub fn length(&self) -> u32 {
1296         let range = self.shape.length_byte_range();
1297         self.data.read_at(range.start).unwrap()
1298     }
1299 
1300     /// For requirements on use of the language field, see “Use of
1301     /// the language field in 'cmap' subtables” in this document.
language(&self) -> u321302     pub fn language(&self) -> u32 {
1303         let range = self.shape.language_byte_range();
1304         self.data.read_at(range.start).unwrap()
1305     }
1306 
1307     /// Number of groupings which follow
num_groups(&self) -> u321308     pub fn num_groups(&self) -> u32 {
1309         let range = self.shape.num_groups_byte_range();
1310         self.data.read_at(range.start).unwrap()
1311     }
1312 
1313     /// Array of SequentialMapGroup records.
groups(&self) -> &'a [SequentialMapGroup]1314     pub fn groups(&self) -> &'a [SequentialMapGroup] {
1315         let range = self.shape.groups_byte_range();
1316         self.data.read_array(range).unwrap()
1317     }
1318 }
1319 
1320 #[cfg(feature = "traversal")]
1321 impl<'a> SomeTable<'a> for Cmap12<'a> {
type_name(&self) -> &str1322     fn type_name(&self) -> &str {
1323         "Cmap12"
1324     }
get_field(&self, idx: usize) -> Option<Field<'a>>1325     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1326         match idx {
1327             0usize => Some(Field::new("format", self.format())),
1328             1usize => Some(Field::new("length", self.length())),
1329             2usize => Some(Field::new("language", self.language())),
1330             3usize => Some(Field::new("num_groups", self.num_groups())),
1331             4usize => Some(Field::new(
1332                 "groups",
1333                 traversal::FieldType::array_of_records(
1334                     stringify!(SequentialMapGroup),
1335                     self.groups(),
1336                     self.offset_data(),
1337                 ),
1338             )),
1339             _ => None,
1340         }
1341     }
1342 }
1343 
1344 #[cfg(feature = "traversal")]
1345 impl<'a> std::fmt::Debug for Cmap12<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1346     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1347         (self as &dyn SomeTable<'a>).fmt(f)
1348     }
1349 }
1350 
1351 impl Format<u16> for Cmap13Marker {
1352     const FORMAT: u16 = 13;
1353 }
1354 
1355 /// [cmap Format 13](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-13-many-to-one-range-mappings): Many-to-one range mappings
1356 #[derive(Debug, Clone, Copy)]
1357 #[doc(hidden)]
1358 pub struct Cmap13Marker {
1359     groups_byte_len: usize,
1360 }
1361 
1362 impl Cmap13Marker {
format_byte_range(&self) -> Range<usize>1363     fn format_byte_range(&self) -> Range<usize> {
1364         let start = 0;
1365         start..start + u16::RAW_BYTE_LEN
1366     }
reserved_byte_range(&self) -> Range<usize>1367     fn reserved_byte_range(&self) -> Range<usize> {
1368         let start = self.format_byte_range().end;
1369         start..start + u16::RAW_BYTE_LEN
1370     }
length_byte_range(&self) -> Range<usize>1371     fn length_byte_range(&self) -> Range<usize> {
1372         let start = self.reserved_byte_range().end;
1373         start..start + u32::RAW_BYTE_LEN
1374     }
language_byte_range(&self) -> Range<usize>1375     fn language_byte_range(&self) -> Range<usize> {
1376         let start = self.length_byte_range().end;
1377         start..start + u32::RAW_BYTE_LEN
1378     }
num_groups_byte_range(&self) -> Range<usize>1379     fn num_groups_byte_range(&self) -> Range<usize> {
1380         let start = self.language_byte_range().end;
1381         start..start + u32::RAW_BYTE_LEN
1382     }
groups_byte_range(&self) -> Range<usize>1383     fn groups_byte_range(&self) -> Range<usize> {
1384         let start = self.num_groups_byte_range().end;
1385         start..start + self.groups_byte_len
1386     }
1387 }
1388 
1389 impl<'a> FontRead<'a> for Cmap13<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>1390     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1391         let mut cursor = data.cursor();
1392         cursor.advance::<u16>();
1393         cursor.advance::<u16>();
1394         cursor.advance::<u32>();
1395         cursor.advance::<u32>();
1396         let num_groups: u32 = cursor.read()?;
1397         let groups_byte_len = num_groups as usize * ConstantMapGroup::RAW_BYTE_LEN;
1398         cursor.advance_by(groups_byte_len);
1399         cursor.finish(Cmap13Marker { groups_byte_len })
1400     }
1401 }
1402 
1403 /// [cmap Format 13](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-13-many-to-one-range-mappings): Many-to-one range mappings
1404 pub type Cmap13<'a> = TableRef<'a, Cmap13Marker>;
1405 
1406 impl<'a> Cmap13<'a> {
1407     /// Subtable format; set to 13.
format(&self) -> u161408     pub fn format(&self) -> u16 {
1409         let range = self.shape.format_byte_range();
1410         self.data.read_at(range.start).unwrap()
1411     }
1412 
1413     /// Byte length of this subtable (including the header)
length(&self) -> u321414     pub fn length(&self) -> u32 {
1415         let range = self.shape.length_byte_range();
1416         self.data.read_at(range.start).unwrap()
1417     }
1418 
1419     /// For requirements on use of the language field, see “Use of
1420     /// the language field in 'cmap' subtables” in this document.
language(&self) -> u321421     pub fn language(&self) -> u32 {
1422         let range = self.shape.language_byte_range();
1423         self.data.read_at(range.start).unwrap()
1424     }
1425 
1426     /// Number of groupings which follow
num_groups(&self) -> u321427     pub fn num_groups(&self) -> u32 {
1428         let range = self.shape.num_groups_byte_range();
1429         self.data.read_at(range.start).unwrap()
1430     }
1431 
1432     /// Array of ConstantMapGroup records.
groups(&self) -> &'a [ConstantMapGroup]1433     pub fn groups(&self) -> &'a [ConstantMapGroup] {
1434         let range = self.shape.groups_byte_range();
1435         self.data.read_array(range).unwrap()
1436     }
1437 }
1438 
1439 #[cfg(feature = "traversal")]
1440 impl<'a> SomeTable<'a> for Cmap13<'a> {
type_name(&self) -> &str1441     fn type_name(&self) -> &str {
1442         "Cmap13"
1443     }
get_field(&self, idx: usize) -> Option<Field<'a>>1444     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1445         match idx {
1446             0usize => Some(Field::new("format", self.format())),
1447             1usize => Some(Field::new("length", self.length())),
1448             2usize => Some(Field::new("language", self.language())),
1449             3usize => Some(Field::new("num_groups", self.num_groups())),
1450             4usize => Some(Field::new(
1451                 "groups",
1452                 traversal::FieldType::array_of_records(
1453                     stringify!(ConstantMapGroup),
1454                     self.groups(),
1455                     self.offset_data(),
1456                 ),
1457             )),
1458             _ => None,
1459         }
1460     }
1461 }
1462 
1463 #[cfg(feature = "traversal")]
1464 impl<'a> std::fmt::Debug for Cmap13<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1465     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1466         (self as &dyn SomeTable<'a>).fmt(f)
1467     }
1468 }
1469 
1470 /// Part of [Cmap13]
1471 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1472 #[repr(C)]
1473 #[repr(packed)]
1474 pub struct ConstantMapGroup {
1475     /// First character code in this group
1476     pub start_char_code: BigEndian<u32>,
1477     /// Last character code in this group
1478     pub end_char_code: BigEndian<u32>,
1479     /// Glyph index to be used for all the characters in the group’s
1480     /// range.
1481     pub glyph_id: BigEndian<u32>,
1482 }
1483 
1484 impl ConstantMapGroup {
1485     /// First character code in this group
start_char_code(&self) -> u321486     pub fn start_char_code(&self) -> u32 {
1487         self.start_char_code.get()
1488     }
1489 
1490     /// Last character code in this group
end_char_code(&self) -> u321491     pub fn end_char_code(&self) -> u32 {
1492         self.end_char_code.get()
1493     }
1494 
1495     /// Glyph index to be used for all the characters in the group’s
1496     /// range.
glyph_id(&self) -> u321497     pub fn glyph_id(&self) -> u32 {
1498         self.glyph_id.get()
1499     }
1500 }
1501 
1502 impl FixedSize for ConstantMapGroup {
1503     const RAW_BYTE_LEN: usize = u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN;
1504 }
1505 
1506 impl sealed::Sealed for ConstantMapGroup {}
1507 
1508 /// SAFETY: see the [`FromBytes`] trait documentation.
1509 unsafe impl FromBytes for ConstantMapGroup {
this_trait_should_only_be_implemented_in_generated_code()1510     fn this_trait_should_only_be_implemented_in_generated_code() {}
1511 }
1512 
1513 #[cfg(feature = "traversal")]
1514 impl<'a> SomeRecord<'a> for ConstantMapGroup {
traverse(self, data: FontData<'a>) -> RecordResolver<'a>1515     fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
1516         RecordResolver {
1517             name: "ConstantMapGroup",
1518             get_field: Box::new(move |idx, _data| match idx {
1519                 0usize => Some(Field::new("start_char_code", self.start_char_code())),
1520                 1usize => Some(Field::new("end_char_code", self.end_char_code())),
1521                 2usize => Some(Field::new("glyph_id", self.glyph_id())),
1522                 _ => None,
1523             }),
1524             data,
1525         }
1526     }
1527 }
1528 
1529 impl Format<u16> for Cmap14Marker {
1530     const FORMAT: u16 = 14;
1531 }
1532 
1533 /// [cmap Format 14](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-14-unicode-variation-sequences): Unicode Variation Sequences
1534 #[derive(Debug, Clone, Copy)]
1535 #[doc(hidden)]
1536 pub struct Cmap14Marker {
1537     var_selector_byte_len: usize,
1538 }
1539 
1540 impl Cmap14Marker {
format_byte_range(&self) -> Range<usize>1541     fn format_byte_range(&self) -> Range<usize> {
1542         let start = 0;
1543         start..start + u16::RAW_BYTE_LEN
1544     }
length_byte_range(&self) -> Range<usize>1545     fn length_byte_range(&self) -> Range<usize> {
1546         let start = self.format_byte_range().end;
1547         start..start + u32::RAW_BYTE_LEN
1548     }
num_var_selector_records_byte_range(&self) -> Range<usize>1549     fn num_var_selector_records_byte_range(&self) -> Range<usize> {
1550         let start = self.length_byte_range().end;
1551         start..start + u32::RAW_BYTE_LEN
1552     }
var_selector_byte_range(&self) -> Range<usize>1553     fn var_selector_byte_range(&self) -> Range<usize> {
1554         let start = self.num_var_selector_records_byte_range().end;
1555         start..start + self.var_selector_byte_len
1556     }
1557 }
1558 
1559 impl<'a> FontRead<'a> for Cmap14<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>1560     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1561         let mut cursor = data.cursor();
1562         cursor.advance::<u16>();
1563         cursor.advance::<u32>();
1564         let num_var_selector_records: u32 = cursor.read()?;
1565         let var_selector_byte_len =
1566             num_var_selector_records as usize * VariationSelector::RAW_BYTE_LEN;
1567         cursor.advance_by(var_selector_byte_len);
1568         cursor.finish(Cmap14Marker {
1569             var_selector_byte_len,
1570         })
1571     }
1572 }
1573 
1574 /// [cmap Format 14](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-14-unicode-variation-sequences): Unicode Variation Sequences
1575 pub type Cmap14<'a> = TableRef<'a, Cmap14Marker>;
1576 
1577 impl<'a> Cmap14<'a> {
1578     /// Subtable format. Set to 14.
format(&self) -> u161579     pub fn format(&self) -> u16 {
1580         let range = self.shape.format_byte_range();
1581         self.data.read_at(range.start).unwrap()
1582     }
1583 
1584     /// Byte length of this subtable (including this header)
length(&self) -> u321585     pub fn length(&self) -> u32 {
1586         let range = self.shape.length_byte_range();
1587         self.data.read_at(range.start).unwrap()
1588     }
1589 
1590     /// Number of variation Selector Records
num_var_selector_records(&self) -> u321591     pub fn num_var_selector_records(&self) -> u32 {
1592         let range = self.shape.num_var_selector_records_byte_range();
1593         self.data.read_at(range.start).unwrap()
1594     }
1595 
1596     /// Array of VariationSelector records.
var_selector(&self) -> &'a [VariationSelector]1597     pub fn var_selector(&self) -> &'a [VariationSelector] {
1598         let range = self.shape.var_selector_byte_range();
1599         self.data.read_array(range).unwrap()
1600     }
1601 }
1602 
1603 #[cfg(feature = "traversal")]
1604 impl<'a> SomeTable<'a> for Cmap14<'a> {
type_name(&self) -> &str1605     fn type_name(&self) -> &str {
1606         "Cmap14"
1607     }
get_field(&self, idx: usize) -> Option<Field<'a>>1608     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1609         match idx {
1610             0usize => Some(Field::new("format", self.format())),
1611             1usize => Some(Field::new("length", self.length())),
1612             2usize => Some(Field::new(
1613                 "num_var_selector_records",
1614                 self.num_var_selector_records(),
1615             )),
1616             3usize => Some(Field::new(
1617                 "var_selector",
1618                 traversal::FieldType::array_of_records(
1619                     stringify!(VariationSelector),
1620                     self.var_selector(),
1621                     self.offset_data(),
1622                 ),
1623             )),
1624             _ => None,
1625         }
1626     }
1627 }
1628 
1629 #[cfg(feature = "traversal")]
1630 impl<'a> std::fmt::Debug for Cmap14<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1631     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1632         (self as &dyn SomeTable<'a>).fmt(f)
1633     }
1634 }
1635 
1636 /// Part of [Cmap14]
1637 #[derive(Clone, Debug)]
1638 #[repr(C)]
1639 #[repr(packed)]
1640 pub struct VariationSelector {
1641     /// Variation selector
1642     pub var_selector: BigEndian<Uint24>,
1643     /// Offset from the start of the [`Cmap14`] subtable to Default UVS
1644     /// Table. May be NULL.
1645     pub default_uvs_offset: BigEndian<Nullable<Offset32>>,
1646     /// Offset from the start of the [`Cmap14`] subtable to Non-Default
1647     /// UVS Table. May be NULL.
1648     pub non_default_uvs_offset: BigEndian<Nullable<Offset32>>,
1649 }
1650 
1651 impl VariationSelector {
1652     /// Variation selector
var_selector(&self) -> Uint241653     pub fn var_selector(&self) -> Uint24 {
1654         self.var_selector.get()
1655     }
1656 
1657     /// Offset from the start of the [`Cmap14`] subtable to Default UVS
1658     /// Table. May be NULL.
default_uvs_offset(&self) -> Nullable<Offset32>1659     pub fn default_uvs_offset(&self) -> Nullable<Offset32> {
1660         self.default_uvs_offset.get()
1661     }
1662 
1663     /// Offset from the start of the [`Cmap14`] subtable to Default UVS
1664     /// Table. May be NULL.
1665     ///
1666     /// The `data` argument should be retrieved from the parent table
1667     /// By calling its `offset_data` method.
default_uvs<'a>(&self, data: FontData<'a>) -> Option<Result<DefaultUvs<'a>, ReadError>>1668     pub fn default_uvs<'a>(&self, data: FontData<'a>) -> Option<Result<DefaultUvs<'a>, ReadError>> {
1669         self.default_uvs_offset().resolve(data)
1670     }
1671 
1672     /// Offset from the start of the [`Cmap14`] subtable to Non-Default
1673     /// UVS Table. May be NULL.
non_default_uvs_offset(&self) -> Nullable<Offset32>1674     pub fn non_default_uvs_offset(&self) -> Nullable<Offset32> {
1675         self.non_default_uvs_offset.get()
1676     }
1677 
1678     /// Offset from the start of the [`Cmap14`] subtable to Non-Default
1679     /// UVS Table. May be NULL.
1680     ///
1681     /// The `data` argument should be retrieved from the parent table
1682     /// By calling its `offset_data` method.
non_default_uvs<'a>( &self, data: FontData<'a>, ) -> Option<Result<NonDefaultUvs<'a>, ReadError>>1683     pub fn non_default_uvs<'a>(
1684         &self,
1685         data: FontData<'a>,
1686     ) -> Option<Result<NonDefaultUvs<'a>, ReadError>> {
1687         self.non_default_uvs_offset().resolve(data)
1688     }
1689 }
1690 
1691 impl FixedSize for VariationSelector {
1692     const RAW_BYTE_LEN: usize =
1693         Uint24::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN;
1694 }
1695 
1696 impl sealed::Sealed for VariationSelector {}
1697 
1698 /// SAFETY: see the [`FromBytes`] trait documentation.
1699 unsafe impl FromBytes for VariationSelector {
this_trait_should_only_be_implemented_in_generated_code()1700     fn this_trait_should_only_be_implemented_in_generated_code() {}
1701 }
1702 
1703 #[cfg(feature = "traversal")]
1704 impl<'a> SomeRecord<'a> for VariationSelector {
traverse(self, data: FontData<'a>) -> RecordResolver<'a>1705     fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
1706         RecordResolver {
1707             name: "VariationSelector",
1708             get_field: Box::new(move |idx, _data| match idx {
1709                 0usize => Some(Field::new("var_selector", self.var_selector())),
1710                 1usize => Some(Field::new(
1711                     "default_uvs_offset",
1712                     FieldType::offset(self.default_uvs_offset(), self.default_uvs(_data)),
1713                 )),
1714                 2usize => Some(Field::new(
1715                     "non_default_uvs_offset",
1716                     FieldType::offset(self.non_default_uvs_offset(), self.non_default_uvs(_data)),
1717                 )),
1718                 _ => None,
1719             }),
1720             data,
1721         }
1722     }
1723 }
1724 
1725 /// [Default UVS table](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#default-uvs-table)
1726 #[derive(Debug, Clone, Copy)]
1727 #[doc(hidden)]
1728 pub struct DefaultUvsMarker {
1729     ranges_byte_len: usize,
1730 }
1731 
1732 impl DefaultUvsMarker {
num_unicode_value_ranges_byte_range(&self) -> Range<usize>1733     fn num_unicode_value_ranges_byte_range(&self) -> Range<usize> {
1734         let start = 0;
1735         start..start + u32::RAW_BYTE_LEN
1736     }
ranges_byte_range(&self) -> Range<usize>1737     fn ranges_byte_range(&self) -> Range<usize> {
1738         let start = self.num_unicode_value_ranges_byte_range().end;
1739         start..start + self.ranges_byte_len
1740     }
1741 }
1742 
1743 impl<'a> FontRead<'a> for DefaultUvs<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>1744     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1745         let mut cursor = data.cursor();
1746         let num_unicode_value_ranges: u32 = cursor.read()?;
1747         let ranges_byte_len = num_unicode_value_ranges as usize * UnicodeRange::RAW_BYTE_LEN;
1748         cursor.advance_by(ranges_byte_len);
1749         cursor.finish(DefaultUvsMarker { ranges_byte_len })
1750     }
1751 }
1752 
1753 /// [Default UVS table](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#default-uvs-table)
1754 pub type DefaultUvs<'a> = TableRef<'a, DefaultUvsMarker>;
1755 
1756 impl<'a> DefaultUvs<'a> {
1757     /// Number of Unicode character ranges.
num_unicode_value_ranges(&self) -> u321758     pub fn num_unicode_value_ranges(&self) -> u32 {
1759         let range = self.shape.num_unicode_value_ranges_byte_range();
1760         self.data.read_at(range.start).unwrap()
1761     }
1762 
1763     /// Array of UnicodeRange records.
ranges(&self) -> &'a [UnicodeRange]1764     pub fn ranges(&self) -> &'a [UnicodeRange] {
1765         let range = self.shape.ranges_byte_range();
1766         self.data.read_array(range).unwrap()
1767     }
1768 }
1769 
1770 #[cfg(feature = "traversal")]
1771 impl<'a> SomeTable<'a> for DefaultUvs<'a> {
type_name(&self) -> &str1772     fn type_name(&self) -> &str {
1773         "DefaultUvs"
1774     }
get_field(&self, idx: usize) -> Option<Field<'a>>1775     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1776         match idx {
1777             0usize => Some(Field::new(
1778                 "num_unicode_value_ranges",
1779                 self.num_unicode_value_ranges(),
1780             )),
1781             1usize => Some(Field::new(
1782                 "ranges",
1783                 traversal::FieldType::array_of_records(
1784                     stringify!(UnicodeRange),
1785                     self.ranges(),
1786                     self.offset_data(),
1787                 ),
1788             )),
1789             _ => None,
1790         }
1791     }
1792 }
1793 
1794 #[cfg(feature = "traversal")]
1795 impl<'a> std::fmt::Debug for DefaultUvs<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1796     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1797         (self as &dyn SomeTable<'a>).fmt(f)
1798     }
1799 }
1800 
1801 /// [Non-Default UVS table](https://learn.microsoft.com/en-us/typography/opentype/spec/cmap#non-default-uvs-table)
1802 #[derive(Debug, Clone, Copy)]
1803 #[doc(hidden)]
1804 pub struct NonDefaultUvsMarker {
1805     uvs_mapping_byte_len: usize,
1806 }
1807 
1808 impl NonDefaultUvsMarker {
num_uvs_mappings_byte_range(&self) -> Range<usize>1809     fn num_uvs_mappings_byte_range(&self) -> Range<usize> {
1810         let start = 0;
1811         start..start + u32::RAW_BYTE_LEN
1812     }
uvs_mapping_byte_range(&self) -> Range<usize>1813     fn uvs_mapping_byte_range(&self) -> Range<usize> {
1814         let start = self.num_uvs_mappings_byte_range().end;
1815         start..start + self.uvs_mapping_byte_len
1816     }
1817 }
1818 
1819 impl<'a> FontRead<'a> for NonDefaultUvs<'a> {
read(data: FontData<'a>) -> Result<Self, ReadError>1820     fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1821         let mut cursor = data.cursor();
1822         let num_uvs_mappings: u32 = cursor.read()?;
1823         let uvs_mapping_byte_len = num_uvs_mappings as usize * UvsMapping::RAW_BYTE_LEN;
1824         cursor.advance_by(uvs_mapping_byte_len);
1825         cursor.finish(NonDefaultUvsMarker {
1826             uvs_mapping_byte_len,
1827         })
1828     }
1829 }
1830 
1831 /// [Non-Default UVS table](https://learn.microsoft.com/en-us/typography/opentype/spec/cmap#non-default-uvs-table)
1832 pub type NonDefaultUvs<'a> = TableRef<'a, NonDefaultUvsMarker>;
1833 
1834 impl<'a> NonDefaultUvs<'a> {
num_uvs_mappings(&self) -> u321835     pub fn num_uvs_mappings(&self) -> u32 {
1836         let range = self.shape.num_uvs_mappings_byte_range();
1837         self.data.read_at(range.start).unwrap()
1838     }
1839 
uvs_mapping(&self) -> &'a [UvsMapping]1840     pub fn uvs_mapping(&self) -> &'a [UvsMapping] {
1841         let range = self.shape.uvs_mapping_byte_range();
1842         self.data.read_array(range).unwrap()
1843     }
1844 }
1845 
1846 #[cfg(feature = "traversal")]
1847 impl<'a> SomeTable<'a> for NonDefaultUvs<'a> {
type_name(&self) -> &str1848     fn type_name(&self) -> &str {
1849         "NonDefaultUvs"
1850     }
get_field(&self, idx: usize) -> Option<Field<'a>>1851     fn get_field(&self, idx: usize) -> Option<Field<'a>> {
1852         match idx {
1853             0usize => Some(Field::new("num_uvs_mappings", self.num_uvs_mappings())),
1854             1usize => Some(Field::new(
1855                 "uvs_mapping",
1856                 traversal::FieldType::array_of_records(
1857                     stringify!(UvsMapping),
1858                     self.uvs_mapping(),
1859                     self.offset_data(),
1860                 ),
1861             )),
1862             _ => None,
1863         }
1864     }
1865 }
1866 
1867 #[cfg(feature = "traversal")]
1868 impl<'a> std::fmt::Debug for NonDefaultUvs<'a> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result1869     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1870         (self as &dyn SomeTable<'a>).fmt(f)
1871     }
1872 }
1873 
1874 /// Part of [Cmap14]
1875 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1876 #[repr(C)]
1877 #[repr(packed)]
1878 pub struct UvsMapping {
1879     /// Base Unicode value of the UVS
1880     pub unicode_value: BigEndian<Uint24>,
1881     /// Glyph ID of the UVS
1882     pub glyph_id: BigEndian<u16>,
1883 }
1884 
1885 impl UvsMapping {
1886     /// Base Unicode value of the UVS
unicode_value(&self) -> Uint241887     pub fn unicode_value(&self) -> Uint24 {
1888         self.unicode_value.get()
1889     }
1890 
1891     /// Glyph ID of the UVS
glyph_id(&self) -> u161892     pub fn glyph_id(&self) -> u16 {
1893         self.glyph_id.get()
1894     }
1895 }
1896 
1897 impl FixedSize for UvsMapping {
1898     const RAW_BYTE_LEN: usize = Uint24::RAW_BYTE_LEN + u16::RAW_BYTE_LEN;
1899 }
1900 
1901 impl sealed::Sealed for UvsMapping {}
1902 
1903 /// SAFETY: see the [`FromBytes`] trait documentation.
1904 unsafe impl FromBytes for UvsMapping {
this_trait_should_only_be_implemented_in_generated_code()1905     fn this_trait_should_only_be_implemented_in_generated_code() {}
1906 }
1907 
1908 #[cfg(feature = "traversal")]
1909 impl<'a> SomeRecord<'a> for UvsMapping {
traverse(self, data: FontData<'a>) -> RecordResolver<'a>1910     fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
1911         RecordResolver {
1912             name: "UvsMapping",
1913             get_field: Box::new(move |idx, _data| match idx {
1914                 0usize => Some(Field::new("unicode_value", self.unicode_value())),
1915                 1usize => Some(Field::new("glyph_id", self.glyph_id())),
1916                 _ => None,
1917             }),
1918             data,
1919         }
1920     }
1921 }
1922 
1923 /// Part of [Cmap14]
1924 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1925 #[repr(C)]
1926 #[repr(packed)]
1927 pub struct UnicodeRange {
1928     /// First value in this range
1929     pub start_unicode_value: BigEndian<Uint24>,
1930     /// Number of additional values in this range
1931     pub additional_count: u8,
1932 }
1933 
1934 impl UnicodeRange {
1935     /// First value in this range
start_unicode_value(&self) -> Uint241936     pub fn start_unicode_value(&self) -> Uint24 {
1937         self.start_unicode_value.get()
1938     }
1939 
1940     /// Number of additional values in this range
additional_count(&self) -> u81941     pub fn additional_count(&self) -> u8 {
1942         self.additional_count
1943     }
1944 }
1945 
1946 impl FixedSize for UnicodeRange {
1947     const RAW_BYTE_LEN: usize = Uint24::RAW_BYTE_LEN + u8::RAW_BYTE_LEN;
1948 }
1949 
1950 impl sealed::Sealed for UnicodeRange {}
1951 
1952 /// SAFETY: see the [`FromBytes`] trait documentation.
1953 unsafe impl FromBytes for UnicodeRange {
this_trait_should_only_be_implemented_in_generated_code()1954     fn this_trait_should_only_be_implemented_in_generated_code() {}
1955 }
1956 
1957 #[cfg(feature = "traversal")]
1958 impl<'a> SomeRecord<'a> for UnicodeRange {
traverse(self, data: FontData<'a>) -> RecordResolver<'a>1959     fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
1960         RecordResolver {
1961             name: "UnicodeRange",
1962             get_field: Box::new(move |idx, _data| match idx {
1963                 0usize => Some(Field::new(
1964                     "start_unicode_value",
1965                     self.start_unicode_value(),
1966                 )),
1967                 1usize => Some(Field::new("additional_count", self.additional_count())),
1968                 _ => None,
1969             }),
1970             data,
1971         }
1972     }
1973 }
1974