diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh index 9d39da591..2a1cd61bf 100644 --- a/src/hb-ot-glyf-table.hh +++ b/src/hb-ot-glyf-table.hh @@ -231,19 +231,18 @@ struct glyf _zero_instruction_length (hb_bytes_t glyph) { const GlyphHeader &glyph_header = StructAtOffset (&glyph, 0); - int16_t num_contours = (int16_t) glyph_header.numberOfContours; - if (num_contours <= 0) return; // only for simple glyphs + if (!glyph_header.is_simple_glyph ()) return; // only for simple glyphs - unsigned int contours_length = GlyphHeader::static_size + 2 * num_contours; - const HBUINT16 &instruction_length = StructAtOffset (&glyph, - contours_length); - (HBUINT16 &) instruction_length = 0; + unsigned int instruction_len_offset = glyph_header.simple_instruction_len_offset (); + const HBUINT16 &instruction_len = StructAtOffset (&glyph, + instruction_len_offset); + (HBUINT16 &) instruction_len = 0; } static bool _remove_composite_instruction_flag (hb_bytes_t glyph) { const GlyphHeader &glyph_header = StructAtOffset (&glyph, 0); - if (glyph_header.numberOfContours >= 0) return true; // only for composites + if (!glyph_header.is_composite_glyph ()) return true; // only for composites /* remove WE_HAVE_INSTRUCTIONS from flags in dest */ OT::glyf::CompositeGlyphHeader::Iterator composite_it; @@ -280,6 +279,24 @@ struct glyf struct GlyphHeader { + unsigned int simple_instruction_len_offset () const + { return static_size + 2 * numberOfContours; } + + unsigned int simple_length (unsigned int instruction_len) const + { return simple_instruction_len_offset () + 2 + instruction_len; } + + bool is_composite_glyph () const { return numberOfContours < 0; } + bool is_simple_glyph () const { return numberOfContours > 0; } + + void get_extents (hb_glyph_extents_t *extents) const + { + extents->x_bearing = hb_min (xMin, xMax); + extents->y_bearing = hb_max (yMin, yMax); + extents->width = hb_max (xMin, xMax) - extents->x_bearing; + extents->height = hb_min (yMin, yMax) - extents->y_bearing; + } + + protected: HBINT16 numberOfContours; /* If the number of contours is * greater than or equal to zero, * this is a simple glyph; if negative, @@ -288,7 +305,7 @@ struct glyf FWORD yMin; /* Minimum y for coordinate data. */ FWORD xMax; /* Maximum x for coordinate data. */ FWORD yMax; /* Maximum y for coordinate data. */ - + public: DEFINE_SIZE_STATIC (10); }; @@ -368,7 +385,7 @@ struct glyf return false; /* Empty glyph; zero extents. */ const GlyphHeader &glyph_header = StructAtOffset (glyph_data, 0); - if (glyph_header.numberOfContours < 0) + if (glyph_header.is_composite_glyph ()) { const CompositeGlyphHeader *possible = &StructAfter (glyph_header); @@ -452,16 +469,15 @@ struct glyf const char *glyph = ((const char *) glyf_table) + start_offset; const char * const glyph_end = glyph + (*end_offset - start_offset); const GlyphHeader &glyph_header = StructAtOffset (glyph, 0); - int16_t num_contours = (int16_t) glyph_header.numberOfContours; - if (num_contours < 0) + if (glyph_header.is_composite_glyph ()) /* Trimming for composites not implemented. * If removing hints it falls out of that. */ return true; - else if (num_contours > 0) + else if (glyph_header.is_simple_glyph ()) { /* simple glyph w/contours, possibly trimmable */ - glyph += GlyphHeader::static_size + 2 * num_contours; + glyph += glyph_header.simple_instruction_len_offset (); if (unlikely (glyph + 2 >= glyph_end)) return false; uint16_t nCoordinates = (uint16_t) StructAtOffset (glyph - 2, 0) + 1; @@ -555,10 +571,8 @@ struct glyf return glyph.length == 0; } const GlyphHeader &glyph_header = StructAtOffset (&glyph, 0); - int16_t num_contours = (int16_t) glyph_header.numberOfContours; - if (num_contours < 0) + if (glyph_header.is_composite_glyph ()) { - // composite glyph unsigned int start = glyph.length; unsigned int end = glyph.length; unsigned int glyph_offset = &glyph - glyf_table; @@ -585,8 +599,7 @@ struct glyf } else { - /* simple glyph */ - unsigned int instruction_len_offset = GlyphHeader::static_size + 2 * num_contours; + unsigned int instruction_len_offset = glyph_header.simple_instruction_len_offset (); if (unlikely (instruction_len_offset + 2 > glyph.length)) { DEBUG_MSG (SUBSET, nullptr, "Glyph size is too short, missing field " @@ -597,7 +610,7 @@ struct glyf const HBUINT16 &instruction_len = StructAtOffset (&glyph, instruction_len_offset); /* Out of bounds of the current glyph */ - if (unlikely (instruction_len_offset + 2 + instruction_len > glyph.length)) + if (unlikely (glyph_header.simple_length (instruction_len) > glyph.length)) { DEBUG_MSG (SUBSET, nullptr, "The instructions array overruns the " "glyph's boundaries."); @@ -619,14 +632,7 @@ struct glyf const GlyphHeader &glyph_header = StructAtOffset (glyf_table, start_offset); - - extents->x_bearing = hb_min (glyph_header.xMin, glyph_header.xMax); - extents->y_bearing = hb_max (glyph_header.yMin, glyph_header.yMax); - extents->width = hb_max (glyph_header.xMin, glyph_header.xMax) - - extents->x_bearing; - extents->height = hb_min (glyph_header.yMin, glyph_header.yMax) - - extents->y_bearing; - + glyph_header.get_extents (extents); return true; } @@ -709,20 +715,17 @@ struct glyf } const GlyphHeader& header = StructAtOffset (&source_glyph, 0); - int16_t num_contours = (int16_t) header.numberOfContours; - DEBUG_MSG (SUBSET, nullptr, "new_gid %d (%d contours) drop %d instruction bytes " + DEBUG_MSG (SUBSET, nullptr, "new_gid %d drop %d instruction bytes " "from %d byte source glyph", - new_gid, num_contours, instruction_len, source_glyph.length); - if (num_contours < 0) + new_gid, instruction_len, source_glyph.length); + if (header.is_composite_glyph ()) { - /* composite, just chop instructions off the end */ + /* just chop instructions off the end for composite glyphs */ dest_start = hb_bytes_t (&source_glyph, source_glyph.length - instruction_len); } else { - /* simple glyph */ - unsigned int glyph_length = GlyphHeader::static_size + 2 * header.numberOfContours - + 2 + instruction_len; + unsigned int glyph_length = header.simple_length (instruction_len); dest_start = hb_bytes_t (&source_glyph, glyph_length - instruction_len); dest_end = hb_bytes_t (&source_glyph + glyph_length, source_glyph.length - glyph_length);