diff --git a/CHANGELOG.md b/CHANGELOG.md
index eeb02be9..8a3f29fc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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)).
diff --git a/epaint/CHANGELOG.md b/epaint/CHANGELOG.md
index 4395c203..0039d9e5 100644
--- a/epaint/CHANGELOG.md
+++ b/epaint/CHANGELOG.md
@@ -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)).
diff --git a/epaint/src/text/font.rs b/epaint/src/text/font.rs
index 1dca6030..1f779ddf 100644
--- a/epaint/src/text/font.rs
+++ b/epaint/src/text/font.rs
@@ -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,
diff --git a/epaint/src/text/fonts.rs b/epaint/src/text/fonts.rs
index bd6a9e2b..790db06b 100644
--- a/epaint/src/text/fonts.rs
+++ b/epaint/src/text/fonts.rs
@@ -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. :
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>,
pixels_per_point: f32,
- ab_glyph_fonts: BTreeMap,
+ ab_glyph_fonts: BTreeMap,
/// Map font pixel sizes and names to the cached `FontImpl`.
cache: ahash::AHashMap<(u32, String), Arc>,
@@ -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 {
- 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()