Skip to content

Commit

Permalink
Add back one of the tests
Browse files Browse the repository at this point in the history
  • Loading branch information
rsheeter committed Dec 3, 2024
1 parent 9a1e107 commit 24db1a6
Showing 1 changed file with 79 additions and 8 deletions.
87 changes: 79 additions & 8 deletions fontir/src/glyph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,13 @@ enum GlyphOp {
}

/// Fix glyphs with mixed components/contours.
///
///
/// We presume component cycles are checked elsewhere and do not check for them here
fn resolve_inconsistencies(
context: &Context,
mut todo: VecDeque<(GlyphOp, Arc<Glyph>)>,
order: &mut GlyphOrder,
mut apply_fix: impl FnMut(GlyphOp, &Glyph, &mut GlyphOrder) -> Result<(), BadGlyph>,
) -> Result<(), BadGlyph> {
let mut pending = todo
.iter()
Expand All @@ -209,12 +210,7 @@ fn resolve_inconsistencies(

// Our component graph doesn't reach any pending component, we are a go!
debug!("{op:?} {}", glyph.name);
match op {
GlyphOp::ConvertToContour => convert_components_to_contours(context, &glyph)?,
GlyphOp::MoveContoursToComponent => {
move_contours_to_new_component(context, order, &glyph)?
}
}
apply_fix(op, &glyph, order)?;

// I ain't a-gonna pend no more
pending.remove(&glyph.name);
Expand Down Expand Up @@ -505,7 +501,17 @@ impl Work<Context, WorkId, Error> for GlyphOrderWork {
}
}
}
resolve_inconsistencies(context, todo, &mut new_glyph_order)?;
resolve_inconsistencies(
context,
todo,
&mut new_glyph_order,
|op, glyph, order| match op {
GlyphOp::ConvertToContour => convert_components_to_contours(context, &glyph),
GlyphOp::MoveContoursToComponent => {
move_contours_to_new_component(context, order, &glyph)
}
},
)?;
drop(original_glyphs); // lets not accidentally use that from here on

apply_optional_transformations(context, &new_glyph_order)?;
Expand Down Expand Up @@ -1039,4 +1045,69 @@ mod tests {
// infected the deep_component and caused it to be decomposed.
assert_is_flattened_component(&context, test_data.deep_component.name);
}

#[derive(Default)]
struct GlyphOrderBuilder(Vec<Arc<Glyph>>);

impl GlyphOrderBuilder {
fn add_glyph<const N: usize>(&mut self, name: &str, components: [&str; N]) {
let instance = GlyphInstance {
components: components
.into_iter()
.map(|name| Component {
base: name.into(),
transform: Default::default(),
})
.collect(),
..Default::default()
};
let loc = NormalizedLocation::for_pos(&[("axis", 0.0)]);
let glyph = Glyph::new(
name.into(),
true,
Default::default(),
HashMap::from([(loc, instance)]),
)
.unwrap();
self.0.push(Arc::new(glyph))
}
}

#[test]
fn component_sorting() {
let mut builder = GlyphOrderBuilder::default();
builder.add_glyph("a", ["b", "c"]);
builder.add_glyph("b", ["z"]);
builder.add_glyph("c", ["d"]);
builder.add_glyph("d", ["x", "y"]);
builder.add_glyph("e", ["z"]);

let mut order: GlyphOrder = builder.0.iter().map(|g| g.name.clone()).collect();
let mut context = test_context();
for glyph in builder.0.iter() {
context.glyphs.set((**glyph).clone());
for component_name in glyph.component_names() {
if order.contains(component_name) {
continue;
}
context.glyphs.set(contour_glyph(component_name.as_str()));
order.insert(component_name.clone());
}
}
let todo = builder
.0
.into_iter()
.map(|g| (GlyphOp::ConvertToContour, g))
.collect();

let mut fix_order = Vec::new();

resolve_inconsistencies(&mut context, todo, &mut order, |_op, glyph, _order| {
fix_order.push(glyph.name.clone());
Ok(())
})
.unwrap();

assert_eq!(fix_order, ["b", "d", "e", "c", "a"]);
}
}

0 comments on commit 24db1a6

Please sign in to comment.