Skip to content

Add font variations API#7859

Merged
emilk merged 7 commits intoemilk:mainfrom
valadaptive:variations
Mar 3, 2026
Merged

Add font variations API#7859
emilk merged 7 commits intoemilk:mainfrom
valadaptive:variations

Conversation

@valadaptive
Copy link
Copy Markdown
Contributor

  • Closes N/A
  • I have followed the instructions in the PR template

This was mostly from last month, but I never got around to submitting it.

This PR adds font variation coordinates to the TextFormat struct, and uses them when rendering text. The coordinates are stored in a SmallVec; I've chosen to store up to 2 inline, which makes it take up 24 bytes (the minimum possible for a SmallVec). The variation axis tags are stored as the font_types::Tag type, which I've chosen to re-export from epaint::text.

The variation coordinates are resolved to a skrifa::Location during font rendering/scaling, and are cached in the same way as all the other scaled metrics. I've renamed the ScaledMetrics struct to StyledMetrics, since it now also contains the resolved variation coordinates. I haven't benchmarked the performance of text layout with variation coordinates, but the existing text layout performance is unchanged.

I've replaced the API for manually overriding a font's weight (#7790) with an API for manually overriding any variation coordinates via FontTweak. This should support the same use case as #7790 while being substantially more flexible.

I have not yet added any higher-level API for mapping style attributes (weight, width, slant, etc) to variation coordinates or to different font faces within a single family. That's a pretty huge can of worms, and it'd involve rethinking the split between FontId and TextFormat (and whether FontId is so big that we should provide a way to reuse it). This API is intentionally pretty low-level for now.

Likewise, I've intentionally not used variation coordinates when computing a font's row height. I can't think of any fonts that change their vertical metrics depending on variation axes, so this should be fine for now.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Jan 23, 2026

Preview available at https://egui-pr-preview.github.io/pr/7859-variations
Note that it might take a couple seconds for the update to show up after the preview_build workflow has completed.

View snapshot changes at kitdiff

Copy link
Copy Markdown
Owner

@emilk emilk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

@emilk emilk added feature New feature or request text Problems related to text egui epaint labels Feb 10, 2026
@emilk emilk added this to egui Mar 3, 2026
@emilk emilk moved this to In review in egui Mar 3, 2026
@emilk emilk added this to the 0.34.0 milestone Mar 3, 2026
@emilk emilk merged commit 699fc7e into emilk:main Mar 3, 2026
25 checks passed
@github-project-automation github-project-automation bot moved this from In review to Done in egui Mar 3, 2026
lucasmerlin pushed a commit that referenced this pull request Mar 5, 2026
<!--
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

This was mostly from last month, but I never got around to submitting
it.

This PR adds font variation coordinates to the `TextFormat` struct, and
uses them when rendering text. The coordinates are stored in a
`SmallVec`; I've chosen to store up to 2 inline, which makes it take up
24 bytes (the minimum possible for a `SmallVec`). The variation axis
tags are stored as the `font_types::Tag` type, which I've chosen to
re-export from `epaint::text`.

The variation coordinates are resolved to a `skrifa::Location` during
font rendering/scaling, and are cached in the same way as all the other
scaled metrics. I've renamed the `ScaledMetrics` struct to
`StyledMetrics`, since it now also contains the resolved variation
coordinates. I haven't benchmarked the performance of text layout with
variation coordinates, but the existing text layout performance is
unchanged.

I've replaced the API for manually overriding a font's weight
(#7790) with an API for manually
overriding any variation coordinates via `FontTweak`. This should
support the same use case as #7790 while being substantially more
flexible.

I have *not* yet added any higher-level API for mapping style attributes
(weight, width, slant, etc) to variation coordinates or to different
font faces within a single family. That's a pretty huge can of worms,
and it'd involve rethinking the split between `FontId` and `TextFormat`
(and whether `FontId` is so big that we should provide a way to reuse
it). This API is intentionally pretty low-level for now.

Likewise, I've intentionally not used variation coordinates when
computing a font's row height. I can't think of any fonts that change
their vertical metrics depending on variation axes, so this should be
fine for now.

---------

Co-authored-by: Emil Ernerfeldt <[email protected]>
lucasmerlin pushed a commit that referenced this pull request Mar 5, 2026
<!--
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

This was mostly from last month, but I never got around to submitting
it.

This PR adds font variation coordinates to the `TextFormat` struct, and
uses them when rendering text. The coordinates are stored in a
`SmallVec`; I've chosen to store up to 2 inline, which makes it take up
24 bytes (the minimum possible for a `SmallVec`). The variation axis
tags are stored as the `font_types::Tag` type, which I've chosen to
re-export from `epaint::text`.

The variation coordinates are resolved to a `skrifa::Location` during
font rendering/scaling, and are cached in the same way as all the other
scaled metrics. I've renamed the `ScaledMetrics` struct to
`StyledMetrics`, since it now also contains the resolved variation
coordinates. I haven't benchmarked the performance of text layout with
variation coordinates, but the existing text layout performance is
unchanged.

I've replaced the API for manually overriding a font's weight
(#7790) with an API for manually
overriding any variation coordinates via `FontTweak`. This should
support the same use case as #7790 while being substantially more
flexible.

I have *not* yet added any higher-level API for mapping style attributes
(weight, width, slant, etc) to variation coordinates or to different
font faces within a single family. That's a pretty huge can of worms,
and it'd involve rethinking the split between `FontId` and `TextFormat`
(and whether `FontId` is so big that we should provide a way to reuse
it). This API is intentionally pretty low-level for now.

Likewise, I've intentionally not used variation coordinates when
computing a font's row height. I can't think of any fonts that change
their vertical metrics depending on variation axes, so this should be
fine for now.

---------

Co-authored-by: Emil Ernerfeldt <[email protected]>
lucasmerlin pushed a commit that referenced this pull request Mar 6, 2026
<!--
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

This was mostly from last month, but I never got around to submitting
it.

This PR adds font variation coordinates to the `TextFormat` struct, and
uses them when rendering text. The coordinates are stored in a
`SmallVec`; I've chosen to store up to 2 inline, which makes it take up
24 bytes (the minimum possible for a `SmallVec`). The variation axis
tags are stored as the `font_types::Tag` type, which I've chosen to
re-export from `epaint::text`.

The variation coordinates are resolved to a `skrifa::Location` during
font rendering/scaling, and are cached in the same way as all the other
scaled metrics. I've renamed the `ScaledMetrics` struct to
`StyledMetrics`, since it now also contains the resolved variation
coordinates. I haven't benchmarked the performance of text layout with
variation coordinates, but the existing text layout performance is
unchanged.

I've replaced the API for manually overriding a font's weight
(#7790) with an API for manually
overriding any variation coordinates via `FontTweak`. This should
support the same use case as #7790 while being substantially more
flexible.

I have *not* yet added any higher-level API for mapping style attributes
(weight, width, slant, etc) to variation coordinates or to different
font faces within a single family. That's a pretty huge can of worms,
and it'd involve rethinking the split between `FontId` and `TextFormat`
(and whether `FontId` is so big that we should provide a way to reuse
it). This API is intentionally pretty low-level for now.

Likewise, I've intentionally not used variation coordinates when
computing a font's row height. I can't think of any fonts that change
their vertical metrics depending on variation axes, so this should be
fine for now.

---------

Co-authored-by: Emil Ernerfeldt <[email protected]>
Masterchef365 pushed a commit to Masterchef365/egui that referenced this pull request Apr 3, 2026
<!--
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

This was mostly from last month, but I never got around to submitting
it.

This PR adds font variation coordinates to the `TextFormat` struct, and
uses them when rendering text. The coordinates are stored in a
`SmallVec`; I've chosen to store up to 2 inline, which makes it take up
24 bytes (the minimum possible for a `SmallVec`). The variation axis
tags are stored as the `font_types::Tag` type, which I've chosen to
re-export from `epaint::text`.

The variation coordinates are resolved to a `skrifa::Location` during
font rendering/scaling, and are cached in the same way as all the other
scaled metrics. I've renamed the `ScaledMetrics` struct to
`StyledMetrics`, since it now also contains the resolved variation
coordinates. I haven't benchmarked the performance of text layout with
variation coordinates, but the existing text layout performance is
unchanged.

I've replaced the API for manually overriding a font's weight
(emilk#7790) with an API for manually
overriding any variation coordinates via `FontTweak`. This should
support the same use case as emilk#7790 while being substantially more
flexible.

I have *not* yet added any higher-level API for mapping style attributes
(weight, width, slant, etc) to variation coordinates or to different
font faces within a single family. That's a pretty huge can of worms,
and it'd involve rethinking the split between `FontId` and `TextFormat`
(and whether `FontId` is so big that we should provide a way to reuse
it). This API is intentionally pretty low-level for now.

Likewise, I've intentionally not used variation coordinates when
computing a font's row height. I can't think of any fonts that change
their vertical metrics depending on variation axes, so this should be
fine for now.

---------

Co-authored-by: Emil Ernerfeldt <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

egui epaint feature New feature or request text Problems related to text

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants