1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-31 05:40:03 -04:00

Improve text sharpness (#5838)

This improves the sharpness of text slightly, thanks to
<https://hikogui.org/2022/10/24/the-trouble-with-anti-aliasing.html> by
@hikogui (🙏 ).

The difference is very small, but in dark mode (bright text on dark
background) text is sometimes significantly sharper, and also slightly
brighter.

The difference in light mode (dark text on light background) is much
smaller (barely perceptable).

To compare the before/after I suggest you open both in new tabs, then
quickly change between them.

### Low-DPI
#### Before
![Code Editor
old](https://github.com/user-attachments/assets/e10a3cad-932f-48cd-b7d6-5bfe70954c5e)

#### After
![Code
Editor](https://github.com/user-attachments/assets/2e7383fe-8023-4425-91c8-93df3c22c0fe)

#### Before

![old-white](https://github.com/user-attachments/assets/51c41c59-e897-4831-857a-f3ffe17ce7d4)

#### After

![new-white](https://github.com/user-attachments/assets/4ac6f951-8c57-4bcc-a5d5-788cf52ea7d8)

### High-DPI
The difference is starkest on low-DPI screens (like the above
screenshots). On high-DPI screens, the difference is much smaller

#### Before
![widget_gallery
old](https://github.com/user-attachments/assets/f2149a30-aef8-4383-b48c-73d33a03ca02)

#### After

![widget_gallery](https://github.com/user-attachments/assets/c9ceb8be-8a32-490c-9364-2c6562b741f6)
This commit is contained in:
Emil Ernerfeldt
2025-03-21 12:56:47 +01:00
committed by GitHub
parent 3f731ec794
commit 2058dcb881
60 changed files with 134 additions and 130 deletions

View File

@@ -306,14 +306,23 @@ impl FontImage {
/// If you are having problems with text looking skinny and pixelated, try using a low gamma, e.g. `0.4`.
#[inline]
pub fn srgba_pixels(&self, gamma: Option<f32>) -> impl ExactSizeIterator<Item = Color32> + '_ {
// TODO(emilk): this default coverage gamma is a magic constant, chosen by eye. I don't even know why we need it.
// Maybe we need to implement the ideas in https://hikogui.org/2022/10/24/the-trouble-with-anti-aliasing.html
let gamma = gamma.unwrap_or(0.55);
// This whole function is less than rigorous.
// Ideally we should do this in a shader instead, and use different computations
// for different text colors.
// See https://hikogui.org/2022/10/24/the-trouble-with-anti-aliasing.html for an in-depth analysis.
self.pixels.iter().map(move |coverage| {
let alpha = coverage.powf(gamma);
// We want to multiply with `vec4(alpha)` in the fragment shader:
let a = fast_round(alpha * 255.0);
Color32::from_rgba_premultiplied(a, a, a, a)
let alpha = if let Some(gamma) = gamma {
coverage.powf(gamma)
} else {
// alpha = coverage * coverage; // recommended by the article for WHITE text (using linear blending)
// The following is recommended by the article for BLACK text (using linear blending).
// Very similar to a gamma of 0.5, but produces sharper text.
// In practice it works well for all text colors (better than a gamma of 0.5, for instance).
// See https://www.desmos.com/calculator/w0ndf5blmn for a visual comparison.
2.0 * coverage - coverage * coverage
};
Color32::from_white_alpha(ecolor::linear_u8_from_linear_f32(alpha))
})
}
@@ -362,11 +371,6 @@ impl From<FontImage> for ImageData {
}
}
#[inline]
fn fast_round(r: f32) -> u8 {
(r + 0.5) as _ // rust does a saturating cast since 1.45
}
// ----------------------------------------------------------------------------
/// A change to an image.