mirror of
https://github.com/emilk/egui.git
synced 2026-09-01 14:20:04 -04:00
Make font hinting target configurable via FontTweak (#8262)
Fixes #8079, where font hinting only sharpens the vertical axis (vertical stems stay blurry), and none of the skrifa knobs were reachable — only switching to `Target::Mono` helped, but that wasn't exposed. This makes the hinting target configurable instead of hardcoding `Target::Smooth { symmetric_rendering: true, preserve_linear_metrics: true }`. ### API - New `epaint::text::HintingTarget` mirroring `skrifa::outline::Target`: - `Mono` - `Smooth(SmoothHinting)` where `SmoothHinting { light, symmetric_rendering, preserve_linear_metrics }` - New field `FontTweak::hinting_target: HintingTarget`. - Each variant/field is documented with what it does and the egui-specific caveats (e.g. `symmetric_rendering` only affects interpreter-hinted fonts; egui positions glyphs from shaper advances so `preserve_linear_metrics` mostly affects sharpness, not layout). ### Render - `font.rs` converts `HintingTarget` → `skrifa::outline::Target` and threads it into the per-glyph `reconfigure` call; the hinting instance is also reconfigured when the target changes. ### UI - The font-tweak settings panel gets a `hinting_target` row: Smooth/Mono radios, `light` / `symmetric_rendering` / `preserve_linear_metrics` checkboxes, and a `Reset` button — all with tooltips. ### Behavior - `HintingTarget::default()` matches egui's previous hardcoded target, so **rendering is unchanged** unless you opt in. To fix the horizontal blur from #8079, uncheck `preserve_linear_metrics` (or pick `Mono`). Whether to flip the *default* is left as a follow-up. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
use emath::Align;
|
||||
use epaint::{
|
||||
CornerRadius, FontColorTransferFunction, Shadow, Stroke, TextOptions,
|
||||
text::{FontTweak, FontVariationAxis},
|
||||
text::{FontTweak, FontVariationAxis, HintingTarget, SmoothHinting},
|
||||
};
|
||||
use std::{collections::BTreeMap, ops::RangeInclusive, sync::Arc};
|
||||
|
||||
@@ -2902,6 +2902,7 @@ pub fn font_tweak_ui(ui: &mut Ui, tweak: &mut FontTweak, axes: &[FontVariationAx
|
||||
y_offset_factor,
|
||||
y_offset,
|
||||
hinting,
|
||||
hinting_target,
|
||||
coords,
|
||||
thin_space_width,
|
||||
tab_size,
|
||||
@@ -2929,6 +2930,59 @@ pub fn font_tweak_ui(ui: &mut Ui, tweak: &mut FontTweak, axes: &[FontVariationAx
|
||||
});
|
||||
ui.end_row();
|
||||
|
||||
ui.label("hinting_target")
|
||||
.on_hover_text("How aggressively to snap glyph outlines to the pixel grid. Only matters when hinting is enabled.");
|
||||
ui.vertical(|ui| {
|
||||
ui.horizontal(|ui| {
|
||||
let is_mono = matches!(hinting_target, HintingTarget::Mono);
|
||||
if ui
|
||||
.radio(!is_mono, "Smooth")
|
||||
.on_hover_text("Hinting tuned for anti-aliased rendering. The normal choice.")
|
||||
.clicked()
|
||||
&& is_mono
|
||||
{
|
||||
*hinting_target = HintingTarget::default();
|
||||
}
|
||||
if ui
|
||||
.radio(is_mono, "Mono")
|
||||
.on_hover_text(
|
||||
"Strongest hinting (designed for 1-bit rendering). Sharpest, but \
|
||||
distorts glyph weight across sizes.",
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
*hinting_target = HintingTarget::Mono;
|
||||
}
|
||||
if ui
|
||||
.button("Reset")
|
||||
.on_hover_text("Reset the hinting target to its default.")
|
||||
.clicked()
|
||||
{
|
||||
*hinting_target = HintingTarget::default();
|
||||
}
|
||||
});
|
||||
if let HintingTarget::Smooth(SmoothHinting {
|
||||
light,
|
||||
symmetric_rendering,
|
||||
preserve_linear_metrics,
|
||||
}) = hinting_target
|
||||
{
|
||||
ui.checkbox(light, "light").on_hover_text(
|
||||
"Hint only vertically, preserving the font's horizontal proportions \
|
||||
(softer). Off also fits horizontally.",
|
||||
);
|
||||
ui.checkbox(symmetric_rendering, "symmetric_rendering").on_hover_text(
|
||||
"Render glyphs the same regardless of sub-pixel position (good for \
|
||||
caching/animation), but can blur stems. Only affects interpreter-hinted fonts.",
|
||||
);
|
||||
ui.checkbox(preserve_linear_metrics, "preserve_linear_metrics").on_hover_text(
|
||||
"Keep spacing independent of hinting. Off lets the hinter snap \
|
||||
horizontally for crisper vertical stems on low-dpi screens.",
|
||||
);
|
||||
}
|
||||
});
|
||||
ui.end_row();
|
||||
|
||||
ui.label("subpixel_binning");
|
||||
ui.horizontal(|ui| {
|
||||
ui.radio_value(subpixel_binning, Some(true), "on");
|
||||
|
||||
Reference in New Issue
Block a user