diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 950a0ee11..5e215a4ad 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -69,6 +69,156 @@ struct CmapSubtableFormat0 struct CmapSubtableFormat4 { + struct segment_plan + { + HBUINT16 start_code; + HBUINT16 end_code; + bool use_delta; + }; + + bool serialize (hb_serialize_context_t *c, + const hb_subset_plan_t *plan, + const hb_vector_t &segments) + { + TRACE_SERIALIZE (this); + + if (unlikely (!c->extend_min (*this))) return_trace (false); + + this->format.set (4); + this->length.set (get_sub_table_size (segments)); + + this->segCountX2.set (segments.len * 2); + this->entrySelector.set (MAX (1u, _hb_bit_storage (segments.len)) - 1); + this->searchRange.set (2 * (1u << this->entrySelector)); + this->rangeShift.set (segments.len * 2 > this->searchRange + ? 2 * segments.len - this->searchRange + : 0); + + HBUINT16 *end_count = c->allocate_size (HBUINT16::static_size * segments.len); + c->allocate_size (HBUINT16::static_size); // 2 bytes of padding. + HBUINT16 *start_count = c->allocate_size (HBUINT16::static_size * segments.len); + HBINT16 *id_delta = c->allocate_size (HBUINT16::static_size * segments.len); + HBUINT16 *id_range_offset = c->allocate_size (HBUINT16::static_size * segments.len); + + if (id_range_offset == nullptr) + return_trace (false); + + for (unsigned int i = 0; i < segments.len; i++) + { + end_count[i].set (segments[i].end_code); + start_count[i].set (segments[i].start_code); + if (segments[i].use_delta) + { + hb_codepoint_t cp = segments[i].start_code; + hb_codepoint_t start_gid = 0; + if (unlikely (!hb_subset_plan_new_gid_for_codepoint (plan, cp, &start_gid) && cp != 0xFFFF)) + return_trace (false); + id_delta[i].set (start_gid - segments[i].start_code); + } else { + id_delta[i].set (0); + unsigned int num_codepoints = segments[i].end_code - segments[i].start_code + 1; + HBUINT16 *glyph_id_array = c->allocate_size (HBUINT16::static_size * num_codepoints); + if (glyph_id_array == nullptr) + return_trace (false); + // From the cmap spec: + // + // id_range_offset[i]/2 + // + (cp - segments[i].start_code) + // + (id_range_offset + i) + // = + // glyph_id_array + (cp - segments[i].start_code) + // + // So, solve for id_range_offset[i]: + // + // id_range_offset[i] + // = + // 2 * (glyph_id_array - id_range_offset - i) + id_range_offset[i].set (2 * ( + glyph_id_array - id_range_offset - i)); + for (unsigned int j = 0; j < num_codepoints; j++) + { + hb_codepoint_t cp = segments[i].start_code + j; + hb_codepoint_t new_gid; + if (unlikely (!hb_subset_plan_new_gid_for_codepoint (plan, cp, &new_gid))) + return_trace (false); + glyph_id_array[j].set (new_gid); + } + } + } + + return_trace (true); + } + + static inline size_t get_sub_table_size (const hb_vector_t &segments) + { + size_t segment_size = 0; + for (unsigned int i = 0; i < segments.len; i++) + { + // Parallel array entries + segment_size += + 2 // end count + + 2 // start count + + 2 // delta + + 2; // range offset + + if (!segments[i].use_delta) + // Add bytes for the glyph index array entries for this segment. + segment_size += (segments[i].end_code - segments[i].start_code + 1) * 2; + } + + return min_size + + 2 // Padding + + segment_size; + } + + static inline bool create_sub_table_plan (const hb_subset_plan_t *plan, + hb_vector_t *segments) + { + segment_plan *segment = nullptr; + hb_codepoint_t last_gid = 0; + for (unsigned int i = 0; i < plan->codepoints.len; i++) { + hb_codepoint_t cp = plan->codepoints[i]; + hb_codepoint_t new_gid; + if (unlikely (!hb_subset_plan_new_gid_for_codepoint (plan, cp, &new_gid))) + { + DEBUG_MSG(SUBSET, nullptr, "Unable to find new gid for %04x", cp); + return false; + } + + if (cp > 0xFFFF) { + // We are now outside of unicode BMP, stop adding to this cmap. + break; + } + + if (!segment + || cp != segment->end_code + 1) + { + segment = segments->push (); + segment->start_code.set (cp); + segment->end_code.set (cp); + segment->use_delta = true; + } else { + segment->end_code.set (cp); + if (last_gid + 1 != new_gid) + // gid's are not consecutive in this segment so delta + // cannot be used. + segment->use_delta = false; + } + + last_gid = new_gid; + } + + // There must be a final entry with end_code == 0xFFFF. Check if we need to add one. + if (segment == nullptr || segment->end_code != 0xFFFF) { + segment = segments->push (); + segment->start_code.set (0xFFFF); + segment->end_code.set (0xFFFF); + segment->use_delta = true; + } + + return true; + } + struct accelerator_t { inline void init (const CmapSubtableFormat4 *subtable) @@ -175,6 +325,8 @@ struct CmapSubtableFormat4 return_trace (16 + 4 * (unsigned int) segCountX2 <= length); } + + protected: HBUINT16 format; /* Format number is set to 4. */ HBUINT16 length; /* This is the length in bytes of the @@ -294,7 +446,7 @@ struct CmapSubtableLongSegmented } inline bool serialize (hb_serialize_context_t *c, - hb_vector_t &group_data) + const hb_vector_t &group_data) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); @@ -319,6 +471,69 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented static inline hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group, hb_codepoint_t u) { return group.glyphID + (u - group.startCharCode); } + + + bool serialize (hb_serialize_context_t *c, + const hb_vector_t &groups) + { + if (unlikely (!c->extend_min (*this))) return false; + + this->format.set (12); + this->reserved.set (0); + this->length.set (get_sub_table_size (groups)); + + return CmapSubtableLongSegmented::serialize (c, groups); + } + + static inline size_t get_sub_table_size (const hb_vector_t &groups) + { + return 16 + 12 * groups.len; + } + + static inline bool create_sub_table_plan (const hb_subset_plan_t *plan, + hb_vector_t *groups) + { + CmapSubtableLongGroup *group = nullptr; + for (unsigned int i = 0; i < plan->codepoints.len; i++) { + + hb_codepoint_t cp = plan->codepoints[i]; + hb_codepoint_t new_gid; + if (unlikely (!hb_subset_plan_new_gid_for_codepoint (plan, cp, &new_gid))) + { + DEBUG_MSG(SUBSET, nullptr, "Unable to find new gid for %04x", cp); + return false; + } + + if (!group || !_is_gid_consecutive (group, cp, new_gid)) + { + group = groups->push (); + group->startCharCode.set (cp); + group->endCharCode.set (cp); + group->glyphID.set (new_gid); + } else + { + group->endCharCode.set (cp); + } + } + + DEBUG_MSG(SUBSET, nullptr, "cmap"); + for (unsigned int i = 0; i < groups->len; i++) { + CmapSubtableLongGroup& group = (*groups)[i]; + DEBUG_MSG(SUBSET, nullptr, " %d: U+%04X-U+%04X, gid %d-%d", i, (uint32_t) group.startCharCode, (uint32_t) group.endCharCode, (uint32_t) group.glyphID, (uint32_t) group.glyphID + ((uint32_t) group.endCharCode - (uint32_t) group.startCharCode)); + } + + return true; + } + + private: + static inline bool _is_gid_consecutive (CmapSubtableLongGroup *group, + hb_codepoint_t cp, + hb_codepoint_t new_gid) + { + return (cp - 1 == group->endCharCode) && + new_gid == group->glyphID + (cp - group->startCharCode); + } + }; struct CmapSubtableFormat13 : CmapSubtableLongSegmented @@ -531,6 +746,33 @@ struct cmap { static const hb_tag_t tableTag = HB_OT_TAG_cmap; + struct subset_plan { + subset_plan(void) + { + format4_segments.init(); + format12_groups.init(); + } + + ~subset_plan(void) + { + format4_segments.fini(); + format12_groups.fini(); + } + + inline size_t final_size() const + { + return 4 // header + + 8 * 3 // 3 EncodingRecord + + CmapSubtableFormat4::get_sub_table_size (this->format4_segments) + + CmapSubtableFormat12::get_sub_table_size (this->format12_groups); + } + + // Format 4 + hb_vector_t format4_segments; + // Format 12 + hb_vector_t format12_groups; + }; + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -539,50 +781,17 @@ struct cmap encodingRecord.sanitize (c, this)); } - static inline bool _is_gid_consecutive (CmapSubtableLongGroup *group, - hb_codepoint_t cp, - hb_codepoint_t new_gid) + inline bool _create_plan (const hb_subset_plan_t *plan, + subset_plan *cmap_plan) const { - return (cp - 1 == group->endCharCode) && - new_gid == group->glyphID + (cp - group->startCharCode); + if (unlikely( !CmapSubtableFormat4::create_sub_table_plan (plan, &cmap_plan->format4_segments))) + return false; + + return CmapSubtableFormat12::create_sub_table_plan (plan, &cmap_plan->format12_groups); } - inline bool populate_groups (hb_subset_plan_t *plan, - hb_vector_t *groups) const - { - CmapSubtableLongGroup *group = nullptr; - for (unsigned int i = 0; i < plan->codepoints.len; i++) { - - hb_codepoint_t cp = plan->codepoints[i]; - hb_codepoint_t new_gid; - if (unlikely (!hb_subset_plan_new_gid_for_codepoint (plan, cp, &new_gid))) - { - DEBUG_MSG(SUBSET, nullptr, "Unable to find new gid for %04x", cp); - return false; - } - - if (!group || !_is_gid_consecutive (group, cp, new_gid)) - { - group = groups->push (); - group->startCharCode.set (cp); - group->endCharCode.set (cp); - group->glyphID.set (new_gid); - } else - { - group->endCharCode.set (cp); - } - } - - DEBUG_MSG(SUBSET, nullptr, "cmap"); - for (unsigned int i = 0; i < groups->len; i++) { - CmapSubtableLongGroup& group = (*groups)[i]; - DEBUG_MSG(SUBSET, nullptr, " %d: U+%04X-U+%04X, gid %d-%d", i, (uint32_t) group.startCharCode, (uint32_t) group.endCharCode, (uint32_t) group.glyphID, (uint32_t) group.glyphID + ((uint32_t) group.endCharCode - (uint32_t) group.startCharCode)); - } - - return true; - } - - inline bool _subset (hb_vector_t &groups, + inline bool _subset (const hb_subset_plan_t *plan, + const subset_plan &cmap_subset_plan, size_t dest_sz, void *dest) const { @@ -596,25 +805,46 @@ struct cmap cmap->version.set (0); - if (unlikely (!cmap->encodingRecord.serialize (&c, /* numTables */ 1))) return false; + if (unlikely (!cmap->encodingRecord.serialize (&c, /* numTables */ 3))) + return false; - EncodingRecord &rec = cmap->encodingRecord[0]; - rec.platformID.set (3); // Windows - rec.encodingID.set (10); // Unicode UCS-4 + // TODO(grieger): Convert the below to a for loop - /* capture offset to subtable */ - CmapSubtable &subtable = rec.subtable.serialize (&c, cmap); + // Format 4, Plat 0 Encoding Record + EncodingRecord &format4_plat0_rec = cmap->encodingRecord[0]; + format4_plat0_rec.platformID.set (0); // Unicode + format4_plat0_rec.encodingID.set (3); - subtable.u.format.set (12); + // Format 4, Plat 3 Encoding Record + EncodingRecord &format4_plat3_rec = cmap->encodingRecord[1]; + format4_plat3_rec.platformID.set (3); // Windows + format4_plat3_rec.encodingID.set (1); // Unicode BMP - CmapSubtableFormat12 &format12 = subtable.u.format12; - if (unlikely (!c.extend_min (format12))) return false; + // Format 12 Encoding Record + EncodingRecord &format12_rec = cmap->encodingRecord[2]; + format12_rec.platformID.set (3); // Windows + format12_rec.encodingID.set (10); // Unicode UCS-4 - format12.format.set (12); - format12.reserved.set (0); - format12.length.set (16 + 12 * groups.len); + // Write out format 4 sub table + { + CmapSubtable &subtable = format4_plat0_rec.subtable.serialize (&c, cmap); + format4_plat3_rec.subtable.set (format4_plat0_rec.subtable); + subtable.u.format.set (4); - if (unlikely (!format12.serialize (&c, groups))) return false; + CmapSubtableFormat4 &format4 = subtable.u.format4; + if (unlikely (!format4.serialize (&c, plan, cmap_subset_plan.format4_segments))) + return false; + } + + // Write out format 12 sub table. + { + CmapSubtable &subtable = format12_rec.subtable.serialize (&c, cmap); + subtable.u.format.set (12); + + CmapSubtableFormat12 &format12 = subtable.u.format12; + if (unlikely (!format12.serialize (&c, cmap_subset_plan.format12_groups))) + return false; + } c.end_serialize (); @@ -623,24 +853,25 @@ struct cmap inline bool subset (hb_subset_plan_t *plan) const { - hb_auto_t > groups; + subset_plan cmap_subset_plan; - if (unlikely (!populate_groups (plan, &groups))) return false; + if (unlikely (!_create_plan (plan, &cmap_subset_plan))) + { + DEBUG_MSG(SUBSET, nullptr, "Failed to generate a cmap subsetting plan."); + return false; + } // We now know how big our blob needs to be - // TODO use APIs from the structs to get size? - size_t dest_sz = 4 // header - + 8 // 1 EncodingRecord - + 16 // Format 12 header - + 12 * groups.len; // SequentialMapGroup records + size_t dest_sz = cmap_subset_plan.final_size(); void *dest = malloc (dest_sz); if (unlikely (!dest)) { DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %lu for cmap subset output", (unsigned long) dest_sz); return false; } - if (unlikely (!_subset (groups, dest_sz, dest))) + if (unlikely (!_subset (plan, cmap_subset_plan, dest_sz, dest))) { + DEBUG_MSG(SUBSET, nullptr, "Failed to perform subsetting of cmap."); free (dest); return false; } diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index 0c11765c5..d70215b00 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -40,7 +40,7 @@ _hb_codepoint_t_cmp (const void *pa, const void *pb) } hb_bool_t -hb_subset_plan_new_gid_for_codepoint (hb_subset_plan_t *plan, +hb_subset_plan_new_gid_for_codepoint (const hb_subset_plan_t *plan, hb_codepoint_t codepoint, hb_codepoint_t *new_gid) { @@ -58,7 +58,7 @@ hb_subset_plan_new_gid_for_codepoint (hb_subset_plan_t *plan, } hb_bool_t -hb_subset_plan_new_gid_for_old_id (hb_subset_plan_t *plan, +hb_subset_plan_new_gid_for_old_id (const hb_subset_plan_t *plan, hb_codepoint_t old_gid, hb_codepoint_t *new_gid) { diff --git a/src/hb-subset-plan.hh b/src/hb-subset-plan.hh index 3b9db03f2..1c8697b66 100644 --- a/src/hb-subset-plan.hh +++ b/src/hb-subset-plan.hh @@ -65,19 +65,19 @@ hb_subset_plan_create (hb_face_t *face, hb_subset_input_t *input); HB_INTERNAL hb_bool_t -hb_subset_plan_new_gid_for_old_id(hb_subset_plan_t *plan, - hb_codepoint_t old_gid, - hb_codepoint_t *new_gid /* OUT */); +hb_subset_plan_new_gid_for_old_id (const hb_subset_plan_t *plan, + hb_codepoint_t old_gid, + hb_codepoint_t *new_gid /* OUT */); HB_INTERNAL hb_bool_t -hb_subset_plan_new_gid_for_codepoint(hb_subset_plan_t *plan, - hb_codepoint_t codepont, - hb_codepoint_t *new_gid /* OUT */); +hb_subset_plan_new_gid_for_codepoint (const hb_subset_plan_t *plan, + hb_codepoint_t codepont, + hb_codepoint_t *new_gid /* OUT */); HB_INTERNAL hb_bool_t -hb_subset_plan_add_table(hb_subset_plan_t *plan, - hb_tag_t tag, - hb_blob_t *contents); +hb_subset_plan_add_table (hb_subset_plan_t *plan, + hb_tag_t tag, + hb_blob_t *contents); HB_INTERNAL void hb_subset_plan_destroy (hb_subset_plan_t *plan); diff --git a/test/api/fonts/Roboto-Regular.D7,D8,D9,DA,DE.ttf b/test/api/fonts/Roboto-Regular.D7,D8,D9,DA,DE.ttf index 38799ccbe..3a71f53f2 100644 Binary files a/test/api/fonts/Roboto-Regular.D7,D8,D9,DA,DE.ttf and b/test/api/fonts/Roboto-Regular.D7,D8,D9,DA,DE.ttf differ diff --git a/test/api/test-subset-cmap.c b/test/api/test-subset-cmap.c index 52548742d..84d34bcd7 100644 --- a/test/api/test-subset-cmap.c +++ b/test/api/test-subset-cmap.c @@ -33,7 +33,7 @@ static void test_subset_cmap (void) { hb_face_t *face_abc = hb_subset_test_open_font ("fonts/Roboto-Regular.abc.ttf"); - hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Roboto-Regular.ac.cmap-format12-only.ttf"); + hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Roboto-Regular.ac.ttf"); hb_set_t *codepoints = hb_set_create (); hb_face_t *face_abc_subset; @@ -74,7 +74,7 @@ test_subset_cmap_non_consecutive_glyphs (void) static void test_subset_cmap_noop (void) { - hb_face_t *face_abc = hb_subset_test_open_font("fonts/Roboto-Regular.abc.cmap-format12-only.ttf"); + hb_face_t *face_abc = hb_subset_test_open_font("fonts/Roboto-Regular.abc.ttf"); hb_set_t *codepoints = hb_set_create(); hb_face_t *face_abc_subset; diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.default.61,62,63.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.default.61,62,63.ttf index 02cd7efb4..12d92081b 100644 Binary files a/test/subset/data/expected/basics/Roboto-Regular.abc.default.61,62,63.ttf and b/test/subset/data/expected/basics/Roboto-Regular.abc.default.61,62,63.ttf differ diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.default.61,63.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.default.61,63.ttf index 4942ad0cd..1af233f48 100644 Binary files a/test/subset/data/expected/basics/Roboto-Regular.abc.default.61,63.ttf and b/test/subset/data/expected/basics/Roboto-Regular.abc.default.61,63.ttf differ diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.default.61.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.default.61.ttf index 08fe7718a..a699eea0b 100644 Binary files a/test/subset/data/expected/basics/Roboto-Regular.abc.default.61.ttf and b/test/subset/data/expected/basics/Roboto-Regular.abc.default.61.ttf differ diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.default.62.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.default.62.ttf index 8d7e6b227..52706dc90 100644 Binary files a/test/subset/data/expected/basics/Roboto-Regular.abc.default.62.ttf and b/test/subset/data/expected/basics/Roboto-Regular.abc.default.62.ttf differ diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.default.63.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.default.63.ttf index 0f3a934ce..3de7c7734 100644 Binary files a/test/subset/data/expected/basics/Roboto-Regular.abc.default.63.ttf and b/test/subset/data/expected/basics/Roboto-Regular.abc.default.63.ttf differ diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61,62,63.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61,62,63.ttf index 70206add6..52dc47457 100644 Binary files a/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61,62,63.ttf and b/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61,62,63.ttf differ diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61,63.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61,63.ttf index c74c02995..1873672bf 100644 Binary files a/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61,63.ttf and b/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61,63.ttf differ diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61.ttf index 8ba816d77..128eae016 100644 Binary files a/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61.ttf and b/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61.ttf differ diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.62.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.62.ttf index 837438a55..122b10976 100644 Binary files a/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.62.ttf and b/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.62.ttf differ diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.63.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.63.ttf index 311737ab4..381e97e93 100644 Binary files a/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.63.ttf and b/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.63.ttf differ diff --git a/test/subset/data/expected/full-font/Roboto-Regular.default.1FC,21,41,20,62,63.ttf b/test/subset/data/expected/full-font/Roboto-Regular.default.1FC,21,41,20,62,63.ttf index 60e361d2c..93efe6553 100644 Binary files a/test/subset/data/expected/full-font/Roboto-Regular.default.1FC,21,41,20,62,63.ttf and b/test/subset/data/expected/full-font/Roboto-Regular.default.1FC,21,41,20,62,63.ttf differ diff --git a/test/subset/data/expected/full-font/Roboto-Regular.default.61,62,63.ttf b/test/subset/data/expected/full-font/Roboto-Regular.default.61,62,63.ttf index 1fc430a4e..d4d26d7ea 100644 Binary files a/test/subset/data/expected/full-font/Roboto-Regular.default.61,62,63.ttf and b/test/subset/data/expected/full-font/Roboto-Regular.default.61,62,63.ttf differ diff --git a/test/subset/data/expected/full-font/Roboto-Regular.default.D7,D8,D9,DA,DE.ttf b/test/subset/data/expected/full-font/Roboto-Regular.default.D7,D8,D9,DA,DE.ttf index 2ff535362..7e271f22b 100644 Binary files a/test/subset/data/expected/full-font/Roboto-Regular.default.D7,D8,D9,DA,DE.ttf and b/test/subset/data/expected/full-font/Roboto-Regular.default.D7,D8,D9,DA,DE.ttf differ diff --git a/test/subset/data/expected/full-font/Roboto-Regular.drop-hints.1FC,21,41,20,62,63.ttf b/test/subset/data/expected/full-font/Roboto-Regular.drop-hints.1FC,21,41,20,62,63.ttf index 98f01e19a..99b91bd31 100644 Binary files a/test/subset/data/expected/full-font/Roboto-Regular.drop-hints.1FC,21,41,20,62,63.ttf and b/test/subset/data/expected/full-font/Roboto-Regular.drop-hints.1FC,21,41,20,62,63.ttf differ diff --git a/test/subset/data/expected/full-font/Roboto-Regular.drop-hints.61,62,63.ttf b/test/subset/data/expected/full-font/Roboto-Regular.drop-hints.61,62,63.ttf index ea212f03d..eb94906a8 100644 Binary files a/test/subset/data/expected/full-font/Roboto-Regular.drop-hints.61,62,63.ttf and b/test/subset/data/expected/full-font/Roboto-Regular.drop-hints.61,62,63.ttf differ diff --git a/test/subset/data/expected/full-font/Roboto-Regular.drop-hints.D7,D8,D9,DA,DE.ttf b/test/subset/data/expected/full-font/Roboto-Regular.drop-hints.D7,D8,D9,DA,DE.ttf index 895c6e6be..ff361baef 100644 Binary files a/test/subset/data/expected/full-font/Roboto-Regular.drop-hints.D7,D8,D9,DA,DE.ttf and b/test/subset/data/expected/full-font/Roboto-Regular.drop-hints.D7,D8,D9,DA,DE.ttf differ diff --git a/test/subset/data/expected/japanese/Mplus1p-Regular.default.3042,3044,3046,3048,304A,304B.ttf b/test/subset/data/expected/japanese/Mplus1p-Regular.default.3042,3044,3046,3048,304A,304B.ttf index db7daa889..33989996e 100644 Binary files a/test/subset/data/expected/japanese/Mplus1p-Regular.default.3042,3044,3046,3048,304A,304B.ttf and b/test/subset/data/expected/japanese/Mplus1p-Regular.default.3042,3044,3046,3048,304A,304B.ttf differ diff --git a/test/subset/data/expected/japanese/Mplus1p-Regular.default.3042,3044,3046,73E0,5EA6,8F38.ttf b/test/subset/data/expected/japanese/Mplus1p-Regular.default.3042,3044,3046,73E0,5EA6,8F38.ttf index d05b5eece..66b98a6d1 100644 Binary files a/test/subset/data/expected/japanese/Mplus1p-Regular.default.3042,3044,3046,73E0,5EA6,8F38.ttf and b/test/subset/data/expected/japanese/Mplus1p-Regular.default.3042,3044,3046,73E0,5EA6,8F38.ttf differ diff --git a/test/subset/data/expected/japanese/Mplus1p-Regular.default.61,63,65,6B.ttf b/test/subset/data/expected/japanese/Mplus1p-Regular.default.61,63,65,6B.ttf index cef6a42cb..22d1bb309 100644 Binary files a/test/subset/data/expected/japanese/Mplus1p-Regular.default.61,63,65,6B.ttf and b/test/subset/data/expected/japanese/Mplus1p-Regular.default.61,63,65,6B.ttf differ diff --git a/test/subset/data/expected/japanese/Mplus1p-Regular.default.660E,6975,73E0,5EA6,8F38,6E05.ttf b/test/subset/data/expected/japanese/Mplus1p-Regular.default.660E,6975,73E0,5EA6,8F38,6E05.ttf index d7852d8a2..28043592e 100644 Binary files a/test/subset/data/expected/japanese/Mplus1p-Regular.default.660E,6975,73E0,5EA6,8F38,6E05.ttf and b/test/subset/data/expected/japanese/Mplus1p-Regular.default.660E,6975,73E0,5EA6,8F38,6E05.ttf differ diff --git a/test/subset/data/expected/japanese/Mplus1p-Regular.default.660E.ttf b/test/subset/data/expected/japanese/Mplus1p-Regular.default.660E.ttf index be607c294..333ca516d 100644 Binary files a/test/subset/data/expected/japanese/Mplus1p-Regular.default.660E.ttf and b/test/subset/data/expected/japanese/Mplus1p-Regular.default.660E.ttf differ diff --git a/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.3042,3044,3046,3048,304A,304B.ttf b/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.3042,3044,3046,3048,304A,304B.ttf index 1e5a7c7fc..c84b20cba 100644 Binary files a/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.3042,3044,3046,3048,304A,304B.ttf and b/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.3042,3044,3046,3048,304A,304B.ttf differ diff --git a/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.3042,3044,3046,73E0,5EA6,8F38.ttf b/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.3042,3044,3046,73E0,5EA6,8F38.ttf index 3845822d8..e757b9e34 100644 Binary files a/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.3042,3044,3046,73E0,5EA6,8F38.ttf and b/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.3042,3044,3046,73E0,5EA6,8F38.ttf differ diff --git a/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.61,63,65,6B.ttf b/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.61,63,65,6B.ttf index fce812323..e869ff1fa 100644 Binary files a/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.61,63,65,6B.ttf and b/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.61,63,65,6B.ttf differ diff --git a/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.ttf b/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.ttf index b72eaf9c6..ed4ed4c10 100644 Binary files a/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.ttf and b/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.ttf differ diff --git a/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.660E.ttf b/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.660E.ttf index ee7baba66..cb502388e 100644 Binary files a/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.660E.ttf and b/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.660E.ttf differ diff --git a/test/subset/data/fonts/Mplus1p-Regular.ttf b/test/subset/data/fonts/Mplus1p-Regular.ttf index 2a5205ef0..f89a28ef3 100644 Binary files a/test/subset/data/fonts/Mplus1p-Regular.ttf and b/test/subset/data/fonts/Mplus1p-Regular.ttf differ