font-optical-sizing applies incorrect value on Windows
(Core :: Graphics: Text, defect)
(Reporter: mmaxfield, Unassigned)
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Safari/605.1.15
Steps to reproduce:
Style some text with a font that supports the opsz variation axis on Windows
The optical sizing value supplied to the variation font is 4/3 of what it should be on Windows.
The OpenType spec states that the scale for the opsz variation is "text size, in points." This refers to typographic (or physical) points, rather than CSS points. This is for two reasons: 1) OpenType has no notion of CSS, as OpenType sits lower in the software stack, and 2) web views (e.g. on Android) are often used in conjunction with native views in the same app, and text should look identical in both of those places, so the fact that one is rendered from a CSS context can't have affect on optical sizing values.
macOS is designed throughout the OS for one pixel to be equal to 1/72 typographic inch, which equals 1 typographic point. Firefox (and, indeed, all major browsers) choose to map one CSS pixel to be equal to 1 physical pixel, which is therefore equal to one typographic point on macOS. Therefore, when the OpenType spec says that opsz values need to be set to typographic points, this is equivalent on macOS to setting opsz to the font size in CSS pixels. Firefox is setting this on macOS correctly.
However, Windows seems to be designed for one pixel to be equal to 1/96 typographic inches, which equals 3/4 typographic points. Firefox (and, indeed, all major browsers) choose to map 1 CSS pixel to be equal to 1 physical pixel, which is therefore equal to 3/4 typographic points on Windows. Therefore, when the OpenType spec says that opsz values need to be set to typographic points, this is equivalent on Windows to setting opsz to the font size in CSS pixels multiplied by 3/4 (which is equivalent to setting opsz to the font size in CSS points). Firefox is not setting this value correctly on Windows - instead it is setting opsz to the font size in CSS pixels.
The distinction between the design of Windows and macOS has caused this thread in the CSSWG.
From a quick look at the code, it looks like one possible fix would be to modify line 285 in nsFont.cpp (inside nsFont::AddFontVariationsToStyle()). If the platform is Windows (or Linux?) the “size” value could be multiplied by 3/4.
 https://docs.microsoft.com/en-us/windows/win32/api/dwrite/nf-dwrite-idwritefactory-createtextformat "The logical size of the font in DIP ("device-independent pixel") units. A DIP equals 1/96 inch."
3 years ago
Bugbug thinks this bug should belong to this component, but please revert this change in case of error.
3 years ago
Jonathan, this looks like it might be up your street?
3 years ago
I haven't caught up with the entirety of https://github.com/w3c/csswg-drafts/issues/4430 yet, but AFAICT it's not at all clear there is consensus on how this should work.
The first step is probably for someone to create a comprehensive test suite, as I don't think we have much WPT coverage here.