Skip to content

Commit 26d52dc

Browse files
committed
Reduce the amount of FontDefinitions cloning
1 parent 5b846b4 commit 26d52dc

File tree

7 files changed

+26
-29
lines changed

7 files changed

+26
-29
lines changed

crates/egui/src/context.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ struct ContextImpl {
401401
/// This is because the `Fonts` depend on `pixels_per_point` for the font atlas
402402
/// as well as kerning, font sizes, etc.
403403
fonts: std::collections::BTreeMap<OrderedFloat<f32>, Fonts>,
404-
font_definitions: FontDefinitions,
404+
font_definitions: Arc<FontDefinitions>,
405405

406406
memory: Memory,
407407
animation_manager: AnimationManager,
@@ -583,22 +583,21 @@ impl ContextImpl {
583583
}
584584

585585
if !self.memory.add_fonts.is_empty() {
586+
// Recreate all the fonts
587+
self.fonts.clear();
588+
let mut font_definitions = self.font_definitions.as_ref().clone();
586589
let fonts = self.memory.add_fonts.drain(..);
587590
for font in fonts {
588-
self.fonts.clear(); // recreate all the fonts
589591
for family in font.families {
590-
let fam = self
591-
.font_definitions
592-
.families
593-
.entry(family.family)
594-
.or_default();
592+
let fam = font_definitions.families.entry(family.family).or_default();
595593
match family.priority {
596594
FontPriority::Highest => fam.insert(0, font.name.clone()),
597595
FontPriority::Lowest => fam.push(font.name.clone()),
598596
}
599597
}
600-
self.font_definitions.font_data.insert(font.name, font.data);
598+
font_definitions.font_data.insert(font.name, font.data);
601599
}
600+
self.font_definitions = Arc::new(font_definitions);
602601

603602
#[cfg(feature = "log")]
604603
log::trace!("Adding new fonts");
@@ -1750,7 +1749,7 @@ impl Context {
17501749
///
17511750
/// The new fonts will become active at the start of the next pass.
17521751
/// This will overwrite the existing fonts.
1753-
pub fn set_fonts(&self, font_definitions: FontDefinitions) {
1752+
pub fn set_fonts(&self, font_definitions: Arc<FontDefinitions>) {
17541753
crate::profile_function!();
17551754

17561755
let pixels_per_point = self.pixels_per_point();
@@ -1760,7 +1759,7 @@ impl Context {
17601759
self.read(|ctx| {
17611760
if let Some(current_fonts) = ctx.fonts.get(&pixels_per_point.into()) {
17621761
// NOTE: this comparison is expensive since it checks TTF data for equality
1763-
if current_fonts.lock().fonts.definitions() == &font_definitions {
1762+
if current_fonts.lock().fonts.definitions() == font_definitions.as_ref() {
17641763
update_fonts = false; // no need to update
17651764
}
17661765
}
@@ -2935,7 +2934,7 @@ impl Context {
29352934
}
29362935

29372936
fn fonts_tweak_ui(&self, ui: &mut Ui) {
2938-
let mut font_definitions = self.write(|ctx| ctx.font_definitions.clone());
2937+
let mut font_definitions = self.write(|ctx| ctx.font_definitions.as_ref().clone());
29392938
let mut changed = false;
29402939

29412940
for (name, data) in &mut font_definitions.font_data {
@@ -2947,7 +2946,7 @@ impl Context {
29472946
}
29482947

29492948
if changed {
2950-
self.set_fonts(font_definitions);
2949+
self.set_fonts(Arc::new(font_definitions));
29512950
}
29522951
}
29532952

crates/egui/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ pub enum WidgetType {
667667
/// For use in tests; especially doctests.
668668
pub fn __run_test_ctx(mut run_ui: impl FnMut(&Context)) {
669669
let ctx = Context::default();
670-
ctx.set_fonts(FontDefinitions::empty()); // prevent fonts from being loaded (save CPU time)
670+
ctx.set_fonts(Arc::new(FontDefinitions::empty())); // prevent fonts from being loaded (save CPU time)
671671
let _ = ctx.run(Default::default(), |ctx| {
672672
run_ui(ctx);
673673
});
@@ -676,7 +676,7 @@ pub fn __run_test_ctx(mut run_ui: impl FnMut(&Context)) {
676676
/// For use in tests; especially doctests.
677677
pub fn __run_test_ui(add_contents: impl Fn(&mut Ui)) {
678678
let ctx = Context::default();
679-
ctx.set_fonts(FontDefinitions::empty()); // prevent fonts from being loaded (save CPU time)
679+
ctx.set_fonts(Arc::new(FontDefinitions::empty())); // prevent fonts from being loaded (save CPU time)
680680
let _ = ctx.run(Default::default(), |ctx| {
681681
crate::CentralPanel::default().show(ctx, |ui| {
682682
add_contents(ui);

crates/egui/src/memory/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ pub struct Memory {
7777
// ------------------------------------------
7878
/// new fonts that will be applied at the start of the next frame
7979
#[cfg_attr(feature = "persistence", serde(skip))]
80-
pub(crate) new_font_definitions: Option<epaint::text::FontDefinitions>,
80+
pub(crate) new_font_definitions: Option<std::sync::Arc<epaint::text::FontDefinitions>>,
8181

8282
/// add new font that will be applied at the start of the next frame
8383
#[cfg_attr(feature = "persistence", serde(skip))]

crates/egui_demo_lib/benches/benchmark.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,8 @@ pub fn criterion_benchmark(c: &mut Criterion) {
9090
let wrap_width = 512.0;
9191
let font_id = egui::FontId::default();
9292
let text_color = egui::Color32::WHITE;
93-
let fonts = egui::epaint::text::Fonts::new(
94-
pixels_per_point,
95-
max_texture_side,
96-
egui::FontDefinitions::default(),
97-
);
93+
let fonts =
94+
egui::epaint::text::Fonts::new(pixels_per_point, max_texture_side, Default::default());
9895
{
9996
let mut locked_fonts = fonts.lock();
10097
c.bench_function("text_layout_uncached", |b| {

crates/epaint/src/text/fonts.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ impl Fonts {
418418
pub fn new(
419419
pixels_per_point: f32,
420420
max_texture_side: usize,
421-
definitions: FontDefinitions,
421+
definitions: Arc<FontDefinitions>,
422422
) -> Self {
423423
let fonts_and_cache = FontsAndCache {
424424
fonts: FontsImpl::new(pixels_per_point, max_texture_side, definitions),
@@ -614,7 +614,7 @@ impl FontsAndCache {
614614
pub struct FontsImpl {
615615
pixels_per_point: f32,
616616
max_texture_side: usize,
617-
definitions: FontDefinitions,
617+
definitions: Arc<FontDefinitions>,
618618
atlas: Arc<Mutex<TextureAtlas>>,
619619
font_impl_cache: FontImplCache,
620620
sized_family: ahash::HashMap<(OrderedFloat<f32>, FontFamily), Font>,
@@ -626,7 +626,7 @@ impl FontsImpl {
626626
pub fn new(
627627
pixels_per_point: f32,
628628
max_texture_side: usize,
629-
definitions: FontDefinitions,
629+
definitions: Arc<FontDefinitions>,
630630
) -> Self {
631631
assert!(
632632
0.0 < pixels_per_point && pixels_per_point < 100.0,

crates/epaint/src/text/text_layout.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,7 +1042,7 @@ mod tests {
10421042

10431043
#[test]
10441044
fn test_zero_max_width() {
1045-
let mut fonts = FontsImpl::new(1.0, 1024, FontDefinitions::default());
1045+
let mut fonts = FontsImpl::new(1.0, 1024, Default::default());
10461046
let mut layout_job = LayoutJob::single_section("W".into(), TextFormat::default());
10471047
layout_job.wrap.max_width = 0.0;
10481048
let galley = layout(&mut fonts, layout_job.into());
@@ -1053,7 +1053,7 @@ mod tests {
10531053
fn test_truncate_with_newline() {
10541054
// No matter where we wrap, we should be appending the newline character.
10551055

1056-
let mut fonts = FontsImpl::new(1.0, 1024, FontDefinitions::default());
1056+
let mut fonts = FontsImpl::new(1.0, 1024, Default::default());
10571057
let text_format = TextFormat {
10581058
font_id: FontId::monospace(12.0),
10591059
..Default::default()
@@ -1098,7 +1098,7 @@ mod tests {
10981098

10991099
#[test]
11001100
fn test_cjk() {
1101-
let mut fonts = FontsImpl::new(1.0, 1024, FontDefinitions::default());
1101+
let mut fonts = FontsImpl::new(1.0, 1024, Default::default());
11021102
let mut layout_job = LayoutJob::single_section(
11031103
"日本語とEnglishの混在した文章".into(),
11041104
TextFormat::default(),
@@ -1113,7 +1113,7 @@ mod tests {
11131113

11141114
#[test]
11151115
fn test_pre_cjk() {
1116-
let mut fonts = FontsImpl::new(1.0, 1024, FontDefinitions::default());
1116+
let mut fonts = FontsImpl::new(1.0, 1024, Default::default());
11171117
let mut layout_job = LayoutJob::single_section(
11181118
"日本語とEnglishの混在した文章".into(),
11191119
TextFormat::default(),
@@ -1128,7 +1128,7 @@ mod tests {
11281128

11291129
#[test]
11301130
fn test_truncate_width() {
1131-
let mut fonts = FontsImpl::new(1.0, 1024, FontDefinitions::default());
1131+
let mut fonts = FontsImpl::new(1.0, 1024, Default::default());
11321132
let mut layout_job =
11331133
LayoutJob::single_section("# DNA\nMore text".into(), TextFormat::default());
11341134
layout_job.wrap.max_width = f32::INFINITY;

examples/custom_font/src/main.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use eframe::{
55
egui,
66
epaint::text::{FontInsert, InsertFontFamily},
77
};
8+
use std::sync::Arc;
89

910
fn main() -> eframe::Result {
1011
env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`).
@@ -68,7 +69,7 @@ fn replace_fonts(ctx: &egui::Context) {
6869
.push("my_font".to_owned());
6970

7071
// Tell egui to use these fonts:
71-
ctx.set_fonts(fonts);
72+
ctx.set_fonts(Arc::new(fonts));
7273
}
7374

7475
struct MyApp {

0 commit comments

Comments
 (0)