[opbd] Use multiformat convention on the table

This commit is contained in:
Ebrahim Byagowi 2019-08-14 13:55:49 +04:30
parent d6206dbcc4
commit bfffe85dd7
1 changed files with 89 additions and 27 deletions

View File

@ -53,42 +53,104 @@ struct OpticalBounds
DEFINE_SIZE_STATIC (8); DEFINE_SIZE_STATIC (8);
}; };
struct opbdFormat0
{
bool get_bounds (hb_font_t *font, hb_codepoint_t glyph_id,
hb_glyph_extents_t *extents, const void *base) const
{
const OffsetTo<OpticalBounds> *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<OffsetTo<OpticalBounds>>
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 opbdFormat1
{
bool get_bounds (hb_font_t *font, hb_codepoint_t glyph_id,
hb_glyph_extents_t *extents, const void *base) const
{
const OffsetTo<OpticalBounds> *bounds_offset = lookupTable.get_value (glyph_id, font->face->get_num_glyphs ());
if (!bounds_offset) return false;
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))
{
if (extents)
*extents = {left, top, right, bottom};
return true;
}
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<OffsetTo<OpticalBounds>>
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 struct opbd
{ {
static constexpr hb_tag_t tableTag = HB_AAT_TAG_opbd; static constexpr hb_tag_t tableTag = HB_AAT_TAG_opbd;
bool get_optical_bounds (hb_font_t *font, hb_codepoint_t glyph_id, bool get_bounds (hb_font_t *font, hb_codepoint_t glyph_id,
hb_position_t *left, hb_position_t *top, hb_glyph_extents_t *extents) const
hb_position_t *right, hb_position_t *bottom) const
{ {
const OffsetTo<OpticalBounds> *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) switch (format)
{ {
case 0: case 0: return u.format0.get_bounds (font, glyph_id, extents, this);
*left = font->em_scale_x (bounds.leftSide); case 1: return u.format1.get_bounds (font, glyph_id, extents, this);
*top = font->em_scale_y (bounds.topSide); default:return false;
*right = font->em_scale_x (bounds.rightSide);
*bottom = font->em_scale_y (bounds.bottomSide);
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;
} }
} }
bool sanitize (hb_sanitize_context_t *c) const bool sanitize (hb_sanitize_context_t *c) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return_trace (likely (c->check_struct (this) && if (unlikely (!c->check_struct (this) || version.major != 1))
version.major == 1 && return_trace (false);
lookupTable.sanitize (c, this)));
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: protected:
@ -97,10 +159,10 @@ struct opbd
HBUINT16 format; /* Format of the optical bounds table. HBUINT16 format; /* Format of the optical bounds table.
* Format 0 indicates distance and Format 1 indicates * Format 0 indicates distance and Format 1 indicates
* control point. */ * control point. */
Lookup<OffsetTo<OpticalBounds>> union {
lookupTable; /* Lookup table associating glyphs with the four opbdFormat0 format0;
* int16 values for the left-side, top-side, opbdFormat1 format1;
* right-side, and bottom-side optical bounds. */ } u;
public: public:
DEFINE_SIZE_MIN (8); DEFINE_SIZE_MIN (8);
}; };