1use core::convert::TryFrom;
8
9use crate::GlyphId;
10use crate::opentype_layout::{Class, ClassDefinition, ContextLookup, Coverage, LookupSubtable};
11use crate::opentype_layout::ChainedContextLookup;
12use crate::parser::{FromData, FromSlice, LazyArray16, LazyArray32, NumFrom, Offset, Offset16, Stream};
13
14#[derive(Clone, Copy)]
18pub struct HintingDevice<'a> {
19 start_size: u16,
20 end_size: u16,
21 delta_format: u16,
22 delta_values: LazyArray16<'a, u16>,
23}
24
25impl HintingDevice<'_> {
26 pub fn x_delta(&self, units_per_em: u16, pixels_per_em: Option<(u16, u16)>) -> Option<i32> {
28 let ppem = pixels_per_em.map(|(x, _)| x)?;
29 self.get_delta(ppem, units_per_em)
30 }
31
32 pub fn y_delta(&self, units_per_em: u16, pixels_per_em: Option<(u16, u16)>) -> Option<i32> {
34 let ppem = pixels_per_em.map(|(_, y)| y)?;
35 self.get_delta(ppem, units_per_em)
36 }
37
38 fn get_delta(&self, ppem: u16, scale: u16) -> Option<i32> {
39 let f = self.delta_format;
40 debug_assert!(matches!(f, 1..=3));
41
42 if ppem == 0 || ppem < self.start_size || ppem > self.end_size {
43 return None;
44 }
45
46 let s = ppem - self.start_size;
47 let byte = self.delta_values.get(s >> (4 - f))?;
48 let bits = byte >> (16 - (((s & ((1 << (4 - f)) - 1)) + 1) << f));
49 let mask = 0xFFFF >> (16 - (1 << f));
50
51 let mut delta = i64::from(bits & mask);
52 if delta >= i64::from(mask + 1 >> 1) {
53 delta -= i64::from(mask + 1);
54 }
55
56 i32::try_from(delta * i64::from(scale) / i64::from(ppem)).ok()
57 }
58}
59
60impl core::fmt::Debug for HintingDevice<'_> {
61 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
62 write!(f, "HintingDevice {{ ... }}")
63 }
64}
65
66#[allow(missing_docs)]
70#[derive(Clone, Copy, Debug)]
71pub struct VariationDevice {
72 pub outer_index: u16,
73 pub inner_index: u16,
74}
75
76
77#[allow(missing_docs)]
80#[derive(Clone, Copy, Debug)]
81pub enum Device<'a> {
82 Hinting(HintingDevice<'a>),
83 Variation(VariationDevice),
84}
85
86impl<'a> Device<'a> {
87 pub(crate) fn parse(data: &'a [u8]) -> Option<Self> {
88 let mut s = Stream::new(data);
89 let first = s.read::<u16>()?;
90 let second = s.read::<u16>()?;
91 let format = s.read::<u16>()?;
92 match format {
93 1..=3 => {
94 let start_size = first;
95 let end_size = second;
96 let count = 1 + (end_size - start_size) >> (4 - format);
97 let delta_values = s.read_array16(count)?;
98 Some(Self::Hinting(HintingDevice {
99 start_size,
100 end_size,
101 delta_format: format,
102 delta_values,
103 }))
104 }
105 0x8000 => {
106 Some(Self::Variation(VariationDevice {
107 outer_index: first,
108 inner_index: second,
109 }))
110 }
111 _ => None,
112 }
113 }
114}
115
116
117#[derive(Clone, Copy, Default, Debug)]
118struct ValueFormatFlags(u8);
119
120impl ValueFormatFlags {
121 #[inline] fn x_placement(self) -> bool { self.0 & 0x01 != 0 }
122 #[inline] fn y_placement(self) -> bool { self.0 & 0x02 != 0 }
123 #[inline] fn x_advance(self) -> bool { self.0 & 0x04 != 0 }
124 #[inline] fn y_advance(self) -> bool { self.0 & 0x08 != 0 }
125 #[inline] fn x_placement_device(self) -> bool { self.0 & 0x10 != 0 }
126 #[inline] fn y_placement_device(self) -> bool { self.0 & 0x20 != 0 }
127 #[inline] fn x_advance_device(self) -> bool { self.0 & 0x40 != 0 }
128 #[inline] fn y_advance_device(self) -> bool { self.0 & 0x80 != 0 }
129
130 fn size(self) -> usize {
133 u16::SIZE * usize::num_from(self.0.count_ones())
135 }
136}
137
138impl FromData for ValueFormatFlags {
139 const SIZE: usize = 2;
140
141 #[inline]
142 fn parse(data: &[u8]) -> Option<Self> {
143 Some(Self(data[1]))
145 }
146}
147
148
149#[derive(Clone, Copy, Default, Debug)]
151pub struct ValueRecord<'a> {
152 pub x_placement: i16,
154 pub y_placement: i16,
156 pub x_advance: i16,
158 pub y_advance: i16,
160
161 pub x_placement_device: Option<Device<'a>>,
163 pub y_placement_device: Option<Device<'a>>,
165 pub x_advance_device: Option<Device<'a>>,
167 pub y_advance_device: Option<Device<'a>>,
169}
170
171impl<'a> ValueRecord<'a> {
172 fn parse(table_data: &'a [u8], s: &mut Stream, flags: ValueFormatFlags) -> Option<ValueRecord<'a>> {
174 let mut record = ValueRecord::default();
175
176 if flags.x_placement() {
177 record.x_placement = s.read::<i16>()?;
178 }
179
180 if flags.y_placement() {
181 record.y_placement = s.read::<i16>()?;
182 }
183
184 if flags.x_advance() {
185 record.x_advance = s.read::<i16>()?;
186 }
187
188 if flags.y_advance() {
189 record.y_advance = s.read::<i16>()?;
190 }
191
192 if flags.x_placement_device() {
193 if let Some(offset) = s.read::<Option<Offset16>>()? {
194 record.x_placement_device = table_data.get(offset.to_usize()..).and_then(Device::parse)
195 }
196 }
197
198 if flags.y_placement_device() {
199 if let Some(offset) = s.read::<Option<Offset16>>()? {
200 record.y_placement_device = table_data.get(offset.to_usize()..).and_then(Device::parse)
201 }
202 }
203
204 if flags.x_advance_device() {
205 if let Some(offset) = s.read::<Option<Offset16>>()? {
206 record.x_advance_device = table_data.get(offset.to_usize()..).and_then(Device::parse)
207 }
208 }
209
210 if flags.y_advance_device() {
211 if let Some(offset) = s.read::<Option<Offset16>>()? {
212 record.y_advance_device = table_data.get(offset.to_usize()..).and_then(Device::parse)
213 }
214 }
215
216 Some(record)
217 }
218}
219
220
221#[derive(Clone, Copy)]
224pub struct ValueRecordsArray<'a> {
225 table_data: &'a [u8],
228 data: &'a [u8],
230 len: u16,
232 value_len: usize,
234 flags: ValueFormatFlags,
236}
237
238impl<'a> ValueRecordsArray<'a> {
239 fn parse(
240 table_data: &'a [u8],
241 count: u16,
242 flags: ValueFormatFlags,
243 s: &mut Stream<'a>,
244 ) -> Option<Self> {
245 Some(Self {
246 table_data,
247 flags,
248 len: count,
249 value_len: flags.size(),
250 data: s.read_bytes(usize::from(count) * flags.size())?,
251 })
252 }
253
254 #[inline]
256 pub fn len(&self) -> u16 {
257 self.len
258 }
259
260 pub fn get(&self, index: u16) -> Option<ValueRecord<'a>> {
262 let start = usize::from(index) * self.value_len;
263 let end = start + self.value_len;
264 let data = self.data.get(start..end)?;
265 let mut s = Stream::new(data);
266 ValueRecord::parse(self.table_data, &mut s, self.flags)
267 }
268}
269
270impl core::fmt::Debug for ValueRecordsArray<'_> {
271 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
272 write!(f, "ValueRecordsArray {{ ... }}")
273 }
274}
275
276
277#[allow(missing_docs)]
280#[derive(Clone, Copy, Debug)]
281pub enum SingleAdjustment<'a> {
282 Format1 {
283 coverage: Coverage<'a>,
284 value: ValueRecord<'a>,
285 },
286 Format2 {
287 coverage: Coverage<'a>,
288 values: ValueRecordsArray<'a>,
289 },
290}
291
292impl<'a> SingleAdjustment<'a> {
293 fn parse(data: &'a [u8]) -> Option<Self> {
294 let mut s = Stream::new(data);
295 match s.read::<u16>()? {
296 1 => {
297 let coverage = Coverage::parse(s.read_at_offset16(data)?)?;
298 let flags = s.read::<ValueFormatFlags>()?;
299 let value = ValueRecord::parse(data, &mut s, flags)?;
300 Some(Self::Format1 {
301 coverage,
302 value,
303 })
304 }
305 2 => {
306 let coverage = Coverage::parse(s.read_at_offset16(data)?)?;
307 let flags = s.read::<ValueFormatFlags>()?;
308 let count = s.read::<u16>()?;
309 let values = ValueRecordsArray::parse(data, count, flags, &mut s)?;
310 Some(Self::Format2 {
311 coverage,
312 values,
313 })
314 }
315 _ => None,
316 }
317 }
318
319 #[inline]
321 pub fn coverage(&self) -> Coverage<'a> {
322 match self {
323 Self::Format1 { coverage, .. } => *coverage,
324 Self::Format2 { coverage, .. } => *coverage,
325 }
326 }
327}
328
329
330#[derive(Clone, Copy)]
332pub struct PairSet<'a> {
333 data: &'a [u8],
334 flags: (ValueFormatFlags, ValueFormatFlags),
335 record_len: u8,
336}
337
338impl<'a> PairSet<'a> {
339 fn parse(data: &'a [u8], flags: (ValueFormatFlags, ValueFormatFlags)) -> Option<Self> {
340 let mut s = Stream::new(data);
341 let count = s.read::<u16>()?;
342 let record_len = (GlyphId::SIZE + flags.0.size() + flags.1.size()) as u8;
344 let data = s.read_bytes(usize::from(count) * usize::from(record_len))?;
345 Some(Self { data, flags, record_len })
346 }
347
348 #[inline]
349 fn binary_search(&self, second: GlyphId) -> Option<&'a [u8]> {
350 let mut size = self.data.len() / usize::from(self.record_len);
353 if size == 0 {
354 return None;
355 }
356
357 let get_record = |index| {
358 let start = index * usize::from(self.record_len);
359 let end = start + usize::from(self.record_len);
360 self.data.get(start..end)
361 };
362
363 let get_glyph = |data: &[u8]| {
364 GlyphId(u16::from_be_bytes([data[0], data[1]]))
365 };
366
367 let mut base = 0;
368 while size > 1 {
369 let half = size / 2;
370 let mid = base + half;
371 let cmp = get_glyph(get_record(mid)?).cmp(&second);
375 base = if cmp == core::cmp::Ordering::Greater { base } else { mid };
376 size -= half;
377 }
378
379 let value = get_record(base)?;
381 if get_glyph(value).cmp(&second) == core::cmp::Ordering::Equal { Some(value) } else { None }
382 }
383
384 pub fn get(&self, second: GlyphId) -> Option<(ValueRecord<'a>, ValueRecord<'a>)> {
386 let record_data = self.binary_search(second)?;
387 let mut s = Stream::new(record_data);
388 s.skip::<GlyphId>();
389 Some((
390 ValueRecord::parse(self.data, &mut s, self.flags.0)?,
391 ValueRecord::parse(self.data, &mut s, self.flags.1)?,
392 ))
393 }
394}
395
396impl core::fmt::Debug for PairSet<'_> {
397 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
398 write!(f, "PairSet {{ ... }}")
399 }
400}
401
402
403#[derive(Clone, Copy)]
407pub struct PairSets<'a> {
408 data: &'a [u8],
409 offsets: LazyArray16<'a, Option<Offset16>>,
411 flags: (ValueFormatFlags, ValueFormatFlags),
412}
413
414impl<'a> PairSets<'a> {
415 fn new(
416 data: &'a [u8],
417 offsets: LazyArray16<'a, Option<Offset16>>,
418 flags: (ValueFormatFlags, ValueFormatFlags),
419 ) -> Self {
420 Self { data, offsets, flags }
421 }
422
423 #[inline]
425 pub fn get(&self, index: u16) -> Option<PairSet<'a>> {
426 let offset = self.offsets.get(index)??.to_usize();
427 self.data.get(offset..).and_then(|data| PairSet::parse(data, self.flags))
428 }
429
430 #[inline]
432 pub fn len(&self) -> u16 {
433 self.offsets.len()
434 }
435}
436
437impl core::fmt::Debug for PairSets<'_> {
438 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
439 write!(f, "PairSets {{ ... }}")
440 }
441}
442
443
444#[derive(Clone, Copy)]
446pub struct ClassMatrix<'a> {
447 table_data: &'a [u8],
450 matrix: &'a [u8],
451 counts: (u16, u16),
452 flags: (ValueFormatFlags, ValueFormatFlags),
453 record_len: u8,
454}
455
456impl<'a> ClassMatrix<'a> {
457 fn parse(
458 table_data: &'a [u8],
459 counts: (u16, u16),
460 flags: (ValueFormatFlags, ValueFormatFlags),
461 s: &mut Stream<'a>,
462 ) -> Option<Self> {
463 let count = usize::num_from(u32::from(counts.0) * u32::from(counts.1));
464 let record_len = (flags.0.size() + flags.1.size()) as u8;
466 let matrix = s.read_bytes(usize::from(count) * usize::from(record_len))?;
467 Some(Self { table_data, matrix, counts, flags, record_len })
468 }
469
470 pub fn get(&self, classes: (u16, u16)) -> Option<(ValueRecord<'a>, ValueRecord<'a>)> {
472 if classes.0 >= self.counts.0 || classes.1 >= self.counts.1 {
473 return None;
474 }
475
476 let idx = usize::from(classes.0) * usize::from(self.counts.1) + usize::from(classes.1);
477 let record = self.matrix.get(idx * usize::from(self.record_len)..)?;
478
479 let mut s = Stream::new(record);
480 Some((
481 ValueRecord::parse(self.table_data, &mut s, self.flags.0)?,
482 ValueRecord::parse(self.table_data, &mut s, self.flags.1)?,
483 ))
484 }
485}
486
487impl core::fmt::Debug for ClassMatrix<'_> {
488 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
489 write!(f, "ClassMatrix {{ ... }}")
490 }
491}
492
493
494#[allow(missing_docs)]
497#[derive(Clone, Copy, Debug)]
498pub enum PairAdjustment<'a> {
499 Format1 {
500 coverage: Coverage<'a>,
501 sets: PairSets<'a>,
502 },
503 Format2 {
504 coverage: Coverage<'a>,
505 classes: (ClassDefinition<'a>, ClassDefinition<'a>),
506 matrix: ClassMatrix<'a>,
507 },
508}
509
510impl<'a> PairAdjustment<'a> {
511 fn parse(data: &'a [u8]) -> Option<Self> {
512 let mut s = Stream::new(data);
513 match s.read::<u16>()? {
514 1 => {
515 let coverage = Coverage::parse(s.read_at_offset16(data)?)?;
516 let flags = (
517 s.read::<ValueFormatFlags>()?,
518 s.read::<ValueFormatFlags>()?,
519 );
520 let count = s.read::<u16>()?;
521 let offsets = s.read_array16(count)?;
522 Some(Self::Format1 {
523 coverage,
524 sets: PairSets::new(data, offsets, flags)
525 })
526 }
527 2 => {
528 let coverage = Coverage::parse(s.read_at_offset16(data)?)?;
529 let flags = (
530 s.read::<ValueFormatFlags>()?,
531 s.read::<ValueFormatFlags>()?,
532 );
533 let classes = (
534 ClassDefinition::parse(s.read_at_offset16(data)?)?,
535 ClassDefinition::parse(s.read_at_offset16(data)?)?,
536 );
537 let counts = (
538 s.read::<u16>()?,
539 s.read::<u16>()?,
540 );
541 Some(Self::Format2 {
542 coverage,
543 classes,
544 matrix: ClassMatrix::parse(data, counts, flags, &mut s)?,
545 })
546 },
547 _ => None,
548 }
549 }
550
551 #[inline]
553 pub fn coverage(&self) -> Coverage<'a> {
554 match self {
555 Self::Format1 { coverage, .. } => *coverage,
556 Self::Format2 { coverage, .. } => *coverage,
557 }
558 }
559}
560
561
562#[derive(Clone, Copy)]
563struct EntryExitRecord {
564 entry_anchor_offset: Option<Offset16>,
565 exit_anchor_offset: Option<Offset16>,
566}
567
568impl FromData for EntryExitRecord {
569 const SIZE: usize = 4;
570
571 #[inline]
572 fn parse(data: &[u8]) -> Option<Self> {
573 let mut s = Stream::new(data);
574 Some(Self {
575 entry_anchor_offset: s.read::<Option<Offset16>>()?,
576 exit_anchor_offset: s.read::<Option<Offset16>>()?,
577 })
578 }
579}
580
581
582#[derive(Clone, Copy)]
584pub struct CursiveAnchorSet<'a> {
585 data: &'a [u8],
586 records: LazyArray16<'a, EntryExitRecord>,
587}
588
589impl<'a> CursiveAnchorSet<'a> {
590 pub fn entry(&self, index: u16) -> Option<Anchor<'a>> {
592 let offset = self.records.get(index)?.entry_anchor_offset?.to_usize();
593 self.data.get(offset..).and_then(Anchor::parse)
594 }
595
596 pub fn exit(&self, index: u16) -> Option<Anchor<'a>> {
598 let offset = self.records.get(index)?.exit_anchor_offset?.to_usize();
599 self.data.get(offset..).and_then(Anchor::parse)
600 }
601
602 pub fn len(&self) -> u16 {
604 self.records.len()
605 }
606}
607
608impl core::fmt::Debug for CursiveAnchorSet<'_> {
609 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
610 write!(f, "CursiveAnchorSet {{ ... }}")
611 }
612}
613
614
615#[allow(missing_docs)]
618#[derive(Clone, Copy, Debug)]
619pub struct CursiveAdjustment<'a> {
620 pub coverage: Coverage<'a>,
621 pub sets: CursiveAnchorSet<'a>,
622}
623
624impl<'a> CursiveAdjustment<'a> {
625 fn parse(data: &'a [u8]) -> Option<Self> {
626 let mut s = Stream::new(data);
627 match s.read::<u16>()? {
628 1 => {
629 let coverage = Coverage::parse(s.read_at_offset16(data)?)?;
630 let count = s.read::<u16>()?;
631 let records = s.read_array16(count)?;
632 Some(Self {
633 coverage,
634 sets: CursiveAnchorSet { data, records }
635 })
636 }
637 _ => None,
638 }
639 }
640}
641
642
643#[derive(Clone, Copy, Debug)]
646pub struct MarkToBaseAdjustment<'a> {
647 pub mark_coverage: Coverage<'a>,
649 pub base_coverage: Coverage<'a>,
651 pub marks: MarkArray<'a>,
653 pub anchors: AnchorMatrix<'a>,
655}
656
657impl<'a> MarkToBaseAdjustment<'a> {
658 fn parse(data: &'a [u8]) -> Option<Self> {
659 let mut s = Stream::new(data);
660 match s.read::<u16>()? {
661 1 => {
662 let mark_coverage = Coverage::parse(s.read_at_offset16(data)?)?;
663 let base_coverage = Coverage::parse(s.read_at_offset16(data)?)?;
664 let class_count = s.read::<u16>()?;
665 let marks = MarkArray::parse(s.read_at_offset16(data)?)?;
666 let anchors = AnchorMatrix::parse(s.read_at_offset16(data)?, class_count)?;
667 Some(Self { mark_coverage, base_coverage, marks, anchors })
668 }
669 _ => None,
670 }
671 }
672}
673
674#[allow(missing_docs)]
677#[derive(Clone, Copy, Debug)]
678pub struct MarkToLigatureAdjustment<'a> {
679 pub mark_coverage: Coverage<'a>,
680 pub ligature_coverage: Coverage<'a>,
681 pub marks: MarkArray<'a>,
682 pub ligature_array: LigatureArray<'a>,
683}
684
685impl<'a> MarkToLigatureAdjustment<'a> {
686 fn parse(data: &'a [u8]) -> Option<Self> {
687 let mut s = Stream::new(data);
688 match s.read::<u16>()? {
689 1 => {
690 let mark_coverage = Coverage::parse(s.read_at_offset16(data)?)?;
691 let ligature_coverage = Coverage::parse(s.read_at_offset16(data)?)?;
692 let class_count = s.read::<u16>()?;
693 let marks = MarkArray::parse(s.read_at_offset16(data)?)?;
694 let ligature_array = LigatureArray::parse(s.read_at_offset16(data)?, class_count)?;
695 Some(Self { mark_coverage, ligature_coverage, marks, ligature_array })
696 }
697 _ => None,
698 }
699 }
700}
701
702#[derive(Clone, Copy)]
704pub struct LigatureArray<'a> {
705 data: &'a [u8],
706 class_count: u16,
707 offsets: LazyArray16<'a, Offset16>,
708}
709
710impl<'a> LigatureArray<'a> {
711 fn parse(data: &'a [u8], class_count: u16) -> Option<Self> {
712 let mut s = Stream::new(data);
713 let count = s.read::<u16>()?;
714 let offsets = s.read_array16(count)?;
715 Some(Self { data, class_count, offsets })
716 }
717
718 pub fn get(&self, index: u16) -> Option<AnchorMatrix<'a>> {
720 let offset = self.offsets.get(index)?.to_usize();
721 let data = self.data.get(offset..)?;
722 AnchorMatrix::parse(data, self.class_count)
723 }
724
725 pub fn len(&self) -> u16 {
727 self.offsets.len()
728 }
729}
730
731impl core::fmt::Debug for LigatureArray<'_> {
732 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
733 write!(f, "LigatureArray {{ ... }}")
734 }
735}
736
737
738#[derive(Clone, Copy)]
739struct MarkRecord {
740 class: Class,
741 mark_anchor: Offset16,
742}
743
744impl FromData for MarkRecord {
745 const SIZE: usize = 4;
746
747 #[inline]
748 fn parse(data: &[u8]) -> Option<Self> {
749 let mut s = Stream::new(data);
750 Some(Self {
751 class: s.read::<Class>()?,
752 mark_anchor: s.read::<Offset16>()?,
753 })
754 }
755}
756
757
758#[derive(Clone, Copy)]
760pub struct MarkArray<'a> {
761 data: &'a [u8],
762 array: LazyArray16<'a, MarkRecord>,
763}
764
765impl<'a> MarkArray<'a> {
766 fn parse(data: &'a [u8]) -> Option<Self> {
767 let mut s = Stream::new(data);
768 let count = s.read::<u16>()?;
769 let array = s.read_array16(count)?;
770 Some(Self { data, array })
771 }
772
773 pub fn get(&self, index: u16) -> Option<(Class, Anchor<'a>)> {
775 let record = self.array.get(index)?;
776 let anchor = self.data.get(record.mark_anchor.to_usize()..).and_then(Anchor::parse)?;
777 Some((record.class, anchor))
778 }
779
780 pub fn len(&self) -> u16 {
782 self.array.len()
783 }
784}
785
786impl core::fmt::Debug for MarkArray<'_> {
787 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
788 write!(f, "MarkArray {{ ... }}")
789 }
790}
791
792
793#[derive(Clone, Copy, Debug)]
797pub struct Anchor<'a> {
798 pub x: i16,
800 pub y: i16,
802 pub x_device: Option<Device<'a>>,
804 pub y_device: Option<Device<'a>>,
806}
807
808impl<'a> Anchor<'a> {
809 fn parse(data: &'a [u8]) -> Option<Self> {
810 let mut s = Stream::new(data);
811 let format = s.read::<u16>()?;
812 if !matches!(format, 1..=3) {
813 return None;
814 }
815
816 let mut table = Anchor {
817 x: s.read::<i16>()?,
818 y: s.read::<i16>()?,
819 x_device: None,
820 y_device: None,
821 };
822
823 if format == 3 {
827 table.x_device = s.read::<Option<Offset16>>()?
828 .and_then(|offset| data.get(offset.to_usize()..))
829 .and_then(Device::parse);
830
831 table.y_device = s.read::<Option<Offset16>>()?
832 .and_then(|offset| data.get(offset.to_usize()..))
833 .and_then(Device::parse);
834 }
835
836 Some(table)
837 }
838}
839
840
841#[derive(Clone, Copy)]
843pub struct AnchorMatrix<'a> {
844 data: &'a [u8],
845 pub rows: u16,
847 pub cols: u16,
849 matrix: LazyArray32<'a, Offset16>,
850}
851
852impl<'a> AnchorMatrix<'a> {
853 fn parse(data: &'a [u8], cols: u16) -> Option<Self> {
854 let mut s = Stream::new(data);
855 let rows = s.read::<u16>()?;
856 let count = u32::from(rows) * u32::from(cols);
857 let matrix = s.read_array32(count)?;
858 Some(Self { data, rows, cols, matrix })
859 }
860
861 pub fn get(&self, row: u16, col: u16) -> Option<Anchor> {
863 let idx = u32::from(row) * u32::from(self.cols) + u32::from(col);
864 let offset = self.matrix.get(idx)?.to_usize();
865 Anchor::parse(self.data.get(offset..)?)
866 }
867}
868
869impl core::fmt::Debug for AnchorMatrix<'_> {
870 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
871 write!(f, "AnchorMatrix {{ ... }}")
872 }
873}
874
875
876#[allow(missing_docs)]
879#[derive(Clone, Copy, Debug)]
880pub struct MarkToMarkAdjustment<'a> {
881 pub mark1_coverage: Coverage<'a>,
882 pub mark2_coverage: Coverage<'a>,
883 pub marks: MarkArray<'a>,
884 pub mark2_matrix: AnchorMatrix<'a>,
885}
886
887impl<'a> MarkToMarkAdjustment<'a> {
888 fn parse(data: &'a [u8]) -> Option<Self> {
889 let mut s = Stream::new(data);
890 match s.read::<u16>()? {
891 1 => {
892 let mark1_coverage = Coverage::parse(s.read_at_offset16(data)?)?;
893 let mark2_coverage = Coverage::parse(s.read_at_offset16(data)?)?;
894 let class_count = s.read::<u16>()?;
895 let marks = MarkArray::parse(s.read_at_offset16(data)?)?;
896 let mark2_matrix = AnchorMatrix::parse(s.read_at_offset16(data)?, class_count)?;
897 Some(Self { mark1_coverage, mark2_coverage, marks, mark2_matrix })
898 }
899 _ => None,
900 }
901 }
902}
903
904
905#[allow(missing_docs)]
909#[derive(Clone, Copy, Debug)]
910pub enum PositioningSubtable<'a> {
911 Single(SingleAdjustment<'a>),
912 Pair(PairAdjustment<'a>),
913 Cursive(CursiveAdjustment<'a>),
914 MarkToBase(MarkToBaseAdjustment<'a>),
915 MarkToLigature(MarkToLigatureAdjustment<'a>),
916 MarkToMark(MarkToMarkAdjustment<'a>),
917 Context(ContextLookup<'a>),
918 ChainContext(ChainedContextLookup<'a>),
919}
920
921impl<'a> LookupSubtable<'a> for PositioningSubtable<'a> {
922 fn parse(data: &'a [u8], kind: u16) -> Option<Self> {
923 match kind {
924 1 => SingleAdjustment::parse(data).map(Self::Single),
925 2 => PairAdjustment::parse(data).map(Self::Pair),
926 3 => CursiveAdjustment::parse(data).map(Self::Cursive),
927 4 => MarkToBaseAdjustment::parse(data).map(Self::MarkToBase),
928 5 => MarkToLigatureAdjustment::parse(data).map(Self::MarkToLigature),
929 6 => MarkToMarkAdjustment::parse(data).map(Self::MarkToMark),
930 7 => ContextLookup::parse(data).map(Self::Context),
931 8 => ChainedContextLookup::parse(data).map(Self::ChainContext),
932 9 => crate::ggg::parse_extension_lookup(data, Self::parse),
933 _ => None,
934 }
935 }
936}
937
938impl<'a> PositioningSubtable<'a> {
939 #[inline]
941 pub fn coverage(&self) -> Coverage<'a> {
942 match self {
943 Self::Single(t) => t.coverage(),
944 Self::Pair(t) => t.coverage(),
945 Self::Cursive(t) => t.coverage,
946 Self::MarkToBase(t) => t.mark_coverage,
947 Self::MarkToLigature(t) => t.mark_coverage,
948 Self::MarkToMark(t) => t.mark1_coverage,
949 Self::Context(t) => t.coverage(),
950 Self::ChainContext(t) => t.coverage(),
951 }
952 }
953}