Skip to content

Commit

Permalink
Add opt-in feature flag for proportional font scaling
Browse files Browse the repository at this point in the history
- This feature disables rounding the glyph cursor advance to the pixel grid
  in text layout. Makes the text bounding boxes retain their size
  proportional to the UI even when the display DPI changes.
- Enabling this feature will cause some unavoidable kerning issues.
  • Loading branch information
parasyte committed Jan 28, 2023
1 parent 507d516 commit 2f3055a
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 2 deletions.
3 changes: 2 additions & 1 deletion crates/epaint/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ All notable changes to the epaint crate will be documented in this file.
* Don't render `\r` (Carriage Return) ([#2452](https://github.com/emilk/egui/pull/2452)).
* Fix bug in `Mesh::split_to_u16` ([#2459](https://github.com/emilk/egui/pull/2459)).
* Improve rendering of very thin rectangles.
* Fix rounding errors with font scaling ([#2490](https://github.com/emilk/egui/pull/2490)).
* Fix rounding errors with font scaling ([#2490](https://github.com/emilk/egui/pull/2490)):
* Added opt-in feature `proportional_font_scaling` to maintain text bounding box sizes when display DPI is changed.


## 0.20.0 - 2022-12-08
Expand Down
3 changes: 3 additions & 0 deletions crates/epaint/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ deadlock_detection = ["dep:backtrace"]
## If you plan on specifying your own fonts you may disable this feature.
default_fonts = []

## Enabling this feature will allow fixed-width fonts to scale correctly for any display DPI.
proportional_font_scaling = []

## Enable additional checks if debug assertions are enabled (debug builds).
extra_debug_asserts = [
"emath/extra_debug_asserts",
Expand Down
9 changes: 9 additions & 0 deletions crates/epaint/src/text/font.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ pub struct Font {
/// Lazily calculated.
characters: Option<BTreeSet<char>>,
replacement_glyph: (FontIndex, GlyphInfo),
pixels_per_point: f32,
row_height: f32,
glyph_info_cache: ahash::HashMap<char, (FontIndex, GlyphInfo)>,
}
Expand All @@ -248,17 +249,20 @@ impl Font {
fonts,
characters: None,
replacement_glyph: Default::default(),
pixels_per_point: 1.0,
row_height: 0.0,
glyph_info_cache: Default::default(),
};
}

let pixels_per_point = fonts[0].pixels_per_point();
let row_height = fonts[0].row_height();

let mut slf = Self {
fonts,
characters: None,
replacement_glyph: Default::default(),
pixels_per_point,
row_height,
glyph_info_cache: Default::default(),
};
Expand Down Expand Up @@ -308,6 +312,11 @@ impl Font {
})
}

#[inline(always)]
pub fn round_to_pixel(&self, point: f32) -> f32 {
(point * self.pixels_per_point).round() / self.pixels_per_point
}

/// Height of one row of text. In points
#[inline(always)]
pub fn row_height(&self) -> f32 {
Expand Down
16 changes: 15 additions & 1 deletion crates/epaint/src/text/text_layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,21 @@ fn layout_section(
});

paragraph.cursor_x += glyph_info.advance_width;
paragraph.cursor_x = paragraph.cursor_x.round();

// This opt-in feature flag makes fixed width fonts scale proportionally to their
// surroundings regardless of the `pixels_per_point` setting. I.e., the text bounding
// box will be proportionally identical even when the window is moved between displays
// with varying DPIs.
//
// By default this feature is off, and text layout will nudge glyph positions to align
// with the pixel grid to retain the appearance of decent spacing between characters.
//
// See https://github.com/emilk/egui/pull/2490 for additional details.
#[cfg(not(feature = "proportional_font_scaling"))]
{
paragraph.cursor_x = font.round_to_pixel(paragraph.cursor_x);
}

last_glyph_id = Some(glyph_info.id);
}
}
Expand Down

0 comments on commit 2f3055a

Please sign in to comment.