1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-14 02:18:07 +00:00

fixup! refactor(core): safe iface for get_glyph_data

This commit is contained in:
obrusvit 2024-12-13 15:36:39 +01:00
parent 80fa6c254d
commit 74a84516f9

View File

@ -46,6 +46,8 @@ impl<'a> Glyph<'a> {
let width = data[0] as i16; let width = data[0] as i16;
let height = data[1] as i16; let height = data[1] as i16;
let size = calculate_glyph_size(data);
ensure!(data.len() == size, "Invalid glyph data size");
Glyph { Glyph {
width, width,
height, height,
@ -144,62 +146,70 @@ impl GlyphData {
}; };
let gl_data = self.get_glyph_data(ch as u16); let gl_data = self.get_glyph_data(ch as u16);
ensure!(gl_data.is_some(), "Failed to load glyph"); Glyph::load(unwrap!(gl_data, "Failed to load glyph"))
Glyph::load(gl_data.unwrap())
}
fn calculate_glyph_size(header: &[u8]) -> usize {
let width = header[0] as i16;
let height = header[1] as i16;
let data_bytes = match constant::FONT_BPP {
1 => (width * height + 7) / 8, // packed bits
2 => (width * height + 3) / 4, // packed bits
4 => (width + 1) / 2 * height, // row aligned to bytes
8 => width * height,
_ => fatal_error!("Unsupported font bpp"),
};
5 + data_bytes as usize // header (5 bytes) + bitmap data
} }
fn get_glyph_data(&self, codepoint: u16) -> Option<&[u8]> { fn get_glyph_data(&self, codepoint: u16) -> Option<&[u8]> {
display::get_font_info(self.font.into()).map(|font_info| { display::get_font_info(self.font.into()).map(|font_info| {
if codepoint >= ' ' as u16 && codepoint < 0x7F { if codepoint >= ' ' as u16 && codepoint < 0x7F {
// ASCII character // ASCII character
let offset = codepoint - ' ' as u16;
unsafe { unsafe {
let ptr = *font_info let ptr = *font_info.glyph_data.offset(offset as isize);
.glyph_data self.load_glyph_from_ptr(ptr)
.offset((codepoint - ' ' as u16) as isize);
let header = slice::from_raw_parts(ptr, 2);
let full_size = Self::calculate_glyph_size(header);
slice::from_raw_parts(ptr, full_size)
} }
} else { } else {
#[cfg(feature = "translations")] #[cfg(feature = "translations")]
{ {
if codepoint >= 0x7F { if codepoint >= 0x7F {
// UTF8 character from embedded blob // UTF8 character from embedded blob
if let Some(guard) = &self.translations_guard { if let Some(glyph) = self
if let Some(translations) = guard.as_ref() { .translations_guard
if let Some(glyph) = .as_ref()
translations.get_utf8_glyph(codepoint, self.font as u16) .and_then(|guard| guard.as_ref())
{ .and_then(|translations| {
return glyph; translations.get_utf8_glyph(codepoint, self.font as u16)
} })
} {
return glyph;
} }
} }
} }
unsafe { self.glyph_nonprintable()
let ptr = font_info.glyph_nonprintable;
let header = slice::from_raw_parts(ptr, 2);
let full_size = Self::calculate_glyph_size(header);
slice::from_raw_parts(ptr, full_size)
}
} }
}) })
} }
/// Returns glyph data slice from a raw pointer by reading the header and calculating full size.
unsafe fn load_glyph_from_ptr(&self, ptr: *const u8) -> &[u8] {
unsafe {
let header = slice::from_raw_parts(ptr, 2);
let full_size = calculate_glyph_size(header);
slice::from_raw_parts(ptr, full_size)
}
}
/// Returns glyph data slize for non-printable characters.
fn glyph_nonprintable(&self) -> &[u8] {
display::get_font_info(self.font.into())
.map(|font_info| unsafe { self.load_glyph_from_ptr(font_info.glyph_nonprintable) })
.unwrap()
}
}
fn calculate_glyph_size(header: &[u8]) -> usize {
let width = header[0] as i16;
let height = header[1] as i16;
let data_bytes = match constant::FONT_BPP {
1 => (width * height + 7) / 8, // packed bits
2 => (width * height + 3) / 4, // packed bits
4 => (width + 1) / 2 * height, // row aligned to bytes
8 => width * height,
_ => fatal_error!("Unsupported font bpp"),
};
5 + data_bytes as usize // header (5 bytes) + bitmap data
} }
/// Font constants. Keep in sync with `font_id_t` definition in /// Font constants. Keep in sync with `font_id_t` definition in