Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add UI to modify FontTweak live #5125

Merged
merged 6 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 30 additions & 3 deletions crates/egui/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@ use std::{borrow::Cow, cell::RefCell, panic::Location, sync::Arc, time::Duration

use containers::area::AreaState;
use epaint::{
emath, emath::TSTransform, mutex::RwLock, pos2, stats::PaintStats, tessellator, text::Fonts,
util::OrderedFloat, vec2, ClippedPrimitive, ClippedShape, Color32, ImageData, ImageDelta, Pos2,
Rect, TessellationOptions, TextureAtlas, TextureId, Vec2,
emath::{self, TSTransform},
mutex::RwLock,
pos2,
stats::PaintStats,
tessellator,
text::Fonts,
util::OrderedFloat,
vec2, ClippedPrimitive, ClippedShape, Color32, ImageData, ImageDelta, Pos2, Rect,
TessellationOptions, TextureAtlas, TextureId, Vec2,
};

use crate::{
Expand Down Expand Up @@ -2817,13 +2823,34 @@ impl Context {
let prev_options = self.options(|o| o.clone());
let mut options = prev_options.clone();

ui.collapsing("🔠 Font tweak", |ui| {
self.fonts_tweak_ui(ui);
});

options.ui(ui);

if options != prev_options {
self.options_mut(move |o| *o = options);
}
}

fn fonts_tweak_ui(&self, ui: &mut Ui) {
let mut font_definitions = self.write(|ctx| ctx.font_definitions.clone());
let mut changed = false;

for (name, data) in &mut font_definitions.font_data {
ui.collapsing(name, |ui| {
if data.tweak.ui(ui).changed() {
changed = true;
}
});
}

if changed {
self.set_fonts(font_definitions);
}
}

/// Show the state of egui, including its input and output.
pub fn inspection_ui(&self, ui: &mut Ui) {
use crate::containers::CollapsingHeader;
Expand Down
47 changes: 46 additions & 1 deletion crates/egui/src/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

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

use epaint::{Rounding, Shadow, Stroke};
use epaint::{text::FontTweak, Rounding, Shadow, Stroke};

use crate::{
ecolor::Color32,
Expand Down Expand Up @@ -2498,3 +2498,48 @@ impl Widget for &mut crate::Frame {
.response
}
}

impl Widget for &mut FontTweak {
fn ui(self, ui: &mut Ui) -> Response {
let original: FontTweak = *self;

let mut response = Grid::new("font_tweak")
.num_columns(2)
.show(ui, |ui| {
let FontTweak {
scale,
y_offset_factor,
y_offset,
baseline_offset_factor,
} = self;

ui.label("Scale");
let speed = *scale * 0.01;
ui.add(DragValue::new(scale).range(0.01..=10.0).speed(speed));
ui.end_row();

ui.label("y_offset_factor");
ui.add(DragValue::new(y_offset_factor).speed(-0.0025));
ui.end_row();

ui.label("y_offset");
ui.add(DragValue::new(y_offset).speed(-0.02));
ui.end_row();

ui.label("baseline_offset_factor");
ui.add(DragValue::new(baseline_offset_factor).speed(-0.0025));
ui.end_row();

if ui.button("Reset").clicked() {
*self = Default::default();
}
})
.response;

if *self != original {
response.mark_changed();
}

response
}
}
2 changes: 1 addition & 1 deletion crates/egui/src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1404,7 +1404,7 @@ impl Ui {
///
/// If this is called multiple times per frame for the same [`crate::ScrollArea`], the deltas will be summed.
///
/// /// See also: [`Response::scroll_to_me`], [`Ui::scroll_to_rect`], [`Ui::scroll_to_cursor`]
/// See also: [`Response::scroll_to_me`], [`Ui::scroll_to_rect`], [`Ui::scroll_to_cursor`]
///
/// ```
/// # use egui::{Align, Vec2};
Expand Down
43 changes: 32 additions & 11 deletions crates/egui_demo_lib/src/demo/font_book.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
use std::collections::BTreeMap;

struct GlyphInfo {
name: String,

// What fonts it is available in
fonts: Vec<String>,
}

pub struct FontBook {
filter: String,
font_id: egui::FontId,
named_chars: BTreeMap<egui::FontFamily, BTreeMap<char, String>>,
available_glyphs: BTreeMap<egui::FontFamily, BTreeMap<char, GlyphInfo>>,
}

impl Default for FontBook {
fn default() -> Self {
Self {
filter: Default::default(),
font_id: egui::FontId::proportional(18.0),
named_chars: Default::default(),
available_glyphs: Default::default(),
}
}
}
Expand All @@ -37,7 +44,7 @@ impl crate::View for FontBook {

ui.label(format!(
"The selected font supports {} characters.",
self.named_chars
self.available_glyphs
.get(&self.font_id.family)
.map(|map| map.len())
.unwrap_or_default()
Expand Down Expand Up @@ -67,8 +74,8 @@ impl crate::View for FontBook {
});

let filter = &self.filter;
let named_chars = self
.named_chars
let available_glyphs = self
.available_glyphs
.entry(self.font_id.family.clone())
.or_insert_with(|| available_characters(ui, self.font_id.family.clone()));

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

for (&chr, name) in named_chars {
if filter.is_empty() || name.contains(filter) || *filter == chr.to_string() {
for (&chr, glyph_info) in available_glyphs {
if filter.is_empty()
|| glyph_info.name.contains(filter)
|| *filter == chr.to_string()
{
let button = egui::Button::new(
egui::RichText::new(chr.to_string()).font(self.font_id.clone()),
)
Expand All @@ -89,7 +99,10 @@ impl crate::View for FontBook {
ui.label(
egui::RichText::new(chr.to_string()).font(self.font_id.clone()),
);
ui.label(format!("{}\nU+{:X}\n\nClick to copy", name, chr as u32));
ui.label(format!(
"{}\nU+{:X}\n\nFound in: {:?}\n\nClick to copy",
glyph_info.name, chr as u32, glyph_info.fonts
));
};

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

fn available_characters(ui: &egui::Ui, family: egui::FontFamily) -> BTreeMap<char, String> {
fn available_characters(ui: &egui::Ui, family: egui::FontFamily) -> BTreeMap<char, GlyphInfo> {
ui.fonts(|f| {
f.lock()
.fonts
.font(&egui::FontId::new(10.0, family)) // size is arbitrary for getting the characters
.characters()
.iter()
.filter(|chr| !chr.is_whitespace() && !chr.is_ascii_control())
.map(|&chr| (chr, char_name(chr)))
.filter(|(chr, _fonts)| !chr.is_whitespace() && !chr.is_ascii_control())
.map(|(chr, fonts)| {
(
*chr,
GlyphInfo {
name: char_name(*chr),
fonts: fonts.clone(),
},
)
})
.collect()
})
}
Expand Down
20 changes: 12 additions & 8 deletions crates/epaint/src/text/font.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use std::collections::BTreeMap;
use std::sync::Arc;

use emath::{vec2, Vec2};

use crate::{
mutex::{Mutex, RwLock},
text::FontTweak,
TextureAtlas,
};
use emath::{vec2, Vec2};
use std::collections::BTreeSet;
use std::sync::Arc;

// ----------------------------------------------------------------------------

Expand Down Expand Up @@ -330,7 +332,7 @@ pub struct Font {
fonts: Vec<Arc<FontImpl>>,

/// Lazily calculated.
characters: Option<BTreeSet<char>>,
characters: Option<BTreeMap<char, Vec<String>>>,

replacement_glyph: (FontIndex, GlyphInfo),
pixels_per_point: f32,
Expand Down Expand Up @@ -398,12 +400,14 @@ impl Font {
self.glyph_info(crate::text::PASSWORD_REPLACEMENT_CHAR);
}

/// All supported characters.
pub fn characters(&mut self) -> &BTreeSet<char> {
/// All supported characters, and in which font they are available in.
pub fn characters(&mut self) -> &BTreeMap<char, Vec<String>> {
self.characters.get_or_insert_with(|| {
let mut characters = BTreeSet::new();
let mut characters: BTreeMap<char, Vec<String>> = Default::default();
for font in &self.fonts {
characters.extend(font.characters());
for chr in font.characters() {
characters.entry(chr).or_default().push(font.name.clone());
}
}
characters
})
Expand Down
4 changes: 4 additions & 0 deletions crates/epaint/src/text/fonts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ pub struct FontTweak {
/// Shift font's glyphs downwards by this fraction of the font size (in points).
/// this is only a visual effect and does not affect the text layout.
///
/// Affects larger font sizes more.
///
/// A positive value shifts the text downwards.
/// A negative value shifts it upwards.
///
Expand All @@ -168,6 +170,8 @@ pub struct FontTweak {
/// Shift font's glyphs downwards by this amount of logical points.
/// this is only a visual effect and does not affect the text layout.
///
/// Affects all font sizes equally.
///
/// Example value: `2.0`.
pub y_offset: f32,

Expand Down
2 changes: 1 addition & 1 deletion crates/epaint/src/text/text_layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ fn replace_last_glyph_with_overflow_character(

/// Horizontally aligned the text on a row.
///
/// /// Ignores the Y coordinate.
/// Ignores the Y coordinate.
fn halign_and_justify_row(
point_scale: PointScale,
row: &mut Row,
Expand Down
Loading