Fix scaling of glyphs and improve type safety in the MCU backend

The code was mixing logical and physical sizes, causing glyphs being
doubly scaled down. Instead, this patch introduces:

 * Physical* and Logical* euclid length/size/rect aliases
 * some extraction traits for getting the scalars in rects/sizes as lengths (until euclid has them
built-in)
 * wrapper traits/types for safely extracting the physical font metrics the
 compiler generates (i16)
 * Fix a bug in the text height calculation where we failed to take the
   descent into account
This commit is contained in:
Simon Hausmann 2022-02-16 18:50:54 +01:00
parent 3af7b6f323
commit f912ec7e6b
9 changed files with 273 additions and 109 deletions

View file

@ -46,8 +46,8 @@ impl Texture {
pub struct BitmapGlyph {
pub x: i16,
pub y: i16,
pub width: u16,
pub height: u16,
pub width: i16,
pub height: i16,
pub x_advance: i16,
pub data: Vec<u8>, // 8bit alpha map
}
@ -55,7 +55,7 @@ pub struct BitmapGlyph {
#[cfg(not(target_arch = "wasm32"))]
#[derive(Debug, Clone)]
pub struct BitmapGlyphs {
pub pixel_size: u16,
pub pixel_size: i16,
pub glyph_data: Vec<BitmapGlyph>,
}

View file

@ -121,11 +121,19 @@ pub fn embed_glyphs<'a>(
#[cfg(not(target_arch = "wasm32"))]
fn embed_font(family_name: String, font: fontdue::Font) -> BitmapFont {
let scale_factor = std::env::var("SLINT_SCALE_FACTOR")
.ok()
.and_then(|x| x.parse::<f64>().ok())
.filter(|f| *f > 0.)
.unwrap_or(1.);
let mut pixel_sizes = std::env::var("SLINT_FONT_SIZES")
.map(|sizes_str| {
sizes_str
.split(',')
.map(|size_str| size_str.parse::<u16>().expect("invalid font size"))
.map(|size_str| {
(size_str.parse::<f64>().expect("invalid font size") * scale_factor) as i16
})
.collect::<Vec<_>>()
})
.expect("please specify SLINT_FONT_SIZES");
@ -156,8 +164,8 @@ fn embed_font(family_name: String, font: fontdue::Font) -> BitmapFont {
let glyph = BitmapGlyph {
x: i16::try_from(metrics.xmin).expect("large glyph x coordinate"),
y: i16::try_from(metrics.ymin).expect("large glyph y coordinate"),
width: u16::try_from(metrics.width).expect("large width"),
height: u16::try_from(metrics.height).expect("large height"),
width: i16::try_from(metrics.width).expect("large width"),
height: i16::try_from(metrics.height).expect("large height"),
x_advance: i16::try_from(metrics.advance_width as i64)
.expect("large advance width"),
data: bitmap,