Skip to content
Draft
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
55 changes: 54 additions & 1 deletion crates/epaint/src/text/font.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::sync::Arc;
use emath::{GuiRounding as _, Vec2, vec2};

use crate::{
TextureAtlas,
ColorImage, TextureAtlas,
mutex::{Mutex, RwLock},
text::FontTweak,
};
Expand Down Expand Up @@ -261,6 +261,49 @@ impl FontImpl {
self.ascent
}

pub fn allocate_custom_glyph(&self, c: char, image: ColorImage) -> GlyphInfo {
let glyph_pos = {
let atlas = &mut self.atlas.lock();
let (glyph_pos, atlas_image) = atlas.allocate((image.width(), image.height()));

for x in 0..image.width() {
for y in 0..image.height() {
let px = glyph_pos.0 + x;
let py = glyph_pos.1 + y;
atlas_image[(px, py)] = image[(x, y)];
}
}

glyph_pos
};

let glyph_width = image.width();
let glyph_height = image.height();

let offset = vec2(0.0, -self.height_in_points / 1.3);

let height = self.height_in_points;
let width = height * (glyph_width as f32 / glyph_height as f32);

let uv_rect = UvRect {
offset,
size: vec2(width, height),
min: [glyph_pos.0 as u16, glyph_pos.1 as u16],
max: [
(glyph_pos.0 + glyph_width) as u16,
(glyph_pos.1 + glyph_height) as u16,
],
};

let advance_width = width;

GlyphInfo {
id: ab_glyph::GlyphId(0),
advance_width: advance_width as f32,
uv_rect,
}
}

fn allocate_glyph(&self, glyph_id: ab_glyph::GlyphId) -> GlyphInfo {
assert!(glyph_id.0 != 0, "Can't allocate glyph for id 0");
use ab_glyph::{Font as _, ScaleFont as _};
Expand Down Expand Up @@ -386,6 +429,16 @@ impl Font {
}
}

pub fn allocate_custom_glyph(&mut self, c: char, image: ColorImage) -> GlyphInfo {
if let Some(font_impl) = self.fonts.first() {
let glyph_info = font_impl.allocate_custom_glyph(c, image);
self.glyph_info_cache.insert(c, (0, glyph_info));
glyph_info
} else {
GlyphInfo::default()
}
}

pub fn preload_common_characters(&mut self) {
// Preload the printable ASCII characters [32, 126] (which excludes control codes):
const FIRST_ASCII: usize = 32; // 32 == space
Expand Down
45 changes: 30 additions & 15 deletions examples/hello_world/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
#![allow(rustdoc::missing_crate_level_docs)] // it's an example

use eframe::egui;
use eframe::egui::{
Color32, ColorImage, FontFamily, FontId, FontSelection, RichText, TextEdit,
global_theme_preference_switch, include_image,
};

fn main() -> eframe::Result {
env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`).
Expand All @@ -26,10 +30,14 @@ struct MyApp {
age: u32,
}

fn font_id() -> FontId {
FontId::new(30.0, FontFamily::Proportional)
}

impl Default for MyApp {
fn default() -> Self {
Self {
name: "Arthur".to_owned(),
name: "Ferris :crab:".to_owned(),
age: 42,
}
}
Expand All @@ -38,21 +46,28 @@ impl Default for MyApp {
impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
ui.heading("My egui Application");
ui.horizontal(|ui| {
let name_label = ui.label("Your name: ");
ui.text_edit_singleline(&mut self.name)
.labelled_by(name_label.id);
global_theme_preference_switch(ui);

ctx.fonts(|f| {
let mut fonts = f.lock();
let font = fonts.fonts.font(&font_id());
if !font.has_glyph('🦀') {
let image = include_bytes!("../../../crates/egui/assets/ferris.png");

let image = egui_extras::image::load_image_bytes(image).unwrap();

font.allocate_custom_glyph('🦀', image);
}
});
ui.add(egui::Slider::new(&mut self.age, 0..=120).text("age"));
if ui.button("Increment").clicked() {
self.age += 1;
}
ui.label(format!("Hello '{}', age {}", self.name, self.age));

ui.image(egui::include_image!(
"../../../crates/egui/assets/ferris.png"
));

TextEdit::singleline(&mut self.name)
.font(FontSelection::FontId(font_id()))
.text_color(Color32::WHITE)
.show(ui);

self.name = self.name.replace(":crab:", "🦀");

ui.label(RichText::new(&self.name).font(font_id()).strong());
});
}
}
Loading