Files
egui/crates/epaint/src/text/mod.rs
T
valadaptive 609dd2d28e Replace ab_glyph with Skrifa + vello_cpu; enable font hinting (#7694)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/main/CONTRIBUTING.md)
before opening a Pull Request!

* Keep your PR:s small and focused.
* The PR title is what ends up in the changelog, so make it descriptive!
* If applicable, add a screenshot or gif.
* If it is a non-trivial addition, consider adding a demo for it to
`egui_demo_lib`, or a new example.
* Do NOT open PR:s from your `master` branch, as that makes it hard for
maintainers to test and add commits to your PR.
* Remember to run `cargo fmt` and `cargo clippy`.
* Open the PR as a draft until you have self-reviewed it and run
`./scripts/check.sh`.
* When you have addressed a PR comment, mark it as resolved.

Please be patient! I will review your PR, but my time is limited!
-->

* Closes N/A
* [x] I have followed the instructions in the PR template

I'll probably come back to this and clean it up a bit. This PR
reimplements ab_glyph's functionality on top of Skrifa, a somewhat
lower-level font API that's being used in Chrome now.

Skrifa doesn't perform rasterization itself, so I'm using
[vello_cpu](https://github.com/linebender/vello) from the Linebender
project for rasterization. It's still in its early days, but I believe
it's already quite fast. It also supports color and gradient fills, so
color emoji support will be easier.

Skrifa also supports font hinting, which should make text look a bit
nicer / less blurry.

Here's the current ab_glyph rendering:

<img width="1592" height="1068" alt="image"
src="https://github.com/user-attachments/assets/2385b66e-23f8-4c6e-b8c2-ea90e0eea4e4"
/>

Here's Skrifa *without* hinting--it looks almost identical, but there
are some subpixel differences, probably due to rasterizer behavior:

<img width="1592" height="1068" alt="image"
src="https://github.com/user-attachments/assets/a815f3e9-65ac-4940-bc00-571177bef53d"
/>

Here's Skrifa  *with* hinting:

<img width="1592" height="1068" alt="image"
src="https://github.com/user-attachments/assets/d6cc0669-3537-4377-bba9-ed5ef09664db"
/>

Hinting does make the horizontal strokes look a bit bolder, which makes
me wonder once again about increasing the font weight from "light" to
"regular".

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2025-12-06 16:11:33 +01:00

51 lines
1.3 KiB
Rust

//! Everything related to text, fonts, text layout, cursors etc.
pub mod cursor;
mod font;
mod fonts;
mod text_layout;
mod text_layout_types;
/// One `\t` character is this many spaces wide.
pub const TAB_SIZE: usize = 4;
pub use {
fonts::{
FontData, FontDefinitions, FontFamily, FontId, FontInsert, FontPriority, FontTweak, Fonts,
FontsImpl, FontsView, InsertFontFamily,
},
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 coverage to alpha.
pub alpha_from_coverage: crate::AlphaFromCoverage,
/// Whether to enable font hinting
///
/// (round some font coordinates to pixels for sharper text).
///
/// Default is `true`.
pub font_hinting: bool,
}
impl Default for TextOptions {
fn default() -> Self {
Self {
max_texture_side: 2048, // Small but portable
alpha_from_coverage: crate::AlphaFromCoverage::default(),
font_hinting: true,
}
}
}