Please fix weight handling for modern multi-weight mixed (variable + static fonts)
Changes in the OpenType spec means that fonts can now come with an unbounded number of weights, in variable and static forms.
The OpenType spec insists weights use the same scale in all metadata layers (STAT, OS/2), for static and variable fonts and that all of those must be consistent to enable substituting instances to static fonts (and vice versa).
The CSS4 spec mandates deriving naming from specific weight values.
However, that does not work in fontconfig today. For example, installing Merriweather (one of the top 20 Google fonts for the past years), without any specific tuning, will produce the following result
https://github.com/SorkinType/Merriweather/
$ fc-scan -f "%{style[0]};%{weight};%{file}\n" . | sort -t ';' -k2,2n | column --separator ';' -t
[50 210] ./Merriweather-Italic-VF.ttf
[50 210] ./Merriweather-Roman-VF.ttf
Light 50 ./Merriweather-Light.ttf
Light Display 50 ./Merriweather-LightDisplay.ttf
Light Display Narrow 50 ./Merriweather-LightDisplayNarrow.ttf
Light Display Wide 50 ./Merriweather-LightDisplayWide.ttf
Light Heading 50 ./Merriweather-LightHeading.ttf
Light Heading Narrow 50 ./Merriweather-LightHeadingNarrow.ttf
Light Heading Wide 50 ./Merriweather-LightHeadingWide.ttf
Light Italic 50 ./Merriweather-LightItalic.ttf
Light Narrow 50 ./Merriweather-LightNarrow.ttf
Light Text 50 ./Merriweather-LightText.ttf
Light Text Narrow 50 ./Merriweather-LightTextNarrow.ttf
Light Text Wide 50 ./Merriweather-LightTextWide.ttf
Light Wide 50 ./Merriweather-LightWide.ttf
Black Text 61,6667 ./Merriweather-BlackText.ttf
Italic 80 ./Merriweather-Italic.ttf
Light 80 ./Merriweather-Roman-VF.ttf
Light Italic 80 ./Merriweather-Italic-VF.ttf
Regular 80 ./Merriweather-Regular.ttf
Regular Display 80 ./Merriweather-RegularDisplay.ttf
Regular Display Narrow 80 ./Merriweather-RegularDisplayNarrow.ttf
Regular Display Wide 80 ./Merriweather-RegularDisplayWide.ttf
Regular Heading 80 ./Merriweather-RegularHeadling.ttf
Regular Heading Narrow 80 ./Merriweather-RegularHeadingNarrow.ttf
Regular Heading Wide 80 ./Merriweather-RegularHeadingWide.ttf
Regular Narrow 80 ./Merriweather-RegularNarrow.ttf
Regular Text 80 ./Merriweather-RegularText.ttf
Regular Text Narrow 80 ./Merriweather-RegularTextNarrow.ttf
Regular Text Wide 80 ./Merriweather-RegularTextWide.ttf
Regular Wide 80 ./Merriweather-RegularWide.ttf
Italic 126,667 ./Merriweather-Italic-VF.ttf
Regular 126,667 ./Merriweather-Roman-VF.ttf
Bold 200 ./Merriweather-Bold.ttf
Bold Display 200 ./Merriweather-BoldDisplay.ttf
Bold Display Narrow 200 ./Merriweather-BoldDisplayNarrow.ttf
Bold Display Wide 200 ./Merriweather-BoldDisplayWide.ttf
Bold Heading 200 ./Merriweather-BoldHeading.ttf
Bold Heading Narrow 200 ./Merriweather-BoldHeadingNarrow.ttf
Bold Heading Wide 200 ./Merriweather-BoldHeadingWide.ttf
Bold Italic 200 ./Merriweather-BoldItalic.ttf
Bold Narrow 200 ./Merriweather-BoldNarrow.ttf
Bold Text 200 ./Merriweather-BoldText.ttf
Bold Text Narrow 200 ./Merriweather-BoldTextNarrow.ttf
Bold Text Wide 200 ./Merriweather-BoldTextWide.ttf
Bold Wide 200 ./Merriweather-BoldWide.ttf
Black 210 ./Merriweather-Black.ttf
Black Display 210 ./Merriweather-BlackDisplay.ttf
Black Display Narrow 210 ./Merriweather-BlackDisplayNarrow.ttf
Black Display Wide 210 ./Merriweather-BlackDisplayWide.ttf
Black Heading 210 ./Merriweather-BlackHeading.ttf
Black Heading Narrow 210 ./Merriweather-BlackHeadingNarrow.ttf
Black Heading Wide 210 ./Merriweather-BlackHeadingWide.ttf
Black Italic 210 ./Merriweather-BlackItalic.ttf
Black Narrow 210 ./Merriweather-BlackNarrow.ttf
Black Text Narrow 210 ./Merriweather-BlackTextNarrow.ttf
Black Text Wide 210 ./Merriweather-BlackTextWide.ttf
Black Wide 210 ./Merriweather-BlackWide.ttf
Bold 211,667 ./Merriweather-Roman-VF.ttf
Bold Italic 211,667 ./Merriweather-Italic-VF.ttf
Black 215 ./Merriweather-Roman-VF.ttf
Black Italic 215 ./Merriweather-Italic-VF.ttf
The weights are completely inconsistent between variable and non variable (Regular is both 80 and 126,667)
The weight ordering is completely off (Black is sometimes heavier than Bold, sometimes lighter, in one instance it‘s even lighter than Regular!)
However, all those files have been generated by the same tools from the same master, which, as far as I can see, uses consistent values for all variants: https://github.com/SorkinType/Merriweather/blob/master/sources/master_ufo/Merriweather.designspace
However, it is not easy to see what is wrong because of fontconfig’s tampering with the OpenType weight scale.
Requirements
-
fontconfig should use coherent weight values for all faces of a font family regardless if they are variable or static
-
fontconfig should make it easy to identify what went wrong in case of problems. It should expose the real opentype weight value exported by font files, so it’s easy to check if the problem is in this value or in what fontconfig made of it
-
once the problem is identified, it should be easy to override problem values with the correct value using a fontconfig xml snippet (and the correct value should not take black magic to compute)
-
the result should work with the rest of the weight axis (ie it’s useless to fix the weight value of a variable instance, if all the weight range around the fixed instance is still broken)