Skip to main content

read_fonts/tables/gpos/closure/
extended.rs

1//! Closure for the extended positioning formats.
2
3use super::super::{
4    CursivePosFormat2, MarkBasePosFormat2, MarkLigPosFormat2, MarkMarkPosFormat2, PairPosFormat3,
5    PairPosFormat4, PairSet2, SinglePosFormat3, SinglePosFormat4,
6};
7use super::*;
8
9#[cfg(test)]
10mod tests;
11
12macro_rules! intersect_coverage {
13    ($table:ident) => {
14        impl Intersect for $table<'_> {
15            fn intersects(&self, glyphs: &IntSet<GlyphId>) -> Result<bool, ReadError> {
16                if self.coverage_offset().is_null() {
17                    return Ok(false);
18                }
19                Ok(self.coverage()?.intersects(glyphs))
20            }
21        }
22    };
23}
24intersect_coverage!(SinglePosFormat3);
25intersect_coverage!(SinglePosFormat4);
26intersect_coverage!(CursivePosFormat2);
27
28macro_rules! intersect_mark_coverages {
29    ($table:ident, $first_offset:ident, $second_offset:ident, $first:ident, $second:ident) => {
30        impl Intersect for $table<'_> {
31            fn intersects(&self, glyphs: &IntSet<GlyphId>) -> Result<bool, ReadError> {
32                if self.$first_offset().is_null() || self.$second_offset().is_null() {
33                    return Ok(false);
34                }
35                Ok(self.$first()?.intersects(glyphs) && self.$second()?.intersects(glyphs))
36            }
37        }
38    };
39}
40intersect_mark_coverages!(
41    MarkBasePosFormat2,
42    mark_coverage_offset,
43    base_coverage_offset,
44    mark_coverage,
45    base_coverage
46);
47intersect_mark_coverages!(
48    MarkLigPosFormat2,
49    mark_coverage_offset,
50    ligature_coverage_offset,
51    mark_coverage,
52    ligature_coverage
53);
54intersect_mark_coverages!(
55    MarkMarkPosFormat2,
56    mark1_coverage_offset,
57    mark2_coverage_offset,
58    mark1_coverage,
59    mark2_coverage
60);
61
62impl Intersect for PairPosFormat3<'_> {
63    fn intersects(&self, glyphs: &IntSet<GlyphId>) -> Result<bool, ReadError> {
64        if self.coverage_offset().is_null() {
65            return Ok(false);
66        }
67        pair_pos_intersects(
68            &self.coverage()?,
69            self.pair_sets(),
70            self.pair_set_count().to_u32(),
71            glyphs,
72        )
73    }
74}
75
76impl Intersect for PairSet2<'_> {
77    fn intersects(&self, glyphs: &IntSet<GlyphId>) -> Result<bool, ReadError> {
78        for record in self.pair_value_records().iter() {
79            if glyphs.contains(GlyphId::from(record?.second_glyph())) {
80                return Ok(true);
81            }
82        }
83        Ok(false)
84    }
85}
86
87impl Intersect for PairPosFormat4<'_> {
88    fn intersects(&self, glyphs: &IntSet<GlyphId>) -> Result<bool, ReadError> {
89        if self.coverage_offset().is_null()
90            || self.class_def1_offset().is_null()
91            || self.class_def2_offset().is_null()
92        {
93            return Ok(false);
94        }
95        Ok(self.coverage()?.intersects(glyphs) && self.class_def2()?.intersects(glyphs)?)
96    }
97}