When the VarStore.optimize() algorithm was improved with the addition of a priority queue where pairs of encodings are sorted by decreasing gain (from merging one into the other), specifically with this commit https://github.com/fonttools/fonttools/commit/47ec18f788, the pre-sorting step of the todo list (before the queue itself was populated) was kept to make sure the algorithm produces stable results no matter the order of the inputs.
The optimizer's output was itself sorted, again for stability, but using a different key function with_sort_key() from the one used on the input todo list gain_sort_key().
The rationale for a distinct gain_sort_key, where encodings get sorted by maximum theoretical gain (decreasing, initally, when reverse=True was set, then incrasing as reverse was somehow dropped), is no longer needed now that a priority queue is used (which sorts by actual gains from merging specific pairs of encodings) and is a remnant of the previous algorithm.
I propose we keep some pre-sorting to ensure stability (in case the priority queue initially contains multiple pairs with the same gain), but we use the same width_sort_key that is used at the end.
Note this doesn't change the overall level of compression achieved by the optimizer, but makes the algorithm a bit less complicated, and easier to match in our alternative Rust implementation.
The "" marker is used when a custom converter expects a list.
For DeltaValues, we expect a list as a single value, not a list
to be enumerated in XML. So, None is appropriate here. Cryptic,
I know...
Fixes https://github.com/fonttools/fonttools/pull/3757
The method that was being used to read the header from the input was
inadvertently dropping the first non-header line on the floor; although
this happens to be okay in some cases (where there is an empty line
after the header) in the case of newer versions of the
ScriptExtensions.txt file, this was causing the generated code to be
missing the first entry, for U+00B7 (MIDDLE DOT)
when getCoordinates is asked to round, e.g. from recalcBounds, only round the simple glyphs' coordinates; don't do any rounding for the coordinates of component glyphs otherwise rounding errors would accummulate if a composite glyph contains transformed/nested components
This avoids pitfalls from type checkers having to work with limited
information, e.g., a type checker may implicitly assume that only
integers are expected where a default value is 1, whereas in reality any
float is accepted.
[Docs] Fill out ttLib table section. Part of a bottom-up docs rework for ttLib.
Note that 23546cf changes the `import`s for ttLib/tables/_g_v_a_r.py to un-confuse autodoc.
When passing a parsed feature file that has variable anchors to
addOpenTypeFeatures(), builder would modify the anchors in place and
discard the variations, which break any subsequent use of the feature
file.
I encountered this building a font that has variable cursing anchors
with ufo2ft. The cursFeatureWriter would write the variable anchors, but
then when kernFeatreWriter compiles the file to get GSUB closure, the
variation would be dropped from the anchors, and later when when the
feature data is compiled into the font, the anchors would be compiled
without variations.