[cbdt] Clean up some more

Almost there..
This commit is contained in:
Behdad Esfahbod 2016-12-02 21:36:42 -08:00
parent ce09e90e15
commit d495fc5e38
2 changed files with 131 additions and 41 deletions

View File

@ -39,6 +39,14 @@ struct SmallGlyphMetrics
return_trace (c->check_struct (this)); return_trace (c->check_struct (this));
} }
inline void get_extents (hb_glyph_extents_t *extents) const
{
extents->x_bearing = bearingX;
extents->y_bearing = bearingY;
extents->width = width;
extents->height = height;
}
BYTE height; BYTE height;
BYTE width; BYTE width;
CHAR bearingX; CHAR bearingX;
@ -75,17 +83,14 @@ struct SBitLineMetrics
/* /*
* Index Subtables. * Index Subtables.
*/ */
struct IndexSubtable struct IndexSubtableHeader
{ {
USHORT firstGlyphIndex; inline bool sanitize (hb_sanitize_context_t *c) const
USHORT lastGlyphIndex; {
ULONG offsetToSubtable; TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
DEFINE_SIZE_STATIC(8);
};
struct IndexSubHeader
{
USHORT indexFormat; USHORT indexFormat;
USHORT imageFormat; USHORT imageFormat;
ULONG imageDataOffset; ULONG imageDataOffset;
@ -95,12 +100,108 @@ struct IndexSubHeader
struct IndexSubtableFormat1 struct IndexSubtableFormat1
{ {
IndexSubHeader header; inline bool sanitize (hb_sanitize_context_t *c, unsigned int glyph_count) const
ULONG offsetArrayZ[VAR]; {
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
c->check_array (offsetArrayZ, offsetArrayZ[0].static_size, glyph_count + 1));
}
bool get_image_data (unsigned int idx,
unsigned int *offset,
unsigned int *length) const
{
if (unlikely (offsetArrayZ[idx + 1] <= offsetArrayZ[idx]))
return false;
*offset = header.imageDataOffset + offsetArrayZ[idx];
*length = offsetArrayZ[idx + 1] - offsetArrayZ[idx];
return true;
}
IndexSubtableHeader header;
Offset<ULONG> offsetArrayZ[VAR];
DEFINE_SIZE_ARRAY(8, offsetArrayZ); DEFINE_SIZE_ARRAY(8, offsetArrayZ);
}; };
struct IndexSubtable
{
inline bool sanitize (hb_sanitize_context_t *c, unsigned int glyph_count) const
{
TRACE_SANITIZE (this);
if (!u.header.sanitize (c)) return_trace (false);
switch (u.header.indexFormat) {
case 1: return_trace (u.format1.sanitize (c, glyph_count));
default:return_trace (true);
}
}
inline bool get_extents (hb_glyph_extents_t *extents) const
{
switch (u.header.indexFormat) {
case 2: case 5: /* TODO */
case 1: case 3: case 4: /* Variable-metrics formats do not have metrics here. */
default:return (false);
}
}
bool get_image_data (unsigned int idx,
unsigned int *offset,
unsigned int *length,
unsigned int *format) const
{
*format = u.header.imageFormat;
switch (u.header.indexFormat) {
case 1: return u.format1.get_image_data (idx, offset, length);
default: return false;
}
}
protected:
union {
IndexSubtableHeader header;
IndexSubtableFormat1 format1;
} u;
public:
DEFINE_SIZE_UNION (8, header);
};
struct IndexSubtableRecord
{
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
firstGlyphIndex <= lastGlyphIndex &&
offsetToSubtable.sanitize (c, this, lastGlyphIndex - firstGlyphIndex + 1));
}
inline bool get_extents (hb_glyph_extents_t *extents) const
{
return (this+offsetToSubtable).get_extents (extents);
}
bool get_image_data (unsigned int gid,
unsigned int *offset,
unsigned int *length,
unsigned int *format) const
{
if (gid < firstGlyphIndex || gid > lastGlyphIndex)
{
return false;
}
return (this+offsetToSubtable).get_image_data (gid - firstGlyphIndex,
offset, length, format);
}
USHORT firstGlyphIndex;
USHORT lastGlyphIndex;
OffsetTo<IndexSubtable, ULONG> offsetToSubtable;
DEFINE_SIZE_STATIC(8);
};
/* /*
* Glyph Bitmap Data Formats. * Glyph Bitmap Data Formats.
*/ */
@ -119,11 +220,16 @@ struct IndexSubtableArray
inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return_trace (c->check_struct (this)); // XXX if (unlikely (!c->check_array (&indexSubtablesZ, indexSubtablesZ[0].static_size, sizeof (count))))
return_trace (false);
for (unsigned int i = 0; i < count; i++)
if (unlikely (!indexSubtablesZ[i].sanitize (c, this)))
return_trace (false);
return_trace (true);
} }
public: public:
const IndexSubtable* find_table (hb_codepoint_t glyph, unsigned int numTables) const const IndexSubtableRecord* find_table (hb_codepoint_t glyph, unsigned int numTables) const
{ {
for (unsigned int i = 0; i < numTables; ++i) for (unsigned int i = 0; i < numTables; ++i)
{ {
@ -137,7 +243,7 @@ struct IndexSubtableArray
} }
protected: protected:
IndexSubtable indexSubtablesZ[VAR]; IndexSubtableRecord indexSubtablesZ[VAR];
public: public:
DEFINE_SIZE_ARRAY(0, indexSubtablesZ); DEFINE_SIZE_ARRAY(0, indexSubtablesZ);

View File

@ -250,41 +250,25 @@ struct hb_ot_face_cbdt_accelerator_t
return false; return false;
} }
const OT::IndexSubtableArray& subtables = const OT::IndexSubtableArray& subtables = this->cblc + sizeTable->indexSubtableArrayOffset;
OT::StructAtOffset<OT::IndexSubtableArray> (this->cblc, sizeTable->indexSubtableArrayOffset); const OT::IndexSubtableRecord *subtable_record = subtables.find_table (glyph, sizeTable->numberOfIndexSubtables);
const OT::IndexSubtable* subtable = subtables.find_table(glyph, sizeTable->numberOfIndexSubtables); if (subtable_record == NULL) {
if (subtable == NULL) {
return false; return false;
} }
unsigned int offsetToSubtable = sizeTable->indexSubtableArrayOffset + subtable->offsetToSubtable; if (subtable_record->get_extents (extents))
const OT::IndexSubHeader& header = return true;
OT::StructAtOffset<OT::IndexSubHeader> (this->cblc, offsetToSubtable);
unsigned int imageDataOffset = header.imageDataOffset; unsigned int image_offset = 0, image_length = 0, image_format = 0;
switch (header.indexFormat) if (!subtable_record->get_image_data (glyph, &image_offset, &image_length, &image_format))
{ return false;
case 1:
{
const OT::IndexSubtableFormat1& format1 =
OT::StructAtOffset<OT::IndexSubtableFormat1> (this->cblc, offsetToSubtable);
imageDataOffset += format1.offsetArrayZ[glyph - subtable->firstGlyphIndex];
}
break;
default:
// TODO: Support other index subtable format.
return false;
}
switch (header.imageFormat) switch (image_format)
{ {
case 17: { case 17: {
const OT::GlyphBitmapDataFormat17& glyphFormat17 = const OT::GlyphBitmapDataFormat17& glyphFormat17 =
OT::StructAtOffset<OT::GlyphBitmapDataFormat17> (this->cbdt, imageDataOffset); OT::StructAtOffset<OT::GlyphBitmapDataFormat17> (this->cbdt, image_offset);
extents->x_bearing = glyphFormat17.glyphMetrics.bearingX; glyphFormat17.glyphMetrics.get_extents (extents);
extents->y_bearing = glyphFormat17.glyphMetrics.bearingY;
extents->width = glyphFormat17.glyphMetrics.width;
extents->height = -glyphFormat17.glyphMetrics.height;
} }
break; break;
default: default: