Skip to content

Commit f4ed394

Browse files
authored
Add UI to modify FontTweak live (#5125)
This will make it easier to get nice sizing and vertical alignments of fonts
1 parent e31b44f commit f4ed394

File tree

7 files changed

+126
-25
lines changed

7 files changed

+126
-25
lines changed

crates/egui/src/context.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,15 @@ use std::{borrow::Cow, cell::RefCell, panic::Location, sync::Arc, time::Duration
44

55
use containers::area::AreaState;
66
use epaint::{
7-
emath, emath::TSTransform, mutex::RwLock, pos2, stats::PaintStats, tessellator, text::Fonts,
8-
util::OrderedFloat, vec2, ClippedPrimitive, ClippedShape, Color32, ImageData, ImageDelta, Pos2,
9-
Rect, TessellationOptions, TextureAtlas, TextureId, Vec2,
7+
emath::{self, TSTransform},
8+
mutex::RwLock,
9+
pos2,
10+
stats::PaintStats,
11+
tessellator,
12+
text::Fonts,
13+
util::OrderedFloat,
14+
vec2, ClippedPrimitive, ClippedShape, Color32, ImageData, ImageDelta, Pos2, Rect,
15+
TessellationOptions, TextureAtlas, TextureId, Vec2,
1016
};
1117

1218
use crate::{
@@ -2817,13 +2823,34 @@ impl Context {
28172823
let prev_options = self.options(|o| o.clone());
28182824
let mut options = prev_options.clone();
28192825

2826+
ui.collapsing("🔠 Font tweak", |ui| {
2827+
self.fonts_tweak_ui(ui);
2828+
});
2829+
28202830
options.ui(ui);
28212831

28222832
if options != prev_options {
28232833
self.options_mut(move |o| *o = options);
28242834
}
28252835
}
28262836

2837+
fn fonts_tweak_ui(&self, ui: &mut Ui) {
2838+
let mut font_definitions = self.write(|ctx| ctx.font_definitions.clone());
2839+
let mut changed = false;
2840+
2841+
for (name, data) in &mut font_definitions.font_data {
2842+
ui.collapsing(name, |ui| {
2843+
if data.tweak.ui(ui).changed() {
2844+
changed = true;
2845+
}
2846+
});
2847+
}
2848+
2849+
if changed {
2850+
self.set_fonts(font_definitions);
2851+
}
2852+
}
2853+
28272854
/// Show the state of egui, including its input and output.
28282855
pub fn inspection_ui(&self, ui: &mut Ui) {
28292856
use crate::containers::CollapsingHeader;

crates/egui/src/style.rs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use std::{collections::BTreeMap, ops::RangeInclusive, sync::Arc};
66

7-
use epaint::{Rounding, Shadow, Stroke};
7+
use epaint::{text::FontTweak, Rounding, Shadow, Stroke};
88

99
use crate::{
1010
ecolor::Color32,
@@ -2498,3 +2498,48 @@ impl Widget for &mut crate::Frame {
24982498
.response
24992499
}
25002500
}
2501+
2502+
impl Widget for &mut FontTweak {
2503+
fn ui(self, ui: &mut Ui) -> Response {
2504+
let original: FontTweak = *self;
2505+
2506+
let mut response = Grid::new("font_tweak")
2507+
.num_columns(2)
2508+
.show(ui, |ui| {
2509+
let FontTweak {
2510+
scale,
2511+
y_offset_factor,
2512+
y_offset,
2513+
baseline_offset_factor,
2514+
} = self;
2515+
2516+
ui.label("Scale");
2517+
let speed = *scale * 0.01;
2518+
ui.add(DragValue::new(scale).range(0.01..=10.0).speed(speed));
2519+
ui.end_row();
2520+
2521+
ui.label("y_offset_factor");
2522+
ui.add(DragValue::new(y_offset_factor).speed(-0.0025));
2523+
ui.end_row();
2524+
2525+
ui.label("y_offset");
2526+
ui.add(DragValue::new(y_offset).speed(-0.02));
2527+
ui.end_row();
2528+
2529+
ui.label("baseline_offset_factor");
2530+
ui.add(DragValue::new(baseline_offset_factor).speed(-0.0025));
2531+
ui.end_row();
2532+
2533+
if ui.button("Reset").clicked() {
2534+
*self = Default::default();
2535+
}
2536+
})
2537+
.response;
2538+
2539+
if *self != original {
2540+
response.mark_changed();
2541+
}
2542+
2543+
response
2544+
}
2545+
}

crates/egui/src/ui.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1404,7 +1404,7 @@ impl Ui {
14041404
///
14051405
/// If this is called multiple times per frame for the same [`crate::ScrollArea`], the deltas will be summed.
14061406
///
1407-
/// /// See also: [`Response::scroll_to_me`], [`Ui::scroll_to_rect`], [`Ui::scroll_to_cursor`]
1407+
/// See also: [`Response::scroll_to_me`], [`Ui::scroll_to_rect`], [`Ui::scroll_to_cursor`]
14081408
///
14091409
/// ```
14101410
/// # use egui::{Align, Vec2};

crates/egui_demo_lib/src/demo/font_book.rs

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11
use std::collections::BTreeMap;
22

3+
struct GlyphInfo {
4+
name: String,
5+
6+
// What fonts it is available in
7+
fonts: Vec<String>,
8+
}
9+
310
pub struct FontBook {
411
filter: String,
512
font_id: egui::FontId,
6-
named_chars: BTreeMap<egui::FontFamily, BTreeMap<char, String>>,
13+
available_glyphs: BTreeMap<egui::FontFamily, BTreeMap<char, GlyphInfo>>,
714
}
815

916
impl Default for FontBook {
1017
fn default() -> Self {
1118
Self {
1219
filter: Default::default(),
1320
font_id: egui::FontId::proportional(18.0),
14-
named_chars: Default::default(),
21+
available_glyphs: Default::default(),
1522
}
1623
}
1724
}
@@ -37,7 +44,7 @@ impl crate::View for FontBook {
3744

3845
ui.label(format!(
3946
"The selected font supports {} characters.",
40-
self.named_chars
47+
self.available_glyphs
4148
.get(&self.font_id.family)
4249
.map(|map| map.len())
4350
.unwrap_or_default()
@@ -67,8 +74,8 @@ impl crate::View for FontBook {
6774
});
6875

6976
let filter = &self.filter;
70-
let named_chars = self
71-
.named_chars
77+
let available_glyphs = self
78+
.available_glyphs
7279
.entry(self.font_id.family.clone())
7380
.or_insert_with(|| available_characters(ui, self.font_id.family.clone()));
7481

@@ -78,8 +85,11 @@ impl crate::View for FontBook {
7885
ui.horizontal_wrapped(|ui| {
7986
ui.spacing_mut().item_spacing = egui::Vec2::splat(2.0);
8087

81-
for (&chr, name) in named_chars {
82-
if filter.is_empty() || name.contains(filter) || *filter == chr.to_string() {
88+
for (&chr, glyph_info) in available_glyphs {
89+
if filter.is_empty()
90+
|| glyph_info.name.contains(filter)
91+
|| *filter == chr.to_string()
92+
{
8393
let button = egui::Button::new(
8494
egui::RichText::new(chr.to_string()).font(self.font_id.clone()),
8595
)
@@ -89,7 +99,10 @@ impl crate::View for FontBook {
8999
ui.label(
90100
egui::RichText::new(chr.to_string()).font(self.font_id.clone()),
91101
);
92-
ui.label(format!("{}\nU+{:X}\n\nClick to copy", name, chr as u32));
102+
ui.label(format!(
103+
"{}\nU+{:X}\n\nFound in: {:?}\n\nClick to copy",
104+
glyph_info.name, chr as u32, glyph_info.fonts
105+
));
93106
};
94107

95108
if ui.add(button).on_hover_ui(tooltip_ui).clicked() {
@@ -102,15 +115,23 @@ impl crate::View for FontBook {
102115
}
103116
}
104117

105-
fn available_characters(ui: &egui::Ui, family: egui::FontFamily) -> BTreeMap<char, String> {
118+
fn available_characters(ui: &egui::Ui, family: egui::FontFamily) -> BTreeMap<char, GlyphInfo> {
106119
ui.fonts(|f| {
107120
f.lock()
108121
.fonts
109122
.font(&egui::FontId::new(10.0, family)) // size is arbitrary for getting the characters
110123
.characters()
111124
.iter()
112-
.filter(|chr| !chr.is_whitespace() && !chr.is_ascii_control())
113-
.map(|&chr| (chr, char_name(chr)))
125+
.filter(|(chr, _fonts)| !chr.is_whitespace() && !chr.is_ascii_control())
126+
.map(|(chr, fonts)| {
127+
(
128+
*chr,
129+
GlyphInfo {
130+
name: char_name(*chr),
131+
fonts: fonts.clone(),
132+
},
133+
)
134+
})
114135
.collect()
115136
})
116137
}

crates/epaint/src/text/font.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
use std::collections::BTreeMap;
2+
use std::sync::Arc;
3+
4+
use emath::{vec2, Vec2};
5+
16
use crate::{
27
mutex::{Mutex, RwLock},
38
text::FontTweak,
49
TextureAtlas,
510
};
6-
use emath::{vec2, Vec2};
7-
use std::collections::BTreeSet;
8-
use std::sync::Arc;
911

1012
// ----------------------------------------------------------------------------
1113

@@ -330,7 +332,7 @@ pub struct Font {
330332
fonts: Vec<Arc<FontImpl>>,
331333

332334
/// Lazily calculated.
333-
characters: Option<BTreeSet<char>>,
335+
characters: Option<BTreeMap<char, Vec<String>>>,
334336

335337
replacement_glyph: (FontIndex, GlyphInfo),
336338
pixels_per_point: f32,
@@ -398,12 +400,14 @@ impl Font {
398400
self.glyph_info(crate::text::PASSWORD_REPLACEMENT_CHAR);
399401
}
400402

401-
/// All supported characters.
402-
pub fn characters(&mut self) -> &BTreeSet<char> {
403+
/// All supported characters, and in which font they are available in.
404+
pub fn characters(&mut self) -> &BTreeMap<char, Vec<String>> {
403405
self.characters.get_or_insert_with(|| {
404-
let mut characters = BTreeSet::new();
406+
let mut characters: BTreeMap<char, Vec<String>> = Default::default();
405407
for font in &self.fonts {
406-
characters.extend(font.characters());
408+
for chr in font.characters() {
409+
characters.entry(chr).or_default().push(font.name.clone());
410+
}
407411
}
408412
characters
409413
})

crates/epaint/src/text/fonts.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ pub struct FontTweak {
159159
/// Shift font's glyphs downwards by this fraction of the font size (in points).
160160
/// this is only a visual effect and does not affect the text layout.
161161
///
162+
/// Affects larger font sizes more.
163+
///
162164
/// A positive value shifts the text downwards.
163165
/// A negative value shifts it upwards.
164166
///
@@ -168,6 +170,8 @@ pub struct FontTweak {
168170
/// Shift font's glyphs downwards by this amount of logical points.
169171
/// this is only a visual effect and does not affect the text layout.
170172
///
173+
/// Affects all font sizes equally.
174+
///
171175
/// Example value: `2.0`.
172176
pub y_offset: f32,
173177

crates/epaint/src/text/text_layout.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ fn replace_last_glyph_with_overflow_character(
482482

483483
/// Horizontally aligned the text on a row.
484484
///
485-
/// /// Ignores the Y coordinate.
485+
/// Ignores the Y coordinate.
486486
fn halign_and_justify_row(
487487
point_scale: PointScale,
488488
row: &mut Row,

0 commit comments

Comments
 (0)