Repository navigation
Keep a glyph's variation metrics stable when several composites use it - #393
Conversation
_getPhantomPoints built the phantom points from this._metrics, which _getContours replaces with the varied metrics. A glyph is decoded again for every composite that uses it, so the gvar delta was applied once per composite: in Mada-VF at wght 100, dotless i advanced 229, 202, 175, 148 after laying out its accented composites. Build the phantom points from the default metrics.
blikblum
left a comment
There was a problem hiding this comment.
What is the visual practical effect of the bug?
| let { advanceWidth, advanceHeight, leftBearing, topBearing } = this._metrics; | ||
| // _getContours replaces this._metrics with the varied metrics, and a glyph | ||
| // is decoded again for every composite using it, so keep the default ones. | ||
| if (this._defaultMetrics == null) { |
There was a problem hiding this comment.
| if (this._defaultMetrics == null) { | |
| if (!this._defaultMetrics) { |
| } | ||
|
|
||
| let { advanceWidth, advanceHeight, leftBearing, topBearing } = this._metrics; | ||
| // _getContours replaces this._metrics with the varied metrics, and a glyph |
There was a problem hiding this comment.
Wondering if _getContours could be made side effect free
|
Applied the suggestion, thanks. The visible effect: in a glyf variable font without HVAR, at a non-default instance, a base letter laid out after two or more different accented letters built from it gets a narrower advance, so the following glyphs move left and crowd it. With
It loses one gvar delta for every additional composite that decodes the base glyph, and it depends on the order glyphs are first touched. So in French text the On making |
|
Lets make minimal changes, one at time |
In a glyf variable font without HVAR, a glyph's advance drifts each time a composite that uses it is decoded:
ıis a component of the other four._getPhantomPointsbuilds the phantom points fromthis._metrics, and_getContoursthen overwritesthis._metricswith the varied values. A component is decoded again for every composite, so its gvar delta (−27 here) is applied once per composite: 229, 202, 175, 148. This keeps a copy of the default metrics on the first call and builds the phantom points from it.The new test in
test/variations.jsfails on master; building from the live metrics, aliasing instead of copying, or re-copying on every call each fail it.npm test: 547 passing, 1 failing (i18n setDefaultLanguage "ar", which also fails on master). #389 touches the same file but not_getPhantomPoints.Written with AI assistance (Claude); I have reviewed the change.