Skip to content

Commit 97fe124

Browse files
lucasmerlinemilk
authored andcommitted
Fix WidgetText::Text ignoring fallback font and overrides (#7361)
* closes #7356
1 parent 4fcd1d1 commit 97fe124

6 files changed

Lines changed: 55 additions & 14 deletions

File tree

crates/egui/src/atomics/atom.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{AtomKind, Id, SizedAtom, Ui};
1+
use crate::{AtomKind, FontSelection, Id, SizedAtom, Ui};
22
use emath::{NumExt as _, Vec2};
33
use epaint::text::TextWrapMode;
44

@@ -69,6 +69,7 @@ impl<'a> Atom<'a> {
6969
ui: &Ui,
7070
mut available_size: Vec2,
7171
mut wrap_mode: Option<TextWrapMode>,
72+
fallback_font: FontSelection,
7273
) -> SizedAtom<'a> {
7374
if !self.shrink && self.max_size.x.is_infinite() {
7475
wrap_mode = Some(TextWrapMode::Extend);
@@ -81,7 +82,9 @@ impl<'a> Atom<'a> {
8182
wrap_mode = Some(TextWrapMode::Truncate);
8283
}
8384

84-
let (intrinsic, kind) = self.kind.into_sized(ui, available_size, wrap_mode);
85+
let (intrinsic, kind) = self
86+
.kind
87+
.into_sized(ui, available_size, wrap_mode, fallback_font);
8588

8689
let size = self
8790
.size

crates/egui/src/atomics/atom_kind.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{Id, Image, ImageSource, SizedAtomKind, TextStyle, Ui, WidgetText};
1+
use crate::{FontSelection, Id, Image, ImageSource, SizedAtomKind, Ui, WidgetText};
22
use emath::Vec2;
33
use epaint::text::TextWrapMode;
44

@@ -78,12 +78,12 @@ impl<'a> AtomKind<'a> {
7878
ui: &Ui,
7979
available_size: Vec2,
8080
wrap_mode: Option<TextWrapMode>,
81+
fallback_font: FontSelection,
8182
) -> (Vec2, SizedAtomKind<'a>) {
8283
match self {
8384
AtomKind::Text(text) => {
8485
let wrap_mode = wrap_mode.unwrap_or(ui.wrap_mode());
85-
let galley =
86-
text.into_galley(ui, Some(wrap_mode), available_size.x, TextStyle::Button);
86+
let galley = text.into_galley(ui, Some(wrap_mode), available_size.x, fallback_font);
8787
(galley.intrinsic_size(), SizedAtomKind::Text(galley))
8888
}
8989
AtomKind::Image(image) => {

crates/egui/src/atomics/atom_layout.rs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::atomics::ATOMS_SMALL_VEC_SIZE;
22
use crate::{
3-
AtomKind, Atoms, Frame, Id, Image, IntoAtoms, Response, Sense, SizedAtom, SizedAtomKind, Ui,
4-
Widget,
3+
AtomKind, Atoms, FontSelection, Frame, Id, Image, IntoAtoms, Response, Sense, SizedAtom,
4+
SizedAtomKind, Ui, Widget,
55
};
66
use emath::{Align2, GuiRounding as _, NumExt as _, Rect, Vec2};
77
use epaint::text::TextWrapMode;
@@ -36,6 +36,7 @@ pub struct AtomLayout<'a> {
3636
pub(crate) frame: Frame,
3737
pub(crate) sense: Sense,
3838
fallback_text_color: Option<Color32>,
39+
fallback_font: Option<FontSelection>,
3940
min_size: Vec2,
4041
wrap_mode: Option<TextWrapMode>,
4142
align2: Option<Align2>,
@@ -56,6 +57,7 @@ impl<'a> AtomLayout<'a> {
5657
frame: Frame::default(),
5758
sense: Sense::hover(),
5859
fallback_text_color: None,
60+
fallback_font: None,
5961
min_size: Vec2::ZERO,
6062
wrap_mode: None,
6163
align2: None,
@@ -94,6 +96,13 @@ impl<'a> AtomLayout<'a> {
9496
self
9597
}
9698

99+
/// Set the fallback (default) font.
100+
#[inline]
101+
pub fn fallback_font(mut self, font: impl Into<FontSelection>) -> Self {
102+
self.fallback_font = Some(font.into());
103+
self
104+
}
105+
97106
/// Set the minimum size of the Widget.
98107
///
99108
/// This will find and expand atoms with `grow: true`.
@@ -154,8 +163,11 @@ impl<'a> AtomLayout<'a> {
154163
min_size,
155164
wrap_mode,
156165
align2,
166+
fallback_font,
157167
} = self;
158168

169+
let fallback_font = fallback_font.unwrap_or_default();
170+
159171
let wrap_mode = wrap_mode.unwrap_or(ui.wrap_mode());
160172

161173
// If the TextWrapMode is not Extend, ensure there is some item marked as `shrink`.
@@ -220,7 +232,12 @@ impl<'a> AtomLayout<'a> {
220232
continue;
221233
}
222234
}
223-
let sized = item.into_sized(ui, available_inner_size, Some(wrap_mode));
235+
let sized = item.into_sized(
236+
ui,
237+
available_inner_size,
238+
Some(wrap_mode),
239+
fallback_font.clone(),
240+
);
224241
let size = sized.size;
225242

226243
desired_width += size.x;
@@ -239,7 +256,12 @@ impl<'a> AtomLayout<'a> {
239256
available_inner_size.y,
240257
);
241258

242-
let sized = item.into_sized(ui, available_size_for_shrink_item, Some(wrap_mode));
259+
let sized = item.into_sized(
260+
ui,
261+
available_size_for_shrink_item,
262+
Some(wrap_mode),
263+
fallback_font,
264+
);
243265
let size = sized.size;
244266

245267
desired_width += size.x;

crates/egui/src/style.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ impl TextStyle {
121121
// ----------------------------------------------------------------------------
122122

123123
/// A way to select [`FontId`], either by picking one directly or by using a [`TextStyle`].
124+
#[derive(Debug, Clone)]
124125
pub enum FontSelection {
125126
/// Default text style - will use [`TextStyle::Body`], unless
126127
/// [`Style::override_font_id`] or [`Style::override_text_style`] is set.
@@ -141,15 +142,26 @@ impl Default for FontSelection {
141142
}
142143

143144
impl FontSelection {
145+
/// Resolve to a [`FontId`].
146+
///
147+
/// On [`Self::Default`] and no override in the style, this will
148+
/// resolve to [`TextStyle::Body`].
144149
pub fn resolve(self, style: &Style) -> FontId {
150+
self.resolve_with_fallback(style, TextStyle::Body.into())
151+
}
152+
153+
/// Resolve with a final fallback.
154+
///
155+
/// Fallback is resolved on [`Self::Default`] and no override in the style.
156+
pub fn resolve_with_fallback(self, style: &Style, fallback: Self) -> FontId {
145157
match self {
146158
Self::Default => {
147159
if let Some(override_font_id) = &style.override_font_id {
148160
override_font_id.clone()
149161
} else if let Some(text_style) = &style.override_text_style {
150162
text_style.resolve(style)
151163
} else {
152-
TextStyle::Body.resolve(style)
164+
fallback.resolve(style)
153165
}
154166
}
155167
Self::FontId(font_id) => font_id,

crates/egui/src/widget_text.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,9 @@ impl WidgetText {
747747
let mut layout_job = LayoutJob::simple_format(
748748
text,
749749
TextFormat {
750-
font_id: FontSelection::Default.resolve(style),
750+
// We want the style overrides to take precedence over the fallback font
751+
font_id: FontSelection::default()
752+
.resolve_with_fallback(style, fallback_font),
751753
color: crate::Color32::PLACEHOLDER,
752754
valign: default_valign,
753755
..Default::default()

crates/egui/src/widgets/button.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{
22
Atom, AtomExt as _, AtomKind, AtomLayout, AtomLayoutResponse, Color32, CornerRadius, Frame,
3-
Image, IntoAtoms, NumExt as _, Response, Sense, Stroke, TextWrapMode, Ui, Vec2, Widget,
4-
WidgetInfo, WidgetText, WidgetType,
3+
Image, IntoAtoms, NumExt as _, Response, Sense, Stroke, TextStyle, TextWrapMode, Ui, Vec2,
4+
Widget, WidgetInfo, WidgetText, WidgetType,
55
};
66

77
/// Clickable button with text.
@@ -40,7 +40,9 @@ pub struct Button<'a> {
4040
impl<'a> Button<'a> {
4141
pub fn new(atoms: impl IntoAtoms<'a>) -> Self {
4242
Self {
43-
layout: AtomLayout::new(atoms.into_atoms()).sense(Sense::click()),
43+
layout: AtomLayout::new(atoms.into_atoms())
44+
.sense(Sense::click())
45+
.fallback_font(TextStyle::Button),
4446
fill: None,
4547
stroke: None,
4648
small: false,

0 commit comments

Comments
 (0)