src/hb-ot-cmap-table.hh | 355 ++++++++-- src/hb-subset-plan.cc | 4 src/hb-subset-plan.hh | 18 test/api/fonts/Roboto-Regular.D7,D8,D9,DA,DE.ttf |binary test/api/test-subset-cmap.c | 4 test/subset/data/expected/basics/Roboto-Regular.abc.default.61,62,63.ttf |binary test/subset/data/expected/basics/Roboto-Regular.abc.default.61,63.ttf |binary test/subset/data/expected/basics/Roboto-Regular.abc.default.61.ttf |binary test/subset/data/expected/basics/Roboto-Regular.abc.default.62.ttf |binary test/subset/data/expected/basics/Roboto-Regular.abc.default.63.ttf |binary test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61,62,63.ttf |binary test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61,63.ttf |binary test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61.ttf |binary test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.62.ttf |binary test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.63.ttf |binary test/subset/data/expected/full-font/Roboto-Regular.default.1FC,21,41,20,62,63.ttf |binary test/subset/data/expected/full-font/Roboto-Regular.default.61,62,63.ttf |binary test/subset/data/expected/full-font/Roboto-Regular.default.D7,D8,D9,DA,DE.ttf |binary test/subset/data/expected/full-font/Roboto-Regular.drop-hints.1FC,21,41,20,62,63.ttf |binary test/subset/data/expected/full-font/Roboto-Regular.drop-hints.61,62,63.ttf |binary test/subset/data/expected/full-font/Roboto-Regular.drop-hints.D7,D8,D9,DA,DE.ttf |binary test/subset/data/expected/japanese/Mplus1p-Regular.default.3042,3044,3046,3048,304A,304B.ttf |binary test/subset/data/expected/japanese/Mplus1p-Regular.default.3042,3044,3046,73E0,5EA6,8F38.ttf |binary test/subset/data/expected/japanese/Mplus1p-Regular.default.61,63,65,6B.ttf |binary test/subset/data/expected/japanese/Mplus1p-Regular.default.660E,6975,73E0,5EA6,8F38,6E05.ttf |binary test/subset/data/expected/japanese/Mplus1p-Regular.default.660E.ttf |binary test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.3042,3044,3046,3048,304A,304B.ttf |binary test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.3042,3044,3046,73E0,5EA6,8F38.ttf |binary test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.61,63,65,6B.ttf |binary test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.ttf |binary test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.660E.ttf |binary test/subset/data/fonts/Mplus1p-Regular.ttf |binary 32 files changed, 306 insertions(+), 75 deletions(-)
New commits: commit 0644d92ef32b09e32d473c758d2a968f2d125628 Merge: 2a2e28e7 3be050f0 Author: Behdad Esfahbod <beh...@behdad.org> Date: Tue May 8 15:21:09 2018 -0700 Merge pull request #1018 from googlefonts/cmap4 [subset] Add cmap format 4 subsetting. commit 3be050f07572d8556726b188668d727e3e7ba643 Author: Garret Rieger <grie...@google.com> Date: Fri May 4 11:23:32 2018 -0700 [subset] entrySelectorZ -> entrySelector. diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 40125b05..dc55c0d7 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> (HBUINT16::static_size * segments.len); c->allocate_size<HBUINT16> (HBUINT16::static_size); // 2 bytes of padding. @@ -479,8 +479,8 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12> 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<CmapSubtableFormat12>::serialize (c, groups); } commit 7c22f98da789f831e1afb9078085b2e33d864d25 Author: Garret Rieger <grie...@google.com> Date: Thu May 3 13:14:28 2018 -0700 [subset] add missing template parameter. diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 83b47b56..40125b05 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -482,7 +482,7 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12> this->reservedZ.set (0); this->lengthZ.set (get_sub_table_size (groups)); - return CmapSubtableLongSegmented::serialize (c, groups); + return CmapSubtableLongSegmented<CmapSubtableFormat12>::serialize (c, groups); } static inline size_t get_sub_table_size (const hb_vector_t<CmapSubtableLongGroup> &groups) commit 95eb0f3bafb7ab0e2451e3e2f8afc5008e18e88e Author: Garret Rieger <grie...@google.com> Date: Thu May 3 13:00:19 2018 -0700 [subset] Switch to a non-log using implementation of caculating searchRangeZ, entrySelectorZ, and rangeShiftZ in cmap4. diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 883ac3a5..83b47b56 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> (HBUINT16::static_size * segments.len); c->allocate_size<HBUINT16> (HBUINT16::static_size); // 2 bytes of padding. commit b0d7971be0fa3c9393b04038b8d0a76398b0d8d7 Author: Garret Rieger <grie...@google.com> Date: Thu May 3 11:22:51 2018 -0700 [subset] Updated expected files for japanese subset integration tests to include cmap4. 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 db7daa88..33989996 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 d05b5eec..66b98a6d 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 cef6a42c..22d1bb30 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 d7852d8a..28043592 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 be607c29..333ca516 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 1e5a7c7f..c84b20cb 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 3845822d..e757b9e3 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 fce81232..e869ff1f 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 b72eaf9c..ed4ed4c1 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 ee7baba6..cb502388 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 2a5205ef..f89a28ef 100644 Binary files a/test/subset/data/fonts/Mplus1p-Regular.ttf and b/test/subset/data/fonts/Mplus1p-Regular.ttf differ commit 79479273170275447042aa50912acee74bbacdf6 Author: Garret Rieger <grie...@google.com> Date: Thu May 3 11:18:02 2018 -0700 [subset] Update expected files for subset integration tests to include cmap4. 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 02cd7efb..12d92081 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 4942ad0c..1af233f4 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 08fe7718..a699eea0 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 8d7e6b22..52706dc9 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 0f3a934c..3de7c773 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 70206add..52dc4745 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 c74c0299..1873672b 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 8ba816d7..128eae01 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 837438a5..122b1097 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 311737ab..381e97e9 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 60e361d2..93efe655 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 1fc430a4..d4d26d7e 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 2ff53536..7e271f22 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 98f01e19..99b91bd3 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 ea212f03..eb94906a 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 895c6e6b..ff361bae 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 commit a8e7f9b958dcb4e00226f78d0ff83f031bc1323d Author: Garret Rieger <grie...@google.com> Date: Thu May 3 10:59:00 2018 -0700 [subset] Get cmap tests passing again. 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 38799ccb..3a71f53f 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 8c519387..84d34bcd 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; commit c817992f495cba21bf468014f22afe349fbc799f Author: Garret Rieger <grie...@google.com> Date: Thu May 3 10:53:20 2018 -0700 [subset] Write out a format 4, plat 0 encoding record to match fontTools. diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 7e42b4fc..883ac3a5 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 52548742..8c519387 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; commit 9ef55a4c1354028f4d5e81300cdaf8ce5e03b8e9 Author: Garret Rieger <grie...@google.com> Date: Wed May 2 18:50:56 2018 -0700 [subset] A few bug fixes for cmap format 4 subsetting. diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 63380cad..7e42b4fc 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<HBINT16> (HBUINT16::static_size * segments.len); HBUINT16 *id_range_offset = c->allocate_size<HBUINT16> (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> (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<segment_plan> &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 (); commit 81ea75f5c860ef682184bd2c9d0ff8b48251e3ce Author: Garret Rieger <grie...@google.com> Date: Wed May 2 17:46:30 2018 -0700 [subset] Complete implementation of cmap4 subsetting. diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 115f3663..63380cad 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> (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<segment_plan> &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; commit 4195a52b041af749046b716dcac7d6560ae37611 Author: Garret Rieger <grie...@google.com> Date: Wed May 2 17:11:18 2018 -0700 [subset] WIP implementation of serialize for cmap format 4. diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 84ad1c7e..115f3663 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<segment_plan> &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> (HBUINT16::static_size * segments.len); + c->allocate_size<HBUINT16> (HBUINT16::static_size); // 2 bytes of padding. + HBUINT16 *start_count = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.len); + HBINT16 *id_delta = c->allocate_size<HBINT16> (HBUINT16::static_size * segments.len); + HBUINT16 *id_range_offset = c->allocate_size<HBUINT16> (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<segment_plan> &segments) commit cfa592d31ce2fd1ec2765a69ab31bf80161479dd Author: Garret Rieger <grie...@google.com> Date: Wed May 2 16:37:38 2018 -0700 [subset] Add an implement for cmap format 4 create_sub_table_plan. diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 7e9675b3..84ad1c7e 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<segment_plan> *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 commit 295d67ea7d0ddac5666bd6aa4b647dd9cbf8e8f7 Author: Garret Rieger <grie...@google.com> Date: Wed May 2 16:12:04 2018 -0700 [subset] WIP cmap format 4 subsetting. diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index f0e70afe..7e9675b3 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<segment_plan> &segments) + { + // TODO + } + + static inline size_t get_sub_table_size (const hb_vector_t<segment_plan> &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<segment_plan> *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<CmapSubtableFormat4::segment_plan> format4_segments; // Format 12 - hb_vector_t<CmapSubtableLongGroup> groups; + hb_vector_t<CmapSubtableLongGroup> 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; + + // TODO(grieger): Convert the below to a for loop - EncodingRecord &rec = cmap->encodingRecord[0]; - rec.platformID.set (3); // Windows - rec.encodingID.set (10); // Unicode UCS-4 + // 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); commit 0053d13283458996372f04bd501001d450523605 Author: Garret Rieger <grie...@google.com> Date: Wed May 2 15:42:43 2018 -0700 [subset] Refactor cmap subsetting to make it possible to add support for more sub tables. diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 83a0b519..f0e70afe 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<CmapSubtableLongGroup> &group_data) + const hb_vector_t<CmapSubtableLongGroup> &group_data) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); @@ -319,6 +319,69 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12> 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<CmapSubtableLongGroup> &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<CmapSubtableLongGroup> &groups) + { + return 16 + 12 * groups.len; + } + + static inline bool create_sub_table_plan (const hb_subset_plan_t *plan, + hb_vector_t<CmapSubtableLongGroup> *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<CmapSubtableFormat13> @@ -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<CmapSubtableLongGroup> 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<CmapSubtableLongGroup> *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<CmapSubtableLongGroup> &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<hb_vector_t<CmapSubtableLongGroup> > 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; } commit 03b27548123756dfd9988a8fc74bc78733fb2c44 Author: Garret Rieger <grie...@google.com> Date: Wed May 2 15:42:08 2018 -0700 [subset] Add const to the hb_subset_plan_t input to a couple functions in hb-subset-plan. diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index 0c11765c..d70215b0 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 3b9db03f..1c8697b6 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); _______________________________________________ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/harfbuzz