appveyor.yml | 1 src/Makefile.sources | 1 src/hb-open-type-private.hh | 3 src/hb-ot-cbdt-table.hh | 347 ++++++++++++++++++++++++++++++++++++++++++++ src/hb-ot-font.cc | 93 +++++++++++ win32/detectenv-msvc.mak | 4 win32/generate-msvc.mak | 2 7 files changed, 448 insertions(+), 3 deletions(-)
New commits: commit c27d6fcf8db6f02e075dd1868ae67d878fff39d4 Author: Behdad Esfahbod <beh...@behdad.org> Date: Fri Dec 2 22:43:05 2016 -0800 [cbdt] Last of sanitization fixes Should be all good now.. diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 5e02170..1a2d382 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -215,22 +215,25 @@ struct hb_ot_face_cbdt_accelerator_t const OT::CBLC *cblc; const OT::CBDT *cbdt; - float upem = 0.0f; + unsigned int cbdt_len; + float upem; inline void init (hb_face_t *face) { - this->cblc_blob = OT::Sanitizer<OT::CBLC>::sanitize (face->reference_table (HB_OT_TAG_CBLC)); - this->cbdt_blob = OT::Sanitizer<OT::CBDT>::sanitize (face->reference_table (HB_OT_TAG_CBDT)); + upem = face->get_upem(); + + cblc_blob = OT::Sanitizer<OT::CBLC>::sanitize (face->reference_table (HB_OT_TAG_CBLC)); + cbdt_blob = OT::Sanitizer<OT::CBDT>::sanitize (face->reference_table (HB_OT_TAG_CBDT)); + cbdt_len = hb_blob_get_length (cbdt_blob); - if (hb_blob_get_length (this->cblc_blob) == 0) { + if (hb_blob_get_length (cblc_blob) == 0) { cblc = NULL; cbdt = NULL; return; /* Not a bitmap font. */ } - cblc = OT::Sanitizer<OT::CBLC>::lock_instance (this->cblc_blob); - cbdt = OT::Sanitizer<OT::CBDT>::lock_instance (this->cbdt_blob); + cblc = OT::Sanitizer<OT::CBLC>::lock_instance (cblc_blob); + cbdt = OT::Sanitizer<OT::CBDT>::lock_instance (cbdt_blob); - upem = face->get_upem(); } inline void fini (void) @@ -263,9 +266,15 @@ struct hb_ot_face_cbdt_accelerator_t if (!subtable_record->get_image_data (glyph, &image_offset, &image_length, &image_format)) return false; + if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length)) + return false; + switch (image_format) { case 17: { + if (unlikely (image_length < OT::GlyphBitmapDataFormat17::min_size)) + return false; + const OT::GlyphBitmapDataFormat17& glyphFormat17 = OT::StructAtOffset<OT::GlyphBitmapDataFormat17> (this->cbdt, image_offset); glyphFormat17.glyphMetrics.get_extents (extents); commit d495fc5e38038f4cfb20425b1109324fa70bf2f9 Author: Behdad Esfahbod <beh...@behdad.org> Date: Fri Dec 2 21:36:42 2016 -0800 [cbdt] Clean up some more Almost there.. diff --git a/src/hb-ot-cbdt-table.hh b/src/hb-ot-cbdt-table.hh index 3a7cc99..4319067 100644 --- a/src/hb-ot-cbdt-table.hh +++ b/src/hb-ot-cbdt-table.hh @@ -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; - - DEFINE_SIZE_STATIC(8); -}; + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } -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); diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 2d1cf09..5e02170 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -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: commit ce09e90e1502d5f944bafd64e51c29e365a963ae Author: Behdad Esfahbod <beh...@behdad.org> Date: Fri Dec 2 20:12:57 2016 -0800 [cbdt] More sanitize work diff --git a/src/hb-ot-cbdt-table.hh b/src/hb-ot-cbdt-table.hh index dda42f2..3a7cc99 100644 --- a/src/hb-ot-cbdt-table.hh +++ b/src/hb-ot-cbdt-table.hh @@ -72,32 +72,6 @@ struct SBitLineMetrics DEFINE_SIZE_STATIC(12); }; -struct BitmapSizeTable -{ - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - horizontal.sanitize (c) && - vertical.sanitize (c)); - } - - ULONG indexSubtableArrayOffset; - ULONG indexTablesSize; - ULONG numberOfIndexSubtables; - ULONG colorRef; - SBitLineMetrics horizontal; - SBitLineMetrics vertical; - USHORT startGlyphIndex; - USHORT endGlyphIndex; - BYTE ppemX; - BYTE ppemY; - BYTE bitDepth; - CHAR flags; - - DEFINE_SIZE_STATIC(48); -}; - /* * Index Subtables. */ @@ -142,6 +116,12 @@ struct GlyphBitmapDataFormat17 struct IndexSubtableArray { + inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); // XXX + } + public: const IndexSubtable* find_table (hb_codepoint_t glyph, unsigned int numTables) const { @@ -158,6 +138,37 @@ struct IndexSubtableArray protected: IndexSubtable indexSubtablesZ[VAR]; + + public: + DEFINE_SIZE_ARRAY(0, indexSubtablesZ); +}; + +struct BitmapSizeTable +{ + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + indexSubtableArrayOffset.sanitize (c, base, numberOfIndexSubtables) && + c->check_range (&(base+indexSubtableArrayOffset), indexTablesSize) && + horizontal.sanitize (c) && + vertical.sanitize (c)); + } + + OffsetTo<IndexSubtableArray, ULONG> indexSubtableArrayOffset; + ULONG indexTablesSize; + ULONG numberOfIndexSubtables; + ULONG colorRef; + SBitLineMetrics horizontal; + SBitLineMetrics vertical; + USHORT startGlyphIndex; + USHORT endGlyphIndex; + BYTE ppemX; + BYTE ppemY; + BYTE bitDepth; + CHAR flags; + + DEFINE_SIZE_STATIC(48); }; /* @@ -175,7 +186,7 @@ struct CBLC TRACE_SANITIZE (this); return_trace (c->check_struct (this) && likely (version.major == 2 || version.major == 3) && - sizeTables.sanitize (c)); + sizeTables.sanitize (c, this)); } public: diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 25a1ef6..2d1cf09 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -262,30 +262,34 @@ struct hb_ot_face_cbdt_accelerator_t OT::StructAtOffset<OT::IndexSubHeader> (this->cblc, offsetToSubtable); 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]; - switch (header.imageFormat) { - 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; - } - break; - default: - // TODO: Support other image formats. - return false; - } + 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; + } + + switch (header.imageFormat) + { + 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; } break; default: - // TODO: Support other index subtable format. - return false; + // TODO: Support other image formats. + return false; } /* Convert to the font units. */ commit 70eb2ff682344688635cebb716fee0b73557c925 Author: Behdad Esfahbod <beh...@behdad.org> Date: Fri Dec 2 19:51:23 2016 -0800 Check for offset overflows during sanitize diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh index 6b64378..66f1c08 100644 --- a/src/hb-open-type-private.hh +++ b/src/hb-open-type-private.hh @@ -806,6 +806,7 @@ struct OffsetTo : Offset<OffsetType> if (unlikely (!c->check_struct (this))) return_trace (false); unsigned int offset = *this; if (unlikely (!offset)) return_trace (true); + if (unlikely (!c->check_range (base, offset))) return_trace (false); const Type &obj = StructAtOffset<Type> (base, offset); return_trace (likely (obj.sanitize (c)) || neuter (c)); } @@ -816,6 +817,7 @@ struct OffsetTo : Offset<OffsetType> if (unlikely (!c->check_struct (this))) return_trace (false); unsigned int offset = *this; if (unlikely (!offset)) return_trace (true); + if (unlikely (!c->check_range (base, offset))) return_trace (false); const Type &obj = StructAtOffset<Type> (base, offset); return_trace (likely (obj.sanitize (c, user_data)) || neuter (c)); } commit 4b58c9e326acde09d389c699014e4e7f6259f50a Author: Behdad Esfahbod <beh...@behdad.org> Date: Fri Dec 2 19:25:54 2016 -0800 [cbdt] Start fixing sanitization (or lack thereof) diff --git a/src/hb-ot-cbdt-table.hh b/src/hb-ot-cbdt-table.hh index 7615138..dda42f2 100644 --- a/src/hb-ot-cbdt-table.hh +++ b/src/hb-ot-cbdt-table.hh @@ -33,6 +33,12 @@ namespace OT { struct SmallGlyphMetrics { + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + BYTE height; BYTE width; CHAR bearingX; @@ -42,7 +48,14 @@ struct SmallGlyphMetrics DEFINE_SIZE_STATIC(5); }; -struct SBitLineMetrics { +struct SBitLineMetrics +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + CHAR ascender; CHAR decender; BYTE widthMax; @@ -61,6 +74,14 @@ struct SBitLineMetrics { struct BitmapSizeTable { + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + horizontal.sanitize (c) && + vertical.sanitize (c)); + } + ULONG indexSubtableArrayOffset; ULONG indexTablesSize; ULONG numberOfIndexSubtables; @@ -94,41 +115,49 @@ struct IndexSubHeader USHORT indexFormat; USHORT imageFormat; ULONG imageDataOffset; + + DEFINE_SIZE_STATIC(8); }; struct IndexSubtableFormat1 { IndexSubHeader header; - ULONG offsetArray[VAR]; + ULONG offsetArrayZ[VAR]; + + DEFINE_SIZE_ARRAY(8, offsetArrayZ); }; /* * Glyph Bitmap Data Formats. */ + struct GlyphBitmapDataFormat17 { SmallGlyphMetrics glyphMetrics; ULONG dataLen; - BYTE data[VAR]; + BYTE dataZ[VAR]; + + DEFINE_SIZE_ARRAY(9, dataZ); }; struct IndexSubtableArray { public: - const IndexSubtable* find_table(hb_codepoint_t glyph, unsigned int numTables) const + const IndexSubtable* find_table (hb_codepoint_t glyph, unsigned int numTables) const { - for (unsigned int i = 0; i < numTables; ++i) { - unsigned int firstGlyphIndex = indexSubtables[i].firstGlyphIndex; - unsigned int lastGlyphIndex = indexSubtables[i].lastGlyphIndex; + for (unsigned int i = 0; i < numTables; ++i) + { + unsigned int firstGlyphIndex = indexSubtablesZ[i].firstGlyphIndex; + unsigned int lastGlyphIndex = indexSubtablesZ[i].lastGlyphIndex; if (firstGlyphIndex <= glyph && glyph <= lastGlyphIndex) { - return &indexSubtables[i]; + return &indexSubtablesZ[i]; } } return NULL; } protected: - IndexSubtable indexSubtables[VAR]; + IndexSubtable indexSubtablesZ[VAR]; }; /* @@ -144,17 +173,19 @@ struct CBLC inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (true); + return_trace (c->check_struct (this) && + likely (version.major == 2 || version.major == 3) && + sizeTables.sanitize (c)); } public: - const BitmapSizeTable* find_table(hb_codepoint_t glyph) const + const BitmapSizeTable* find_table (hb_codepoint_t glyph) const { // TODO: Make it possible to select strike. - const uint32_t tableSize = numSizes; - for (uint32_t i = 0; i < tableSize; ++i) { - unsigned int startGlyphIndex = sizeTables[i].startGlyphIndex; - unsigned int endGlyphIndex = sizeTables[i].endGlyphIndex; + unsigned int count = sizeTables.len; + for (uint32_t i = 0; i < count; ++i) { + unsigned int startGlyphIndex = sizeTables.array[i].startGlyphIndex; + unsigned int endGlyphIndex = sizeTables.array[i].endGlyphIndex; if (startGlyphIndex <= glyph && glyph <= endGlyphIndex) { return &sizeTables[i]; } @@ -163,10 +194,11 @@ struct CBLC } protected: - ULONG version; - ULONG numSizes; + FixedVersion<>version; + ArrayOf<BitmapSizeTable, ULONG> sizeTables; - BitmapSizeTable sizeTables[VAR]; + public: + DEFINE_SIZE_ARRAY(8, sizeTables); }; /* @@ -181,11 +213,16 @@ struct CBDT inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (true); + return_trace (c->check_struct (this) && + likely (version.major == 2 || version.major == 3)); } protected: - BYTE data[VAR]; + FixedVersion<>version; + BYTE dataZ[VAR]; + + public: + DEFINE_SIZE_ARRAY(4, dataZ); }; } /* namespace OT */ diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index c53fcd5..25a1ef6 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -210,10 +210,10 @@ struct hb_ot_face_glyf_accelerator_t struct hb_ot_face_cbdt_accelerator_t { - hb_blob_t *cblc_blob = NULL; - hb_blob_t *cbdt_blob = NULL; - const OT::CBLC *cblc = NULL; - const OT::CBDT *cbdt = NULL; + hb_blob_t *cblc_blob; + hb_blob_t *cbdt_blob; + const OT::CBLC *cblc; + const OT::CBDT *cbdt; float upem = 0.0f; @@ -223,6 +223,8 @@ struct hb_ot_face_cbdt_accelerator_t this->cbdt_blob = OT::Sanitizer<OT::CBDT>::sanitize (face->reference_table (HB_OT_TAG_CBDT)); if (hb_blob_get_length (this->cblc_blob) == 0) { + cblc = NULL; + cbdt = NULL; return; /* Not a bitmap font. */ } cblc = OT::Sanitizer<OT::CBLC>::lock_instance (this->cblc_blob); @@ -233,10 +235,8 @@ struct hb_ot_face_cbdt_accelerator_t inline void fini (void) { - if (this->cblc_blob) { - hb_blob_destroy (this->cblc_blob); - hb_blob_destroy (this->cbdt_blob); - } + hb_blob_destroy (this->cblc_blob); + hb_blob_destroy (this->cbdt_blob); } inline bool get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const @@ -266,7 +266,7 @@ struct hb_ot_face_cbdt_accelerator_t case 1: { const OT::IndexSubtableFormat1& format1 = OT::StructAtOffset<OT::IndexSubtableFormat1> (this->cblc, offsetToSubtable); - imageDataOffset += format1.offsetArray[glyph - subtable->firstGlyphIndex]; + imageDataOffset += format1.offsetArrayZ[glyph - subtable->firstGlyphIndex]; switch (header.imageFormat) { case 17: { const OT::GlyphBitmapDataFormat17& glyphFormat17 = @@ -288,7 +288,7 @@ struct hb_ot_face_cbdt_accelerator_t return false; } - // Convert to the font units. + /* Convert to the font units. */ extents->x_bearing *= upem / (float)(sizeTable->ppemX); extents->y_bearing *= upem / (float)(sizeTable->ppemY); extents->width *= upem / (float)(sizeTable->ppemX); @@ -558,7 +558,7 @@ hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED, { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; bool ret = ot_font->glyf->get_extents (glyph, extents); - if ( !ret ) + if (!ret) ret = ot_font->cbdt->get_extents (glyph, extents); extents->x_bearing = font->em_scale_x (extents->x_bearing); extents->y_bearing = font->em_scale_y (extents->y_bearing); commit b92ba7bafcd9545a401fb871eb342e6284032c47 Author: Behdad Esfahbod <beh...@behdad.org> Date: Fri Dec 2 15:21:43 2016 -0800 [CBDT] Use CHAR instead of int8_t diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh index df683ca..6b64378 100644 --- a/src/hb-open-type-private.hh +++ b/src/hb-open-type-private.hh @@ -650,6 +650,7 @@ struct IntType DEFINE_SIZE_STATIC (Size); }; +typedef IntType<int8_t , 1> CHAR; /* 8-bit signed integer. */ typedef IntType<uint8_t , 1> BYTE; /* 8-bit unsigned integer. */ typedef IntType<uint16_t, 2> USHORT; /* 16-bit unsigned integer. */ typedef IntType<int16_t, 2> SHORT; /* 16-bit signed integer. */ diff --git a/src/hb-ot-cbdt-table.hh b/src/hb-ot-cbdt-table.hh index 17f15dc..7615138 100644 --- a/src/hb-ot-cbdt-table.hh +++ b/src/hb-ot-cbdt-table.hh @@ -35,26 +35,26 @@ struct SmallGlyphMetrics { BYTE height; BYTE width; - int8_t bearingX; - int8_t bearingY; + CHAR bearingX; + CHAR bearingY; BYTE advance; DEFINE_SIZE_STATIC(5); }; struct SBitLineMetrics { - int8_t ascender; - int8_t decender; + CHAR ascender; + CHAR decender; BYTE widthMax; - int8_t caretSlopeNumerator; - int8_t caretSlopeDenominator; - int8_t caretOffset; - int8_t minOriginSB; - int8_t minAdvanceSB; - int8_t maxBeforeBL; - int8_t minAfterBL; - int8_t padding1; - int8_t padding2; + CHAR caretSlopeNumerator; + CHAR caretSlopeDenominator; + CHAR caretOffset; + CHAR minOriginSB; + CHAR minAdvanceSB; + CHAR maxBeforeBL; + CHAR minAfterBL; + CHAR padding1; + CHAR padding2; DEFINE_SIZE_STATIC(12); }; @@ -72,7 +72,7 @@ struct BitmapSizeTable BYTE ppemX; BYTE ppemY; BYTE bitDepth; - int8_t flags; + CHAR flags; DEFINE_SIZE_STATIC(48); }; commit efca7bf97f9967af4fa399a6665b723af643cecd Author: Behdad Esfahbod <beh...@behdad.org> Date: Fri Dec 2 15:11:37 2016 -0800 Rename 'ebdt' to 'cbdt' since we only support the PNG format diff --git a/src/Makefile.sources b/src/Makefile.sources index 8d2f3c6..166793a 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -20,8 +20,8 @@ HB_BASE_sources = \ hb-object-private.hh \ hb-open-file-private.hh \ hb-open-type-private.hh \ + hb-ot-cbdt-table.hh \ hb-ot-cmap-table.hh \ - hb-ot-ebdt-table.hh \ hb-ot-glyf-table.hh \ hb-ot-head-table.hh \ hb-ot-hhea-table.hh \ diff --git a/src/hb-ot-cbdt-table.hh b/src/hb-ot-cbdt-table.hh new file mode 100644 index 0000000..17f15dc --- /dev/null +++ b/src/hb-ot-cbdt-table.hh @@ -0,0 +1,193 @@ +/* + * Copyright © 2016 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Seigo Nonaka + */ + +#ifndef HB_OT_CBDT_TABLE_HH +#define HB_OT_CBDT_TABLE_HH + +#include "hb-open-type-private.hh" + +namespace OT { + +struct SmallGlyphMetrics +{ + BYTE height; + BYTE width; + int8_t bearingX; + int8_t bearingY; + BYTE advance; + + DEFINE_SIZE_STATIC(5); +}; + +struct SBitLineMetrics { + int8_t ascender; + int8_t decender; + BYTE widthMax; + int8_t caretSlopeNumerator; + int8_t caretSlopeDenominator; + int8_t caretOffset; + int8_t minOriginSB; + int8_t minAdvanceSB; + int8_t maxBeforeBL; + int8_t minAfterBL; + int8_t padding1; + int8_t padding2; + + DEFINE_SIZE_STATIC(12); +}; + +struct BitmapSizeTable +{ + ULONG indexSubtableArrayOffset; + ULONG indexTablesSize; + ULONG numberOfIndexSubtables; + ULONG colorRef; + SBitLineMetrics horizontal; + SBitLineMetrics vertical; + USHORT startGlyphIndex; + USHORT endGlyphIndex; + BYTE ppemX; + BYTE ppemY; + BYTE bitDepth; + int8_t flags; + + DEFINE_SIZE_STATIC(48); +}; + +/* + * Index Subtables. + */ +struct IndexSubtable +{ + USHORT firstGlyphIndex; + USHORT lastGlyphIndex; + ULONG offsetToSubtable; + + DEFINE_SIZE_STATIC(8); +}; + +struct IndexSubHeader +{ + USHORT indexFormat; + USHORT imageFormat; + ULONG imageDataOffset; +}; + +struct IndexSubtableFormat1 +{ + IndexSubHeader header; + ULONG offsetArray[VAR]; +}; + +/* + * Glyph Bitmap Data Formats. + */ +struct GlyphBitmapDataFormat17 +{ + SmallGlyphMetrics glyphMetrics; + ULONG dataLen; + BYTE data[VAR]; +}; + +struct IndexSubtableArray +{ + public: + const IndexSubtable* find_table(hb_codepoint_t glyph, unsigned int numTables) const + { + for (unsigned int i = 0; i < numTables; ++i) { + unsigned int firstGlyphIndex = indexSubtables[i].firstGlyphIndex; + unsigned int lastGlyphIndex = indexSubtables[i].lastGlyphIndex; + if (firstGlyphIndex <= glyph && glyph <= lastGlyphIndex) { + return &indexSubtables[i]; + } + } + return NULL; + } + + protected: + IndexSubtable indexSubtables[VAR]; +}; + +/* + * CBLC -- Color Bitmap Location Table + */ + +#define HB_OT_TAG_CBLC HB_TAG('C','B','L','C') + +struct CBLC +{ + static const hb_tag_t tableTag = HB_OT_TAG_CBLC; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (true); + } + + public: + const BitmapSizeTable* find_table(hb_codepoint_t glyph) const + { + // TODO: Make it possible to select strike. + const uint32_t tableSize = numSizes; + for (uint32_t i = 0; i < tableSize; ++i) { + unsigned int startGlyphIndex = sizeTables[i].startGlyphIndex; + unsigned int endGlyphIndex = sizeTables[i].endGlyphIndex; + if (startGlyphIndex <= glyph && glyph <= endGlyphIndex) { + return &sizeTables[i]; + } + } + return NULL; + } + + protected: + ULONG version; + ULONG numSizes; + + BitmapSizeTable sizeTables[VAR]; +}; + +/* + * CBDT -- Color Bitmap Data Table + */ +#define HB_OT_TAG_CBDT HB_TAG('C','B','D','T') + +struct CBDT +{ + static const hb_tag_t tableTag = HB_OT_TAG_CBDT; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (true); + } + + protected: + BYTE data[VAR]; +}; + +} /* namespace OT */ + +#endif /* HB_OT_CBDT_TABLE_HH */ diff --git a/src/hb-ot-ebdt-table.hh b/src/hb-ot-ebdt-table.hh deleted file mode 100644 index f3d0de6..0000000 --- a/src/hb-ot-ebdt-table.hh +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright © 2016 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Seigo Nonaka - */ - -#ifndef HB_OT_EBDT_TABLE_HH -#define HB_OT_EBDT_TABLE_HH - -#include "hb-open-type-private.hh" - -namespace OT { - -struct SmallGlyphMetrics -{ - BYTE height; - BYTE width; - int8_t bearingX; - int8_t bearingY; - BYTE advance; - - DEFINE_SIZE_STATIC(5); -}; - -struct SBitLineMetrics { - int8_t ascender; - int8_t decender; - BYTE widthMax; - int8_t caretSlopeNumerator; - int8_t caretSlopeDenominator; - int8_t caretOffset; - int8_t minOriginSB; - int8_t minAdvanceSB; - int8_t maxBeforeBL; - int8_t minAfterBL; - int8_t padding1; - int8_t padding2; - - DEFINE_SIZE_STATIC(12); -}; - -struct BitmapSizeTable -{ - ULONG indexSubtableArrayOffset; - ULONG indexTablesSize; - ULONG numberOfIndexSubtables; - ULONG colorRef; - SBitLineMetrics horizontal; - SBitLineMetrics vertical; - USHORT startGlyphIndex; - USHORT endGlyphIndex; - BYTE ppemX; - BYTE ppemY; - BYTE bitDepth; - int8_t flags; - - DEFINE_SIZE_STATIC(48); -}; - -/* - * Index Subtables. - */ -struct IndexSubtable -{ - USHORT firstGlyphIndex; - USHORT lastGlyphIndex; - ULONG offsetToSubtable; - - DEFINE_SIZE_STATIC(8); -}; - -struct IndexSubHeader -{ - USHORT indexFormat; - USHORT imageFormat; - ULONG imageDataOffset; -}; - -struct IndexSubtableFormat1 -{ - IndexSubHeader header; - ULONG offsetArray[VAR]; -}; - -/* - * Glyph Bitmap Data Formats. - */ -struct GlyphBitmapDataFormat17 -{ - SmallGlyphMetrics glyphMetrics; - ULONG dataLen; - BYTE data[VAR]; -}; - -struct IndexSubtableArray -{ - public: - const IndexSubtable* find_table(hb_codepoint_t glyph, unsigned int numTables) const - { - for (unsigned int i = 0; i < numTables; ++i) { - unsigned int firstGlyphIndex = indexSubtables[i].firstGlyphIndex; - unsigned int lastGlyphIndex = indexSubtables[i].lastGlyphIndex; - if (firstGlyphIndex <= glyph && glyph <= lastGlyphIndex) { - return &indexSubtables[i]; - } - } - return NULL; - } - - protected: - IndexSubtable indexSubtables[VAR]; -}; - -/* - * CBLC -- Color Bitmap Location Table - */ - -#define HB_OT_TAG_CBLC HB_TAG('C','B','L','C') - -struct CBLC -{ - static const hb_tag_t tableTag = HB_OT_TAG_CBLC; - - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (true); - } - - public: - const BitmapSizeTable* find_table(hb_codepoint_t glyph) const - { - // TODO: Make it possible to select strike. - const uint32_t tableSize = numSizes; - for (uint32_t i = 0; i < tableSize; ++i) { - unsigned int startGlyphIndex = sizeTables[i].startGlyphIndex; - unsigned int endGlyphIndex = sizeTables[i].endGlyphIndex; - if (startGlyphIndex <= glyph && glyph <= endGlyphIndex) { - return &sizeTables[i]; - } - } - return NULL; - } - - protected: - ULONG version; - ULONG numSizes; - - BitmapSizeTable sizeTables[VAR]; -}; - -/* - * CBDT -- Color Bitmap Data Table - */ -#define HB_OT_TAG_CBDT HB_TAG('C','B','D','T') - -struct CBDT -{ - static const hb_tag_t tableTag = HB_OT_TAG_CBDT; - - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (true); - } - - protected: - BYTE data[VAR]; -}; - -} /* namespace OT */ - -#endif /* HB_OT_EBDT_TABLE_HH */ diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index d9be196..c53fcd5 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -31,7 +31,7 @@ #include "hb-font-private.hh" #include "hb-ot-cmap-table.hh" -#include "hb-ot-ebdt-table.hh" +#include "hb-ot-cbdt-table.hh" #include "hb-ot-glyf-table.hh" #include "hb-ot-head-table.hh" #include "hb-ot-hhea-table.hh" @@ -208,7 +208,7 @@ struct hb_ot_face_glyf_accelerator_t } }; -struct hb_ot_face_ebdt_accelerator_t +struct hb_ot_face_cbdt_accelerator_t { hb_blob_t *cblc_blob = NULL; hb_blob_t *cbdt_blob = NULL; @@ -470,7 +470,7 @@ struct hb_ot_font_t hb_ot_face_metrics_accelerator_t h_metrics; hb_ot_face_metrics_accelerator_t v_metrics; hb_lazy_loader_t<hb_ot_face_glyf_accelerator_t> glyf; - hb_lazy_loader_t<hb_ot_face_ebdt_accelerator_t> ebdt; + hb_lazy_loader_t<hb_ot_face_cbdt_accelerator_t> cbdt; }; @@ -487,7 +487,7 @@ _hb_ot_font_create (hb_face_t *face) ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, HB_TAG_NONE, ot_font->h_metrics.ascender - ot_font->h_metrics.descender); /* TODO Can we do this lazily? */ ot_font->glyf.init (face); - ot_font->ebdt.init (face); + ot_font->cbdt.init (face); return ot_font; } @@ -499,7 +499,7 @@ _hb_ot_font_destroy (hb_ot_font_t *ot_font) ot_font->h_metrics.fini (); ot_font->v_metrics.fini (); ot_font->glyf.fini (); - ot_font->ebdt.fini (); + ot_font->cbdt.fini (); free (ot_font); } @@ -559,7 +559,7 @@ hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED, const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; bool ret = ot_font->glyf->get_extents (glyph, extents); if ( !ret ) - ret = ot_font->ebdt->get_extents (glyph, extents); + ret = ot_font->cbdt->get_extents (glyph, extents); extents->x_bearing = font->em_scale_x (extents->x_bearing); extents->y_bearing = font->em_scale_y (extents->y_bearing); extents->width = font->em_scale_x (extents->width); commit 831852594b777f250efedb76d19bee1cfc8eeaa4 Author: Seigo Nonaka <n...@google.com> Date: Fri Dec 2 15:03:50 2016 -0800 Introduce get_extent support for color bitmap font. (#351) hb_font_get_glyph_extents now works for color bitmap fonts. Currently only font having index format 1 and image format 17 is supported. diff --git a/src/Makefile.sources b/src/Makefile.sources index 5c695c5..8d2f3c6 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -21,6 +21,7 @@ HB_BASE_sources = \ hb-open-file-private.hh \ hb-open-type-private.hh \ hb-ot-cmap-table.hh \ + hb-ot-ebdt-table.hh \ hb-ot-glyf-table.hh \ hb-ot-head-table.hh \ hb-ot-hhea-table.hh \ diff --git a/src/hb-ot-ebdt-table.hh b/src/hb-ot-ebdt-table.hh new file mode 100644 index 0000000..f3d0de6 --- /dev/null +++ b/src/hb-ot-ebdt-table.hh @@ -0,0 +1,193 @@ +/* + * Copyright © 2016 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Seigo Nonaka + */ + +#ifndef HB_OT_EBDT_TABLE_HH +#define HB_OT_EBDT_TABLE_HH + +#include "hb-open-type-private.hh" + +namespace OT { + +struct SmallGlyphMetrics +{ + BYTE height; + BYTE width; + int8_t bearingX; + int8_t bearingY; + BYTE advance; + + DEFINE_SIZE_STATIC(5); +}; + +struct SBitLineMetrics { + int8_t ascender; + int8_t decender; + BYTE widthMax; + int8_t caretSlopeNumerator; + int8_t caretSlopeDenominator; + int8_t caretOffset; + int8_t minOriginSB; + int8_t minAdvanceSB; + int8_t maxBeforeBL; + int8_t minAfterBL; + int8_t padding1; + int8_t padding2; + + DEFINE_SIZE_STATIC(12); +}; + +struct BitmapSizeTable +{ + ULONG indexSubtableArrayOffset; + ULONG indexTablesSize; + ULONG numberOfIndexSubtables; + ULONG colorRef; + SBitLineMetrics horizontal; + SBitLineMetrics vertical; + USHORT startGlyphIndex; + USHORT endGlyphIndex; + BYTE ppemX; + BYTE ppemY; + BYTE bitDepth; + int8_t flags; + + DEFINE_SIZE_STATIC(48); +}; + +/* + * Index Subtables. + */ +struct IndexSubtable +{ + USHORT firstGlyphIndex; + USHORT lastGlyphIndex; + ULONG offsetToSubtable; + + DEFINE_SIZE_STATIC(8); +}; + +struct IndexSubHeader +{ + USHORT indexFormat; + USHORT imageFormat; + ULONG imageDataOffset; +}; + +struct IndexSubtableFormat1 +{ + IndexSubHeader header; + ULONG offsetArray[VAR]; +}; + +/* + * Glyph Bitmap Data Formats. + */ +struct GlyphBitmapDataFormat17 +{ + SmallGlyphMetrics glyphMetrics; + ULONG dataLen; + BYTE data[VAR]; +}; + +struct IndexSubtableArray +{ + public: + const IndexSubtable* find_table(hb_codepoint_t glyph, unsigned int numTables) const + { + for (unsigned int i = 0; i < numTables; ++i) { + unsigned int firstGlyphIndex = indexSubtables[i].firstGlyphIndex; + unsigned int lastGlyphIndex = indexSubtables[i].lastGlyphIndex; + if (firstGlyphIndex <= glyph && glyph <= lastGlyphIndex) { + return &indexSubtables[i]; + } + } + return NULL; + } + + protected: + IndexSubtable indexSubtables[VAR]; +}; + +/* + * CBLC -- Color Bitmap Location Table + */ + +#define HB_OT_TAG_CBLC HB_TAG('C','B','L','C') + +struct CBLC +{ + static const hb_tag_t tableTag = HB_OT_TAG_CBLC; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (true); + } + + public: + const BitmapSizeTable* find_table(hb_codepoint_t glyph) const + { + // TODO: Make it possible to select strike. + const uint32_t tableSize = numSizes; + for (uint32_t i = 0; i < tableSize; ++i) { + unsigned int startGlyphIndex = sizeTables[i].startGlyphIndex; + unsigned int endGlyphIndex = sizeTables[i].endGlyphIndex; + if (startGlyphIndex <= glyph && glyph <= endGlyphIndex) { + return &sizeTables[i]; + } + } + return NULL; + } + + protected: + ULONG version; + ULONG numSizes; + + BitmapSizeTable sizeTables[VAR]; +}; + +/* + * CBDT -- Color Bitmap Data Table + */ +#define HB_OT_TAG_CBDT HB_TAG('C','B','D','T') + +struct CBDT +{ + static const hb_tag_t tableTag = HB_OT_TAG_CBDT; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (true); + } + + protected: + BYTE data[VAR]; +}; + +} /* namespace OT */ + +#endif /* HB_OT_EBDT_TABLE_HH */ diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 20f2f89..d9be196 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -31,6 +31,7 @@ #include "hb-font-private.hh" #include "hb-ot-cmap-table.hh" +#include "hb-ot-ebdt-table.hh" #include "hb-ot-glyf-table.hh" #include "hb-ot-head-table.hh" #include "hb-ot-hhea-table.hh" @@ -207,6 +208,96 @@ struct hb_ot_face_glyf_accelerator_t } }; +struct hb_ot_face_ebdt_accelerator_t +{ + hb_blob_t *cblc_blob = NULL; + hb_blob_t *cbdt_blob = NULL; + const OT::CBLC *cblc = NULL; + const OT::CBDT *cbdt = NULL; + + float upem = 0.0f; + + inline void init (hb_face_t *face) + { + this->cblc_blob = OT::Sanitizer<OT::CBLC>::sanitize (face->reference_table (HB_OT_TAG_CBLC)); + this->cbdt_blob = OT::Sanitizer<OT::CBDT>::sanitize (face->reference_table (HB_OT_TAG_CBDT)); + + if (hb_blob_get_length (this->cblc_blob) == 0) { + return; /* Not a bitmap font. */ + } + cblc = OT::Sanitizer<OT::CBLC>::lock_instance (this->cblc_blob); + cbdt = OT::Sanitizer<OT::CBDT>::lock_instance (this->cbdt_blob); + + upem = face->get_upem(); + } + + inline void fini (void) + { + if (this->cblc_blob) { + hb_blob_destroy (this->cblc_blob); + hb_blob_destroy (this->cbdt_blob); + } + } + + inline bool get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const + { + if (cblc == NULL) { + return false; // Not a color bitmap font. + } + + const OT::BitmapSizeTable* sizeTable = this->cblc->find_table(glyph); + if (sizeTable == NULL) { + 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) { + return false; + } + + unsigned int offsetToSubtable = sizeTable->indexSubtableArrayOffset + subtable->offsetToSubtable; + const OT::IndexSubHeader& header = + OT::StructAtOffset<OT::IndexSubHeader> (this->cblc, offsetToSubtable); + + unsigned int imageDataOffset = header.imageDataOffset; + switch (header.indexFormat) { + case 1: { + const OT::IndexSubtableFormat1& format1 = + OT::StructAtOffset<OT::IndexSubtableFormat1> (this->cblc, offsetToSubtable); + imageDataOffset += format1.offsetArray[glyph - subtable->firstGlyphIndex]; + switch (header.imageFormat) { + 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; + } + break; + default: + // TODO: Support other image formats. + return false; + } + } + break; + default: + // TODO: Support other index subtable format. + return false; + } + + // Convert to the font units. + extents->x_bearing *= upem / (float)(sizeTable->ppemX); + extents->y_bearing *= upem / (float)(sizeTable->ppemY); + extents->width *= upem / (float)(sizeTable->ppemX); + extents->height *= upem / (float)(sizeTable->ppemY); + + return true; + } +}; + typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph); @@ -379,6 +470,7 @@ struct hb_ot_font_t hb_ot_face_metrics_accelerator_t h_metrics; hb_ot_face_metrics_accelerator_t v_metrics; hb_lazy_loader_t<hb_ot_face_glyf_accelerator_t> glyf; + hb_lazy_loader_t<hb_ot_face_ebdt_accelerator_t> ebdt; }; @@ -395,6 +487,7 @@ _hb_ot_font_create (hb_face_t *face) ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, HB_TAG_NONE, ot_font->h_metrics.ascender - ot_font->h_metrics.descender); /* TODO Can we do this lazily? */ ot_font->glyf.init (face); + ot_font->ebdt.init (face); return ot_font; } @@ -406,6 +499,7 @@ _hb_ot_font_destroy (hb_ot_font_t *ot_font) ot_font->h_metrics.fini (); ot_font->v_metrics.fini (); ot_font->glyf.fini (); + ot_font->ebdt.fini (); free (ot_font); } @@ -464,6 +558,8 @@ hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED, { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; bool ret = ot_font->glyf->get_extents (glyph, extents); + if ( !ret ) + ret = ot_font->ebdt->get_extents (glyph, extents); extents->x_bearing = font->em_scale_x (extents->x_bearing); extents->y_bearing = font->em_scale_y (extents->y_bearing); extents->width = font->em_scale_x (extents->width); commit 261837e7202ec584f653f379851e1c6457396b07 Author: Ebrahim Byagowi <ebra...@gnu.org> Date: Fri Oct 28 21:49:11 2016 +0330 Fix "nmake install" when ADDITIONAL_LIB_DIR is provided and test it on CI (#356) diff --git a/appveyor.yml b/appveyor.yml index ddcc9a4..2a0e7c5 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -43,6 +43,7 @@ build_script: - 'if "%compiler%"=="msvc" C:\msys64\usr\bin\bash -lc "cd $APPVEYOR_BUILD_FOLDER; PATH=$PATH:/mingw64/bin:/mingw32/bin; ./autogen.sh; make distdir"' - 'if "%compiler%"=="msvc" cd harfbuzz-*\win32' - 'if "%compiler%"=="msvc" nmake /f Makefile.vc CFG=%CFG% UNISCRIBE=1 DIRECTWRITE=1 FREETYPE=1 FREETYPE_DIR=..\..\vcpkg\installed\%VCPKG_ARCH%\include ADDITIONAL_LIB_DIR=..\..\vcpkg\installed\%VCPKG_ARCH%\lib' + - 'if "%compiler%"=="msvc" nmake /f Makefile.vc CFG=%CFG% UNISCRIBE=1 DIRECTWRITE=1 FREETYPE=1 install' - 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-$MSYS2_ARCH-{freetype,cairo,icu,gettext,gobject-introspection,gcc,gcc-libs,glib2,graphite2,pkg-config}"' - 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "cd $APPVEYOR_BUILD_FOLDER; PATH=$PATH:/mingw64/bin:/mingw32/bin; ./autogen.sh --with-uniscribe --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2 --build=$MINGW_CHOST --host=$MINGW_CHOST --prefix=$MINGW_PREFIX; make; make check"' diff --git a/win32/detectenv-msvc.mak b/win32/detectenv-msvc.mak index 41f4bd0..80a5eed 100644 --- a/win32/detectenv-msvc.mak +++ b/win32/detectenv-msvc.mak @@ -129,10 +129,10 @@ LDFLAGS_ARCH = /machine:x86 !if "$(VALID_CFGSET)" == "TRUE" CFLAGS = $(CFLAGS_ADD) /W3 /Zi /I.. /I..\src /I. /I$(PREFIX)\include -LDFLAGS_BASE = $(LDFLAGS_ARCH) /libpath:$(PREFIX)\lib /DEBUG !if "$(ADDITIONAL_LIB_DIR)" != "" -LDFLAGS_BASE = $(LDFLAGS_ARCH) /libpath:$(ADDITIONAL_LIB_DIR) +ADDITIONAL_LIB_ARG = /libpath:$(ADDITIONAL_LIB_DIR) !endif +LDFLAGS_BASE = $(LDFLAGS_ARCH) /libpath:$(PREFIX)\lib $(ADDITIONAL_LIB_ARG) /DEBUG !if "$(CFG)" == "debug" LDFLAGS = $(LDFLAGS_BASE) diff --git a/win32/generate-msvc.mak b/win32/generate-msvc.mak index 7c17a94..57cfb6e 100644 --- a/win32/generate-msvc.mak +++ b/win32/generate-msvc.mak @@ -23,4 +23,4 @@ $(HB_GOBJECT_ENUM_GENERATED_SOURCES): ..\src\hb-gobject-enums.h.tmpl ..\src\hb-g # Create the build directories $(CFG)\$(PLAT)\harfbuzz $(CFG)\$(PLAT)\harfbuzz-icu $(CFG)\$(PLAT)\harfbuzz-gobject $(CFG)\$(PLAT)\util: - @-mkdir -p $@ + @-md $@
_______________________________________________ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/harfbuzz