Skip to content

Commit

Permalink
Adjust the processing of ContextualSubstitution(Format2)
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanUkhov committed Jul 18, 2024
1 parent ac8bc0b commit d69deb5
Showing 1 changed file with 29 additions and 19 deletions.
48 changes: 29 additions & 19 deletions src/formats/opentype/features/rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,26 +146,27 @@ impl Table for opentype::tables::glyph_substitution::Type {
let (classes, mapping) = unclass(&table.class);
let classes = &classes;
values.extend(
uncover(&table.coverage)
.filter_map(|glyph_id| mapping.get(&glyph_id).cloned())
.collect::<BTreeSet<_>>()
.into_iter()
.filter_map(|class_index| {
table.records.get(class_index as usize).and_then(|record| {
record.as_ref().map(|record| (class_index, record))
})
})
.flat_map(|(class_index, record)| {
record.records.iter().map(move |record| {
let mut value = Vec::with_capacity(record.glyph_count as usize);
value.push(classes.get(&class_index)?.clone());
for class_index in &record.indices {
value.push(classes.get(class_index)?.clone());
}
Some(Self::expand(value, &record.records, directory))
})
deduplicate(
uncover(&table.coverage)
.filter_map(|glyph_id| mapping.get(&glyph_id).cloned()),
)
.filter_map(|class_index| {
table
.records
.get(class_index as usize)
.and_then(|record| record.as_ref().map(|record| (class_index, record)))
})
.flat_map(|(class_index, record)| {
record.records.iter().map(move |record| {
let mut value = Vec::with_capacity(record.glyph_count as usize);
value.push(classes.get(&class_index)?.clone());
for class_index in &record.indices {
value.push(classes.get(class_index)?.clone());
}
Some(Self::expand(value, &record.records, directory))
})
.collect::<Option<Vec<_>>>()?,
})
.collect::<Option<Vec<_>>>()?,
);
}
Type::ContextualSubstitution(Context::Format3(table)) => {
Expand Down Expand Up @@ -275,6 +276,15 @@ impl Table for opentype::tables::glyph_substitution::Type {
}
}

fn deduplicate<T, U>(values: T) -> impl Iterator<Item = U>
where
T: Iterator<Item = U>,
U: std::cmp::Ord + Clone,
{
let mut seen = BTreeSet::new();
values.filter(move |value| seen.insert(value.clone()))
}

fn unclass(value: &Class) -> (BTreeMap<u16, Glyph>, BTreeMap<GlyphID, u16>) {
let mut forward = BTreeMap::<_, BTreeSet<_>>::default();
let mut reverse = BTreeMap::default();
Expand Down

0 comments on commit d69deb5

Please sign in to comment.