Skip to content

Commit

Permalink
In the "Font Book" demo, show what font contains the glyph
Browse files Browse the repository at this point in the history
  • Loading branch information
emilk committed Sep 18, 2024
1 parent 2294954 commit 09600d8
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 19 deletions.
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

0 comments on commit 09600d8

Please sign in to comment.