gems/vfs_font: sanity-check glyph against font bb

When using the fonts_fs, the geometry of individual glyphs can change
potentially at any time, after having obtained font-global constraints
once. In particular, a glyph can exceed the bounding box of the font
cell. The VFS font utility must take safety precautions against such
violations.

Fixes #5374
This commit is contained in:
Norman Feske 2024-11-01 16:47:39 +01:00 committed by Christian Helmuth
parent cb5eb740c0
commit ec1316e1cb

View File

@ -60,11 +60,22 @@ class Genode::Vfs_font : public Text_painter::Font
Glyph_header() { } Glyph_header() { }
Glyph glyph() const { return Glyph { .width = _width, Advance_info advance_info() const
.height = _height, {
return { .width = _width, .advance = _advance() };
}
void with_glyph(Text_painter::Area const bb, auto const &fn) const
{
/* consider glyph bounds exceeding the font's bounding box */
uint8_t const clipped_h = uint8_t(_width ? (bb.count() / _width) : 0u);
fn(Glyph { .width = _width,
.height = min(_height, clipped_h),
.vpos = _vpos, .vpos = _vpos,
.advance = _advance(), .advance = _advance(),
.values = _values }; } .values = _values });
}
} __attribute__((packed)); } __attribute__((packed));
@ -149,7 +160,8 @@ class Genode::Vfs_font : public Text_painter::Font
{ {
_glyphs_file.read(_file_pos(c), _buffer); _glyphs_file.read(_file_pos(c), _buffer);
fn.apply(_buffer.header.glyph()); _buffer.header.with_glyph(_bounding_box, [&] (Glyph const &glyph) {
fn.apply(glyph); });
} }
Advance_info advance_info(Codepoint c) const override Advance_info advance_info(Codepoint c) const override
@ -158,9 +170,7 @@ class Genode::Vfs_font : public Text_painter::Font
_glyphs_file.read(_file_pos(c), header_buffer); _glyphs_file.read(_file_pos(c), header_buffer);
Glyph const glyph = _buffer.header.glyph(); return _buffer.header.advance_info();
return Advance_info { .width = glyph.width, .advance = glyph.advance };
} }
unsigned baseline() const override { return _baseline; } unsigned baseline() const override { return _baseline; }