parent
ce09e90e15
commit
d495fc5e38
|
@ -39,6 +39,14 @@ struct SmallGlyphMetrics
|
|||
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 width;
|
||||
CHAR bearingX;
|
||||
|
@ -75,17 +83,14 @@ struct SBitLineMetrics
|
|||
/*
|
||||
* Index Subtables.
|
||||
*/
|
||||
struct IndexSubtable
|
||||
struct IndexSubtableHeader
|
||||
{
|
||||
USHORT firstGlyphIndex;
|
||||
USHORT lastGlyphIndex;
|
||||
ULONG offsetToSubtable;
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
DEFINE_SIZE_STATIC(8);
|
||||
};
|
||||
|
||||
struct IndexSubHeader
|
||||
{
|
||||
USHORT indexFormat;
|
||||
USHORT imageFormat;
|
||||
ULONG imageDataOffset;
|
||||
|
@ -95,12 +100,108 @@ struct IndexSubHeader
|
|||
|
||||
struct IndexSubtableFormat1
|
||||
{
|
||||
IndexSubHeader header;
|
||||
ULONG offsetArrayZ[VAR];
|
||||
inline bool sanitize (hb_sanitize_context_t *c, unsigned int glyph_count) const
|
||||
{
|
||||
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);
|
||||
};
|
||||
|
||||
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.
|
||||
*/
|
||||
|
@ -119,11 +220,16 @@ struct IndexSubtableArray
|
|||
inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
|
||||
{
|
||||
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:
|
||||
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)
|
||||
{
|
||||
|
@ -137,7 +243,7 @@ struct IndexSubtableArray
|
|||
}
|
||||
|
||||
protected:
|
||||
IndexSubtable indexSubtablesZ[VAR];
|
||||
IndexSubtableRecord indexSubtablesZ[VAR];
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY(0, indexSubtablesZ);
|
||||
|
|
|
@ -250,41 +250,25 @@ struct hb_ot_face_cbdt_accelerator_t
|
|||
return false;
|
||||
}
|
||||
|
||||
const OT::IndexSubtableArray& subtables =
|
||||
OT::StructAtOffset<OT::IndexSubtableArray> (this->cblc, sizeTable->indexSubtableArrayOffset);
|
||||
const OT::IndexSubtable* subtable = subtables.find_table(glyph, sizeTable->numberOfIndexSubtables);
|
||||
if (subtable == NULL) {
|
||||
const OT::IndexSubtableArray& subtables = this->cblc + sizeTable->indexSubtableArrayOffset;
|
||||
const OT::IndexSubtableRecord *subtable_record = subtables.find_table (glyph, sizeTable->numberOfIndexSubtables);
|
||||
if (subtable_record == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int offsetToSubtable = sizeTable->indexSubtableArrayOffset + subtable->offsetToSubtable;
|
||||
const OT::IndexSubHeader& header =
|
||||
OT::StructAtOffset<OT::IndexSubHeader> (this->cblc, offsetToSubtable);
|
||||
if (subtable_record->get_extents (extents))
|
||||
return true;
|
||||
|
||||
unsigned int imageDataOffset = header.imageDataOffset;
|
||||
switch (header.indexFormat)
|
||||
{
|
||||
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;
|
||||
}
|
||||
unsigned int image_offset = 0, image_length = 0, image_format = 0;
|
||||
if (!subtable_record->get_image_data (glyph, &image_offset, &image_length, &image_format))
|
||||
return false;
|
||||
|
||||
switch (header.imageFormat)
|
||||
switch (image_format)
|
||||
{
|
||||
case 17: {
|
||||
const OT::GlyphBitmapDataFormat17& glyphFormat17 =
|
||||
OT::StructAtOffset<OT::GlyphBitmapDataFormat17> (this->cbdt, imageDataOffset);
|
||||
extents->x_bearing = glyphFormat17.glyphMetrics.bearingX;
|
||||
extents->y_bearing = glyphFormat17.glyphMetrics.bearingY;
|
||||
extents->width = glyphFormat17.glyphMetrics.width;
|
||||
extents->height = -glyphFormat17.glyphMetrics.height;
|
||||
OT::StructAtOffset<OT::GlyphBitmapDataFormat17> (this->cbdt, image_offset);
|
||||
glyphFormat17.glyphMetrics.get_extents (extents);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
Loading…
Reference in New Issue