1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-29 04:40:03 -04:00
Files
egui/crates/epaint/src/text/mod.rs
Emil Ernerfeldt 3e19bd1404 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>
2026-06-25 03:18:21 +02:00

66 lines
2.0 KiB
Rust

//! Everything related to text, fonts, text layout, cursors etc.
pub mod cursor;
mod font;
mod fonts;
mod index;
mod text_layout;
mod text_layout_types;
pub use {
fonts::{
FontData, FontDefinitions, FontFamily, FontId, FontInsert, FontPriority, FontTweak,
FontVariationAxis, Fonts, FontsImpl, FontsView, HintingTarget, InsertFontFamily,
SmoothHinting,
},
index::{ByteIndex, ByteRange, ByteRangeExt, CharIndex, CharRange, CharRangeExt},
text_layout::*,
text_layout_types::*,
};
/// Suggested character to use to replace those in password text fields.
pub const PASSWORD_REPLACEMENT_CHAR: char = '•';
/// Controls how we render text
#[derive(Clone, Copy, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct TextOptions {
/// Maximum size of the font texture.
pub max_texture_side: usize,
/// Controls how to convert glyph colors when writing to the font atlas.
pub color_transfer_function: crate::FontColorTransferFunction,
/// Whether to enable font hinting
///
/// (round some font coordinates to pixels for sharper text).
///
/// Default is `true`.
pub font_hinting: bool,
/// Enable sub-pixel binning for glyphs.
///
/// Sub-pixel binning renders each glyph at up to four fractional horizontal offsets,
/// giving more even kerning at the cost of more atlas space.
///
/// It also lead to text looking more blurry.
///
/// This is always disabled for CJK characters (which have too many unique glyphs).
///
/// Can be overridden per font with [`FontTweak::subpixel_binning`].
///
/// Default: `true`.
pub subpixel_binning: bool,
}
impl Default for TextOptions {
fn default() -> Self {
Self {
max_texture_side: 2048, // Small but portable
color_transfer_function: crate::FontColorTransferFunction::default(),
font_hinting: true,
subpixel_binning: true,
}
}
}