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`.
|
||||
* Added `Ui::text_style_height`.
|
||||
* 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)).
|
||||
* 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)).
|
||||
|
|
|
@ -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)):
|
||||
* 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.
|
||||
* 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 `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)).
|
||||
|
|
|
@ -73,20 +73,22 @@ impl FontImpl {
|
|||
pixels_per_point: f32,
|
||||
ab_glyph_font: ab_glyph::FontArc,
|
||||
scale_in_pixels: u32,
|
||||
y_offset: f32,
|
||||
y_offset_points: f32,
|
||||
) -> FontImpl {
|
||||
assert!(scale_in_pixels > 0);
|
||||
assert!(pixels_per_point > 0.0);
|
||||
|
||||
let height_in_points = scale_in_pixels as f32 / pixels_per_point;
|
||||
|
||||
// TODO: use v_metrics for line spacing ?
|
||||
// let v = rusttype_font.v_metrics(Scale::uniform(scale_in_pixels));
|
||||
// let height_in_pixels = v.ascent - v.descent + v.line_gap;
|
||||
// let height_in_points = height_in_pixels / pixels_per_point;
|
||||
// TODO: use these font metrics?
|
||||
// use ab_glyph::ScaleFont as _;
|
||||
// let scaled = ab_glyph_font.as_scaled(scale_in_pixels as f32);
|
||||
// dbg!(scaled.ascent());
|
||||
// dbg!(scaled.descent());
|
||||
// dbg!(scaled.line_gap());
|
||||
|
||||
// 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 {
|
||||
ab_glyph_font,
|
||||
|
|
|
@ -120,6 +120,9 @@ pub struct FontData {
|
|||
/// Which font face in the file to use.
|
||||
/// When in doubt, use `0`.
|
||||
pub index: u32,
|
||||
|
||||
/// Extra scale and vertical tweak to apply to all text of this font.
|
||||
pub tweak: FontTweak,
|
||||
}
|
||||
|
||||
impl FontData {
|
||||
|
@ -127,6 +130,7 @@ impl FontData {
|
|||
Self {
|
||||
font: std::borrow::Cow::Borrowed(font),
|
||||
index: 0,
|
||||
tweak: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,10 +138,52 @@ impl FontData {
|
|||
Self {
|
||||
font: std::borrow::Cow::Owned(font),
|
||||
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 {
|
||||
match &data.font {
|
||||
std::borrow::Cow::Borrowed(bytes) => {
|
||||
|
@ -220,10 +266,17 @@ impl Default for FontDefinitions {
|
|||
"NotoEmoji-Regular".to_owned(),
|
||||
FontData::from_static(include_bytes!("../../fonts/NotoEmoji-Regular.ttf")),
|
||||
);
|
||||
|
||||
// Bigger emojis, and more. <http://jslegers.github.io/emoji-icon-font/>:
|
||||
font_data.insert(
|
||||
"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(
|
||||
|
@ -603,7 +656,7 @@ impl GalleyCache {
|
|||
struct FontImplCache {
|
||||
atlas: Arc<Mutex<TextureAtlas>>,
|
||||
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`.
|
||||
cache: ahash::AHashMap<(u32, String), Arc<FontImpl>>,
|
||||
|
@ -617,7 +670,11 @@ impl FontImplCache {
|
|||
) -> Self {
|
||||
let ab_glyph_fonts = font_data
|
||||
.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();
|
||||
|
||||
Self {
|
||||
|
@ -638,35 +695,28 @@ impl FontImplCache {
|
|||
}
|
||||
|
||||
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" {
|
||||
(scale_in_pixels as f32 * 0.8).round() as u32 // TODO: remove font scale HACK!
|
||||
} else {
|
||||
scale_in_pixels
|
||||
};
|
||||
let (tweak, ab_glyph_font) = self
|
||||
.ab_glyph_fonts
|
||||
.get(font_name)
|
||||
.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;
|
||||
scale_in_points * 0.29375 // TODO: remove font alignment hack
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
let y_offset = y_offset - 3.0; // Tweaked to make text look centered in buttons and text edit fields
|
||||
scale_in_points * tweak.y_offset_factor
|
||||
} + tweak.y_offset;
|
||||
|
||||
self.cache
|
||||
.entry((scale_in_pixels, font_name.to_owned()))
|
||||
.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(
|
||||
self.atlas.clone(),
|
||||
self.pixels_per_point,
|
||||
ab_glyph_font,
|
||||
scale_in_pixels,
|
||||
y_offset,
|
||||
y_offset_points,
|
||||
))
|
||||
})
|
||||
.clone()
|
||||
|
|
Loading…
Reference in a new issue