Skip to content

Add runtime control for SK_FONT_HOST_USE_SYSTEM_SETTINGS#14

Merged
tonsky merged 3 commits into
HumbleUI:m119from
vladimirsamsonov:m119_config
Mar 9, 2026
Merged

Add runtime control for SK_FONT_HOST_USE_SYSTEM_SETTINGS#14
tonsky merged 3 commits into
HumbleUI:m119from
vladimirsamsonov:m119_config

Conversation

@vladimirsamsonov
Copy link
Copy Markdown

@vladimirsamsonov vladimirsamsonov commented Mar 7, 2026

Problem

When SK_FONT_HOST_USE_SYSTEM_SETTINGS is defined at compile time, Skia reads
gamma and contrast from Windows ClearType settings via DirectWrite API. While this
makes text match native Windows rendering, it introduces two issues:

  • Cross-wrapper inconsistency: apps combining Skija with other Skia wrappers
    (e.g. SkiaSharp) that are built without this flag will produce visually different
    text on the same machine
  • Machine-dependent visual testing: pixel-level regression tests may pass on
    one machine and fail on another due to different ClearType settings

Solution

Instead of removing SK_FONT_HOST_USE_SYSTEM_SETTINGS (which would change the
default behavior), this PR exposes it as a runtime option via a small patch to
SkTypeface_win_dw.cpp:

// -1 = follow compile-time default (SK_FONT_HOST_USE_SYSTEM_SETTINGS)
//  0 = force off (consistent, machine-independent rendering)
//  1 = force on (match Windows native rendering)
static std::atomic gUseSystemRenderingParams{-1};

This preserves the existing default behavior while allowing callers to opt out
when needed.

Testing

Verified pixel-level output matches SkiaSharp on the same machine after removing the flag.
text_JAVA_Skija
text_NET - SkiaSharp

Below is an outdated attempt at a solution


Remove SK_FONT_HOST_USE_SYSTEM_SETTINGS flag on Windows

Problem

Text rendered via Skija produces slightly different antialiasing compared to other Skia wrappers (e.g. SkiaSharp) even when using the same Skia version (m119), same font, same size, and same paint settings. The difference is visible at the pixel color level in subpixel intensity of glyph edges.

Root Cause

The Windows build configuration included -DSK_FONT_HOST_USE_SYSTEM_SETTINGS in extra_cflags. When this flag is defined, Skia reads gamma and contrast values from the system via the DirectWrite API (IDWriteRenderingParams):

// SkTypeface_win_dw.cpp
#if defined(SK_FONT_HOST_USE_SYSTEM_SETTINGS)
    factory->CreateRenderingParams(&defaultRenderingParams);
    rec->setDeviceGamma(defaultRenderingParams->GetGamma());         // e.g. 1.8
    rec->setContrast(defaultRenderingParams->GetEnhancedContrast()); // e.g. 0.5
#endif

Without this flag, Skia uses its own hardcoded defaults (gamma ~1.4), which is consistent with the behavior of other wrappers and produces identical rendering across environments regardless of per-machine Windows ClearType settings.

Effect of the flag

Setting With flag Without flag
Gamma source DirectWrite system params Skia hardcoded default (~1.4)
Rendering Varies per machine Consistent across machines
Cross-wrapper consistency

Change

Removed -DSK_FONT_HOST_USE_SYSTEM_SETTINGS from Windows build args in script/build.py.

@vladimirsamsonov
Copy link
Copy Markdown
Author

Hi @tonsky!
I’m continuing my investigation into using this library as a replacement for Skia bindings in .NET projects that currently rely on SkiaSharp.

I was able to reach near-complete parity for primitive rendering. However, there is still an important issue with text rendering. During my investigation I found differences related to how gamma correction is handled.

I understand that this is a rather specific area, but I would really appreciate it if you could update the current experimental m119 branch to include/support this setting.

Thanks.

@tonsky
Copy link
Copy Markdown
Contributor

tonsky commented Mar 7, 2026

As much as I value consistency, it sounds like we want SK_FONT_HOST_USE_SYSTEM_SETTINGS? In the sense that I want text rendered in Skia apps to match text seen in other areas of Windows. Think about it from user's perspective: user can see inconsistencies between native apps and skia apps, but they can't see inconsistencies between e.g. different versions of windows/different monitor settings. Yes, that means that Skia rendering output is system-dependent, but for a good reason?Unless I misunderstood something?

@tonsky
Copy link
Copy Markdown
Contributor

tonsky commented Mar 7, 2026

This is what I’m getting. With flag looks more close to what Notepad renders, and No flag is a bit too light?

Untitled

@vladimirsamsonov
Copy link
Copy Markdown
Author

You're right about the user-facing consistency argument, and I agree it's more important in general.
The original motivation was pixel-level inconsistency between Skija and SkiaSharp when used side by side in the same application — both wrapping the same Skia m119 but producing different subpixel intensities due to this flag.
Another practical concern: with SK_FONT_HOST_USE_SYSTEM_SETTINGS enabled, visual regression testing becomes machine-dependent — the same test may pass on one machine and fail on another simply because of different ClearType settings. Of course, one workaround would be to override the system gamma before running tests and restore it afterwards, but that feels fragile and invasive — it modifies global Windows settings and could interfere with other running applications.

As a possible middle ground — we could expose this as a runtime option on the native side:

// on by default (current behavior, matches Windows native rendering)
static bool gUseSystemRenderingParams = true;

void DWriteFontTypeface::onFilterRec(SkScalerContextRec* rec) const {
    // ...
    if (gUseSystemRenderingParams) {
        // read gamma/contrast from DirectWrite
    }
}

This would require a small patch to SkTypeface_win_dw.cpp in the Skia source, but it's minimal and self-contained. This way the default behavior stays as-is and matches Windows native rendering, while apps that need cross-wrapper consistency or machine-independent visual testing can explicitly opt out.
What do you think?

@tonsky
Copy link
Copy Markdown
Contributor

tonsky commented Mar 8, 2026

I like that!

@vladimirsamsonov vladimirsamsonov marked this pull request as draft March 8, 2026 21:49
@vladimirsamsonov vladimirsamsonov changed the title Remove SK_FONT_HOST_USE_SYSTEM_SETTINGS flag on Windows Add runtime control for DirectWrite system font rendering params on Windows Mar 9, 2026
@vladimirsamsonov vladimirsamsonov marked this pull request as ready for review March 9, 2026 16:13
@vladimirsamsonov vladimirsamsonov changed the title Add runtime control for DirectWrite system font rendering params on Windows Add runtime control for SK_FONT_HOST_USE_SYSTEM_SETTINGS Mar 9, 2026
@tonsky tonsky merged commit d1647c2 into HumbleUI:m119 Mar 9, 2026
@tonsky
Copy link
Copy Markdown
Contributor

tonsky commented Mar 9, 2026

Thanks! Building...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants