Make v-align and scale of user fonts tweakable (#1241)
* Add ability to "tweak" the scale and y-offsets of individual fonts * Change default font tweak This help vertically center large text.
This commit is contained in:
parent
3f8ba3a542
commit
69626296f1
4 changed files with 81 additions and 27 deletions
|
@ -13,6 +13,7 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui_w
|
||||||
* Easily change text styles with `Style::text_styles`.
|
* Easily change text styles with `Style::text_styles`.
|
||||||
* Added `Ui::text_style_height`.
|
* Added `Ui::text_style_height`.
|
||||||
* Added `TextStyle::resolve`.
|
* Added `TextStyle::resolve`.
|
||||||
|
* Made v-align and scale of user fonts tweakable ([#1241](https://github.com/emilk/egui/pull/1027)).
|
||||||
* `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)).
|
* `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 `Ui::add_visible` and `Ui::add_visible_ui`.
|
||||||
* Opt-in dependency on `tracing` crate for logging warnings ([#1192](https://github.com/emilk/egui/pull/1192)).
|
* Opt-in dependency on `tracing` crate for logging warnings ([#1192](https://github.com/emilk/egui/pull/1192)).
|
||||||
|
|
|
@ -7,6 +7,7 @@ All notable changes to the epaint crate will be documented in this file.
|
||||||
* Much improved font selection ([#1154](https://github.com/emilk/egui/pull/1154)):
|
* Much improved font selection ([#1154](https://github.com/emilk/egui/pull/1154)):
|
||||||
* Replaced `TextStyle` with `FontId` which lets you pick any font size and font family.
|
* Replaced `TextStyle` with `FontId` which lets you pick any font size and font family.
|
||||||
* Replaced `Fonts::font_image` with `font_image_delta` for partial font atlas updates.
|
* Replaced `Fonts::font_image` with `font_image_delta` for partial font atlas updates.
|
||||||
|
* Made v-align and scale of user fonts tweakable ([#1241](https://github.com/emilk/egui/pull/1027)).
|
||||||
* Added `ImageData` and `TextureManager` for loading images into textures ([#1110](https://github.com/emilk/egui/pull/1110)).
|
* Added `ImageData` and `TextureManager` for loading images into textures ([#1110](https://github.com/emilk/egui/pull/1110)).
|
||||||
* Added `Shape::dashed_line_many` ([#1027](https://github.com/emilk/egui/pull/1027)).
|
* Added `Shape::dashed_line_many` ([#1027](https://github.com/emilk/egui/pull/1027)).
|
||||||
* Replaced `corner_radius: f32` with `rounding: Rounding`, allowing per-corner rounding settings ([#1206](https://github.com/emilk/egui/pull/1206)).
|
* Replaced `corner_radius: f32` with `rounding: Rounding`, allowing per-corner rounding settings ([#1206](https://github.com/emilk/egui/pull/1206)).
|
||||||
|
|
|
@ -73,20 +73,22 @@ impl FontImpl {
|
||||||
pixels_per_point: f32,
|
pixels_per_point: f32,
|
||||||
ab_glyph_font: ab_glyph::FontArc,
|
ab_glyph_font: ab_glyph::FontArc,
|
||||||
scale_in_pixels: u32,
|
scale_in_pixels: u32,
|
||||||
y_offset: f32,
|
y_offset_points: f32,
|
||||||
) -> FontImpl {
|
) -> FontImpl {
|
||||||
assert!(scale_in_pixels > 0);
|
assert!(scale_in_pixels > 0);
|
||||||
assert!(pixels_per_point > 0.0);
|
assert!(pixels_per_point > 0.0);
|
||||||
|
|
||||||
let height_in_points = scale_in_pixels as f32 / pixels_per_point;
|
let height_in_points = scale_in_pixels as f32 / pixels_per_point;
|
||||||
|
|
||||||
// TODO: use v_metrics for line spacing ?
|
// TODO: use these font metrics?
|
||||||
// let v = rusttype_font.v_metrics(Scale::uniform(scale_in_pixels));
|
// use ab_glyph::ScaleFont as _;
|
||||||
// let height_in_pixels = v.ascent - v.descent + v.line_gap;
|
// let scaled = ab_glyph_font.as_scaled(scale_in_pixels as f32);
|
||||||
// let height_in_points = height_in_pixels / pixels_per_point;
|
// dbg!(scaled.ascent());
|
||||||
|
// dbg!(scaled.descent());
|
||||||
|
// dbg!(scaled.line_gap());
|
||||||
|
|
||||||
// Round to closest pixel:
|
// Round to closest pixel:
|
||||||
let y_offset = (y_offset * pixels_per_point).round() / pixels_per_point;
|
let y_offset = (y_offset_points * pixels_per_point).round() / pixels_per_point;
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
ab_glyph_font,
|
ab_glyph_font,
|
||||||
|
|
|
@ -120,6 +120,9 @@ pub struct FontData {
|
||||||
/// Which font face in the file to use.
|
/// Which font face in the file to use.
|
||||||
/// When in doubt, use `0`.
|
/// When in doubt, use `0`.
|
||||||
pub index: u32,
|
pub index: u32,
|
||||||
|
|
||||||
|
/// Extra scale and vertical tweak to apply to all text of this font.
|
||||||
|
pub tweak: FontTweak,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FontData {
|
impl FontData {
|
||||||
|
@ -127,6 +130,7 @@ impl FontData {
|
||||||
Self {
|
Self {
|
||||||
font: std::borrow::Cow::Borrowed(font),
|
font: std::borrow::Cow::Borrowed(font),
|
||||||
index: 0,
|
index: 0,
|
||||||
|
tweak: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,10 +138,52 @@ impl FontData {
|
||||||
Self {
|
Self {
|
||||||
font: std::borrow::Cow::Owned(font),
|
font: std::borrow::Cow::Owned(font),
|
||||||
index: 0,
|
index: 0,
|
||||||
|
tweak: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tweak(self, tweak: FontTweak) -> Self {
|
||||||
|
Self { tweak, ..self }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// Extra scale and vertical tweak to apply to all text of a certain font.
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||||
|
pub struct FontTweak {
|
||||||
|
/// Scale the font by this much.
|
||||||
|
///
|
||||||
|
/// Default: `1.0` (no scaling).
|
||||||
|
pub scale: f32,
|
||||||
|
|
||||||
|
/// Shift font downwards by this fraction of the font size (in points).
|
||||||
|
///
|
||||||
|
/// A positive value shifts the text upwards.
|
||||||
|
/// A negative value shifts it downwards.
|
||||||
|
///
|
||||||
|
/// Example value: `-0.2`.
|
||||||
|
pub y_offset_factor: f32,
|
||||||
|
|
||||||
|
/// Shift font downwards by this amount of logical points.
|
||||||
|
///
|
||||||
|
/// Example value: `-1.0`.
|
||||||
|
pub y_offset: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for FontTweak {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
scale: 1.0,
|
||||||
|
y_offset_factor: -0.2, // makes the default fonts look more centered in buttons and such
|
||||||
|
y_offset: 0.0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
fn ab_glyph_font_from_font_data(name: &str, data: &FontData) -> ab_glyph::FontArc {
|
fn ab_glyph_font_from_font_data(name: &str, data: &FontData) -> ab_glyph::FontArc {
|
||||||
match &data.font {
|
match &data.font {
|
||||||
std::borrow::Cow::Borrowed(bytes) => {
|
std::borrow::Cow::Borrowed(bytes) => {
|
||||||
|
@ -220,10 +266,17 @@ impl Default for FontDefinitions {
|
||||||
"NotoEmoji-Regular".to_owned(),
|
"NotoEmoji-Regular".to_owned(),
|
||||||
FontData::from_static(include_bytes!("../../fonts/NotoEmoji-Regular.ttf")),
|
FontData::from_static(include_bytes!("../../fonts/NotoEmoji-Regular.ttf")),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Bigger emojis, and more. <http://jslegers.github.io/emoji-icon-font/>:
|
// Bigger emojis, and more. <http://jslegers.github.io/emoji-icon-font/>:
|
||||||
font_data.insert(
|
font_data.insert(
|
||||||
"emoji-icon-font".to_owned(),
|
"emoji-icon-font".to_owned(),
|
||||||
FontData::from_static(include_bytes!("../../fonts/emoji-icon-font.ttf")),
|
FontData::from_static(include_bytes!("../../fonts/emoji-icon-font.ttf")).tweak(
|
||||||
|
FontTweak {
|
||||||
|
scale: 0.8, // make it smaller
|
||||||
|
y_offset_factor: 0.07, // move it down slightly
|
||||||
|
y_offset: 0.0,
|
||||||
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
families.insert(
|
families.insert(
|
||||||
|
@ -603,7 +656,7 @@ impl GalleyCache {
|
||||||
struct FontImplCache {
|
struct FontImplCache {
|
||||||
atlas: Arc<Mutex<TextureAtlas>>,
|
atlas: Arc<Mutex<TextureAtlas>>,
|
||||||
pixels_per_point: f32,
|
pixels_per_point: f32,
|
||||||
ab_glyph_fonts: BTreeMap<String, ab_glyph::FontArc>,
|
ab_glyph_fonts: BTreeMap<String, (FontTweak, ab_glyph::FontArc)>,
|
||||||
|
|
||||||
/// Map font pixel sizes and names to the cached `FontImpl`.
|
/// Map font pixel sizes and names to the cached `FontImpl`.
|
||||||
cache: ahash::AHashMap<(u32, String), Arc<FontImpl>>,
|
cache: ahash::AHashMap<(u32, String), Arc<FontImpl>>,
|
||||||
|
@ -617,7 +670,11 @@ impl FontImplCache {
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let ab_glyph_fonts = font_data
|
let ab_glyph_fonts = font_data
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(name, font_data)| (name.clone(), ab_glyph_font_from_font_data(name, font_data)))
|
.map(|(name, font_data)| {
|
||||||
|
let tweak = font_data.tweak;
|
||||||
|
let ab_glyph = ab_glyph_font_from_font_data(name, font_data);
|
||||||
|
(name.clone(), (tweak, ab_glyph))
|
||||||
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
@ -638,35 +695,28 @@ impl FontImplCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn font_impl(&mut self, scale_in_pixels: u32, font_name: &str) -> Arc<FontImpl> {
|
pub fn font_impl(&mut self, scale_in_pixels: u32, font_name: &str) -> Arc<FontImpl> {
|
||||||
let scale_in_pixels = if font_name == "emoji-icon-font" {
|
let (tweak, ab_glyph_font) = self
|
||||||
(scale_in_pixels as f32 * 0.8).round() as u32 // TODO: remove font scale HACK!
|
.ab_glyph_fonts
|
||||||
} else {
|
.get(font_name)
|
||||||
scale_in_pixels
|
.unwrap_or_else(|| panic!("No font data found for {:?}", font_name))
|
||||||
};
|
.clone();
|
||||||
|
|
||||||
let y_offset = if font_name == "emoji-icon-font" {
|
let scale_in_pixels = (scale_in_pixels as f32 * tweak.scale).round() as u32;
|
||||||
|
|
||||||
|
let y_offset_points = {
|
||||||
let scale_in_points = scale_in_pixels as f32 / self.pixels_per_point;
|
let scale_in_points = scale_in_pixels as f32 / self.pixels_per_point;
|
||||||
scale_in_points * 0.29375 // TODO: remove font alignment hack
|
scale_in_points * tweak.y_offset_factor
|
||||||
} else {
|
} + tweak.y_offset;
|
||||||
0.0
|
|
||||||
};
|
|
||||||
let y_offset = y_offset - 3.0; // Tweaked to make text look centered in buttons and text edit fields
|
|
||||||
|
|
||||||
self.cache
|
self.cache
|
||||||
.entry((scale_in_pixels, font_name.to_owned()))
|
.entry((scale_in_pixels, font_name.to_owned()))
|
||||||
.or_insert_with(|| {
|
.or_insert_with(|| {
|
||||||
let ab_glyph_font = self
|
|
||||||
.ab_glyph_fonts
|
|
||||||
.get(font_name)
|
|
||||||
.unwrap_or_else(|| panic!("No font data found for {:?}", font_name))
|
|
||||||
.clone();
|
|
||||||
|
|
||||||
Arc::new(FontImpl::new(
|
Arc::new(FontImpl::new(
|
||||||
self.atlas.clone(),
|
self.atlas.clone(),
|
||||||
self.pixels_per_point,
|
self.pixels_per_point,
|
||||||
ab_glyph_font,
|
ab_glyph_font,
|
||||||
scale_in_pixels,
|
scale_in_pixels,
|
||||||
y_offset,
|
y_offset_points,
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
.clone()
|
.clone()
|
||||||
|
|
Loading…
Reference in a new issue