mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 05:47:34 +00:00
LibGfx/OpenType: Validate we can read the active cmap subtable format
We now reject fonts where the active cmap subtable is in a format we can't read yet, instead of silently drawing squares for all glyphs. This doesn't fire at all for my 1000-file PDF test set, but seems like a good thing to check. (Instead of duplicating the switch, I first tried making a glyph_id_for_code_point_or_else() that returns ErrorOr<u32> and then make both glyph_id_for_code_point() and validate_format_can_be_read() call that, but I liked less how that worked out -- felt too clever.)
This commit is contained in:
parent
be8b5b794f
commit
93ee01041f
3 changed files with 27 additions and 0 deletions
|
@ -79,9 +79,31 @@ Optional<Cmap::Subtable> Cmap::subtable(u32 index) const
|
|||
return Subtable(subtable_slice, platform_id, encoding_id);
|
||||
}
|
||||
|
||||
ErrorOr<void> Cmap::validate_active_cmap_format() const
|
||||
{
|
||||
auto opt_subtable = subtable(m_active_index);
|
||||
VERIFY(opt_subtable.has_value());
|
||||
return opt_subtable.value().validate_format_can_be_read();
|
||||
}
|
||||
|
||||
ErrorOr<void> Cmap::Subtable::validate_format_can_be_read() const
|
||||
{
|
||||
// Keep in sync with switch in glyph_id_for_code_point().
|
||||
switch (format()) {
|
||||
case Format::ByteEncoding:
|
||||
case Format::SegmentToDelta:
|
||||
case Format::TrimmedTable:
|
||||
case Format::SegmentedCoverage:
|
||||
return {};
|
||||
default:
|
||||
return Error::from_string_view("Unimplemented cmap format"sv);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Implement the missing formats.
|
||||
u32 Cmap::Subtable::glyph_id_for_code_point(u32 code_point) const
|
||||
{
|
||||
// Keep in sync with switch in validate_format_can_be_read().
|
||||
switch (format()) {
|
||||
case Format::ByteEncoding:
|
||||
return glyph_id_for_code_point_table_0(code_point);
|
||||
|
|
|
@ -55,6 +55,9 @@ public:
|
|||
, m_encoding_id(encoding_id)
|
||||
{
|
||||
}
|
||||
|
||||
ErrorOr<void> validate_format_can_be_read() const;
|
||||
|
||||
// Returns 0 if glyph not found. This corresponds to the "missing glyph"
|
||||
u32 glyph_id_for_code_point(u32 code_point) const;
|
||||
Optional<Platform> platform_id() const;
|
||||
|
@ -107,6 +110,7 @@ public:
|
|||
u32 num_subtables() const;
|
||||
Optional<Subtable> subtable(u32 index) const;
|
||||
void set_active_index(u32 index) { m_active_index = index; }
|
||||
ErrorOr<void> validate_active_cmap_format() const;
|
||||
// Returns 0 if glyph not found. This corresponds to the "missing glyph"
|
||||
u32 glyph_id_for_code_point(u32 code_point) const;
|
||||
|
||||
|
|
|
@ -264,6 +264,7 @@ ErrorOr<NonnullRefPtr<Font>> Font::try_load_from_offset(ReadonlyBytes buffer, u3
|
|||
}
|
||||
if (!active_cmap_index.has_value())
|
||||
return Error::from_string_literal("No suitable cmap subtable found");
|
||||
TRY(cmap.subtable(active_cmap_index.value()).value().validate_format_can_be_read());
|
||||
cmap.set_active_index(active_cmap_index.value());
|
||||
|
||||
return adopt_ref(*new Font(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue