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

Choose your own font and size #1154

Merged
merged 27 commits into from
Jan 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
dd36449
Refactor text layout: don't need &Fonts in all functions
emilk Jan 22, 2022
4e42923
Replace indexing in Fonts with member function
emilk Jan 22, 2022
fabf533
Wrap Fonts in a Mutex
emilk Jan 22, 2022
22fbfbf
Remove mutex for Font::glyph_info_cache
emilk Jan 22, 2022
1a1e3da
Remove RwLock around Font::characters
emilk Jan 22, 2022
9f8a2c7
Put FontsImpl and GalleyCache behind the same Mutex
emilk Jan 22, 2022
bae0df9
Round font sizes to whole pixels before deduplicating them
emilk Jan 22, 2022
dd920fa
Make TextStyle !Copy
emilk Jan 22, 2022
bb96a2a
Implement user-named TextStyle:s
emilk Jan 22, 2022
aa22aea
round font size earlier
emilk Jan 22, 2022
296272a
Cache fonts based on family and size
emilk Jan 22, 2022
7c983df
Move TextStyle into egui and Style
emilk Jan 23, 2022
5c25a6d
Remove body_text_style
emilk Jan 23, 2022
2adeeda
Query graphics about max texture size and use that as font atlas size
emilk Jan 23, 2022
1326f39
Recreate texture atlas when it is getting full
emilk Jan 23, 2022
64639e5
small optimization
emilk Jan 23, 2022
e7beb2a
Tweaks
emilk Jan 23, 2022
e7eacc5
fix clippy, docstrings etc
emilk Jan 23, 2022
ac6e420
Use correct style when calculating font height
emilk Jan 23, 2022
88e9cb1
Remove accidentally included file
emilk Jan 23, 2022
5e1fa71
Clean up the interface for Fonts
emilk Jan 24, 2022
09630df
Use list of all text styles in uis
emilk Jan 24, 2022
3f90163
Update changelogs
emilk Jan 24, 2022
224860f
RichText::font_id -> RichText::font
emilk Jan 24, 2022
9fc865a
More doc improvements
emilk Jan 24, 2022
257ddfa
Improve docs of RichText
emilk Jan 24, 2022
b6f6e74
Final cleanup
emilk Jan 24, 2022
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
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui_w
## Unreleased

