On Fri, 28 Aug 2026 22:03:28 GMT, Andy Goryachev <[email protected]> wrote:

>> This PR attempts to improve LCD text rendering on Windows and Linux. Changes 
>> include:
>> 
>> - (Windows only) When setting up DirectWrite the code now uses the 
>> NATURAL_SYMMETRIC rendering mode except for very small glyphs where it uses 
>> NATURAL. Using NATURAL_SYMMETRIC avoids distorted glyphs at specific pixel 
>> sizes (see [JDK-8389632](https://bugs.openjdk.org/browse/JDK-8389632)) and 
>> retains the curves along the top and bottom of the glyphs. Using NATURAL at 
>> small sizes avoids glyphs turning very fuzzy and light.
>> 
>> - The code is now consistently converts the colors from sRGB to a linear 
>> space (more or less), composites them, and then converts the result back to 
>> sRGB.
>> 
>> - The shader applies a contrast equation to the LCD glyph mask which helps 
>> emphasize the stems. The same equation is used by Skia and probably added by 
>> Microsoft when they cleaned up text rendering for Chromium. BTW it’s just 
>> the equation for a parabola that goes through points (0, 0) and (1, 1).
>> 
>> My testing was mostly done on a 27 inch display with a resolution of 
>> 2560x1440 and a screen scale of 150%. This was low enough to notice a 
>> difference. Resolutions higher than that (like full-on Retina) tend to hide 
>> a lot of sins.
>> 
>> I recommend reading “The Raster Tragedy in Skia” which is concise but covers 
>> a lot of ground. It contains a section on the challenges of compositing text 
>> in sRGB space and also the issues getting LCD text to look dark enough 
>> without inflating the stems. I wish I had found this earlier in the process.
>> 
>> ---------
>> - [x] I confirm that I make this contribution in accordance with the 
>> [OpenJDK Interim AI Policy](https://openjdk.org/legal/ai).
>
> modules/javafx.graphics/src/main/java/com/sun/prism/impl/ps/BaseShaderGraphics.java
>  line 2104:
> 
>> 2102:             // 2.233333 which more closely approximates the real sRGB
>> 2103:             // function compared to the usual value of 2.2.
>> 2104:             float gamma = 2.233333f;
> 
> 1) `PrismFontFactory.getLCDContrast()` contains platform-specific code 
> (isWindows) and used in multiple places (also in `SWGraphics`).  would it 
> make more sense to move this change there?
> 
> 2) should a similar change be applied to SWGraphics:668 ?

I don't know what to do with getLCDContrast. The value it's picking up from the 
OS seems to be related to older technologies; DirectWrite has a different 
system for retrieving rendering parameters. I haven't found MS documentation on 
how to use this value. JavaFX treats it sort of like a gamma value. It applies 
it to the source color's RGB channels which are *not* premultiplied and also to 
the destination's RGB channels which *are* premultiplied. It also applies it to 
the alpha channel of both (?!). And then after compositing these values (with 
their modified alphas) it applies the inverse of that sort-of-gamma value to 
the result (including its alpha channel) and puts it into an sRGB buffer which 
assumes a fixed gamma of ~2.2.

I decided to play this by the book. JavaFX uses sRGB and my code linearizes 
into and out of that space and that doesn't involve any platform-specific 
information.

I forgot about the software renderer. Once things settle down in the GPU path 
I'll update the sw backend.

-------------

PR Review Comment: https://git.openjdk.org/jfx/pull/2284#discussion_r3896041421

Reply via email to