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
