From 03b27548123756dfd9988a8fc74bc78733fb2c44 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Wed, 2 May 2018 15:42:08 -0700 Subject: [PATCH 01/14] [subset] Add const to the hb_subset_plan_t input to a couple functions in hb-subset-plan. --- src/hb-subset-plan.cc | 4 ++-- src/hb-subset-plan.hh | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) 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); From 0053d13283458996372f04bd501001d450523605 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Wed, 2 May 2018 15:42:43 -0700 Subject: [PATCH 02/14] [subset] Refactor cmap subsetting to make it possible to add support for more sub tables. --- src/hb-ot-cmap-table.hh | 161 +++++++++++++++++++++++++--------------- 1 file changed, 102 insertions(+), 59 deletions(-) diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 83a0b519b..f0e70afee 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -294,7 +294,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 +319,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->reservedZ.set (0); + this->lengthZ.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 +594,29 @@ struct cmap { static const hb_tag_t tableTag = HB_OT_TAG_cmap; + struct subset_plan { + subset_plan(void) + { + groups.init(); + } + + ~subset_plan(void) + { + groups.fini(); + } + + inline size_t final_size() const + { + return + 4 // header + + 8 // 1 EncodingRecord + + CmapSubtableFormat12::get_sub_table_size (this->groups); + } + + // Format 12 + hb_vector_t groups; + }; + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -539,50 +625,13 @@ 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); + return CmapSubtableFormat12::create_sub_table_plan (plan, &cmap_plan->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 subset_plan &cmap_subset_plan, size_t dest_sz, void *dest) const { @@ -602,19 +651,12 @@ struct cmap rec.platformID.set (3); // Windows rec.encodingID.set (10); // Unicode UCS-4 - /* capture offset to subtable */ + // Write out format 12 sub table. CmapSubtable &subtable = rec.subtable.serialize (&c, cmap); - subtable.u.format.set (12); CmapSubtableFormat12 &format12 = subtable.u.format12; - if (unlikely (!c.extend_min (format12))) return false; - - format12.format.set (12); - format12.reserved.set (0); - format12.length.set (16 + 12 * groups.len); - - if (unlikely (!format12.serialize (&c, groups))) return false; + if (unlikely (!format12.serialize (&c, cmap_subset_plan.groups))) return false; c.end_serialize (); @@ -623,24 +665,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 (cmap_subset_plan, dest_sz, dest))) { + DEBUG_MSG(SUBSET, nullptr, "Failed to perform subsetting of cmap."); free (dest); return false; } From 295d67ea7d0ddac5666bd6aa4b647dd9cbf8e8f7 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Wed, 2 May 2018 16:12:04 -0700 Subject: [PATCH 03/14] [subset] WIP cmap format 4 subsetting. --- src/hb-ot-cmap-table.hh | 104 +++++++++++++++++++++++++++++++++------- 1 file changed, 88 insertions(+), 16 deletions(-) diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index f0e70afee..7e9675b3c 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -69,6 +69,48 @@ 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) + { + // TODO + } + + 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) + { + // TODO + } + struct accelerator_t { inline void init (const CmapSubtableFormat4 *subtable) @@ -175,6 +217,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 @@ -597,24 +641,29 @@ struct cmap struct subset_plan { subset_plan(void) { - groups.init(); + format4_segments.init(); + format12_groups.init(); } ~subset_plan(void) { - groups.fini(); + format4_segments.fini(); + format12_groups.fini(); } inline size_t final_size() const { return 4 // header - + 8 // 1 EncodingRecord - + CmapSubtableFormat12::get_sub_table_size (this->groups); + + 8 * 2 // 2 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 groups; + hb_vector_t format12_groups; }; inline bool sanitize (hb_sanitize_context_t *c) const @@ -628,10 +677,14 @@ struct cmap inline bool _create_plan (const hb_subset_plan_t *plan, subset_plan *cmap_plan) const { - return CmapSubtableFormat12::create_sub_table_plan (plan, &cmap_plan->groups); + 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 _subset (const subset_plan &cmap_subset_plan, + inline bool _subset (const hb_subset_plan_t *plan, + const subset_plan &cmap_subset_plan, size_t dest_sz, void *dest) const { @@ -645,18 +698,37 @@ struct cmap cmap->version.set (0); - if (unlikely (!cmap->encodingRecord.serialize (&c, /* numTables */ 1))) return false; + if (unlikely (!cmap->encodingRecord.serialize (&c, /* numTables */ 2))) 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 + + // Format 4 Encoding Record + EncodingRecord &format4_rec = cmap->encodingRecord[0]; + format4_rec.platformID.set (3); // Windows + format4_rec.encodingID.set (1); // Unicode BMP + + // Format 12 Encoding Record + EncodingRecord &format12_rec = cmap->encodingRecord[1]; + format12_rec.platformID.set (3); // Windows + format12_rec.encodingID.set (10); // Unicode UCS-4 + + // Write out format 4 sub table. + { + CmapSubtable &subtable = format4_rec.subtable.serialize (&c, cmap); + subtable.u.format.set (4); + + 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 = rec.subtable.serialize (&c, cmap); - subtable.u.format.set (12); + { + 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.groups))) return false; + CmapSubtableFormat12 &format12 = subtable.u.format12; + if (unlikely (!format12.serialize (&c, cmap_subset_plan.format12_groups))) return false; + } c.end_serialize (); @@ -681,7 +753,7 @@ struct cmap return false; } - if (unlikely (!_subset (cmap_subset_plan, 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); From cfa592d31ce2fd1ec2765a69ab31bf80161479dd Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Wed, 2 May 2018 16:37:38 -0700 Subject: [PATCH 04/14] [subset] Add an implement for cmap format 4 create_sub_table_plan. --- src/hb-ot-cmap-table.hh | 43 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 7e9675b3c..84ad1c7ea 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -108,7 +108,48 @@ struct CmapSubtableFormat4 static inline bool create_sub_table_plan (const hb_subset_plan_t *plan, hb_vector_t *segments) { - // TODO + 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; + } + + // 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; + } + + last_gid = new_gid; + } + return true; } struct accelerator_t From 4195a52b041af749046b716dcac7d6560ae37611 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Wed, 2 May 2018 17:11:18 -0700 Subject: [PATCH 05/14] [subset] WIP implementation of serialize for cmap format 4. --- src/hb-ot-cmap-table.hh | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 84ad1c7ea..115f36636 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -80,7 +80,44 @@ struct CmapSubtableFormat4 const hb_subset_plan_t *plan, const hb_vector_t &segments) { - // TODO + TRACE_SERIALIZE (this); + + if (unlikely (!c->extend_min (*this))) return_trace (false); + + this->format.set (4); + this->length.set (get_sub_table_size (segments)); + + // 2 * segCount + this->segCountX2.set (segments.len * 2); + // 2 * (2**floor(log2(segCount))) + this->searchRangeZ.set (2 * (1 << (int) (log (segments.len) / log (2.0)))); + // log2(searchRange/2) + this->entrySelectorZ.set (log ((double) this->searchRangeZ) / log (2.0)); + // 2 x segCount - searchRange + this->rangeShiftZ.set (2 * segments.len - this->searchRangeZ); + + 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); + + 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 start_gid; + if (unlikely (!hb_subset_plan_new_gid_for_codepoint (plan, segments[i].start_code, &start_gid))) + return false; + id_delta[i].set (start_gid - segments[i].start_code); + } else { + // TODO: fill out glyphIdArray and id_range_offset. + } + } + + // TODO: glyphdIdArray } static inline size_t get_sub_table_size (const hb_vector_t &segments) From 81ea75f5c860ef682184bd2c9d0ff8b48251e3ce Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Wed, 2 May 2018 17:46:30 -0700 Subject: [PATCH 06/14] [subset] Complete implementation of cmap4 subsetting. --- src/hb-ot-cmap-table.hh | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 115f36636..63380cad2 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -113,11 +113,36 @@ struct CmapSubtableFormat4 return false; id_delta[i].set (start_gid - segments[i].start_code); } else { - // TODO: fill out glyphIdArray and id_range_offset. + 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); + // 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 = 0; // Default to not def for 0xFFFF + if (unlikely (!hb_subset_plan_new_gid_for_codepoint (plan, cp, &new_gid) && cp != 0xFFFF)) + return false; + glyph_id_array[j].set (new_gid); + } } } - // TODO: glyphdIdArray + return true; } static inline size_t get_sub_table_size (const hb_vector_t &segments) @@ -181,7 +206,7 @@ struct CmapSubtableFormat4 segment = segments->push (); segment->start_code.set (0xFFFF); segment->end_code.set (0xFFFF); - segment->use_delta = true; + segment->use_delta = false; } last_gid = new_gid; From 9ef55a4c1354028f4d5e81300cdaf8ce5e03b8e9 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Wed, 2 May 2018 18:50:56 -0700 Subject: [PATCH 07/14] [subset] A few bug fixes for cmap format 4 subsetting. --- src/hb-ot-cmap-table.hh | 57 ++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 63380cad2..7e42b4fc8 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -92,7 +92,7 @@ struct CmapSubtableFormat4 // 2 * (2**floor(log2(segCount))) this->searchRangeZ.set (2 * (1 << (int) (log (segments.len) / log (2.0)))); // log2(searchRange/2) - this->entrySelectorZ.set (log ((double) this->searchRangeZ) / log (2.0)); + this->entrySelectorZ.set (log ((double) this->searchRangeZ / 2.0) / log (2.0)); // 2 x segCount - searchRange this->rangeShiftZ.set (2 * segments.len - this->searchRangeZ); @@ -102,20 +102,26 @@ struct CmapSubtableFormat4 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 start_gid; - if (unlikely (!hb_subset_plan_new_gid_for_codepoint (plan, segments[i].start_code, &start_gid))) - return false; + 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 @@ -134,15 +140,15 @@ struct CmapSubtableFormat4 for (unsigned int j = 0; j < num_codepoints; j++) { hb_codepoint_t cp = segments[i].start_code + j; - hb_codepoint_t new_gid = 0; // Default to not def for 0xFFFF - if (unlikely (!hb_subset_plan_new_gid_for_codepoint (plan, cp, &new_gid) && cp != 0xFFFF)) - return false; + 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 true; + return_trace (true); } static inline size_t get_sub_table_size (const hb_vector_t &segments) @@ -201,16 +207,17 @@ struct CmapSubtableFormat4 segment->use_delta = false; } - // 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 = 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; } @@ -756,11 +763,10 @@ struct cmap inline size_t final_size() const { - return - 4 // header - + 8 * 2 // 2 EncodingRecord - + CmapSubtableFormat4::get_sub_table_size (this->format4_segments); - + CmapSubtableFormat12::get_sub_table_size (this->format12_groups); + return 4 // header + + 8 * 2 // 2 EncodingRecord + + CmapSubtableFormat4::get_sub_table_size (this->format4_segments) + + CmapSubtableFormat12::get_sub_table_size (this->format12_groups); } // Format 4 @@ -801,7 +807,8 @@ struct cmap cmap->version.set (0); - if (unlikely (!cmap->encodingRecord.serialize (&c, /* numTables */ 2))) return false; + if (unlikely (!cmap->encodingRecord.serialize (&c, /* numTables */ 2))) + return false; // TODO(grieger): Convert the below to a for loop @@ -821,7 +828,8 @@ struct cmap subtable.u.format.set (4); CmapSubtableFormat4 &format4 = subtable.u.format4; - if (unlikely (!format4.serialize (&c, plan, cmap_subset_plan.format4_segments))) return false; + if (unlikely (!format4.serialize (&c, plan, cmap_subset_plan.format4_segments))) + return false; } // Write out format 12 sub table. @@ -830,7 +838,8 @@ struct cmap subtable.u.format.set (12); CmapSubtableFormat12 &format12 = subtable.u.format12; - if (unlikely (!format12.serialize (&c, cmap_subset_plan.format12_groups))) return false; + if (unlikely (!format12.serialize (&c, cmap_subset_plan.format12_groups))) + return false; } c.end_serialize (); From c817992f495cba21bf468014f22afe349fbc799f Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Thu, 3 May 2018 10:53:20 -0700 Subject: [PATCH 08/14] [subset] Write out a format 4, plat 0 encoding record to match fontTools. --- src/hb-ot-cmap-table.hh | 24 +++++++++++++++--------- test/api/test-subset-cmap.c | 2 +- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 7e42b4fc8..883ac3a5f 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -764,7 +764,7 @@ struct cmap inline size_t final_size() const { return 4 // header - + 8 * 2 // 2 EncodingRecord + + 8 * 3 // 3 EncodingRecord + CmapSubtableFormat4::get_sub_table_size (this->format4_segments) + CmapSubtableFormat12::get_sub_table_size (this->format12_groups); } @@ -807,24 +807,30 @@ struct cmap cmap->version.set (0); - if (unlikely (!cmap->encodingRecord.serialize (&c, /* numTables */ 2))) + if (unlikely (!cmap->encodingRecord.serialize (&c, /* numTables */ 3))) return false; // TODO(grieger): Convert the below to a for loop - // Format 4 Encoding Record - EncodingRecord &format4_rec = cmap->encodingRecord[0]; - format4_rec.platformID.set (3); // Windows - format4_rec.encodingID.set (1); // Unicode BMP + // 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); + + // 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 // Format 12 Encoding Record - EncodingRecord &format12_rec = cmap->encodingRecord[1]; + EncodingRecord &format12_rec = cmap->encodingRecord[2]; format12_rec.platformID.set (3); // Windows format12_rec.encodingID.set (10); // Unicode UCS-4 - // Write out format 4 sub table. + // Write out format 4 sub table { - CmapSubtable &subtable = format4_rec.subtable.serialize (&c, cmap); + CmapSubtable &subtable = format4_plat0_rec.subtable.serialize (&c, cmap); + format4_plat3_rec.subtable.set (format4_plat0_rec.subtable); subtable.u.format.set (4); CmapSubtableFormat4 &format4 = subtable.u.format4; diff --git a/test/api/test-subset-cmap.c b/test/api/test-subset-cmap.c index 52548742d..8c5193870 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; From a8e7f9b958dcb4e00226f78d0ff83f031bc1323d Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Thu, 3 May 2018 10:59:00 -0700 Subject: [PATCH 09/14] [subset] Get cmap tests passing again. --- .../fonts/Roboto-Regular.D7,D8,D9,DA,DE.ttf | Bin 2972 -> 2816 bytes test/api/test-subset-cmap.c | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) 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 38799ccbea2cc5574c8d362f1b446042a15017ee..3a71f53f2d0e2e246d409bbcb94255ff53918ada 100644 GIT binary patch delta 316 zcmbOu-XJzXyk3NXfkDSTz(1Jv``b+n3|tOCew%x6sMBQ8CNUuY1dwm$AFOXwa=)pQ zfq^vv$WKVlO)Ox1&MpJwUjgzPlFLdIv{$gtWnkcp0rErA3et1Se*MKz`-C4G>-!)&y${0nO0zS>^s7~q->|&)WCqHEundr7gwk9<+J}LK!2n3J0cl1C zCWc!K_x}F}@~=ba{~AD1HXxq?D9_5k&cLzx0qbODbtVQmkU=b*KxrPJB!tbxzz5_7 SG2}BO0dWaK{^l|+HAVo2!$wU2 delta 451 zcmYj~ze@sP9LAsP?zFq4piGAxZW5t1Q_!KMAA>X*Sq%-L`Qu8od+`oSA`FS3%{YjL zYKVrQC2|dF3WA7+rU?22s=0`uzWyNO<@@q{p7;4a@0R1xS#_2#01QQ@qcQRG;}Vcx zh<75fxe2qs;sCl*#Gz048%COMwJ+QZ*_4ICdsYzm#v@=aNe)FJTUV7*G&^A0u=WMCer`KNmupa0;tP!bfTxIXVhv{@3&d xrJ+-@fFj)~_{;}sAUNM}bV_QpU$6I3c@SZYHmLqtn3^;!(HJz|+Oy>5{s7WnSDOF; diff --git a/test/api/test-subset-cmap.c b/test/api/test-subset-cmap.c index 8c5193870..84d34bcd7 100644 --- a/test/api/test-subset-cmap.c +++ b/test/api/test-subset-cmap.c @@ -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; From 79479273170275447042aa50912acee74bbacdf6 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Thu, 3 May 2018 11:18:02 -0700 Subject: [PATCH 10/14] [subset] Update expected files for subset integration tests to include cmap4. --- .../Roboto-Regular.abc.default.61,62,63.ttf | Bin 2120 -> 2168 bytes .../Roboto-Regular.abc.default.61,63.ttf | Bin 1932 -> 1988 bytes .../basics/Roboto-Regular.abc.default.61.ttf | Bin 1744 -> 1792 bytes .../basics/Roboto-Regular.abc.default.62.ttf | Bin 1692 -> 1740 bytes .../basics/Roboto-Regular.abc.default.63.ttf | Bin 1668 -> 1716 bytes ...Roboto-Regular.abc.drop-hints.61,62,63.ttf | Bin 876 -> 924 bytes .../Roboto-Regular.abc.drop-hints.61,63.ttf | Bin 792 -> 848 bytes .../Roboto-Regular.abc.drop-hints.61.ttf | Bin 684 -> 732 bytes .../Roboto-Regular.abc.drop-hints.62.ttf | Bin 652 -> 700 bytes .../Roboto-Regular.abc.drop-hints.63.ttf | Bin 656 -> 704 bytes ...oto-Regular.default.1FC,21,41,20,62,63.ttf | Bin 3700 -> 3772 bytes .../Roboto-Regular.default.61,62,63.ttf | Bin 3320 -> 3368 bytes .../Roboto-Regular.default.D7,D8,D9,DA,DE.ttf | Bin 3668 -> 3732 bytes ...-Regular.drop-hints.1FC,21,41,20,62,63.ttf | Bin 2152 -> 2224 bytes .../Roboto-Regular.drop-hints.61,62,63.ttf | Bin 1968 -> 2016 bytes ...boto-Regular.drop-hints.D7,D8,D9,DA,DE.ttf | Bin 2188 -> 2252 bytes 16 files changed, 0 insertions(+), 0 deletions(-) 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 02cd7efb4de6e6a1cac4364eea570b04096aa2bf..12d92081b31eda6deaf2aa8b62e69c0535dfe225 100644 GIT binary patch delta 175 zcmX>h@IzpNqPaBVdjZgX$9%I(l!h%3<^M+1qean$^ZWY$;AKv|1SXZ88+vz++hX) Drp7AK delta 127 zcmew%a6({$qB%dqPX-2-1O^5MjpVWt1??5=a~T-eCjj{&X$9%I!_U}W*Q zRpmSR4AXf>W}q|(%K%A6D9r_=T^LvxG=MZ4kY;3HVn}32{{J7y2h;x-{GSh24HVeC Ig!u(C0QS%=*8l(j delta 127 zcmX@Y-@`va(VU<03+rT$L(OjDGH3I|F3kC*;h~%;o1??5=a~T-eJb?U=w1V{9@*fGS85o!y7#JA$ zq$d^^FmNyk1LeO=jHp+f15{*DkY8N#KbIi|D0l_PS12e-Em)NH>m&mM%b$%uG#Qy| yj$NIs!gSn{87K?FGC-0MN^=2e8wM5z1t84=gdp+6|NkN6{{>(^!{#qccbEaH{42Tu delta 126 zcmZqRyTCg^(VU;*I|BpL3kC)TjpVWt1??5=a~T-eB!K*ow1V{9@*fGS85o!a7#JA$ zq$d^^FmNyk1LcoQjHp-40V=X6$S*GWpUaQ}6kG!2D-;x^7A#8pb&`RB<;=z(nvBd- ZPVr7wVLHyq$iU3N1ysSaS%vuyGXPLmA;JIv 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 8d7e6b2279e0d37a78ad39cb522cc85c13269a24..52706dc90320133d24a0a6c3109b9d1ef1bf8ec7 100644 GIT binary patch delta 173 zcmbQkdxm#{qPaBVI|c@(Ees3{5y@pG3fe2!=Q1#`i2(T_X$9%I;VBla72Ff3p7*Vg70aRpBkY8N#KbIi|D7XN~S12e-Em)NH>m&mM%ZZ6UzB0?L yNT2+H@wg>3P!fb?fFvW7<^s|-3@i)^K$-;zLE=gO|3k?C^TB+E%?Ft7FarP_87jd5 delta 125 zcmX@ZJBN3IqB%dqPX-32Ees3{8p&lP3fe2!=Q1#`J^}JW(hAaZ%YP)S2Fl-IU|`&n zo>*MKz`-EQz`!Rje#^aof49pB%Km|OTKQP^41^}m&mM%Z73P!fb?fFvW7<^s|-3@i)^K$-;zLE_2(|3k?C^T2$D%`2GhFarR%F)OnG delta 125 zcmdnO+rm3R(VU;*HvR0cD-;x^7A#8pb&`RBrD5WayUaI= YJtyB_JkH6;z|6n}RKTVv!VC<|6DC^Z3t9jLEei6BOaA9FqyPmA zHttAaWQlt%czv=0(_u?ypfm`}07*tD%>|@w7+4q-fHVsbg2a>m{|AzZ|NsAA0Om7H Ie#6uN02|U9ivR!s delta 78 zcmbQk{)TOWqBuXpPX-322Mi1h8tI9}1q>Vv!VC<|2@@^y1v!9%76tjmCI537QhZ=ZaGala!oP#T0~fFvW7<^s|#3@i*9K$;CmGcqtSBr+ub{}1GY>HiD< O&j+gp3QX={>Hz@sHyxM& delta 78 zcmcb>HiK<~qBuX}83qQX1_lNOlk~*m0tOBSVFm_fo{1Luf?I%s76tjmCI537Qh2IFo^W}qYp%K%A6D9r_=Z5UV>6o51f5Q4-L|Nn=O{}+Jy43l-38UPT_ B8)yIk delta 76 zcmcb^x`uUvqBuXpcLoL~1qKENjr7Fg0tOBSVIY6OM2mbu51^n$L4I+`|6GO?pkTwq c9c!6yF~m;JVBF2g$iU3N1ysN@IfkhL0K=XVZvX%Q 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 837438a55fef2308c78ed0624df113ba7cb59af0..122b10976839df2becb1c9175f66b58195a1d4e8 100644 GIT binary patch delta 124 zcmeBS-NQOTQCynw9RmXs0}w={Cl(hla4-l1`5Pu$NX7A42}059TvW=3#080Jb_B ARsaA1 delta 76 zcmdnP+QT|QQJkOQCj$c$0}yDWCl(hla4-l1`3(~-@&z@3f))k&#U=l98B&0P2@`kp aGT%Hkf3gSTZcau9W(F>x0-nh>Obr04T@qXX 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 311737ab4ef7749105ca1aaea3a229819eaabd01..381e97e933aeeaa87eeb65132c6e889abcc5372c 100644 GIT binary patch delta 124 zcmbQhdVqC;qPR5UM+OEa76t}}i1ftb0tOBSVIY6YM2mdE7@(j!l{|TS$!?@d$87K+DGC-0MN^=2e8wM5z1t84=gdp+c|NkN6|9N0O!(;)b1^|Nq B8H)e_ delta 76 zcmX@WI)Qb9qBuXpZw3Y?76t|ejr7Fg0tOBSVIaR{qD8)-4p7jdAiucee=b7`P%vfU cj)~0v|CuNIFz)7LWMF3C0xIB{?7-9j0G;g-kpKVy 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 60e361d2c72972f37995d7ace5023551387ca817..93efe6553c6fab572e866dc986f60311d565a0c0 100644 GIT binary patch delta 200 zcmew&vqyG~k3yxI}>bkhFsI-0~j@s~H&Bc^DWN z_oOEl7cg)z2s1G7ZI~EQub9EWz@k==UtID(mmvixI02|hp`a+WU{TtylMDEP?5orA(`>d|NlTS1t2>K Z#Qy*A|Dpej{_%iy0wq9Ta|_!Cb^r|oGZ_E? delta 128 zcmdlZ`$cAgf&~LV>uUxEwh9IY2A|}z5(VuQ>~k3yIL`q2A!!Bax#d3+Rs-daFfcIg zNlz>;VBla7W?5y7sKCI$qE?V!T=GAcAq6Pt0o0^WP?TD*DDBrt1_q9XjX$Qa du=HMfmpOR?>uXL%24)5>pc0!oa}u2dGJ*peVIqQQEJQ3=Hfh8-Ii{ zGjsl2Iyr#lvL!Q67KCMhBqNmO0@5}NEDQ=jngs|!;>rL21Ifhy|Nk!l^BFelu%2ND E06ak{zyJUM delta 126 zcmZ1>^+R%kqB%dqPX-271qKENjpVWt1??5=a~T*o0)YIGw1V{9@*fGSf$|;<42*ly z6N?KNI2eQ(7~k3yINt#IA!!Bax#d3+Rs-dqFfcIg zNlz>;VBla7W?5y7=)l0hqE?V!T=GAc0cZeU22hhiK~ZYKqO@Np85lSgZ2Zx{ z!jiJn*>Q3W>uXPDpfm`}07*tD%>|@=7+4q#fHWJBW@KPuxW#bq|9>F=I)whO0Tg8e T@`1K7urjbSaBMDMd%_L?%8D)3 delta 128 zcmbOtdqrk~f&~LVYb^rFU>uUxE<`WDI3_j_J#RUu;48jZy95E9u@&!d07+BN_@{3FU=Q5-K j1#LF&uwY{OCG=?T(qBuXpPX-2N69xtbjr7Fg0tOBSVFm{FB@-?31!EW(Skwygi%b6JGNb?n hTQ=_4!N{U6!0>l+3DaRtMh0dEE}%Z1%>~Q_EC32E6CwZr 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 895c6e6bed9cc8e5ab8419a63cc66acbcea298a5..ff361baef7eb5cb0e98a1cdd8976fd1d6ce0659f 100644 GIT binary patch delta 144 zcmeAXJR>+kL4xr)y9@&Z^A83FhKBUS;sOQ^24MyUjsp`d@&zjx7+BN_@{3FU=Q5-K z1s81Gk-@~$Atuv0S%vw!Co@nF2+IITMkvh%qj*dsVWL4tvwwU&W_`3D07gF|{^aRCDdgD?XFN5e#md_fBa1{Sq~{Nj@TxeO^l i!Gw)FGMHGpk0~6UtipVqlaYa$feWaQXR`}S2MYiVJQGX+ From b0d7971be0fa3c9393b04038b8d0a76398b0d8d7 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Thu, 3 May 2018 11:22:51 -0700 Subject: [PATCH 11/14] [subset] Updated expected files for japanese subset integration tests to include cmap4. --- ....default.3042,3044,3046,3048,304A,304B.ttf | Bin 3032 -> 3112 bytes ....default.3042,3044,3046,73E0,5EA6,8F38.ttf | Bin 3268 -> 3356 bytes .../Mplus1p-Regular.default.61,63,65,6B.ttf | Bin 2584 -> 2656 bytes ....default.660E,6975,73E0,5EA6,8F38,6E05.ttf | Bin 3564 -> 3652 bytes .../japanese/Mplus1p-Regular.default.660E.ttf | Bin 2348 -> 2396 bytes ...op-hints.3042,3044,3046,3048,304A,304B.ttf | Bin 2304 -> 2384 bytes ...op-hints.3042,3044,3046,73E0,5EA6,8F38.ttf | Bin 2540 -> 2628 bytes ...Mplus1p-Regular.drop-hints.61,63,65,6B.ttf | Bin 1856 -> 1928 bytes ...op-hints.660E,6975,73E0,5EA6,8F38,6E05.ttf | Bin 2836 -> 2924 bytes .../Mplus1p-Regular.drop-hints.660E.ttf | Bin 1620 -> 1668 bytes test/subset/data/fonts/Mplus1p-Regular.ttf | Bin 1758820 -> 1757292 bytes 11 files changed, 0 insertions(+), 0 deletions(-) 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 db7daa889c8b3b544919087e38efc41166721a22..33989996ebb10407976a9294b08606039055d2c8 100644 GIT binary patch delta 294 zcmca1zCvPxLP)~yl9vn&EI$|+7*-^gl_;=HVfx6xz+nO8^Q9G}=kjmSU(Ue5x`2U! zDK$N@xZwYP24)5Z?l(Yrj`W<$G+VLl+zbqiJV5y`8L5dW0v!`1Czb>`adE z%^Zvd%rf7EO1k6uZN4&TGrs_;V7P2#DFdRf3o_529Ky0Z66hL`ix^~pBqNmO0@5)I zEDR1nnumddfr){|z{$YHz|FwJz#HfT1~|{_|Nry*&+j|G_xzsoyTST_S|DIE3+oj& E0F&uSr~m)} delta 214 zcmZ1>aYKB9LI{JvV-p4jmLCiZ3=zp?B?@d)m_9Nvu)hHE`O*r~bNRREFK1w24Pank zN=;8JF8KeSfti7Udk#>ZBR!`w%~otXHv_8Kl8w>J_ zOa8Yp7y)(E0Cgx76r~ny_@pfYv|$I3uU7`t!hTR-J5YWLkgrmfTT;QYh50CuzhpB9 yqXDzb-ed*gcz&C&OxnyKH!)l`vXlYQSA-pYOb%gL&dCUL4;N5?XLAVa6*d5%AUL!D 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 d05b5eece76d073922c2378a0b4747eaafb17e55..66b98a6d1b6d1d7df61f2ae0573ed8479cf88cfe 100644 GIT binary patch delta 302 zcmX>iIY(-OLP&;ip$h{8>kS45hCRt;B?@d)m_9NvaOwd0d}#&gx%^x7moqT1O<`bQ zN=;8JF8KeSfti7U=K)ZjBR!`w&F5W21_J{l4+8`9m5kKH6oHNjk`qgUoH%WOB8>(4 z#U=mS7>s~A4ghs16cnWvZ1|)t0@VBm$k!_aYGFSpupKD>1ISk?%Ppy3*}&Wm^ZdystjiODt^v7-K?X=NLTN4_ox;Gv z-~puh7&sW17}yM)3|tJ{;+7RZ=(hm+fdQ3&e*gJ>=l3p*>rpK@2Q~$$5e7CtVST^` E05!T#MF0Q* delta 214 zcmbOubwqN4LI{J<(|HUGtTz}K7*dkUN)*_pFnwfT;J5qsCX$9%I{9E*w1Lf~9FfgU2 zCl(j{|Ifh8z`&⪙=p#sZ850-kZU|z{mr{9vP{LDFPi6Bqx>xJGKBdH5TL-m;7&I zFam1e0BTSuC`v8Z@JU+)Xn_lmuU7`t!G2I+J5b&R$X6-LEvaCuVF?2A4K{NyHZaOa zR;lU7^V@u7(q?`ERKalB$WjJGUl(MaKY0n$@<5cKIzT>OT0wd){}%n_K=~;Q3{0u% ziNyu~|1&T%FmOHq%5$XWRHkhg@6BLfVB`T}kBrpB6yC10MH5Sc9c_S`8VmA^Oa8Yp z7y&gL0BTSuC`v8Z@JU;Qfr0f8kgrz;)WLpGU^`I$3y`l;mRnN6R>Kkm$gGOcgo{~pzXb6`_|8ew2F5Bmc)01i-2 A82|tP delta 213 zcmX>i^G14tLI{J1y%+-nI|C4;B$t&auuWn5$iTq)2gv73D@f1f-=e=9D4)W>z?7Pv zSX}V`KLaxZ1Mdc)JV$y?W!huQ(4!0tj64hsEWa{R6H|D*&K6B933dbuFgF(D7nl5R zV=w}0m;ltEP*9Xwu;G)o2+)EvK)zlXPzU=#f$c!~6F|O7S#C)MOD?lJkiTOy2cre6 wjBuK@dpy6*S0-)d7eEyZmyIlCK=c)1haZz;*p_oL0-eJJ6yVvM!v25_0Hr85DgXcg 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 be607c294ecddd8f73c637da5f96979e833f22fe..333ca516d6c4108e27ffe88a044d483746a56e86 100644 GIT binary patch delta 259 zcmZ1@bVq1{Vz7+SCk6(l76t}}h~%;o1-2v3I9~9UQl(zu#RmyTpDp;(UW&!yIlQ|eq$grHh z5+2WQ^OZ@P`2|n`!(}5&84!J4ka_;(H;l6_fo=i0hd~BNGD2xCAZ^3I!k_@8S%45I Vp2i1sH<+CH8LW$teIv3`3#de7*EJ> vJ<*sR&u{aUNt^ivPyxebBTE?&eMQ*e$K*GRvpE@ouHga-@N7Q7G=~iUye2j4 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 1e5a7c7fc3b0f379bc8fcaee4503beae498b1044..c84b20cba0a8bc98b8afbdbafb0120063bab9e56 100644 GIT binary patch delta 244 zcmZn=x*#+`!6adK$x8+XmJpSir!*+*pubT=Kt-!3e1K3s8|l8BhiLL4oZ+19X6Vm9pHD3YIO* zM}d5qjW-OKWey6>TpiDE^OZ@P`2|n`!(}5&84!J4ka_-O6_(|ZK)XTqGspl*Mkvh% zq+=LZ7#x5!4+94S69bEZlYxtYn}LUcH_*KdaGuxy|L6Cg-*g;j?I E0Q(0kk0-2hCS(t#RdQWGcYqSaB%?n9O*fgX+G~FGJxzm3=GUy zGEx&$1Ue>2P7Db)OaTfs7UUO~{BL70VqoBW0aT<=22{a*P+&XI00kglr7X9kf@K49 zJCHB1@rD44%;c1oi@!$N;kMFfcG* z$w*C1;q5wGG%+ODkOwHxSdd>_^1qG22&iEKP?16zPzC!zf$c#42_RpkEVrbBWdn0N zkiTQ&4FMLJ%tU40cz&C&OxnyZfC?Bc8(GSL=qthwKPI!VF6U$f+RgX2Ajg DgUc)h 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 fce812323fea7f028f1e3dc7163f2a12d45bed8c..e869ff1faaeb94808eba591625f2a308f00b21ee 100644 GIT binary patch delta 235 zcmX@W*TFwQ(fB{BBm)Dp1Oo%Zl=Q^ng8%;+m>C$@1Au&v^qk7H?c%)|K=vI521bvJ z)Wj5ljtPR-mODfoESb~83 zh>bTI7-gPRxiQD{+k9oxW_|%wz;M~fQU*j{7i6A4xrAwXAkc1*{R}cdk`YRC0qGD1 v76uC-&BegMzyySe49N_s4B0@}G9cLh7yO_9f8PI@V4Xk-5ZJ83EW-i-1e!Op delta 163 zcmeC+KfpIZ(U_mPmw|yuk})kYK|Upr*!x{Nj@TZ45>X3~VoeiWJI#D%cMSYzG=31LUie<(5>i)vyEs z`2rhnG%(7%3B4d0&u{aUNt+p@f#I@|B}gH|6=8=TlS`PEb20*L=K>1wY|depVF3WR CPAR?s 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 b72eaf9c64a4d332d20e6a2643de2f76d44453b4..ed4ed4c10b763341a1bade8fb360ef8b33816ae7 100644 GIT binary patch delta 252 zcmbOt_C{=if=Snvkev(+Y!?_981|$m78m^g&%n&Uz-<8JbEM}~raiU{Jql#sVPIhS zm64j5BG55Ga$-oZVGjcXb7Mh%amoKS1|y&b0iYsRkUgA9;lgwk9< zI)#CS0c0c}0|x^W16$m(G``HzJl5g|{T4tMGobPpM$h~*t#9K09@T<#U{in^VPNwe HHVYO2b`?WU delta 164 zcmaDOHbrcLf(e6&y%+-n+XV&&hLrTg;)4JG8JHOuxNZRX9O*fgX^$;Kj{@0u7#LW7 zWuzvi@OGUonivvnXu`n2+*pubT=Kt-!3d~f2T+kh8BhiLL4oZ+{s$mmr7X9kf+d&P z9ms#M@rDJf%)PYK&GGy;UzxO-UjP*_TsE?l0nt~49ezyKVO!402(+CGD8RGXgx!J# E0BqnbU;qFB 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 ee7baba664bedfebb2584b729bf98b5b79f85674..cb502388e50be4426f03bbaf1a4787e0fc2c8956 100644 GIT binary patch delta 210 zcmcb@)51GJ(OAal69WTN2m=E{M0#Rz!Twc@ zCf+z9bM=YK?Rb8huT0v^FF+bD8(GSL=qthwKPK;CoXyDyw44hlz_WP*(-&p{pdTwD diff --git a/test/subset/data/fonts/Mplus1p-Regular.ttf b/test/subset/data/fonts/Mplus1p-Regular.ttf index 2a5205ef09f962fd4b25f5644354fc5a7a6364a2..f89a28ef32b9aebefaf3a39764d1d15e20855fb8 100644 GIT binary patch delta 414 zcmWm7O(=tL90&04|9RNFKQqicmUhslR%jg14ohkmWi^zOEoL&ygBeQXrI^zuU2aR|2YfuyK%o`K2_(G=5nS?rD z1`Guu_$!osk3aV}ta!d9m#p{U$=zww<8!5aa1j*FtvZ>R&c;_C(qjoQx3r!~US*P^ x$+3Bx6(o^N1yo1|GExy0Qwfz)8I@B7DP*EbGE)^*Qw>?DmaJ5Fb(>X>?Eh<1jhX-e delta 1966 zcmbuAdr(w$6vw}J*X1Sdf+&v_=^S+sg~TvZ5fq$e_(Mmbg%!&bT%IbrEMW4`J0hs8 z%&@2ahL%bZ%6F}r`#S?E;5Z^O4NE-O7Xt&{a&UiGR7RZ~{=(V)qDo(I%(%+vGo52spZ z!+&23r1%)KCEaYl8rnr%C`1(MH$$B0x~p3$^d+anajzLU`7`YUdRIU{s{=4D1(JwL zy84#I))*BN0OamATa?=EkNJsrQ0D8gZl+i06kmwV+bW8c4y3BB~S# z6SIdBpW9HewV^@^36`N1Th5D|t5(_J7-O~4-|O{SN#zWxy|t23TMTuARubivp~=-s z%2kzRvsQAwyF4LgFBtaICM0g)U`)70%V3J6OGsbK9>_G(A!OCiX2{cfvJWhg+!2=3 z+z-{qX*m`b&=%C>aujMdvM1_x(Pb=OPw$GNMTifkt%%=CO-P8~PDmI{Kf!Q}eum*B z_eSCcI*cScy$53ihrl?3>R}v3pTpS9eULnmuHeN!ti|{Q+K!joNZx@7OIe2rC)o=V zYq>8b?xa_d>c-xf6w9G7MblN7#?r4aS!gFryXgqhil`N7cKQNoXXqL-GN=LBlju6K zr_)!+w$l5^Uc#M`eSm($NKSglz80U0@EP-(e1> zn=mKSEtqH0E|^Q`8|03rW3Y^(+pvtIH&C#HpTR4u*$;)Wv!JOIT7{49z$(zhsXVxV{*`=j^-4@5~ReFXU;t%iI>rZt$8%gOtpV9m*1{)95=`x3LP=o3tMbwXDX%Fb+axAwMOf@-lZo)ppjP>H|8D zst;)cs`fCU>O5_P&5yo^Er4BM>p^e97R3zPc)9>vD*b@!r`ZkFBk4yhcA<~4cp1B6 ziGh1yX&rrnnlfrcO)XtS?KQHaPQyJ>=S2rlH(W?3hk|Kr+V%;l5-K`Q>aprQMvSIr__?o1-zD z&S_v+M=MaEybDLW);VrP@m>5voJrUbW{1y6d*AqE`~22MNuUy_1swz$fs4RZ;3jYv ocnCTQJO!NuT7gdBCGZw>7WfFd2)YV<1%3j5LBQ75Mtv>)1 Date: Thu, 3 May 2018 13:00:19 -0700 Subject: [PATCH 12/14] [subset] Switch to a non-log using implementation of caculating searchRangeZ, entrySelectorZ, and rangeShiftZ in cmap4. --- src/hb-ot-cmap-table.hh | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 883ac3a5f..83b47b56c 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -87,14 +87,12 @@ struct CmapSubtableFormat4 this->format.set (4); this->length.set (get_sub_table_size (segments)); - // 2 * segCount this->segCountX2.set (segments.len * 2); - // 2 * (2**floor(log2(segCount))) - this->searchRangeZ.set (2 * (1 << (int) (log (segments.len) / log (2.0)))); - // log2(searchRange/2) - this->entrySelectorZ.set (log ((double) this->searchRangeZ / 2.0) / log (2.0)); - // 2 x segCount - searchRange - this->rangeShiftZ.set (2 * segments.len - this->searchRangeZ); + this->entrySelectorZ.set (MAX (1u, _hb_bit_storage (segments.len)) - 1); + this->searchRangeZ.set (2 * (1u << this->entrySelectorZ)); + this->rangeShiftZ.set (segments.len * 2 > this->searchRangeZ + ? 2 * segments.len - this->searchRangeZ + : 0); HBUINT16 *end_count = c->allocate_size (HBUINT16::static_size * segments.len); c->allocate_size (HBUINT16::static_size); // 2 bytes of padding. From 7c22f98da789f831e1afb9078085b2e33d864d25 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Thu, 3 May 2018 13:14:28 -0700 Subject: [PATCH 13/14] [subset] add missing template parameter. --- src/hb-ot-cmap-table.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 83b47b56c..40125b05b 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -482,7 +482,7 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented this->reservedZ.set (0); this->lengthZ.set (get_sub_table_size (groups)); - return CmapSubtableLongSegmented::serialize (c, groups); + return CmapSubtableLongSegmented::serialize (c, groups); } static inline size_t get_sub_table_size (const hb_vector_t &groups) From 3be050f07572d8556726b188668d727e3e7ba643 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Fri, 4 May 2018 11:23:32 -0700 Subject: [PATCH 14/14] [subset] entrySelectorZ -> entrySelector. --- src/hb-ot-cmap-table.hh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 40125b05b..dc55c0d79 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -88,11 +88,11 @@ struct CmapSubtableFormat4 this->length.set (get_sub_table_size (segments)); this->segCountX2.set (segments.len * 2); - this->entrySelectorZ.set (MAX (1u, _hb_bit_storage (segments.len)) - 1); - this->searchRangeZ.set (2 * (1u << this->entrySelectorZ)); - this->rangeShiftZ.set (segments.len * 2 > this->searchRangeZ - ? 2 * segments.len - this->searchRangeZ - : 0); + 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. @@ -479,8 +479,8 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented if (unlikely (!c->extend_min (*this))) return false; this->format.set (12); - this->reservedZ.set (0); - this->lengthZ.set (get_sub_table_size (groups)); + this->reserved.set (0); + this->length.set (get_sub_table_size (groups)); return CmapSubtableLongSegmented::serialize (c, groups); }