From 75376d68344c556d8739a0ef30eea8cb0e8328af Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Thu, 26 Oct 2023 17:16:40 +0100 Subject: [PATCH] LibGfx: Remove bit casting in OpenType Hmtx table after construction Store the variable-length data in Spans instead. --- .../Libraries/LibGfx/Font/OpenType/Tables.cpp | 28 ++++++++++++------- .../Libraries/LibGfx/Font/OpenType/Tables.h | 12 ++++---- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/Userland/Libraries/LibGfx/Font/OpenType/Tables.cpp b/Userland/Libraries/LibGfx/Font/OpenType/Tables.cpp index 4a74d2dd8d..706d8dc08f 100644 --- a/Userland/Libraries/LibGfx/Font/OpenType/Tables.cpp +++ b/Userland/Libraries/LibGfx/Font/OpenType/Tables.cpp @@ -145,27 +145,35 @@ u16 Maxp::num_glyphs() const ErrorOr Hmtx::from_slice(ReadonlyBytes slice, u32 num_glyphs, u32 number_of_h_metrics) { - if (slice.size() < number_of_h_metrics * sizeof(LongHorMetric) + (num_glyphs - number_of_h_metrics) * sizeof(u16)) { + if (slice.size() < number_of_h_metrics * sizeof(LongHorMetric) + (num_glyphs - number_of_h_metrics) * sizeof(i16)) return Error::from_string_literal("Could not load Hmtx: Not enough data"); + + // The Horizontal Metrics table is LongHorMetric[number_of_h_metrics] followed by i16[num_glyphs - number_of_h_metrics]; + ReadonlySpan long_hor_metrics { bit_cast(slice.data()), number_of_h_metrics }; + ReadonlySpan left_side_bearings {}; + auto number_of_left_side_bearings = num_glyphs - number_of_h_metrics; + if (number_of_left_side_bearings > 0) { + left_side_bearings = { + bit_cast(slice.offset(number_of_h_metrics * sizeof(LongHorMetric))), + number_of_left_side_bearings + }; } - return Hmtx(slice, num_glyphs, number_of_h_metrics); + return Hmtx(long_hor_metrics, left_side_bearings); } GlyphHorizontalMetrics Hmtx::get_glyph_horizontal_metrics(u32 glyph_id) const { - VERIFY(glyph_id < m_num_glyphs); - auto const* long_hor_metrics = bit_cast(m_slice.data()); - if (glyph_id < m_number_of_h_metrics) { + VERIFY(glyph_id < m_long_hor_metrics.size() + m_left_side_bearings.size()); + if (glyph_id < m_long_hor_metrics.size()) { return GlyphHorizontalMetrics { - .advance_width = static_cast(long_hor_metrics[glyph_id].advance_width), - .left_side_bearing = static_cast(long_hor_metrics[glyph_id].lsb), + .advance_width = m_long_hor_metrics[glyph_id].advance_width, + .left_side_bearing = m_long_hor_metrics[glyph_id].lsb, }; } - auto const* left_side_bearings = bit_cast const*>(m_slice.offset(m_number_of_h_metrics * sizeof(LongHorMetric))); return GlyphHorizontalMetrics { - .advance_width = static_cast(long_hor_metrics[m_number_of_h_metrics - 1].advance_width), - .left_side_bearing = static_cast(left_side_bearings[glyph_id - m_number_of_h_metrics]), + .advance_width = m_long_hor_metrics.last().advance_width, + .left_side_bearing = m_left_side_bearings[glyph_id - m_long_hor_metrics.size()], }; } diff --git a/Userland/Libraries/LibGfx/Font/OpenType/Tables.h b/Userland/Libraries/LibGfx/Font/OpenType/Tables.h index b03ce0d34f..57d3696e90 100644 --- a/Userland/Libraries/LibGfx/Font/OpenType/Tables.h +++ b/Userland/Libraries/LibGfx/Font/OpenType/Tables.h @@ -260,16 +260,14 @@ private: }; static_assert(AssertSize()); - Hmtx(ReadonlyBytes slice, u32 num_glyphs, u32 number_of_h_metrics) - : m_slice(slice) - , m_num_glyphs(num_glyphs) - , m_number_of_h_metrics(number_of_h_metrics) + Hmtx(ReadonlySpan long_hor_metrics, ReadonlySpan left_side_bearings) + : m_long_hor_metrics(long_hor_metrics) + , m_left_side_bearings(left_side_bearings) { } - ReadonlyBytes m_slice; - u32 m_num_glyphs { 0 }; - u32 m_number_of_h_metrics { 0 }; + ReadonlySpan m_long_hor_metrics; + ReadonlySpan m_left_side_bearings; }; // https://learn.microsoft.com/en-us/typography/opentype/spec/os2