mirror of
https://github.com/emilk/egui.git
synced 2026-06-26 22:53:14 -04:00
Pre-populate font variation axes in the FontTweak UI (#8258)
The `FontTweak` settings UI previously let you edit variable-font variation coordinates only via free-form tag + value entry — you had to *know* that e.g. `wght` exists and what range is valid. This PR queries the font's actual variation axes and pre-populates the UI. ### Changes - **`epaint`**: new `FontData::variation_axes() -> Vec<FontVariationAxis>` (skrifa-backed). Each `FontVariationAxis` exposes the axis `tag`, human-readable `name`, `min`/`default`/`max`, and `hidden`. Empty for static (non-variable) fonts. - **`egui`**: extracted the `FontTweak` body into a public `style::font_tweak_ui(ui, tweak, axes)`. When `axes` is non-empty, each axis is shown as a named **slider** pre-filled with the font's default and clamped to its valid range, with a ⟲ button to drop the override. `impl Widget for &mut FontTweak` still exists and delegates with no axes (free-form fallback, also used for unknown/manual tags). - The font settings panel (`Context::fonts_tweak_ui`) now passes `data.variation_axes()`. - UI label renamed `coords` → **Axes** (matching Google Fonts' terminology); the underlying `FontTweak.coords` field keeps the OpenType "design coordinates" name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Example (Weight and Width): <img width="340" height="239" alt="Screenshot 2026-06-24 at 11 51 33" src="https://github.com/user-attachments/assets/f898289a-e329-453a-ba86-c60858901466" /> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -10,11 +10,11 @@ use std::{
|
||||
use crate::{
|
||||
TextureAtlas,
|
||||
text::{
|
||||
ByteIndex, Galley, LayoutJob, LayoutSection, TextOptions, VariationCoords,
|
||||
ByteIndex, Galley, LayoutJob, LayoutSection, Tag, TextOptions, VariationCoords,
|
||||
font::{Font, FontFace},
|
||||
},
|
||||
};
|
||||
use emath::{NumExt as _, OrderedFloat};
|
||||
use emath::{NumExt as _, OrderedFloat, Rangef};
|
||||
|
||||
#[cfg(feature = "default_fonts")]
|
||||
use epaint_default_fonts::{EMOJI_ICON, HACK_REGULAR, NOTO_EMOJI_REGULAR, UBUNTU_LIGHT};
|
||||
@@ -147,6 +147,57 @@ impl FontData {
|
||||
pub fn tweak(self, tweak: FontTweak) -> Self {
|
||||
Self { tweak, ..self }
|
||||
}
|
||||
|
||||
/// The variation axes of this font, e.g. `wght` (weight) and `wdth` (width).
|
||||
///
|
||||
/// Use this to discover which axes a variable font supports, and their valid
|
||||
/// ranges, so a UI can offer the right knobs instead of making the user guess
|
||||
/// tags and values for [`FontTweak::coords`].
|
||||
///
|
||||
/// Returns an empty list for non-variable (static) fonts, or if the font data
|
||||
/// fails to parse.
|
||||
pub fn variation_axes(&self) -> Vec<FontVariationAxis> {
|
||||
use skrifa::MetadataProvider as _;
|
||||
|
||||
let Ok(font) = skrifa::FontRef::from_index(self.font.as_ref(), self.index) else {
|
||||
return Vec::new();
|
||||
};
|
||||
|
||||
font.axes()
|
||||
.iter()
|
||||
.map(|axis| FontVariationAxis {
|
||||
tag: axis.tag(),
|
||||
name: font
|
||||
.localized_strings(axis.name_id())
|
||||
.english_or_first()
|
||||
.map(|name| name.chars().collect()),
|
||||
range: Rangef::new(axis.min_value(), axis.max_value()),
|
||||
default: axis.default_value(),
|
||||
hidden: axis.is_hidden(),
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
/// A single variation axis of a variable font, e.g. weight (`wght`) or width (`wdth`).
|
||||
///
|
||||
/// Obtained via [`FontData::variation_axes`].
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct FontVariationAxis {
|
||||
/// The axis tag, e.g. `wght` or `wdth`.
|
||||
pub tag: Tag,
|
||||
|
||||
/// Human-readable axis name, if the font provides one (e.g. "Weight").
|
||||
pub name: Option<String>,
|
||||
|
||||
/// Valid range of values for this axis, `min..=max`.
|
||||
pub range: Rangef,
|
||||
|
||||
/// The value used when the axis is not overridden.
|
||||
pub default: f32,
|
||||
|
||||
/// Whether the font recommends hiding this axis from user interfaces.
|
||||
pub hidden: bool,
|
||||
}
|
||||
|
||||
impl AsRef<[u8]> for FontData {
|
||||
@@ -196,7 +247,7 @@ pub struct FontTweak {
|
||||
/// `None` means use the global setting in [`TextOptions::subpixel_binning`].
|
||||
pub subpixel_binning: Option<bool>,
|
||||
|
||||
/// Override the font's default variation coordinates.
|
||||
/// Override the font's default variation coordinates for its axes ("wght", etc.).
|
||||
pub coords: VariationCoords,
|
||||
|
||||
/// Width of a thin space (`\u{2009}`) and narrow no-break space (`\u{202F}`),
|
||||
|
||||
@@ -9,8 +9,8 @@ mod text_layout_types;
|
||||
|
||||
pub use {
|
||||
fonts::{
|
||||
FontData, FontDefinitions, FontFamily, FontId, FontInsert, FontPriority, FontTweak, Fonts,
|
||||
FontsImpl, FontsView, InsertFontFamily,
|
||||
FontData, FontDefinitions, FontFamily, FontId, FontInsert, FontPriority, FontTweak,
|
||||
FontVariationAxis, Fonts, FontsImpl, FontsView, InsertFontFamily,
|
||||
},
|
||||
index::{ByteIndex, ByteRange, ByteRangeExt, CharIndex, CharRange, CharRangeExt},
|
||||
text_layout::*,
|
||||
|
||||
Reference in New Issue
Block a user