mirror of
https://github.com/emilk/egui.git
synced 2026-06-27 07:03:14 -04:00
Replace the character-by-character glyph lookup in `layout_section()` with a proper text shaping pipeline using harfrust (a Rust port of HarfBuzz). This enables GPOS kerning, ligatures (fi, fl), and correct positioning of combining diacritical marks. The shaping pipeline works as follows: 1. Split text into font-fallback runs (grapheme-cluster-aware) 2. Shape each run with harfrust (GSUB + GPOS) 3. Allocate and position glyphs from the shaping output Key changes: - Add harfrust, unicode-segmentation, unicode-general-category deps - Cache ShaperData on FontFace (parsed GSUB/GPOS tables) - Add shape_text() with buffer flags and variable font support - Add allocate_glyph_by_id() for shaper-produced glyph IDs - Recycle harfrust UnicodeBuffer across layout calls - Handle NOTDEF fallback (combining marks via unicode-general-category) Addresses #2517.
373 lines
13 KiB
TOML
373 lines
13 KiB
TOML
[workspace]
|
|
resolver = "2"
|
|
members = [
|
|
"crates/ecolor",
|
|
"crates/egui_demo_app",
|
|
"crates/egui_demo_lib",
|
|
"crates/egui_extras",
|
|
"crates/egui_glow",
|
|
"crates/egui_kittest",
|
|
"crates/egui-wgpu",
|
|
"crates/egui-winit",
|
|
"crates/egui",
|
|
"crates/emath",
|
|
"crates/epaint",
|
|
"crates/epaint_default_fonts",
|
|
|
|
"examples/*",
|
|
"tests/*",
|
|
|
|
"xtask",
|
|
]
|
|
|
|
[workspace.package]
|
|
edition = "2024"
|
|
license = "MIT OR Apache-2.0"
|
|
rust-version = "1.92"
|
|
version = "0.33.3"
|
|
|
|
|
|
[profile.release]
|
|
# lto = true # VERY slightly smaller wasm
|
|
# opt-level = 's' # 10-20% smaller wasm compared to `opt-level = 3`
|
|
# opt-level = 1 # very slow and big wasm. Don't do this.
|
|
opt-level = 2 # fast and small wasm, basically same as `opt-level = 's'`
|
|
# opt-level = 3 # unnecessarily large wasm for no performance gain
|
|
|
|
# debug = true # include debug symbols, useful when profiling wasm
|
|
|
|
panic = "abort" # This leads to better optimizations and smaller binaries (and is the default in Wasm anyways).
|
|
|
|
|
|
[profile.dev]
|
|
# Can't leave this on by default, because it breaks the Windows build. Related: https://github.com/rust-lang/cargo/issues/4897
|
|
# split-debuginfo = "unpacked" # faster debug builds on mac
|
|
# opt-level = 1 # Make debug builds run faster
|
|
|
|
# panic = "abort" leads to better optimizations and smaller binaries (and is the default in Wasm anyways),
|
|
# but it also means backtraces don't work with the `backtrace` library (https://github.com/rust-lang/backtrace-rs/issues/397).
|
|
# egui has a feature where if you hold down all modifiers keys on your keyboard and hover any UI widget,
|
|
# you will see the backtrace to that widget, and we don't want to break that feature in dev builds.
|
|
|
|
[profile.dev.package."*"]
|
|
# Optimize all dependencies even in debug builds (does not affect workspace packages):
|
|
opt-level = 2
|
|
|
|
|
|
[workspace.dependencies]
|
|
emath = { version = "0.33.3", path = "crates/emath", default-features = false }
|
|
ecolor = { version = "0.33.3", path = "crates/ecolor", default-features = false }
|
|
epaint = { version = "0.33.3", path = "crates/epaint", default-features = false }
|
|
epaint_default_fonts = { version = "0.33.3", path = "crates/epaint_default_fonts" }
|
|
egui = { version = "0.33.3", path = "crates/egui", default-features = false }
|
|
egui-winit = { version = "0.33.3", path = "crates/egui-winit", default-features = false }
|
|
egui_extras = { version = "0.33.3", path = "crates/egui_extras", default-features = false }
|
|
egui-wgpu = { version = "0.33.3", path = "crates/egui-wgpu", default-features = false }
|
|
egui_demo_lib = { version = "0.33.3", path = "crates/egui_demo_lib", default-features = false }
|
|
egui_glow = { version = "0.33.3", path = "crates/egui_glow", default-features = false }
|
|
egui_kittest = { version = "0.33.3", path = "crates/egui_kittest", default-features = false }
|
|
eframe = { version = "0.33.3", path = "crates/eframe", default-features = false }
|
|
|
|
accesskit = "0.24.0"
|
|
accesskit_consumer = "0.35.0"
|
|
accesskit_winit = "0.32.0"
|
|
ahash = { version = "0.8.12", default-features = false, features = [
|
|
"no-rng", # we don't need DOS-protection, so we let users opt-in to it instead
|
|
"std",
|
|
] }
|
|
android_logger = "0.15.1"
|
|
arboard = { version = "3.6.1", default-features = false }
|
|
backtrace = "0.3.76"
|
|
bitflags = "2.9.4"
|
|
bytemuck = "1.24.0"
|
|
cint = "0.3.1"
|
|
color-hex = "0.2.0"
|
|
criterion = { version = "0.7.0", default-features = false }
|
|
dify = { version = "0.8", default-features = false }
|
|
directories = "6.0.0"
|
|
document-features = "0.2.11"
|
|
ehttp = { version = "0.7.1", default-features = false }
|
|
enum-map = "2.7.3"
|
|
env_logger = { version = "0.11.8", default-features = false }
|
|
font-types = { version = "0.11.0", default-features = false, features = ["std"] }
|
|
harfrust = "0.5.2"
|
|
unicode-general-category = "1.1.0"
|
|
glow = "0.17.0"
|
|
glutin = { version = "0.32.3", default-features = false }
|
|
glutin-winit = { version = "0.5.0", default-features = false }
|
|
home = "0.5.9"
|
|
image = { version = "0.25.6", default-features = false }
|
|
jiff = { version = "0.2.23", default-features = false }
|
|
js-sys = "0.3.77"
|
|
kittest = { version = "0.4.0" }
|
|
log = { version = "0.4.28", features = ["std"] }
|
|
memoffset = "0.9.1"
|
|
mimalloc = "0.1.48"
|
|
mime_guess2 = { version = "2.3.1", default-features = false }
|
|
mint = "0.5.9"
|
|
nohash-hasher = "0.2.0"
|
|
objc2 = "0.6.4"
|
|
objc2-app-kit = { version = "0.3.2", default-features = false }
|
|
objc2-foundation = { version = "0.3.2", default-features = false }
|
|
objc2-ui-kit = { version = "0.3.2", default-features = false }
|
|
open = "5.3.2"
|
|
parking_lot = "0.12.5"
|
|
percent-encoding = "2.3.2"
|
|
poll-promise = { version = "0.3.0", default-features = false }
|
|
pollster = "0.4.0"
|
|
profiling = { version = "1.0.17", default-features = false }
|
|
puffin = "0.19.1"
|
|
puffin_http = "0.16.1"
|
|
rand = "0.9.2"
|
|
raw-window-handle = "0.6.2"
|
|
rayon = "1.11.0"
|
|
resvg = { version = "0.45.1", default-features = false }
|
|
rfd = "0.17.2"
|
|
ron = "0.12.0"
|
|
self_cell = "1.2.1"
|
|
serde = { version = "1.0.228", features = ["derive"] }
|
|
similar-asserts = "1.7.0"
|
|
skrifa = { version = "0.40.0", default-features = false, features = ["std", "autohint_shaping"] }
|
|
smallvec = "1.15.1"
|
|
smithay-clipboard = "0.7.2"
|
|
static_assertions = "1.1.0"
|
|
syntect = { version = "5.3.0", default-features = false }
|
|
tempfile = "3.23.0"
|
|
thiserror = "2.0.17"
|
|
tokio = "1.49"
|
|
toml = {version = "1.0.0", default-features = false }
|
|
type-map = "0.5.1"
|
|
unicode_names2 = { version = "2.0.0", default-features = false }
|
|
unicode-segmentation = "1.12.0"
|
|
vello_cpu = { version = "0.0.6", default-features = false, features = ["std", "u8_pipeline", "f32_pipeline"] }
|
|
wasm-bindgen = "0.2.108" # Keep wasm-bindgen version in sync in: setup_web.sh, Cargo.toml, Cargo.lock, rust.yml. Don't update this spuriously, because of https://github.com/rerun-io/rerun/issues/8766
|
|
wasm-bindgen-futures = "0.4.58"
|
|
wayland-cursor = { version = "0.31.11", default-features = false }
|
|
web-sys = "0.3.77"
|
|
web-time = "1.1.0" # Timekeeping for native and web
|
|
webbrowser = "1.0.5"
|
|
wgpu = { version = "29.0.0", default-features = false, features = ["std"] }
|
|
windows-sys = "0.61.2"
|
|
winit = { version = "0.30.13", default-features = false }
|
|
|
|
[workspace.lints.rust]
|
|
unsafe_code = "deny"
|
|
|
|
elided_lifetimes_in_paths = "warn"
|
|
future_incompatible = { level = "warn", priority = -1 }
|
|
nonstandard_style = { level = "warn", priority = -1 }
|
|
rust_2018_idioms = { level = "warn", priority = -1 }
|
|
rust_2021_prelude_collisions = "warn"
|
|
semicolon_in_expressions_from_macros = "warn"
|
|
trivial_numeric_casts = "warn"
|
|
unexpected_cfgs = "warn"
|
|
unsafe_op_in_unsafe_fn = "warn" # `unsafe_op_in_unsafe_fn` may become the default in future Rust versions: https://github.com/rust-lang/rust/issues/71668
|
|
unused_extern_crates = "warn"
|
|
unused_import_braces = "warn"
|
|
unused_lifetimes = "warn"
|
|
|
|
trivial_casts = "allow"
|
|
unused_qualifications = "allow"
|
|
|
|
[workspace.lints.rustdoc]
|
|
all = "warn"
|
|
missing_crate_level_docs = "warn"
|
|
broken_intra_doc_links = "warn"
|
|
|
|
# See also clippy.toml
|
|
[workspace.lints.clippy]
|
|
all = { level = "warn", priority = -1 }
|
|
|
|
allow_attributes = "warn"
|
|
as_ptr_cast_mut = "warn"
|
|
await_holding_lock = "warn"
|
|
bool_to_int_with_if = "warn"
|
|
branches_sharing_code = "warn"
|
|
char_lit_as_u8 = "warn"
|
|
checked_conversions = "warn"
|
|
clear_with_drain = "warn"
|
|
clone_on_ref_ptr = "warn"
|
|
cloned_instead_of_copied = "warn"
|
|
coerce_container_to_any = "warn"
|
|
dbg_macro = "warn"
|
|
debug_assert_with_mut_call = "warn"
|
|
default_union_representation = "warn"
|
|
derive_partial_eq_without_eq = "warn"
|
|
disallowed_macros = "warn" # See clippy.toml
|
|
disallowed_methods = "warn" # See clippy.toml
|
|
disallowed_names = "warn" # See clippy.toml
|
|
disallowed_script_idents = "warn" # See clippy.toml
|
|
disallowed_types = "warn" # See clippy.toml
|
|
doc_broken_link = "warn"
|
|
doc_comment_double_space_linebreaks = "warn"
|
|
doc_include_without_cfg = "warn"
|
|
doc_link_with_quotes = "warn"
|
|
doc_markdown = "warn"
|
|
elidable_lifetime_names = "warn"
|
|
empty_enum = "warn"
|
|
empty_enum_variants_with_brackets = "warn"
|
|
empty_line_after_outer_attr = "warn"
|
|
enum_glob_use = "warn"
|
|
equatable_if_let = "warn"
|
|
exit = "warn"
|
|
expl_impl_clone_on_copy = "warn"
|
|
explicit_deref_methods = "warn"
|
|
explicit_into_iter_loop = "warn"
|
|
explicit_iter_loop = "warn"
|
|
fallible_impl_from = "warn"
|
|
filter_map_next = "warn"
|
|
flat_map_option = "warn"
|
|
float_cmp_const = "warn"
|
|
fn_params_excessive_bools = "warn"
|
|
fn_to_numeric_cast_any = "warn"
|
|
from_iter_instead_of_collect = "warn"
|
|
get_unwrap = "warn"
|
|
if_let_mutex = "warn"
|
|
ignore_without_reason = "warn"
|
|
implicit_clone = "warn"
|
|
implied_bounds_in_impls = "warn"
|
|
imprecise_flops = "warn"
|
|
inconsistent_struct_constructor = "warn"
|
|
index_refutable_slice = "warn"
|
|
inefficient_to_string = "warn"
|
|
infinite_loop = "warn"
|
|
into_iter_without_iter = "warn"
|
|
invalid_upcast_comparisons = "warn"
|
|
ip_constant = "warn"
|
|
iter_filter_is_ok = "warn"
|
|
iter_filter_is_some = "warn"
|
|
iter_not_returning_iterator = "warn"
|
|
iter_on_empty_collections = "warn"
|
|
iter_on_single_items = "warn"
|
|
iter_over_hash_type = "warn"
|
|
iter_without_into_iter = "warn"
|
|
large_digit_groups = "warn"
|
|
large_futures = "warn"
|
|
large_include_file = "warn"
|
|
large_stack_arrays = "warn"
|
|
large_stack_frames = "warn"
|
|
large_types_passed_by_value = "warn"
|
|
let_unit_value = "warn"
|
|
linkedlist = "warn"
|
|
literal_string_with_formatting_args = "warn"
|
|
lossy_float_literal = "warn"
|
|
macro_use_imports = "warn"
|
|
manual_assert = "warn"
|
|
manual_clamp = "warn"
|
|
manual_instant_elapsed = "warn"
|
|
manual_is_power_of_two = "warn"
|
|
manual_is_variant_and = "warn"
|
|
manual_let_else = "warn"
|
|
manual_midpoint = "warn" # NOTE `midpoint` is often a lot slower for floats, so we have our own `emath::fast_midpoint` function.
|
|
manual_ok_or = "warn"
|
|
manual_string_new = "warn"
|
|
map_err_ignore = "warn"
|
|
map_flatten = "warn"
|
|
match_bool = "warn"
|
|
match_same_arms = "warn"
|
|
match_wild_err_arm = "warn"
|
|
match_wildcard_for_single_variants = "warn"
|
|
mem_forget = "warn"
|
|
mismatching_type_param_order = "warn"
|
|
missing_assert_message = "warn"
|
|
missing_enforced_import_renames = "warn"
|
|
missing_errors_doc = "warn"
|
|
missing_safety_doc = "warn"
|
|
mixed_attributes_style = "warn"
|
|
mut_mut = "warn"
|
|
mutex_integer = "warn"
|
|
needless_borrow = "warn"
|
|
needless_continue = "warn"
|
|
needless_for_each = "warn"
|
|
needless_pass_by_ref_mut = "warn"
|
|
needless_pass_by_value = "warn"
|
|
negative_feature_names = "warn"
|
|
non_std_lazy_statics = "warn"
|
|
non_zero_suggestions = "warn"
|
|
nonstandard_macro_braces = "warn"
|
|
option_as_ref_cloned = "warn"
|
|
option_option = "warn"
|
|
or_fun_call = "warn"
|
|
path_buf_push_overwrite = "warn"
|
|
pathbuf_init_then_push = "warn"
|
|
precedence_bits = "warn"
|
|
print_stderr = "warn"
|
|
print_stdout = "warn"
|
|
ptr_as_ptr = "warn"
|
|
ptr_cast_constness = "warn"
|
|
pub_underscore_fields = "warn"
|
|
pub_without_shorthand = "warn"
|
|
rc_mutex = "warn"
|
|
readonly_write_lock = "warn"
|
|
redundant_type_annotations = "warn"
|
|
ref_as_ptr = "warn"
|
|
ref_option_ref = "warn"
|
|
ref_patterns = "warn"
|
|
rest_pat_in_fully_bound_structs = "warn"
|
|
return_and_then = "warn"
|
|
same_functions_in_if_condition = "warn"
|
|
self_only_used_in_recursion = "warn"
|
|
semicolon_if_nothing_returned = "warn"
|
|
set_contains_or_insert = "warn"
|
|
single_char_pattern = "warn"
|
|
single_match_else = "warn"
|
|
single_option_map = "warn"
|
|
str_split_at_newline = "warn"
|
|
str_to_string = "warn"
|
|
string_add = "warn"
|
|
string_add_assign = "warn"
|
|
string_lit_as_bytes = "warn"
|
|
string_lit_chars_any = "warn"
|
|
suspicious_command_arg_space = "warn"
|
|
suspicious_xor_used_as_pow = "warn"
|
|
todo = "warn"
|
|
too_long_first_doc_paragraph = "warn"
|
|
trailing_empty_array = "warn"
|
|
trait_duplication_in_bounds = "warn"
|
|
transmute_ptr_to_ptr = "warn"
|
|
tuple_array_conversions = "warn"
|
|
unchecked_time_subtraction = "warn"
|
|
undocumented_unsafe_blocks = "warn"
|
|
unimplemented = "warn"
|
|
uninhabited_references = "warn"
|
|
uninlined_format_args = "warn"
|
|
unnecessary_box_returns = "warn"
|
|
unnecessary_debug_formatting = "warn"
|
|
unnecessary_literal_bound = "warn"
|
|
unnecessary_safety_comment = "warn"
|
|
unnecessary_safety_doc = "warn"
|
|
unnecessary_self_imports = "warn"
|
|
unnecessary_semicolon = "warn"
|
|
unnecessary_struct_initialization = "warn"
|
|
unnecessary_wraps = "warn"
|
|
unnested_or_patterns = "warn"
|
|
unused_async = "warn"
|
|
unused_peekable = "warn"
|
|
unused_rounding = "warn"
|
|
unused_self = "warn"
|
|
unused_trait_names = "warn"
|
|
unwrap_used = "warn"
|
|
use_self = "warn"
|
|
useless_let_if_seq = "warn"
|
|
useless_transmute = "warn"
|
|
verbose_file_reads = "warn"
|
|
wildcard_dependencies = "warn"
|
|
zero_sized_map_values = "warn"
|
|
|
|
|
|
# TODO(emilk): maybe enable more of these lints?
|
|
cast_possible_wrap = "allow"
|
|
comparison_chain = "allow"
|
|
should_panic_without_expect = "allow"
|
|
too_many_lines = "allow"
|
|
|
|
# These are meh:
|
|
assigning_clones = "allow" # No please
|
|
let_underscore_must_use = "allow"
|
|
let_underscore_untyped = "allow"
|
|
manual_range_contains = "allow" # this one is just worse imho
|
|
map_unwrap_or = "allow" # so is this one
|
|
self_named_module_files = "allow" # Disabled waiting on https://github.com/rust-lang/rust-clippy/issues/9602
|
|
significant_drop_tightening = "allow" # Too many false positives
|
|
wildcard_imports = "allow" # `use crate::*` is useful to avoid merge conflicts when adding/removing imports
|