### Added ⭐
* Much improved font selection ([#1154](https://github.com/emilk/egui/pull/1154)):
* You can now select any font size and family using `RichText::size` amd `RichText::family` and the new `FontId`.
* Easily change text styles with `Style::text_styles`.
* Added `Ui::text_style_height`.
* Added `TextStyle::resolve`.
* `Context::load_texture` to convert an image into a texture which can be displayed using e.g. `ui.image(texture, size)` ([#1110](https://github.com/emilk/egui/pull/1110)).
* Added `Ui::add_visible` and `Ui::add_visible_ui`.
* Added `CollapsingHeader::icon` to override the default open/close icon using a custom function. ([1147](https://github.com/emilk/egui/pull/1147))
Expand All @@ -23,6 +28,10 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui_w
* For integrations:
* `FontImage` has been replaced by `TexturesDelta` (found in `Output`), describing what textures were loaded and freed each frame ([#1110](https://github.com/emilk/egui/pull/1110)).
* The painter must support partial texture updates ([#1149](https://github.com/emilk/egui/pull/1149)).
* Added `RawInput::max_texture_side` which should be filled in with e.g. `GL_MAX_TEXTURE_SIZE` ([#1154](https://github.com/emilk/egui/pull/1154)).
* Replaced `Style::body_text_style` with more generic `Style::text_styles` ([#1154](https://github.com/emilk/egui/pull/1154)).
* `TextStyle` is no longer `Copy` ([#1154](https://github.com/emilk/egui/pull/1154)).
* Replaced `TextEdit::text_style` with `TextEdit::font` ([#1154](https://github.com/emilk/egui/pull/1154)).

### Fixed 🐛
* Context menu now respects the theme ([#1043](https://github.com/emilk/egui/pull/1043))
Expand Down Expand Up @@ -533,6 +542,7 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui_w
* Optimization: coarse culling in the tessellator
* CHANGED: switch argument order of `ui.checkbox` and `ui.radio`


## 0.1.4 - 2020-09-08

This is when I started the CHANGELOG.md, after almost two years of development. Better late than never.
Expand Down
2 changes: 1 addition & 1 deletion eframe/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ NOTE: [`egui_web`](../egui_web/CHANGELOG.md), [`egui-winit`](../egui-winit/CHANG
* The default web painter is now `egui_glow` (instead of WebGL) ([#1020](https://github.com/emilk/egui/pull/1020)).
* Fix horizontal scrolling direction on Linux.
* Added `App::on_exit_event` ([#1038](https://github.com/emilk/egui/pull/1038))
* Shift-scroll will now result in horizontal scrolling on all platforms ((#1136)[https://github.com/emilk/egui/pull/1136]).
* Shift-scroll will now result in horizontal scrolling on all platforms ([#1136](https://github.com/emilk/egui/pull/1136)).


## 0.16.0 - 2021-12-29
Expand Down
4 changes: 2 additions & 2 deletions eframe/examples/custom_font.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ impl epi::App for MyApp {

// Put my font first (highest priority) for proportional text:
fonts
.fonts_for_family
.families
.entry(egui::FontFamily::Proportional)
.or_default()
.insert(0, "my_font".to_owned());

// Put my font as last fallback for monospace:
fonts
.fonts_for_family
.families
.entry(egui::FontFamily::Monospace)
.or_default()
.push("my_font".to_owned());
Expand Down
2 changes: 1 addition & 1 deletion eframe/examples/file_dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ impl MyApp {
screen_rect.center(),
Align2::CENTER_CENTER,
text,
TextStyle::Heading,
TextStyle::Heading.resolve(&ctx.style()),
Color32::WHITE,
);
}
Expand Down
5 changes: 3 additions & 2 deletions egui-winit/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ All notable changes to the `egui-winit` integration will be noted in this file.


## Unreleased
* Fix horizontal scrolling direction on Linux.
* Fixed horizontal scrolling direction on Linux.
* Replaced `std::time::Instant` with `instant::Instant` for WebAssembly compatability ([#1023](https://github.com/emilk/egui/pull/1023))
* Shift-scroll will now result in horizontal scrolling on all platforms ((#1136)[https://github.com/emilk/egui/pull/1136]).
* Shift-scroll will now result in horizontal scrolling on all platforms ([#1136](https://github.com/emilk/egui/pull/1136)).
* Require knowledge about max texture side (e.g. `GL_MAX_TEXTURE_SIZE`)) ([#1154](https://github.com/emilk/egui/pull/1154)).


## 0.16.0 - 2021-12-29
Expand Down
3 changes: 2 additions & 1 deletion egui-winit/src/epi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ pub struct EpiIntegration {
impl EpiIntegration {
pub fn new(
integration_name: &'static str,
max_texture_side: usize,
window: &winit::window::Window,
repaint_signal: std::sync::Arc<dyn epi::backend::RepaintSignal>,
persistence: crate::epi::Persistence,
Expand All @@ -223,7 +224,7 @@ impl EpiIntegration {
frame,
persistence,
egui_ctx,
egui_winit: crate::State::new(window),
egui_winit: crate::State::new(max_texture_side, window),
app,
quit: false,
};
Expand Down
15 changes: 10 additions & 5 deletions egui-winit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,17 +129,22 @@ pub struct State {
}

impl State {
/// Initialize with the native `pixels_per_point` (dpi scaling).
pub fn new(window: &winit::window::Window) -> Self {
Self::from_pixels_per_point(native_pixels_per_point(window))
/// Initialize with:
/// * `max_texture_side`: e.g. `GL_MAX_TEXTURE_SIZE`
/// * the native `pixels_per_point` (dpi scaling).
pub fn new(max_texture_side: usize, window: &winit::window::Window) -> Self {
Self::from_pixels_per_point(max_texture_side, native_pixels_per_point(window))
}

/// Initialize with a given dpi scaling.
pub fn from_pixels_per_point(pixels_per_point: f32) -> Self {
/// Initialize with:
/// * `max_texture_side`: e.g. `GL_MAX_TEXTURE_SIZE`
/// * the given `pixels_per_point` (dpi scaling).
pub fn from_pixels_per_point(max_texture_side: usize, pixels_per_point: f32) -> Self {
Self {
start_time: instant::Instant::now(),
egui_input: egui::RawInput {
pixels_per_point: Some(pixels_per_point),
max_texture_side,
..Default::default()
},
pointer_pos_in_points: None,
Expand Down
2 changes: 1 addition & 1 deletion egui/src/containers/collapsing_header.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::hash::Hash;

use crate::*;
use epaint::{Shape, TextStyle};
use epaint::Shape;

#[derive(Clone, Copy, Debug, Default)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
Expand Down
2 changes: 1 addition & 1 deletion egui/src/containers/scroll_area.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ impl ScrollArea {
/// ```
/// # egui::__run_test_ui(|ui| {
/// let text_style = egui::TextStyle::Body;
/// let row_height = ui.fonts()[text_style].row_height();
/// let row_height = ui.text_style_height(&text_style);
/// // let row_height = ui.spacing().interact_size.y; // if you are adding buttons instead of labels.
/// let total_rows = 10_000;
/// egui::ScrollArea::vertical().show_rows(ui, row_height, total_rows, |ui, row_range| {
Expand Down
5 changes: 3 additions & 2 deletions egui/src/containers/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,8 @@ impl<'open> Window<'open> {
.and_then(|window_interaction| {
// Calculate roughly how much larger the window size is compared to the inner rect
let title_bar_height = if with_title_bar {
title.font_height(ctx) + title_content_spacing
let style = ctx.style();
title.font_height(&ctx.fonts(), &style) + title_content_spacing
} else {
0.0
};
Expand Down Expand Up @@ -764,7 +765,7 @@ fn show_title_bar(
) -> TitleBar {
let inner_response = ui.horizontal(|ui| {
let height = title
.font_height(ui.ctx())
.font_height(&ui.fonts(), ui.style())
.max(ui.spacing().interact_size.y);
ui.set_min_height(height);

Expand Down
63 changes: 28 additions & 35 deletions egui/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ impl ContextImpl {
self.input = input.begin_frame(new_raw_input);
self.frame_state.begin_frame(&self.input);

self.update_fonts_mut(self.input.pixels_per_point());
self.update_fonts_mut();

// Ensure we register the background area so panels and background ui can catch clicks:
let screen_rect = self.input.screen_rect();
Expand All @@ -77,27 +77,21 @@ impl ContextImpl {
}

/// Load fonts unless already loaded.
fn update_fonts_mut(&mut self, pixels_per_point: f32) {
let new_font_definitions = self.memory.new_font_definitions.take();
fn update_fonts_mut(&mut self) {
let pixels_per_point = self.input.pixels_per_point();
let max_texture_side = self.input.raw.max_texture_side;

let pixels_per_point_changed = match &self.fonts {
None => true,
Some(current_fonts) => {
(current_fonts.pixels_per_point() - pixels_per_point).abs() > 1e-3
}
};

if self.fonts.is_none() || new_font_definitions.is_some() || pixels_per_point_changed {
self.fonts = Some(Fonts::new(
pixels_per_point,
new_font_definitions.unwrap_or_else(|| {
self.fonts
.as_ref()
.map(|font| font.definitions().clone())
.unwrap_or_default()
}),
));
if let Some(font_definitions) = self.memory.new_font_definitions.take() {
let fonts = Fonts::new(pixels_per_point, max_texture_side, font_definitions);
self.fonts = Some(fonts);
}

let fonts = self.fonts.get_or_insert_with(|| {
let font_definitions = FontDefinitions::default();
Fonts::new(pixels_per_point, max_texture_side, font_definitions)
});

fonts.begin_frame(pixels_per_point, max_texture_side);
}
}

Expand Down Expand Up @@ -521,7 +515,7 @@ impl Context {
pub fn set_fonts(&self, font_definitions: FontDefinitions) {
if let Some(current_fonts) = &*self.fonts_mut() {
// NOTE: this comparison is expensive since it checks TTF data for equality
if current_fonts.definitions() == &font_definitions {
if current_fonts.lock().fonts.definitions() == &font_definitions {
return; // no change - save us from reloading font textures
}
}
Expand Down Expand Up @@ -700,8 +694,6 @@ impl Context {
self.request_repaint();
}

self.fonts().end_frame();

{
let ctx_impl = &mut *self.write();
ctx_impl
Expand Down Expand Up @@ -953,16 +945,6 @@ impl Context {
self.style_ui(ui);
});

CollapsingHeader::new("🔠 Fonts")
.default_open(false)
.show(ui, |ui| {
let mut font_definitions = self.fonts().definitions().clone();
font_definitions.ui(ui);
let font_image_size = self.fonts().font_image_size();
crate::introspection::font_texture_ui(ui, font_image_size);
self.set_fonts(font_definitions);
});

CollapsingHeader::new("✒ Painting")
.default_open(true)
.show(ui, |ui| {
Expand Down Expand Up @@ -1039,6 +1021,13 @@ impl Context {
.show(ui, |ui| {
self.texture_ui(ui);
});

CollapsingHeader::new("🔠 Font texture")
.default_open(false)
.show(ui, |ui| {
let font_image_size = self.fonts().font_image_size();
crate::introspection::font_texture_ui(ui, font_image_size);
});
}

/// Show stats about the allocated textures.
Expand Down Expand Up @@ -1080,8 +1069,12 @@ impl Context {
size *= (max_preview_size.x / size.x).min(1.0);
size *= (max_preview_size.y / size.y).min(1.0);
ui.image(texture_id, size).on_hover_ui(|ui| {
// show full size on hover
ui.image(texture_id, Vec2::new(w as f32, h as f32));
// show larger on hover
let max_size = 0.5 * ui.ctx().input().screen_rect().size();
let mut size = Vec2::new(w as f32, h as f32);
size *= max_size.x / size.x.max(max_size.x);
size *= max_size.y / size.y.max(max_size.y);
ui.image(texture_id, size);
});

ui.label(format!("{} x {}", w, h));
Expand Down
13 changes: 13 additions & 0 deletions egui/src/data/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ pub struct RawInput {
/// Set this the first frame, whenever it changes, or just on every frame.
pub pixels_per_point: Option<f32>,

/// Maximum size of one side of the font texture.
///
/// Ask your graphics drivers about this. This corresponds to `GL_MAX_TEXTURE_SIZE`.
///
/// The default is a very small (but very portable) 2048.
pub max_texture_side: usize,

/// Monotonically increasing time, in seconds. Relative to whatever. Used for animations.
/// If `None` is provided, egui will assume a time delta of `predicted_dt` (default 1/60 seconds).
pub time: Option<f64>,
Expand Down Expand Up @@ -62,6 +69,7 @@ impl Default for RawInput {
Self {
screen_rect: None,
pixels_per_point: None,
max_texture_side: 2048,
time: None,
predicted_dt: 1.0 / 60.0,
modifiers: Modifiers::default(),
Expand All @@ -81,6 +89,7 @@ impl RawInput {
RawInput {
screen_rect: self.screen_rect.take(),
pixels_per_point: self.pixels_per_point.take(),
max_texture_side: self.max_texture_side,
time: self.time.take(),
predicted_dt: self.predicted_dt,
modifiers: self.modifiers,
Expand All @@ -95,6 +104,7 @@ impl RawInput {
let Self {
screen_rect,
pixels_per_point,
max_texture_side,
time,
predicted_dt,
modifiers,
Expand All @@ -105,6 +115,7 @@ impl RawInput {

self.screen_rect = screen_rect.or(self.screen_rect);
self.pixels_per_point = pixels_per_point.or(self.pixels_per_point);
self.max_texture_side = max_texture_side; // use latest
self.time = time; // use latest time
self.predicted_dt = predicted_dt; // use latest dt
self.modifiers = modifiers; // use latest
Expand Down Expand Up @@ -357,6 +368,7 @@ impl RawInput {
let Self {
screen_rect,
pixels_per_point,
max_texture_side,
time,
predicted_dt,
modifiers,
Expand All @@ -370,6 +382,7 @@ impl RawInput {
.on_hover_text(
"Also called HDPI factor.\nNumber of physical pixels per each logical pixel.",
);
ui.label(format!("max_texture_side: {}", max_texture_side));
if let Some(time) = time {
ui.label(format!("time: {:.3} s", time));
} else {
Expand Down
7 changes: 6 additions & 1 deletion egui/src/input_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,12 @@ impl InputState {
events,
} = self;

ui.style_mut().body_text_style = epaint::TextStyle::Monospace;
ui.style_mut()
.text_styles
.get_mut(&crate::TextStyle::Body)
.unwrap()
.family = crate::FontFamily::Monospace;

ui.collapsing("Raw Input", |ui| raw.ui(ui));

crate::containers::CollapsingHeader::new("🖱 Pointer")
Expand Down
Loading