LibGfx: Remove bit casting in OpenType Maxp table after construction

Store references to both versions of the struct in a Variant, and reject
versions we don't support.
This commit is contained in:
Sam Atkins 2023-10-26 16:05:18 +01:00 committed by Andreas Kling
parent e4b3ee09e2
commit cef4d4821b
Notes: sideshowbarker 2024-07-17 01:55:29 +09:00
2 changed files with 22 additions and 8 deletions

View file

@ -118,15 +118,29 @@ u16 Hhea::number_of_h_metrics() const
ErrorOr<Maxp> Maxp::from_slice(ReadonlyBytes slice)
{
if (slice.size() < sizeof(MaximumProfileVersion0_5))
// All Maximum Profile tables begin with a version.
if (slice.size() < sizeof(Version16Dot16))
return Error::from_string_literal("Could not load Maxp: Not enough data");
Version16Dot16 const& version = *bit_cast<Version16Dot16 const*>(slice.data());
return Maxp(slice);
if (version.major == 0 && version.minor == 5) {
if (slice.size() < sizeof(MaximumProfileVersion0_5))
return Error::from_string_literal("Could not load Maxp: Not enough data");
return Maxp(bit_cast<MaximumProfileVersion0_5 const*>(slice.data()));
}
if (version.major == 1 && version.minor == 0) {
if (slice.size() < sizeof(MaximumProfileVersion1_0))
return Error::from_string_literal("Could not load Maxp: Not enough data");
return Maxp(bit_cast<MaximumProfileVersion1_0 const*>(slice.data()));
}
return Error::from_string_literal("Could not load Maxp: Unrecognized version");
}
u16 Maxp::num_glyphs() const
{
return header().num_glyphs;
return m_data.visit([](auto const* any) { return any->num_glyphs; });
}
ErrorOr<Hmtx> Hmtx::from_slice(ReadonlyBytes slice, u32 num_glyphs, u32 number_of_h_metrics)

View file

@ -201,14 +201,14 @@ private:
};
static_assert(AssertSize<MaximumProfileVersion1_0, 32>());
MaximumProfileVersion0_5 const& header() const { return *bit_cast<MaximumProfileVersion0_5 const*>(m_slice.data()); }
Maxp(ReadonlyBytes slice)
: m_slice(slice)
Maxp(Variant<MaximumProfileVersion0_5 const*, MaximumProfileVersion1_0 const*> data)
: m_data(move(data))
{
VERIFY(m_data.visit([](auto const* any) { return any != nullptr; }));
}
ReadonlyBytes m_slice;
// NOTE: Whichever pointer is present is non-null, but Variant can't contain references.
Variant<MaximumProfileVersion0_5 const*, MaximumProfileVersion1_0 const*> m_data;
};
struct GlyphHorizontalMetrics {