mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-20 09:49:15 +03: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
Notes:
sideshowbarker
2024-07-17 06:46:15 +09:00
Author: https://github.com/nico Commit: https://github.com/SerenityOS/serenity/commit/93ee01041f Pull-request: https://github.com/SerenityOS/serenity/pull/23118 Reviewed-by: https://github.com/AtkinsSJ
@ -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…
Reference in New Issue
Block a user