mirror of
https://github.com/storytold/photocraft.git
synced 2026-10-29 04:17:11 -06:00
* fix(text): lay out a variable font's named instance from its PostScript name
A PSD type style set in a named instance of a variable font, such as
Bahnschrift Light Condensed, keeps the instance only as its PostScript
name ("Bahnschrift-LightCondensed"); its variations are empty. When
PhotoCraft re-laid the layer out, FontDb::select_named_face looked for a
face with that PostScript name, or one whose style and weight matched. A
variable family is a single face, so neither matched, and the text was
laid out at the font's default instance: about 35% wider than the
instance Photoshop drew with Bahnschrift.
select_named_face now falls back to the family's variable faces when the
PostScript name matches no face. It reads each face's fvar named
instances and compares the name with the instance's own PostScript name,
or, when the instance has none, with the name Adobe Technical Note #5902
derives (variations prefix or family name, a hyphen, then the subfamily
without spaces). Names compare without punctuation or case. On a match,
that face is selected and the instance's axis values are added to the
style's variations, keeping any axis the style already sets. Static
faces still match exactly as before, and PSD import is unchanged.
Tests:
- font_names_tests::postscript_name_of_a_named_instance_selects_its_axis_values
rebuilds the bundled Inter at test time as a variable font (fvar with
wght/wdth axes and two named instances, one with its own PostScript
name and one derived) and checks the axis values each name selects, an
unknown name, and a style's own axis value. It needs no installed font
and no font file in the repository.
- font_names_tests::exact_static_face_gets_no_instance_axes checks that
an exact static match gets no axis values.
- tests::postscript_name_of_a_variable_instance_lays_out_at_that_instance
lays out "Hamburgefonstiv 0123" with Bahnschrift (Windows) or Ubuntu
Sans (Ubuntu) when installed and checks that the instance's PostScript
name gives the same width as its axis values. With Ubuntu Sans before
the fix: UbuntuSans-CondensedLight 980.3 px (= the default instance),
its axes 766.4 px; after the fix both are 766.4 px.
A style with only a weight (no PostScript name) is still not turned into
a wght axis value on a variable font; the issue reports that too, but its
fix and test are about the PostScript name, so that is left for a
separate change.
Fixes #8797
* fix(text): try a variable font's named instance before the style fallback
Review pointed out that select_named_face ran the style-and-weight
fallback before the named-instance lookup. A style that carries a named
instance's PostScript name and also a populated font_style matching the
variable face itself ("Regular", 400) selected that face at its default
instance, and the instance's axis values were never added.
Faces are now tried in order: exact PostScript name, named instance,
then style, weight and italic.
Review also noted that the layout-width test only runs when Bahnschrift
or Ubuntu Sans is installed. The synthesized variable font in
font_names_tests now carries an HVAR table that narrows every advance on
wdth, so layout width shows which instance was used. Two tests run
everywhere:
- named_instance_wins_over_a_matching_font_style
- postscript_name_of_a_named_instance_lays_out_at_that_instance
Both fail before this change. The installed-font test is kept as a check
against a real font.
---------
Co-authored-by: John Turnbach <jturnbach@users.noreply.github.com>