1#[allow(unused_imports)]
6use crate::codegen_prelude::*;
7
8pub use read_fonts::tables::cmap::PlatformId;
9
10#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13pub struct Cmap {
14 pub encoding_records: Vec<EncodingRecord>,
15}
16
17impl Cmap {
18 pub fn new(encoding_records: Vec<EncodingRecord>) -> Self {
20 Self { encoding_records }
21 }
22}
23
24impl FontWrite for Cmap {
25 #[allow(clippy::unnecessary_cast)]
26 fn write_into(&self, writer: &mut TableWriter) {
27 (0 as u16).write_into(writer);
28 (u16::try_from(array_len(&self.encoding_records)).unwrap()).write_into(writer);
29 self.encoding_records.write_into(writer);
30 }
31 fn table_type(&self) -> TableType {
32 TableType::TopLevel(Cmap::TAG)
33 }
34}
35
36impl Validate for Cmap {
37 fn validate_impl(&self, ctx: &mut ValidationCtx) {
38 ctx.in_table("Cmap", |ctx| {
39 ctx.in_field("encoding_records", |ctx| {
40 if self.encoding_records.len() > (u16::MAX as usize) {
41 ctx.report("array exceeds max length");
42 }
43 self.encoding_records.validate_impl(ctx);
44 });
45 })
46 }
47}
48
49impl TopLevelTable for Cmap {
50 const TAG: Tag = Tag::new(b"cmap");
51}
52
53impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap<'a>> for Cmap {
54 fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap<'a>, _: FontData) -> Self {
55 let offset_data = obj.offset_data();
56 Cmap {
57 encoding_records: obj.encoding_records().to_owned_obj(offset_data),
58 }
59 }
60}
61
62#[allow(clippy::needless_lifetimes)]
63impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap<'a>> for Cmap {}
64
65impl<'a> FontRead<'a> for Cmap {
66 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
67 <read_fonts::tables::cmap::Cmap as FontRead>::read(data).map(|x| x.to_owned_table())
68 }
69}
70
71#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
73#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
74pub struct EncodingRecord {
75 pub platform_id: PlatformId,
77 pub encoding_id: u16,
79 pub subtable: OffsetMarker<CmapSubtable, WIDTH_32>,
82}
83
84impl EncodingRecord {
85 pub fn new(platform_id: PlatformId, encoding_id: u16, subtable: CmapSubtable) -> Self {
87 Self {
88 platform_id,
89 encoding_id,
90 subtable: subtable.into(),
91 }
92 }
93}
94
95impl FontWrite for EncodingRecord {
96 fn write_into(&self, writer: &mut TableWriter) {
97 self.platform_id.write_into(writer);
98 self.encoding_id.write_into(writer);
99 self.subtable.write_into(writer);
100 }
101 fn table_type(&self) -> TableType {
102 TableType::Named("EncodingRecord")
103 }
104}
105
106impl Validate for EncodingRecord {
107 fn validate_impl(&self, ctx: &mut ValidationCtx) {
108 ctx.in_table("EncodingRecord", |ctx| {
109 ctx.in_field("subtable", |ctx| {
110 self.subtable.validate_impl(ctx);
111 });
112 })
113 }
114}
115
116impl FromObjRef<read_fonts::tables::cmap::EncodingRecord> for EncodingRecord {
117 fn from_obj_ref(obj: &read_fonts::tables::cmap::EncodingRecord, offset_data: FontData) -> Self {
118 EncodingRecord {
119 platform_id: obj.platform_id(),
120 encoding_id: obj.encoding_id(),
121 subtable: obj.subtable(offset_data).to_owned_table(),
122 }
123 }
124}
125
126impl FontWrite for PlatformId {
127 fn write_into(&self, writer: &mut TableWriter) {
128 let val = *self as u16;
129 writer.write_slice(&val.to_be_bytes())
130 }
131}
132
133#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
135#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
136pub enum CmapSubtable {
137 Format0(Cmap0),
138 Format2(Cmap2),
139 Format4(Cmap4),
140 Format6(Cmap6),
141 Format8(Cmap8),
142 Format10(Cmap10),
143 Format12(Cmap12),
144 Format13(Cmap13),
145 Format14(Cmap14),
146}
147
148impl CmapSubtable {
149 pub fn format_0(language: u16, glyph_id_array: Vec<u8>) -> Self {
151 Self::Format0(Cmap0::new(language, glyph_id_array))
152 }
153
154 pub fn format_2(length: u16, language: u16, sub_header_keys: Vec<u16>) -> Self {
156 Self::Format2(Cmap2::new(length, language, sub_header_keys))
157 }
158
159 pub fn format_4(
161 language: u16,
162 end_code: Vec<u16>,
163 start_code: Vec<u16>,
164 id_delta: Vec<i16>,
165 id_range_offsets: Vec<u16>,
166 glyph_id_array: Vec<u16>,
167 ) -> Self {
168 Self::Format4(Cmap4::new(
169 language,
170 end_code,
171 start_code,
172 id_delta,
173 id_range_offsets,
174 glyph_id_array,
175 ))
176 }
177
178 pub fn format_6(
180 length: u16,
181 language: u16,
182 first_code: u16,
183 entry_count: u16,
184 glyph_id_array: Vec<u16>,
185 ) -> Self {
186 Self::Format6(Cmap6::new(
187 length,
188 language,
189 first_code,
190 entry_count,
191 glyph_id_array,
192 ))
193 }
194
195 pub fn format_8(
197 length: u32,
198 language: u32,
199 is32: Vec<u8>,
200 num_groups: u32,
201 groups: Vec<SequentialMapGroup>,
202 ) -> Self {
203 Self::Format8(Cmap8::new(length, language, is32, num_groups, groups))
204 }
205
206 pub fn format_10(
208 length: u32,
209 language: u32,
210 start_char_code: u32,
211 glyph_id_array: Vec<u16>,
212 ) -> Self {
213 Self::Format10(Cmap10::new(
214 length,
215 language,
216 start_char_code,
217 glyph_id_array,
218 ))
219 }
220
221 pub fn format_12(language: u32, groups: Vec<SequentialMapGroup>) -> Self {
223 Self::Format12(Cmap12::new(language, groups))
224 }
225
226 pub fn format_13(
228 length: u32,
229 language: u32,
230 num_groups: u32,
231 groups: Vec<ConstantMapGroup>,
232 ) -> Self {
233 Self::Format13(Cmap13::new(length, language, num_groups, groups))
234 }
235
236 pub fn format_14(
238 length: u32,
239 num_var_selector_records: u32,
240 var_selector: Vec<VariationSelector>,
241 ) -> Self {
242 Self::Format14(Cmap14::new(length, num_var_selector_records, var_selector))
243 }
244}
245
246impl Default for CmapSubtable {
247 fn default() -> Self {
248 Self::Format0(Default::default())
249 }
250}
251
252impl FontWrite for CmapSubtable {
253 fn write_into(&self, writer: &mut TableWriter) {
254 match self {
255 Self::Format0(item) => item.write_into(writer),
256 Self::Format2(item) => item.write_into(writer),
257 Self::Format4(item) => item.write_into(writer),
258 Self::Format6(item) => item.write_into(writer),
259 Self::Format8(item) => item.write_into(writer),
260 Self::Format10(item) => item.write_into(writer),
261 Self::Format12(item) => item.write_into(writer),
262 Self::Format13(item) => item.write_into(writer),
263 Self::Format14(item) => item.write_into(writer),
264 }
265 }
266 fn table_type(&self) -> TableType {
267 match self {
268 Self::Format0(item) => item.table_type(),
269 Self::Format2(item) => item.table_type(),
270 Self::Format4(item) => item.table_type(),
271 Self::Format6(item) => item.table_type(),
272 Self::Format8(item) => item.table_type(),
273 Self::Format10(item) => item.table_type(),
274 Self::Format12(item) => item.table_type(),
275 Self::Format13(item) => item.table_type(),
276 Self::Format14(item) => item.table_type(),
277 }
278 }
279}
280
281impl Validate for CmapSubtable {
282 fn validate_impl(&self, ctx: &mut ValidationCtx) {
283 match self {
284 Self::Format0(item) => item.validate_impl(ctx),
285 Self::Format2(item) => item.validate_impl(ctx),
286 Self::Format4(item) => item.validate_impl(ctx),
287 Self::Format6(item) => item.validate_impl(ctx),
288 Self::Format8(item) => item.validate_impl(ctx),
289 Self::Format10(item) => item.validate_impl(ctx),
290 Self::Format12(item) => item.validate_impl(ctx),
291 Self::Format13(item) => item.validate_impl(ctx),
292 Self::Format14(item) => item.validate_impl(ctx),
293 }
294 }
295}
296
297impl FromObjRef<read_fonts::tables::cmap::CmapSubtable<'_>> for CmapSubtable {
298 fn from_obj_ref(obj: &read_fonts::tables::cmap::CmapSubtable, _: FontData) -> Self {
299 use read_fonts::tables::cmap::CmapSubtable as ObjRefType;
300 match obj {
301 ObjRefType::Format0(item) => CmapSubtable::Format0(item.to_owned_table()),
302 ObjRefType::Format2(item) => CmapSubtable::Format2(item.to_owned_table()),
303 ObjRefType::Format4(item) => CmapSubtable::Format4(item.to_owned_table()),
304 ObjRefType::Format6(item) => CmapSubtable::Format6(item.to_owned_table()),
305 ObjRefType::Format8(item) => CmapSubtable::Format8(item.to_owned_table()),
306 ObjRefType::Format10(item) => CmapSubtable::Format10(item.to_owned_table()),
307 ObjRefType::Format12(item) => CmapSubtable::Format12(item.to_owned_table()),
308 ObjRefType::Format13(item) => CmapSubtable::Format13(item.to_owned_table()),
309 ObjRefType::Format14(item) => CmapSubtable::Format14(item.to_owned_table()),
310 }
311 }
312}
313
314impl FromTableRef<read_fonts::tables::cmap::CmapSubtable<'_>> for CmapSubtable {}
315
316impl<'a> FontRead<'a> for CmapSubtable {
317 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
318 <read_fonts::tables::cmap::CmapSubtable as FontRead>::read(data).map(|x| x.to_owned_table())
319 }
320}
321
322impl From<Cmap0> for CmapSubtable {
323 fn from(src: Cmap0) -> CmapSubtable {
324 CmapSubtable::Format0(src)
325 }
326}
327
328impl From<Cmap2> for CmapSubtable {
329 fn from(src: Cmap2) -> CmapSubtable {
330 CmapSubtable::Format2(src)
331 }
332}
333
334impl From<Cmap4> for CmapSubtable {
335 fn from(src: Cmap4) -> CmapSubtable {
336 CmapSubtable::Format4(src)
337 }
338}
339
340impl From<Cmap6> for CmapSubtable {
341 fn from(src: Cmap6) -> CmapSubtable {
342 CmapSubtable::Format6(src)
343 }
344}
345
346impl From<Cmap8> for CmapSubtable {
347 fn from(src: Cmap8) -> CmapSubtable {
348 CmapSubtable::Format8(src)
349 }
350}
351
352impl From<Cmap10> for CmapSubtable {
353 fn from(src: Cmap10) -> CmapSubtable {
354 CmapSubtable::Format10(src)
355 }
356}
357
358impl From<Cmap12> for CmapSubtable {
359 fn from(src: Cmap12) -> CmapSubtable {
360 CmapSubtable::Format12(src)
361 }
362}
363
364impl From<Cmap13> for CmapSubtable {
365 fn from(src: Cmap13) -> CmapSubtable {
366 CmapSubtable::Format13(src)
367 }
368}
369
370impl From<Cmap14> for CmapSubtable {
371 fn from(src: Cmap14) -> CmapSubtable {
372 CmapSubtable::Format14(src)
373 }
374}
375
376#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
378#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
379pub struct Cmap0 {
380 pub language: u16,
383 pub glyph_id_array: Vec<u8>,
385}
386
387impl Cmap0 {
388 pub fn new(language: u16, glyph_id_array: Vec<u8>) -> Self {
390 Self {
391 language,
392 glyph_id_array,
393 }
394 }
395}
396
397impl FontWrite for Cmap0 {
398 #[allow(clippy::unnecessary_cast)]
399 fn write_into(&self, writer: &mut TableWriter) {
400 (0 as u16).write_into(writer);
401 (256 + 6 as u16).write_into(writer);
402 self.language.write_into(writer);
403 self.glyph_id_array.write_into(writer);
404 }
405 fn table_type(&self) -> TableType {
406 TableType::Named("Cmap0")
407 }
408}
409
410impl Validate for Cmap0 {
411 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
412}
413
414impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap0<'a>> for Cmap0 {
415 fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap0<'a>, _: FontData) -> Self {
416 let offset_data = obj.offset_data();
417 Cmap0 {
418 language: obj.language(),
419 glyph_id_array: obj.glyph_id_array().to_owned_obj(offset_data),
420 }
421 }
422}
423
424#[allow(clippy::needless_lifetimes)]
425impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap0<'a>> for Cmap0 {}
426
427impl<'a> FontRead<'a> for Cmap0 {
428 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
429 <read_fonts::tables::cmap::Cmap0 as FontRead>::read(data).map(|x| x.to_owned_table())
430 }
431}
432
433#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
435#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
436pub struct Cmap2 {
437 pub length: u16,
439 pub language: u16,
442 pub sub_header_keys: Vec<u16>,
445}
446
447impl Cmap2 {
448 pub fn new(length: u16, language: u16, sub_header_keys: Vec<u16>) -> Self {
450 Self {
451 length,
452 language,
453 sub_header_keys,
454 }
455 }
456}
457
458impl FontWrite for Cmap2 {
459 #[allow(clippy::unnecessary_cast)]
460 fn write_into(&self, writer: &mut TableWriter) {
461 (2 as u16).write_into(writer);
462 self.length.write_into(writer);
463 self.language.write_into(writer);
464 self.sub_header_keys.write_into(writer);
465 }
466 fn table_type(&self) -> TableType {
467 TableType::Named("Cmap2")
468 }
469}
470
471impl Validate for Cmap2 {
472 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
473}
474
475impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap2<'a>> for Cmap2 {
476 fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap2<'a>, _: FontData) -> Self {
477 let offset_data = obj.offset_data();
478 Cmap2 {
479 length: obj.length(),
480 language: obj.language(),
481 sub_header_keys: obj.sub_header_keys().to_owned_obj(offset_data),
482 }
483 }
484}
485
486#[allow(clippy::needless_lifetimes)]
487impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap2<'a>> for Cmap2 {}
488
489impl<'a> FontRead<'a> for Cmap2 {
490 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
491 <read_fonts::tables::cmap::Cmap2 as FontRead>::read(data).map(|x| x.to_owned_table())
492 }
493}
494
495#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
497#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
498pub struct SubHeader {
499 pub first_code: u16,
501 pub entry_count: u16,
503 pub id_delta: i16,
505 pub id_range_offset: u16,
507}
508
509impl SubHeader {
510 pub fn new(first_code: u16, entry_count: u16, id_delta: i16, id_range_offset: u16) -> Self {
512 Self {
513 first_code,
514 entry_count,
515 id_delta,
516 id_range_offset,
517 }
518 }
519}
520
521impl FontWrite for SubHeader {
522 fn write_into(&self, writer: &mut TableWriter) {
523 self.first_code.write_into(writer);
524 self.entry_count.write_into(writer);
525 self.id_delta.write_into(writer);
526 self.id_range_offset.write_into(writer);
527 }
528 fn table_type(&self) -> TableType {
529 TableType::Named("SubHeader")
530 }
531}
532
533impl Validate for SubHeader {
534 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
535}
536
537impl FromObjRef<read_fonts::tables::cmap::SubHeader> for SubHeader {
538 fn from_obj_ref(obj: &read_fonts::tables::cmap::SubHeader, _: FontData) -> Self {
539 SubHeader {
540 first_code: obj.first_code(),
541 entry_count: obj.entry_count(),
542 id_delta: obj.id_delta(),
543 id_range_offset: obj.id_range_offset(),
544 }
545 }
546}
547
548#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
550#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
551pub struct Cmap4 {
552 pub language: u16,
555 pub end_code: Vec<u16>,
557 pub start_code: Vec<u16>,
559 pub id_delta: Vec<i16>,
561 pub id_range_offsets: Vec<u16>,
563 pub glyph_id_array: Vec<u16>,
565}
566
567impl Cmap4 {
568 pub fn new(
570 language: u16,
571 end_code: Vec<u16>,
572 start_code: Vec<u16>,
573 id_delta: Vec<i16>,
574 id_range_offsets: Vec<u16>,
575 glyph_id_array: Vec<u16>,
576 ) -> Self {
577 Self {
578 language,
579 end_code,
580 start_code,
581 id_delta,
582 id_range_offsets,
583 glyph_id_array,
584 }
585 }
586}
587
588impl FontWrite for Cmap4 {
589 #[allow(clippy::unnecessary_cast)]
590 fn write_into(&self, writer: &mut TableWriter) {
591 (4 as u16).write_into(writer);
592 (self.compute_length() as u16).write_into(writer);
593 self.language.write_into(writer);
594 (u16::try_from(2 * array_len(&self.end_code)).unwrap()).write_into(writer);
595 (self.compute_search_range() as u16).write_into(writer);
596 (self.compute_entry_selector() as u16).write_into(writer);
597 (self.compute_range_shift() as u16).write_into(writer);
598 self.end_code.write_into(writer);
599 (0 as u16).write_into(writer);
600 self.start_code.write_into(writer);
601 self.id_delta.write_into(writer);
602 self.id_range_offsets.write_into(writer);
603 self.glyph_id_array.write_into(writer);
604 }
605 fn table_type(&self) -> TableType {
606 TableType::Named("Cmap4")
607 }
608}
609
610impl Validate for Cmap4 {
611 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
612}
613
614impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap4<'a>> for Cmap4 {
615 fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap4<'a>, _: FontData) -> Self {
616 let offset_data = obj.offset_data();
617 Cmap4 {
618 language: obj.language(),
619 end_code: obj.end_code().to_owned_obj(offset_data),
620 start_code: obj.start_code().to_owned_obj(offset_data),
621 id_delta: obj.id_delta().to_owned_obj(offset_data),
622 id_range_offsets: obj.id_range_offsets().to_owned_obj(offset_data),
623 glyph_id_array: obj.glyph_id_array().to_owned_obj(offset_data),
624 }
625 }
626}
627
628#[allow(clippy::needless_lifetimes)]
629impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap4<'a>> for Cmap4 {}
630
631impl<'a> FontRead<'a> for Cmap4 {
632 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
633 <read_fonts::tables::cmap::Cmap4 as FontRead>::read(data).map(|x| x.to_owned_table())
634 }
635}
636
637#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
639#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
640pub struct Cmap6 {
641 pub length: u16,
643 pub language: u16,
646 pub first_code: u16,
648 pub entry_count: u16,
650 pub glyph_id_array: Vec<u16>,
652}
653
654impl Cmap6 {
655 pub fn new(
657 length: u16,
658 language: u16,
659 first_code: u16,
660 entry_count: u16,
661 glyph_id_array: Vec<u16>,
662 ) -> Self {
663 Self {
664 length,
665 language,
666 first_code,
667 entry_count,
668 glyph_id_array,
669 }
670 }
671}
672
673impl FontWrite for Cmap6 {
674 #[allow(clippy::unnecessary_cast)]
675 fn write_into(&self, writer: &mut TableWriter) {
676 (6 as u16).write_into(writer);
677 self.length.write_into(writer);
678 self.language.write_into(writer);
679 self.first_code.write_into(writer);
680 self.entry_count.write_into(writer);
681 self.glyph_id_array.write_into(writer);
682 }
683 fn table_type(&self) -> TableType {
684 TableType::Named("Cmap6")
685 }
686}
687
688impl Validate for Cmap6 {
689 fn validate_impl(&self, ctx: &mut ValidationCtx) {
690 ctx.in_table("Cmap6", |ctx| {
691 ctx.in_field("glyph_id_array", |ctx| {
692 if self.glyph_id_array.len() > (u16::MAX as usize) {
693 ctx.report("array exceeds max length");
694 }
695 });
696 })
697 }
698}
699
700impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap6<'a>> for Cmap6 {
701 fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap6<'a>, _: FontData) -> Self {
702 let offset_data = obj.offset_data();
703 Cmap6 {
704 length: obj.length(),
705 language: obj.language(),
706 first_code: obj.first_code(),
707 entry_count: obj.entry_count(),
708 glyph_id_array: obj.glyph_id_array().to_owned_obj(offset_data),
709 }
710 }
711}
712
713#[allow(clippy::needless_lifetimes)]
714impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap6<'a>> for Cmap6 {}
715
716impl<'a> FontRead<'a> for Cmap6 {
717 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
718 <read_fonts::tables::cmap::Cmap6 as FontRead>::read(data).map(|x| x.to_owned_table())
719 }
720}
721
722#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
724#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
725pub struct Cmap8 {
726 pub length: u32,
728 pub language: u32,
731 pub is32: Vec<u8>,
735 pub num_groups: u32,
737 pub groups: Vec<SequentialMapGroup>,
739}
740
741impl Cmap8 {
742 pub fn new(
744 length: u32,
745 language: u32,
746 is32: Vec<u8>,
747 num_groups: u32,
748 groups: Vec<SequentialMapGroup>,
749 ) -> Self {
750 Self {
751 length,
752 language,
753 is32,
754 num_groups,
755 groups,
756 }
757 }
758}
759
760impl FontWrite for Cmap8 {
761 #[allow(clippy::unnecessary_cast)]
762 fn write_into(&self, writer: &mut TableWriter) {
763 (8 as u16).write_into(writer);
764 (0 as u16).write_into(writer);
765 self.length.write_into(writer);
766 self.language.write_into(writer);
767 self.is32.write_into(writer);
768 self.num_groups.write_into(writer);
769 self.groups.write_into(writer);
770 }
771 fn table_type(&self) -> TableType {
772 TableType::Named("Cmap8")
773 }
774}
775
776impl Validate for Cmap8 {
777 fn validate_impl(&self, ctx: &mut ValidationCtx) {
778 ctx.in_table("Cmap8", |ctx| {
779 ctx.in_field("groups", |ctx| {
780 if self.groups.len() > (u32::MAX as usize) {
781 ctx.report("array exceeds max length");
782 }
783 self.groups.validate_impl(ctx);
784 });
785 })
786 }
787}
788
789impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap8<'a>> for Cmap8 {
790 fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap8<'a>, _: FontData) -> Self {
791 let offset_data = obj.offset_data();
792 Cmap8 {
793 length: obj.length(),
794 language: obj.language(),
795 is32: obj.is32().to_owned_obj(offset_data),
796 num_groups: obj.num_groups(),
797 groups: obj.groups().to_owned_obj(offset_data),
798 }
799 }
800}
801
802#[allow(clippy::needless_lifetimes)]
803impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap8<'a>> for Cmap8 {}
804
805impl<'a> FontRead<'a> for Cmap8 {
806 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
807 <read_fonts::tables::cmap::Cmap8 as FontRead>::read(data).map(|x| x.to_owned_table())
808 }
809}
810
811#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
813#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
814pub struct SequentialMapGroup {
815 pub start_char_code: u32,
820 pub end_char_code: u32,
823 pub start_glyph_id: u32,
825}
826
827impl SequentialMapGroup {
828 pub fn new(start_char_code: u32, end_char_code: u32, start_glyph_id: u32) -> Self {
830 Self {
831 start_char_code,
832 end_char_code,
833 start_glyph_id,
834 }
835 }
836}
837
838impl FontWrite for SequentialMapGroup {
839 fn write_into(&self, writer: &mut TableWriter) {
840 self.start_char_code.write_into(writer);
841 self.end_char_code.write_into(writer);
842 self.start_glyph_id.write_into(writer);
843 }
844 fn table_type(&self) -> TableType {
845 TableType::Named("SequentialMapGroup")
846 }
847}
848
849impl Validate for SequentialMapGroup {
850 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
851}
852
853impl FromObjRef<read_fonts::tables::cmap::SequentialMapGroup> for SequentialMapGroup {
854 fn from_obj_ref(obj: &read_fonts::tables::cmap::SequentialMapGroup, _: FontData) -> Self {
855 SequentialMapGroup {
856 start_char_code: obj.start_char_code(),
857 end_char_code: obj.end_char_code(),
858 start_glyph_id: obj.start_glyph_id(),
859 }
860 }
861}
862
863#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
865#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
866pub struct Cmap10 {
867 pub length: u32,
869 pub language: u32,
872 pub start_char_code: u32,
874 pub glyph_id_array: Vec<u16>,
876}
877
878impl Cmap10 {
879 pub fn new(length: u32, language: u32, start_char_code: u32, glyph_id_array: Vec<u16>) -> Self {
881 Self {
882 length,
883 language,
884 start_char_code,
885 glyph_id_array,
886 }
887 }
888}
889
890impl FontWrite for Cmap10 {
891 #[allow(clippy::unnecessary_cast)]
892 fn write_into(&self, writer: &mut TableWriter) {
893 (10 as u16).write_into(writer);
894 (0 as u16).write_into(writer);
895 self.length.write_into(writer);
896 self.language.write_into(writer);
897 self.start_char_code.write_into(writer);
898 (u32::try_from(array_len(&self.glyph_id_array)).unwrap()).write_into(writer);
899 self.glyph_id_array.write_into(writer);
900 }
901 fn table_type(&self) -> TableType {
902 TableType::Named("Cmap10")
903 }
904}
905
906impl Validate for Cmap10 {
907 fn validate_impl(&self, ctx: &mut ValidationCtx) {
908 ctx.in_table("Cmap10", |ctx| {
909 ctx.in_field("glyph_id_array", |ctx| {
910 if self.glyph_id_array.len() > (u32::MAX as usize) {
911 ctx.report("array exceeds max length");
912 }
913 });
914 })
915 }
916}
917
918impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap10<'a>> for Cmap10 {
919 fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap10<'a>, _: FontData) -> Self {
920 let offset_data = obj.offset_data();
921 Cmap10 {
922 length: obj.length(),
923 language: obj.language(),
924 start_char_code: obj.start_char_code(),
925 glyph_id_array: obj.glyph_id_array().to_owned_obj(offset_data),
926 }
927 }
928}
929
930#[allow(clippy::needless_lifetimes)]
931impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap10<'a>> for Cmap10 {}
932
933impl<'a> FontRead<'a> for Cmap10 {
934 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
935 <read_fonts::tables::cmap::Cmap10 as FontRead>::read(data).map(|x| x.to_owned_table())
936 }
937}
938
939#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
941#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
942pub struct Cmap12 {
943 pub language: u32,
946 pub groups: Vec<SequentialMapGroup>,
948}
949
950impl Cmap12 {
951 pub fn new(language: u32, groups: Vec<SequentialMapGroup>) -> Self {
953 Self { language, groups }
954 }
955}
956
957impl FontWrite for Cmap12 {
958 #[allow(clippy::unnecessary_cast)]
959 fn write_into(&self, writer: &mut TableWriter) {
960 (12 as u16).write_into(writer);
961 (0 as u16).write_into(writer);
962 (self.compute_length() as u32).write_into(writer);
963 self.language.write_into(writer);
964 (u32::try_from(array_len(&self.groups)).unwrap()).write_into(writer);
965 self.groups.write_into(writer);
966 }
967 fn table_type(&self) -> TableType {
968 TableType::Named("Cmap12")
969 }
970}
971
972impl Validate for Cmap12 {
973 fn validate_impl(&self, ctx: &mut ValidationCtx) {
974 ctx.in_table("Cmap12", |ctx| {
975 ctx.in_field("groups", |ctx| {
976 if self.groups.len() > (u32::MAX as usize) {
977 ctx.report("array exceeds max length");
978 }
979 self.groups.validate_impl(ctx);
980 });
981 })
982 }
983}
984
985impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap12<'a>> for Cmap12 {
986 fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap12<'a>, _: FontData) -> Self {
987 let offset_data = obj.offset_data();
988 Cmap12 {
989 language: obj.language(),
990 groups: obj.groups().to_owned_obj(offset_data),
991 }
992 }
993}
994
995#[allow(clippy::needless_lifetimes)]
996impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap12<'a>> for Cmap12 {}
997
998impl<'a> FontRead<'a> for Cmap12 {
999 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1000 <read_fonts::tables::cmap::Cmap12 as FontRead>::read(data).map(|x| x.to_owned_table())
1001 }
1002}
1003
1004#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1006#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1007pub struct Cmap13 {
1008 pub length: u32,
1010 pub language: u32,
1013 pub num_groups: u32,
1015 pub groups: Vec<ConstantMapGroup>,
1017}
1018
1019impl Cmap13 {
1020 pub fn new(length: u32, language: u32, num_groups: u32, groups: Vec<ConstantMapGroup>) -> Self {
1022 Self {
1023 length,
1024 language,
1025 num_groups,
1026 groups,
1027 }
1028 }
1029}
1030
1031impl FontWrite for Cmap13 {
1032 #[allow(clippy::unnecessary_cast)]
1033 fn write_into(&self, writer: &mut TableWriter) {
1034 (13 as u16).write_into(writer);
1035 (0 as u16).write_into(writer);
1036 self.length.write_into(writer);
1037 self.language.write_into(writer);
1038 self.num_groups.write_into(writer);
1039 self.groups.write_into(writer);
1040 }
1041 fn table_type(&self) -> TableType {
1042 TableType::Named("Cmap13")
1043 }
1044}
1045
1046impl Validate for Cmap13 {
1047 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1048 ctx.in_table("Cmap13", |ctx| {
1049 ctx.in_field("groups", |ctx| {
1050 if self.groups.len() > (u32::MAX as usize) {
1051 ctx.report("array exceeds max length");
1052 }
1053 self.groups.validate_impl(ctx);
1054 });
1055 })
1056 }
1057}
1058
1059impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap13<'a>> for Cmap13 {
1060 fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap13<'a>, _: FontData) -> Self {
1061 let offset_data = obj.offset_data();
1062 Cmap13 {
1063 length: obj.length(),
1064 language: obj.language(),
1065 num_groups: obj.num_groups(),
1066 groups: obj.groups().to_owned_obj(offset_data),
1067 }
1068 }
1069}
1070
1071#[allow(clippy::needless_lifetimes)]
1072impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap13<'a>> for Cmap13 {}
1073
1074impl<'a> FontRead<'a> for Cmap13 {
1075 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1076 <read_fonts::tables::cmap::Cmap13 as FontRead>::read(data).map(|x| x.to_owned_table())
1077 }
1078}
1079
1080#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1082#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1083pub struct ConstantMapGroup {
1084 pub start_char_code: u32,
1086 pub end_char_code: u32,
1088 pub glyph_id: u32,
1091}
1092
1093impl ConstantMapGroup {
1094 pub fn new(start_char_code: u32, end_char_code: u32, glyph_id: u32) -> Self {
1096 Self {
1097 start_char_code,
1098 end_char_code,
1099 glyph_id,
1100 }
1101 }
1102}
1103
1104impl FontWrite for ConstantMapGroup {
1105 fn write_into(&self, writer: &mut TableWriter) {
1106 self.start_char_code.write_into(writer);
1107 self.end_char_code.write_into(writer);
1108 self.glyph_id.write_into(writer);
1109 }
1110 fn table_type(&self) -> TableType {
1111 TableType::Named("ConstantMapGroup")
1112 }
1113}
1114
1115impl Validate for ConstantMapGroup {
1116 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
1117}
1118
1119impl FromObjRef<read_fonts::tables::cmap::ConstantMapGroup> for ConstantMapGroup {
1120 fn from_obj_ref(obj: &read_fonts::tables::cmap::ConstantMapGroup, _: FontData) -> Self {
1121 ConstantMapGroup {
1122 start_char_code: obj.start_char_code(),
1123 end_char_code: obj.end_char_code(),
1124 glyph_id: obj.glyph_id(),
1125 }
1126 }
1127}
1128
1129#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1131#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1132pub struct Cmap14 {
1133 pub length: u32,
1135 pub num_var_selector_records: u32,
1137 pub var_selector: Vec<VariationSelector>,
1139}
1140
1141impl Cmap14 {
1142 pub fn new(
1144 length: u32,
1145 num_var_selector_records: u32,
1146 var_selector: Vec<VariationSelector>,
1147 ) -> Self {
1148 Self {
1149 length,
1150 num_var_selector_records,
1151 var_selector,
1152 }
1153 }
1154}
1155
1156impl FontWrite for Cmap14 {
1157 #[allow(clippy::unnecessary_cast)]
1158 fn write_into(&self, writer: &mut TableWriter) {
1159 (14 as u16).write_into(writer);
1160 self.length.write_into(writer);
1161 self.num_var_selector_records.write_into(writer);
1162 self.var_selector.write_into(writer);
1163 }
1164 fn table_type(&self) -> TableType {
1165 TableType::Named("Cmap14")
1166 }
1167}
1168
1169impl Validate for Cmap14 {
1170 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1171 ctx.in_table("Cmap14", |ctx| {
1172 ctx.in_field("var_selector", |ctx| {
1173 if self.var_selector.len() > (u32::MAX as usize) {
1174 ctx.report("array exceeds max length");
1175 }
1176 self.var_selector.validate_impl(ctx);
1177 });
1178 })
1179 }
1180}
1181
1182impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap14<'a>> for Cmap14 {
1183 fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap14<'a>, _: FontData) -> Self {
1184 let offset_data = obj.offset_data();
1185 Cmap14 {
1186 length: obj.length(),
1187 num_var_selector_records: obj.num_var_selector_records(),
1188 var_selector: obj.var_selector().to_owned_obj(offset_data),
1189 }
1190 }
1191}
1192
1193#[allow(clippy::needless_lifetimes)]
1194impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap14<'a>> for Cmap14 {}
1195
1196impl<'a> FontRead<'a> for Cmap14 {
1197 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1198 <read_fonts::tables::cmap::Cmap14 as FontRead>::read(data).map(|x| x.to_owned_table())
1199 }
1200}
1201
1202#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1204#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1205pub struct VariationSelector {
1206 pub var_selector: Uint24,
1208 pub default_uvs: NullableOffsetMarker<DefaultUvs, WIDTH_32>,
1211 pub non_default_uvs: NullableOffsetMarker<NonDefaultUvs, WIDTH_32>,
1214}
1215
1216impl VariationSelector {
1217 pub fn new(
1219 var_selector: Uint24,
1220 default_uvs: Option<DefaultUvs>,
1221 non_default_uvs: Option<NonDefaultUvs>,
1222 ) -> Self {
1223 Self {
1224 var_selector,
1225 default_uvs: default_uvs.into(),
1226 non_default_uvs: non_default_uvs.into(),
1227 }
1228 }
1229}
1230
1231impl FontWrite for VariationSelector {
1232 fn write_into(&self, writer: &mut TableWriter) {
1233 self.var_selector.write_into(writer);
1234 self.default_uvs.write_into(writer);
1235 self.non_default_uvs.write_into(writer);
1236 }
1237 fn table_type(&self) -> TableType {
1238 TableType::Named("VariationSelector")
1239 }
1240}
1241
1242impl Validate for VariationSelector {
1243 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1244 ctx.in_table("VariationSelector", |ctx| {
1245 ctx.in_field("default_uvs", |ctx| {
1246 self.default_uvs.validate_impl(ctx);
1247 });
1248 ctx.in_field("non_default_uvs", |ctx| {
1249 self.non_default_uvs.validate_impl(ctx);
1250 });
1251 })
1252 }
1253}
1254
1255impl FromObjRef<read_fonts::tables::cmap::VariationSelector> for VariationSelector {
1256 fn from_obj_ref(
1257 obj: &read_fonts::tables::cmap::VariationSelector,
1258 offset_data: FontData,
1259 ) -> Self {
1260 VariationSelector {
1261 var_selector: obj.var_selector(),
1262 default_uvs: obj.default_uvs(offset_data).to_owned_table(),
1263 non_default_uvs: obj.non_default_uvs(offset_data).to_owned_table(),
1264 }
1265 }
1266}
1267
1268#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1270#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1271pub struct DefaultUvs {
1272 pub num_unicode_value_ranges: u32,
1274 pub ranges: Vec<UnicodeRange>,
1276}
1277
1278impl DefaultUvs {
1279 pub fn new(num_unicode_value_ranges: u32, ranges: Vec<UnicodeRange>) -> Self {
1281 Self {
1282 num_unicode_value_ranges,
1283 ranges,
1284 }
1285 }
1286}
1287
1288impl FontWrite for DefaultUvs {
1289 fn write_into(&self, writer: &mut TableWriter) {
1290 self.num_unicode_value_ranges.write_into(writer);
1291 self.ranges.write_into(writer);
1292 }
1293 fn table_type(&self) -> TableType {
1294 TableType::Named("DefaultUvs")
1295 }
1296}
1297
1298impl Validate for DefaultUvs {
1299 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1300 ctx.in_table("DefaultUvs", |ctx| {
1301 ctx.in_field("ranges", |ctx| {
1302 if self.ranges.len() > (u32::MAX as usize) {
1303 ctx.report("array exceeds max length");
1304 }
1305 self.ranges.validate_impl(ctx);
1306 });
1307 })
1308 }
1309}
1310
1311impl<'a> FromObjRef<read_fonts::tables::cmap::DefaultUvs<'a>> for DefaultUvs {
1312 fn from_obj_ref(obj: &read_fonts::tables::cmap::DefaultUvs<'a>, _: FontData) -> Self {
1313 let offset_data = obj.offset_data();
1314 DefaultUvs {
1315 num_unicode_value_ranges: obj.num_unicode_value_ranges(),
1316 ranges: obj.ranges().to_owned_obj(offset_data),
1317 }
1318 }
1319}
1320
1321#[allow(clippy::needless_lifetimes)]
1322impl<'a> FromTableRef<read_fonts::tables::cmap::DefaultUvs<'a>> for DefaultUvs {}
1323
1324impl<'a> FontRead<'a> for DefaultUvs {
1325 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1326 <read_fonts::tables::cmap::DefaultUvs as FontRead>::read(data).map(|x| x.to_owned_table())
1327 }
1328}
1329
1330#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1332#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1333pub struct NonDefaultUvs {
1334 pub num_uvs_mappings: u32,
1335 pub uvs_mapping: Vec<UvsMapping>,
1336}
1337
1338impl NonDefaultUvs {
1339 pub fn new(num_uvs_mappings: u32, uvs_mapping: Vec<UvsMapping>) -> Self {
1341 Self {
1342 num_uvs_mappings,
1343 uvs_mapping,
1344 }
1345 }
1346}
1347
1348impl FontWrite for NonDefaultUvs {
1349 fn write_into(&self, writer: &mut TableWriter) {
1350 self.num_uvs_mappings.write_into(writer);
1351 self.uvs_mapping.write_into(writer);
1352 }
1353 fn table_type(&self) -> TableType {
1354 TableType::Named("NonDefaultUvs")
1355 }
1356}
1357
1358impl Validate for NonDefaultUvs {
1359 fn validate_impl(&self, ctx: &mut ValidationCtx) {
1360 ctx.in_table("NonDefaultUvs", |ctx| {
1361 ctx.in_field("uvs_mapping", |ctx| {
1362 if self.uvs_mapping.len() > (u32::MAX as usize) {
1363 ctx.report("array exceeds max length");
1364 }
1365 self.uvs_mapping.validate_impl(ctx);
1366 });
1367 })
1368 }
1369}
1370
1371impl<'a> FromObjRef<read_fonts::tables::cmap::NonDefaultUvs<'a>> for NonDefaultUvs {
1372 fn from_obj_ref(obj: &read_fonts::tables::cmap::NonDefaultUvs<'a>, _: FontData) -> Self {
1373 let offset_data = obj.offset_data();
1374 NonDefaultUvs {
1375 num_uvs_mappings: obj.num_uvs_mappings(),
1376 uvs_mapping: obj.uvs_mapping().to_owned_obj(offset_data),
1377 }
1378 }
1379}
1380
1381#[allow(clippy::needless_lifetimes)]
1382impl<'a> FromTableRef<read_fonts::tables::cmap::NonDefaultUvs<'a>> for NonDefaultUvs {}
1383
1384impl<'a> FontRead<'a> for NonDefaultUvs {
1385 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
1386 <read_fonts::tables::cmap::NonDefaultUvs as FontRead>::read(data)
1387 .map(|x| x.to_owned_table())
1388 }
1389}
1390
1391#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1393#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1394pub struct UvsMapping {
1395 pub unicode_value: Uint24,
1397 pub glyph_id: u16,
1399}
1400
1401impl UvsMapping {
1402 pub fn new(unicode_value: Uint24, glyph_id: u16) -> Self {
1404 Self {
1405 unicode_value,
1406 glyph_id,
1407 }
1408 }
1409}
1410
1411impl FontWrite for UvsMapping {
1412 fn write_into(&self, writer: &mut TableWriter) {
1413 self.unicode_value.write_into(writer);
1414 self.glyph_id.write_into(writer);
1415 }
1416 fn table_type(&self) -> TableType {
1417 TableType::Named("UvsMapping")
1418 }
1419}
1420
1421impl Validate for UvsMapping {
1422 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
1423}
1424
1425impl FromObjRef<read_fonts::tables::cmap::UvsMapping> for UvsMapping {
1426 fn from_obj_ref(obj: &read_fonts::tables::cmap::UvsMapping, _: FontData) -> Self {
1427 UvsMapping {
1428 unicode_value: obj.unicode_value(),
1429 glyph_id: obj.glyph_id(),
1430 }
1431 }
1432}
1433
1434#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
1436#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1437pub struct UnicodeRange {
1438 pub start_unicode_value: Uint24,
1440 pub additional_count: u8,
1442}
1443
1444impl UnicodeRange {
1445 pub fn new(start_unicode_value: Uint24, additional_count: u8) -> Self {
1447 Self {
1448 start_unicode_value,
1449 additional_count,
1450 }
1451 }
1452}
1453
1454impl FontWrite for UnicodeRange {
1455 fn write_into(&self, writer: &mut TableWriter) {
1456 self.start_unicode_value.write_into(writer);
1457 self.additional_count.write_into(writer);
1458 }
1459 fn table_type(&self) -> TableType {
1460 TableType::Named("UnicodeRange")
1461 }
1462}
1463
1464impl Validate for UnicodeRange {
1465 fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
1466}
1467
1468impl FromObjRef<read_fonts::tables::cmap::UnicodeRange> for UnicodeRange {
1469 fn from_obj_ref(obj: &read_fonts::tables::cmap::UnicodeRange, _: FontData) -> Self {
1470 UnicodeRange {
1471 start_unicode_value: obj.start_unicode_value(),
1472 additional_count: obj.additional_count(),
1473 }
1474 }
1475}