Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose and fix broken processing of bbox for components whose transform is more than scale and transform #1050

Merged
merged 2 commits into from
Oct 22, 2024

Conversation

rsheeter
Copy link
Contributor

@rsheeter rsheeter commented Oct 17, 2024

Simplified reproduction of problem impacting Luxurious Roman (python resources/scripts/ttx_diff.py https://github.com/googlefonts/luxurious-roman#sources/Luxurious-Roman.glyphs)

$ python resources/scripts/ttx_diff.py resources/testdata/glyphs2/MatrixComponent.glyphs
...glyf, head, hhea, hmtx diff...

$ diff ~/oss/fontc/build/default/fontc.glyf.ttx ~/oss/fontc/build/default/fontmake.glyf.ttx
38c38
<     <TTGlyph name="infinity" xMin="750" yMin="272" xMax="877" yMax="443">
---
>     <TTGlyph name="infinity" xMin="767" yMin="284" xMax="863" yMax="431">

This appears to be due to fontc assuming it can simply apply the component transform to the control box when in fact it needs to transform the points and compute the control box of the new points. https://codepen.io/rs42/pen/wvVqVPL?editors=1000 sketches the impact of transformation for the new test font.

Reproduced in simplified test that now passes. Luxurious Roman is now identical when ttx_diff'd locally.

@rsheeter rsheeter added the bug Something isn't working label Oct 17, 2024
@rsheeter rsheeter changed the title Add simplified reproduction of ttx_diff failure Expose and fix broken processing of bbox for components whose transform is more than scale and transform Oct 17, 2024
@rsheeter rsheeter changed the title Expose and fix broken processing of bbox for components whose transform is more than scale and transform [WIP] Expose and fix broken processing of bbox for components whose transform is more than scale and transform Oct 17, 2024
@rsheeter rsheeter marked this pull request as draft October 17, 2024 04:54
@rsheeter rsheeter force-pushed the matrix branch 2 times, most recently from cce9792 to 0c25b6d Compare October 22, 2024 00:20
@rsheeter rsheeter changed the title [WIP] Expose and fix broken processing of bbox for components whose transform is more than scale and transform Expose and fix broken processing of bbox for components whose transform is more than scale and transform Oct 22, 2024
@rsheeter rsheeter marked this pull request as ready for review October 22, 2024 00:46
Comment on lines +765 to +766
// The transform we get here has changed because it got turned into F2Dot14 and i16 parts
// We could go get the "real" transform from IR but ... this seems to match fontmake so far
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the 'real' transform from source or IR doesn't actually matter any more, it's the one that's stored in the glyf table that matters for bbox computation, that's what fonttools TTGlyph.recalcBounds() does (and ufo2ft uses the same method on the compiled TTGlyphs when building the glyf table).

RawGlyph::Composite(composite) => Some((*gn, composite)),
RawGlyph::Simple(..) | RawGlyph::Empty => None,
}) {
let bbox = bbox_of_composite(&glyph_order, &glyphs, glyph, Affine::IDENTITY)?;
Copy link
Member

@anthrotype anthrotype Oct 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you went for a recursive traversal instead of iterative one. I'm ok with it (fonttools does the same), but I was wondering, even though unlikely, should you prevent from a component cycle triggering an infinite recursion? Python has a max recursion depth after which it raises an exception. Does Rust protect you as well?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for glyphs sources at least we already check against component cycles when we propagate anchors, see glyphs-reader's propagate_anchors.rs (depth_sorted_composite_glyphs)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me take confirmation of no cycles as a follow-on. I have the vague notion we might already do it but I'll double-check.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

affine: Affine,
) -> Result<Option<Rect>, Error> {
// For simple scale+translate transforms, which seem to be common, we could just transform a bbox
// Let's wait to see if that pops out in a profile and do the simple solution for now
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's wait to see if that pops out in a profile

did you actually try to profile before/after this? I suggest filing an issue

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, #1061

Copy link
Member

@anthrotype anthrotype left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with minor comments

@rsheeter rsheeter added this pull request to the merge queue Oct 22, 2024
Merged via the queue into main with commit 081b604 Oct 22, 2024
10 checks passed
@rsheeter rsheeter deleted the matrix branch October 22, 2024 15:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants