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