From bfffe85dd7d7557e10ec9f9886b86fe0d8b4a7a2 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Wed, 14 Aug 2019 13:55:49 +0430 Subject: [PATCH] [opbd] Use multiformat convention on the table --- src/hb-aat-layout-opbd-table.hh | 116 ++++++++++++++++++++++++-------- 1 file changed, 89 insertions(+), 27 deletions(-) diff --git a/src/hb-aat-layout-opbd-table.hh b/src/hb-aat-layout-opbd-table.hh index 80ed1034..4e023407 100644 --- a/src/hb-aat-layout-opbd-table.hh +++ b/src/hb-aat-layout-opbd-table.hh @@ -53,42 +53,104 @@ struct OpticalBounds DEFINE_SIZE_STATIC (8); }; -struct opbd +struct opbdFormat0 { - static constexpr hb_tag_t tableTag = HB_AAT_TAG_opbd; + bool get_bounds (hb_font_t *font, hb_codepoint_t glyph_id, + hb_glyph_extents_t *extents, const void *base) const + { + const OffsetTo *bounds_offset = lookupTable.get_value (glyph_id, font->face->get_num_glyphs ()); + if (!bounds_offset) return false; + const OpticalBounds &bounds = base+*bounds_offset; + + if (extents) + *extents = { + font->em_scale_x (bounds.leftSide), + font->em_scale_y (bounds.topSide), + font->em_scale_x (bounds.rightSide), + font->em_scale_y (bounds.bottomSide) + }; + return true; + } + + bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && lookupTable.sanitize (c, base))); + } + + protected: + Lookup> + lookupTable; /* Lookup table associating glyphs with the four + * int16 values for the left-side, top-side, + * right-side, and bottom-side optical bounds. */ + public: + DEFINE_SIZE_MIN (2); +}; - bool get_optical_bounds (hb_font_t *font, hb_codepoint_t glyph_id, - hb_position_t *left, hb_position_t *top, - hb_position_t *right, hb_position_t *bottom) const +struct opbdFormat1 +{ + bool get_bounds (hb_font_t *font, hb_codepoint_t glyph_id, + hb_glyph_extents_t *extents, const void *base) const { const OffsetTo *bounds_offset = lookupTable.get_value (glyph_id, font->face->get_num_glyphs ()); if (!bounds_offset) return false; - const OpticalBounds &bounds = this+*bounds_offset; - switch (format) + const OpticalBounds &bounds = base+*bounds_offset; + + hb_position_t left = 0, top = 0, right = 0, bottom = 0, ignore; + if (font->get_glyph_contour_point (glyph_id, bounds.leftSide, &left, &ignore) || + font->get_glyph_contour_point (glyph_id, bounds.topSide, &ignore, &top) || + font->get_glyph_contour_point (glyph_id, bounds.rightSide, &right, &ignore) || + font->get_glyph_contour_point (glyph_id, bounds.bottomSide, &ignore, &bottom)) { - case 0: - *left = font->em_scale_x (bounds.leftSide); - *top = font->em_scale_y (bounds.topSide); - *right = font->em_scale_x (bounds.rightSide); - *bottom = font->em_scale_y (bounds.bottomSide); + if (extents) + *extents = {left, top, right, bottom}; return true; - case 1: - hb_position_t ignore; - return font->get_glyph_contour_point (glyph_id, bounds.leftSide, left, &ignore) && - font->get_glyph_contour_point (glyph_id, bounds.topSide, &ignore, top) && - font->get_glyph_contour_point (glyph_id, bounds.rightSide, right, &ignore) && - font->get_glyph_contour_point (glyph_id, bounds.bottomSide, &ignore, bottom); - default: - return false; + } + return false; + } + + bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && lookupTable.sanitize (c, base))); + } + + protected: + Lookup> + lookupTable; /* Lookup table associating glyphs with the four + * int16 values for the left-side, top-side, + * right-side, and bottom-side optical bounds. */ + public: + DEFINE_SIZE_MIN (2); +}; + +struct opbd +{ + static constexpr hb_tag_t tableTag = HB_AAT_TAG_opbd; + + bool get_bounds (hb_font_t *font, hb_codepoint_t glyph_id, + hb_glyph_extents_t *extents) const + { + switch (format) + { + case 0: return u.format0.get_bounds (font, glyph_id, extents, this); + case 1: return u.format1.get_bounds (font, glyph_id, extents, this); + default:return false; } } bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && - version.major == 1 && - lookupTable.sanitize (c, this))); + if (unlikely (!c->check_struct (this) || version.major != 1)) + return_trace (false); + + switch (format) + { + case 0: return_trace (u.format0.sanitize (c, this)); + case 1: return_trace (u.format1.sanitize (c, this)); + default:return_trace (true); + } } protected: @@ -97,10 +159,10 @@ struct opbd HBUINT16 format; /* Format of the optical bounds table. * Format 0 indicates distance and Format 1 indicates * control point. */ - Lookup> - lookupTable; /* Lookup table associating glyphs with the four - * int16 values for the left-side, top-side, - * right-side, and bottom-side optical bounds. */ + union { + opbdFormat0 format0; + opbdFormat1 format1; + } u; public: DEFINE_SIZE_MIN (8); }; -- GitLab