[lcar] Use multiformat convention

This commit is contained in:
Ebrahim Byagowi 2019-08-14 14:29:01 +04:30
parent bfffe85dd7
commit a5aa67b9f2
1 changed files with 92 additions and 27 deletions

View File

@ -38,6 +38,80 @@ namespace AAT {
typedef ArrayOf<HBINT16> LigCaretClassEntry; typedef ArrayOf<HBINT16> LigCaretClassEntry;
struct lcarFormat0
{
unsigned int get_lig_carets (hb_font_t *font,
hb_direction_t direction,
hb_codepoint_t glyph,
unsigned int start_offset,
unsigned int *caret_count /* IN/OUT */,
hb_position_t *caret_array /* OUT */,
const void *base) const
{
const OffsetTo<LigCaretClassEntry>* entry_offset = lookupTable.get_value (glyph,
font->face->get_num_glyphs ());
const LigCaretClassEntry& array = entry_offset ? base+*entry_offset : Null (LigCaretClassEntry);
if (caret_count)
{
hb_array_t<const HBINT16> arr = array.sub_array (start_offset, caret_count);
for (unsigned int i = 0; i < arr.length; ++i)
caret_array[i] = font->em_scale_dir (arr[i], direction);
}
return array.len;
}
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<LigCaretClassEntry>>
lookupTable; /* data Lookup table associating glyphs */
public:
DEFINE_SIZE_MIN (2);
};
struct lcarFormat1
{
unsigned int get_lig_carets (hb_font_t *font,
hb_direction_t direction,
hb_codepoint_t glyph,
unsigned int start_offset,
unsigned int *caret_count /* IN/OUT */,
hb_position_t *caret_array /* OUT */,
const void *base) const
{
const OffsetTo<LigCaretClassEntry>* entry_offset = lookupTable.get_value (glyph,
font->face->get_num_glyphs ());
const LigCaretClassEntry& array = entry_offset ? base+*entry_offset : Null (LigCaretClassEntry);
if (caret_count)
{
hb_array_t<const HBINT16> arr = array.sub_array (start_offset, caret_count);
for (unsigned int i = 0; i < arr.length; ++i)
{
hb_position_t x = 0, y = 0;
font->get_glyph_contour_point_for_origin (glyph, arr[i], direction, &x, &y);
caret_array[i] = HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y;
}
}
return array.len;
}
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<LigCaretClassEntry>>
lookupTable; /* data Lookup table associating glyphs */
public:
DEFINE_SIZE_MIN (2);
};
struct lcar struct lcar
{ {
static constexpr hb_tag_t tableTag = HB_AAT_TAG_lcar; static constexpr hb_tag_t tableTag = HB_AAT_TAG_lcar;
@ -49,45 +123,36 @@ struct lcar
unsigned int *caret_count /* IN/OUT */, unsigned int *caret_count /* IN/OUT */,
hb_position_t *caret_array /* OUT */) const hb_position_t *caret_array /* OUT */) const
{ {
const OffsetTo<LigCaretClassEntry>* entry_offset = lookup.get_value (glyph,
font->face->get_num_glyphs ());
const LigCaretClassEntry& array = entry_offset ? this+*entry_offset : Null (LigCaretClassEntry);
if (caret_count)
{
hb_array_t<const HBINT16> arr = array.sub_array (start_offset, caret_count);
switch (format) switch (format)
{ {
case 0: case 0: return u.format0.get_lig_carets (font, direction, glyph, start_offset,
for (unsigned int i = 0; i < arr.length; ++i) caret_count, caret_array, this);
caret_array[i] = font->em_scale_dir (arr[i], direction); case 1: return u.format1.get_lig_carets (font, direction, glyph, start_offset,
break; caret_count, caret_array, this);
case 1: default:if (caret_count) *caret_count = 0; return 0;
for (unsigned int i = 0; i < arr.length; ++i)
{
hb_position_t x, y;
font->get_glyph_contour_point_for_origin (glyph, arr[i], direction, &x, &y);
caret_array[i] = HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y;
} }
break;
}
}
return array.len;
} }
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);
lookup.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:
FixedVersion<>version; /* Version number of the ligature caret table */ FixedVersion<>version; /* Version number of the ligature caret table */
HBUINT16 format; /* Format of the ligature caret table. */ HBUINT16 format; /* Format of the ligature caret table. */
Lookup<OffsetTo<LigCaretClassEntry>> union {
lookup; /* data Lookup table associating glyphs */ lcarFormat0 format0;
lcarFormat0 format1;
} u;
public: public:
DEFINE_SIZE_MIN (8); DEFINE_SIZE_MIN (8);
}; };