* Closes#4654
* Related #4667
* [x] I have followed the instructions in the PR template
This PR avoids materializing the contents of a file that was dragged
into an egui application on the web. It does so by storing the
`web_sys::File` handle directly on WASM.
This breaks the existing API of `DroppedFile` on the web, because there
is no way to retrieve the bytes synchronously form a `DroppedFile`
anymore, forcing handling call sites to become asynchronous.
The native API remains the same.
---------
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
Hi, I may or may not have used your crate but I'd like to say a quick
thank you for it anyway!
I'm going down the list of reverse dependencies on `memoffset`.
This PR aims to remove the `memoffset` crate from your dependencies.
[`core::mem::offset_of`](https://doc.rust-lang.org/core/mem/macro.offset_of.html)
was stabilised in rustc 1.77 which I believe is at or below your MSRV.
The `memoffset` crate 0.9.1 says that
> If you're using a rustc version greater or equal to 1.77,
> this crate's offset_of!() macro simply forwards to
core::mem::offset_of!().
I consider it very unlikely (see
[here](https://github.com/rust-lang/rust/issues/111839)) for any usage
of the `offset_of!` macro to break but please check anyway.
I hope we can all enjoy the benefits of one less dependency :)
---
<!--
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!
-->
* [x] I have followed the instructions in the PR template *except for
`./scripts/check.sh` which doesn't run in my environment* (I'm unwilling
to chase it down because I'm firing off a whole bunch of these PRs to
various repositories, sorry.)
`cargo clippy` gives 1 unrelated warning.
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
Replaces `home::home_dir` with `std::env::home_dir` as these functions
do the exact same thing
<!--
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!
-->
Removes dependency home from eframe by replacing `home::home_dir` with
`std::env::home_dir`. `home` was probably originally used since
`std::env::home_dir` was once deprecated because of a bug. Post Rust
version 1.87 this has been fixed and now these two functions do exactly
the same thing.
* [X] I have followed the instructions in the PR template
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
Semver-compatible dependency updates (~200 transitive crates in
`Cargo.lock`), plus housekeeping of the version pins in `Cargo.toml`.
## Changes
* Normalize version strings in `[workspace.dependencies]`
(`similar-asserts = "2.0"`, `unicode_names2 = "3.1"`)
* `cargo update`: bump all semver-compatible transitive dependencies
* `itertools` 0.14 → 0.15; the duplicate with puffin's 0.14 /
criterion's 0.13 is now allowed in `deny.toml`
* `rand_core` duplicate (0.6 via phf_generator's rand 0.8, 0.10 via
getrandom 0.4/chacha20) also allowed in `deny.toml` — rand ecosystem is
mid-migration
* `toml` lock moved to 1.1.2 — the old winnow-duplicate blocker is gone
(winit's `toml_edit` now uses winnow 1.x), so the stale comment is
removed
* `wgpu` got a lock-only patch bump 29.0.1 → 29.0.4 (still on the 29.x
line; wgpu 30 intentionally not taken)
## Held back (would fail `cargo deny` with duplicate crates)
* `env_logger` 0.11.8 — newer pulls env_filter 1.x, duplicating the
0.1.x that android_logger needs
* `image` 0.25.6 — needs png 0.18, blocked on resvg
* `smithay-clipboard` 0.7.2 — pulls calloop 0.14, duplicating winit's
0.13
* accesskit platform adapters — newer ones need accesskit_consumer
0.36/0.37, duplicating the 0.35 that kittest 0.4 pins (comments added
for `accesskit_consumer`/`accesskit_winit`)
* wasm-bindgen family kept at 0.2.108 per the sync comment
Majors still blocked (documented in `Cargo.toml`):
`font-types`/`skrifa`/`harfrust` (vello_cpu 0.0.9), `resvg` (winit
0.30).
Verified: `scripts/cargo_deny.sh` green on all targets, `cargo clippy
--all-features --all-targets` clean.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
When an agent screenshots the app using the mcp and then interacts with
the app by clicking at coords, they see the coords in the native image
coords. Since the mcp does everything else in logical coordinates, it
helps if the image they see is also in logical resoltution, so we always
downscale it to 1.0.
I've added this here to avioid having to decode and re-encode the image
in the mcp.
Unfortunately it only does downscaling for now, since adding some way to
upscale the image just for the screenshot would add a lot of complexity,
and might be invasive from a plugin.
I've also changed the submit call to take a closure, to make it easier
to use other transport channel (makes the implementation for reruns mcp
nicer).
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Lucas Meurer <lucas@rerun.io>
Introduces live inspection for running egui apps over a small TCP
request/response protocol, plus the `egui::Plugin` that serves it.
This is the minimal surface to get the egui mcp in, we may want to
extend this in the future to add support for the inspection gui.
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Related to #56 (Improve text — tracking issue)
## Summary
This PR integrates [harfrust](https://crates.io/crates/harfrust) (a
pure-Rust port of HarfBuzz) into epaint's text layout pipeline,
replacing the character-by-character glyph positioning with proper
OpenType text shaping.
### What this enables
- **GPOS kerning**: most modern fonts only ship kerning in GPOS tables
(not the legacy `kern` table). Pairs like "AV", "VA", "AT" are now
properly tightened.
- **GSUB substitutions**: ligatures (fi, fl), contextual alternates, and
other OpenType features.
- **Combining marks**: diacritics (e.g. ɔ̃) are positioned via anchor
tables instead of being rendered as standalone replacement glyphs.
### Before/After
#### Kerning, etc.
<img width="838" height="726" alt="before_main"
src="https://github.com/user-attachments/assets/f0f26d5f-b117-43a6-b39c-ea40d2e73836"
/>
<img width="838" height="726" alt="after_harfrust"
src="https://github.com/user-attachments/assets/d983e5da-486c-4f39-bd4f-5782a90c6b39"
/>
#### Ligatures
<img width="1117" height="698" alt="before_closeup"
src="https://github.com/user-attachments/assets/7a3b08b4-cf6f-45b7-98ba-07c473cd3b02"
/>
<img width="1117" height="698" alt="after_closeup"
src="https://github.com/user-attachments/assets/6cfc5f21-d32f-4f09-be0c-59c8c553d44f"
/>
### Architecture
The shaping integrates into the existing pipeline without changing the
public API:
1. **`Font::segment_into_runs`** — segments text into contiguous runs by
font face (grapheme-cluster aware, never splits combining sequences)
2. **`FontFace::shape_text`** — calls harfrust to shape each run,
returning glyph IDs + positioned advances/offsets
3. **`layout_shaped_run`** — emits `Glyph` structs from the shaping
output, with NOTDEF fallback to other font faces for missing glyphs
4. **Buffer recycling** — `FontsImpl` pools a `harfrust::UnicodeBuffer`
to avoid per-layout allocations
### Disclaimer
I'm far from being a good Rust programmer. Claude Code did most of the
heavy lifting here. I did my best and used my limited knowledge to avoid
making too many mistakes. If this PR isn't up to quality standards,
please don't hesitate to close it.
## Test plan
- [x] `cargo test -p epaint` — all 18 text tests pass, including 6 new
ones
- [x] `cargo clippy -p epaint --all-features` — clean
- [x] `cargo fmt` — clean
- [ ] Snapshot tests need regeneration (expected: shaping changes glyph
positions)
- New tests added:
- `test_gpos_kerning` — verifies GPOS kerning tightens "AV", "VA", "AT"
pairs
- `test_combining_diacritics` — combining tilde doesn't add extra width
- `test_shaping_basic_latin` — sanity check for Latin text
- `test_shaping_empty_string` — empty input doesn't panic
- `test_shaping_multiple_newlines` — newline splitting works correctly
- `test_shaping_mixed_font_fallback` — Latin + emoji in same string
---------
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
<!--
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!
-->
Update some dependencies to get rid of old ones (especially nice to get
rid of windows-sys 0.45...).
* Closes <https://github.com/emilk/egui/issues/THE_RELEVANT_ISSUE>
* [x] I have followed the instructions in the PR template
* Fix for https://github.com/emilk/eframe_template/issues/223
* Related: https://github.com/gfx-rs/wgpu/pull/9319
By default, we would only turn on the WebGPU backend on web, which means
browsers without WebGPU support would just crash.
You can still opt-out of all the default `wgpu` features by enabling
`eframe/wgpu_no_default_features` instead of `eframe/wgpu`
* [x] I have followed the instructions in the PR template
This updates wgpu to v29 across the egui crate stack.
There a a few API changes due to the requirement to provide a display
handle up front to properly support GLES on linux. I have done my best
to make the api changes as reasonable as possible, but I don't have all
the greater project context, so lmk if things should be done a bit
differently.
I've also updated glow to 0.17 to make cargo deny happy, there are no
source changes. I'm not sure how you want to land these.
---------
Co-authored-by: lucasmerlin <hi@lucasmerlin.me>
<!--
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
(https://github.com/emilk/egui/pull/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 <emil.ernerfeldt@gmail.com>
<!--
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!
-->
* [x] I have followed the instructions in the PR template
A number of separate commits to possibly easily revert some of them.
General idea: selectively update dependencies to remove transitive
dependencies and multiple versions etc. As well as updating "major" (the
one that `cargo update` doesn't update) version for some in Cargo.toml.
Rendering pipelines in `vello_cpu` wasn't obvious. Now both are used.
<!--
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>