From 21ede867df28d1214ca677a24ac65ab0b7e95f42 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 25 Oct 2018 13:19:34 -0700 Subject: [PATCH 001/255] Fix possible overflow in bsearch impls From bungeman. Fixes https://github.com/harfbuzz/harfbuzz/pull/1314 --- src/hb-dsalgs.hh | 2 +- src/hb-open-type.hh | 4 ++-- src/hb-ot-cmap-table.hh | 2 +- src/hb-ot-layout-gpos-table.hh | 2 +- src/hb-vector.hh | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index 7e846161d..d22e8809e 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -321,7 +321,7 @@ hb_bsearch_r (const void *key, const void *base, int min = 0, max = (int) nmemb - 1; while (min <= max) { - int mid = (min + max) / 2; + int mid = ((unsigned int) min + (unsigned int) max) / 2; const void *p = (const void *) (((const char *) base) + (mid * size)); int c = compar (key, p, arg); if (c < 0) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 2b1b432ba..8b7ea0939 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -702,7 +702,7 @@ struct SortedArrayOf : ArrayOf int min = 0, max = (int) this->len - 1; while (min <= max) { - int mid = (min + max) / 2; + int mid = ((unsigned int) min + (unsigned int) max) / 2; int c = arr[mid].cmp (x); if (c < 0) max = mid - 1; @@ -825,7 +825,7 @@ struct VarSizedBinSearchArrayOf int min = 0, max = (int) header.nUnits - 1; while (min <= max) { - int mid = (min + max) / 2; + int mid = ((unsigned int) min + (unsigned int) max) / 2; const Type *p = (const Type *) (((const char *) &bytesZ) + (mid * size)); int c = p->cmp (key); if (c < 0) diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index e5793c387..9978d1b02 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -249,7 +249,7 @@ struct CmapSubtableFormat4 unsigned int i; while (min <= max) { - int mid = (min + max) / 2; + int mid = ((unsigned int) min + (unsigned int) max) / 2; if (codepoint < startCount[mid]) max = mid - 1; else if (codepoint > endCount[mid]) diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index dad6c4ea9..dd4e62792 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -663,7 +663,7 @@ struct PairSet int min = 0, max = (int) count - 1; while (min <= max) { - int mid = (min + max) / 2; + int mid = ((unsigned int) min + (unsigned int) max) / 2; const PairValueRecord *record = &StructAtOffset (&firstPairValueRecord, record_size * mid); hb_codepoint_t mid_x = record->secondGlyph; if (x < mid_x) diff --git a/src/hb-vector.hh b/src/hb-vector.hh index 766e5fb8e..eed4507ff 100644 --- a/src/hb-vector.hh +++ b/src/hb-vector.hh @@ -232,7 +232,7 @@ struct hb_vector_t const Type *array = this->arrayZ(); while (min <= max) { - int mid = (min + max) / 2; + int mid = ((unsigned int) min + (unsigned int) max) / 2; int c = array[mid].cmp (&x); if (c < 0) max = mid - 1; From 5739c876d0d080e7feaefd323245702c663f33be Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 25 Oct 2018 13:23:33 -0700 Subject: [PATCH 002/255] [test] Rename some fonts If we have duplicae font files in different directories, that would break the oss-fuzz build currently. So, rename some to avoid name class with text-rendering-test. Would be better to find another solution. --- ...ORXTwentyeight.ttf => MORXTwentyeight.ttf} | Bin .../in-house/fonts/{TestTRAK.ttf => TRAK.tff} | Bin .../in-house/fonts/{TestTTC.ttc => TTC.ttc} | Bin .../data/in-house/fonts/TestDFONT.dfont | Bin 3505 -> 0 bytes .../data/in-house/tests/aat-morx.tests | 2 +- .../data/in-house/tests/aat-trak.tests | 22 +++++++++--------- .../data/in-house/tests/collections.tests | 12 +++++----- 7 files changed, 18 insertions(+), 18 deletions(-) rename test/shaping/data/in-house/fonts/{TestMORXTwentyeight.ttf => MORXTwentyeight.ttf} (100%) rename test/shaping/data/in-house/fonts/{TestTRAK.ttf => TRAK.tff} (100%) rename test/shaping/data/in-house/fonts/{TestTTC.ttc => TTC.ttc} (100%) delete mode 100644 test/shaping/data/in-house/fonts/TestDFONT.dfont diff --git a/test/shaping/data/in-house/fonts/TestMORXTwentyeight.ttf b/test/shaping/data/in-house/fonts/MORXTwentyeight.ttf similarity index 100% rename from test/shaping/data/in-house/fonts/TestMORXTwentyeight.ttf rename to test/shaping/data/in-house/fonts/MORXTwentyeight.ttf diff --git a/test/shaping/data/in-house/fonts/TestTRAK.ttf b/test/shaping/data/in-house/fonts/TRAK.tff similarity index 100% rename from test/shaping/data/in-house/fonts/TestTRAK.ttf rename to test/shaping/data/in-house/fonts/TRAK.tff diff --git a/test/shaping/data/in-house/fonts/TestTTC.ttc b/test/shaping/data/in-house/fonts/TTC.ttc similarity index 100% rename from test/shaping/data/in-house/fonts/TestTTC.ttc rename to test/shaping/data/in-house/fonts/TTC.ttc diff --git a/test/shaping/data/in-house/fonts/TestDFONT.dfont b/test/shaping/data/in-house/fonts/TestDFONT.dfont deleted file mode 100644 index a6ea7009be3ed3c1083254effaf54bc6fbfed685..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3505 zcmeHJPiS0482`<@O?J24G@FRUKT91=Xj-tl$<{WI_8=r#DYP3+mUt=Dx7nB7*xh~0 zzL$_h4?-(QQRu19*R`_1A4GptU`~ zLH=p-TgE0*>0*E91wcGU{)wrIU28kIZ66>xTjZzad__6Qstn_8!t@J2y?284N6D8i$XN3P&i^52qA zl-(&Ck7Azlee&^&Jzql{cTunXsj6LZp2908-dhP66aV)uP;&asb=NL zU?mM(6b>ZeU``CyO?nydAyE~_(Z<G5hr%8l)zkPJse=$XJ@YhfTe zmL0`8bf~TJVxt`&SVzT!)G{V^m*rUw3PN1gkyCPj-Br^rVUQ8)y;-IuOk@X5j0x7o z!_>us$a%`F28E>B+Gr53(`6jtRtR{c%M~eAxuu}?7F|Jk1Z{Zr>`%`i`Tl-^4PUG?OFuqbq0&HrRCtx zJ9`F?99dkXif6*JWc4k^x9UoY_p!eObcN9-SoPYTeL_qwAIL*^(qO?8e%oNlC_XgU z!reT<<^hHf5ov?l&>I7&Qf@J95=mko}g$7R~6F*uBIal+sT zy5$`PM~Mdv-iVAGGdM>4uECoyXZ0D}jkt9l!*Ef<0_vDSk4yAMK3$(+qTU)5l6idF^Hnm-)`v-QZ{DR83 zRX^vtWiP3+t_t*?sym)jpK}VFmE&|T2r5UMp}_HcmCF&0Q&q$)nmINb-UnH?D}ElPOmtJwGwzEL4Tyx1?01!JPaYlUy+gfEUQ_TP?BZkGTIceLs=n+ zKgF1vW#w~hmK93AU-O1isp5=Zn$0Jt+)66%lnQnsHO+$Yb;0PX^>6c~cV6Zm^UQ%h zHC@^IlBBR7`*;;cd6_2ICn=w2TTdQR`Ldf&Rcz09>Z$$vhDWm#qe*|BlW(n}iM zX+Vu5`u$#m!juU}{_9!j!W(jUJmC4#Zs1$p8N77*OJ_5iewzjKORN73&B}oVmL5Bu zpzP-F5Xjf!80@9E5yP(>g8$I0w&V0%b6nM%b%S}JH%%V_8{X1kXo~;Nk5B44ez&u- z&aY>M|84%>4CwC$UL%tDlLXPZ>IK&8tVszzufm(I@_wN^GnO6UxMi@{d{vTZR%ldz Ky&}?jb$ Date: Thu, 25 Oct 2018 13:37:08 -0700 Subject: [PATCH 003/255] Fixup --- .../data/in-house/fonts/{TRAK.tff => TRAK.ttf} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename test/shaping/data/in-house/fonts/{TRAK.tff => TRAK.ttf} (100%) diff --git a/test/shaping/data/in-house/fonts/TRAK.tff b/test/shaping/data/in-house/fonts/TRAK.ttf similarity index 100% rename from test/shaping/data/in-house/fonts/TRAK.tff rename to test/shaping/data/in-house/fonts/TRAK.ttf From eceeb85666814023f57ee3517bbb304830a60c55 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Fri, 26 Oct 2018 00:23:45 +0330 Subject: [PATCH 004/255] [docs] Add hb-ot-color section --- docs/harfbuzz-sections.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index fccfcb0ed..7bca7ca20 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -457,6 +457,20 @@ hb_map_t HB_OT_H_IN +
+hb-ot-color +hb_ot_color_glyph_get_layers +hb_ot_color_has_layers +hb_ot_color_has_palettes +hb_ot_color_layer_t +hb_ot_color_palette_color_get_name_id +hb_ot_color_palette_flags_t +hb_ot_color_palette_get_colors +hb_ot_color_palette_get_count +hb_ot_color_palette_get_flags +hb_ot_color_palette_get_name_id +
+
hb-ot-font hb_ot_font_set_funcs From e3ceb2dde3525824de68914e12ad4e8a873ab90a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 25 Oct 2018 14:30:24 -0700 Subject: [PATCH 005/255] Fix again --- test/shaping/data/in-house/fonts/DFONT.dfont | Bin 0 -> 3505 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 test/shaping/data/in-house/fonts/DFONT.dfont diff --git a/test/shaping/data/in-house/fonts/DFONT.dfont b/test/shaping/data/in-house/fonts/DFONT.dfont new file mode 100644 index 0000000000000000000000000000000000000000..a6ea7009be3ed3c1083254effaf54bc6fbfed685 GIT binary patch literal 3505 zcmeHJPiS0482`<@O?J24G@FRUKT91=Xj-tl$<{WI_8=r#DYP3+mUt=Dx7nB7*xh~0 zzL$_h4?-(QQRu19*R`_1A4GptU`~ zLH=p-TgE0*>0*E91wcGU{)wrIU28kIZ66>xTjZzad__6Qstn_8!t@J2y?284N6D8i$XN3P&i^52qA zl-(&Ck7Azlee&^&Jzql{cTunXsj6LZp2908-dhP66aV)uP;&asb=NL zU?mM(6b>ZeU``CyO?nydAyE~_(Z<G5hr%8l)zkPJse=$XJ@YhfTe zmL0`8bf~TJVxt`&SVzT!)G{V^m*rUw3PN1gkyCPj-Br^rVUQ8)y;-IuOk@X5j0x7o z!_>us$a%`F28E>B+Gr53(`6jtRtR{c%M~eAxuu}?7F|Jk1Z{Zr>`%`i`Tl-^4PUG?OFuqbq0&HrRCtx zJ9`F?99dkXif6*JWc4k^x9UoY_p!eObcN9-SoPYTeL_qwAIL*^(qO?8e%oNlC_XgU z!reT<<^hHf5ov?l&>I7&Qf@J95=mko}g$7R~6F*uBIal+sT zy5$`PM~Mdv-iVAGGdM>4uECoyXZ0D}jkt9l!*Ef<0_vDSk4yAMK3$(+qTU)5l6idF^Hnm-)`v-QZ{DR83 zRX^vtWiP3+t_t*?sym)jpK}VFmE&|T2r5UMp}_HcmCF&0Q&q$)nmINb-UnH?D}ElPOmtJwGwzEL4Tyx1?01!JPaYlUy+gfEUQ_TP?BZkGTIceLs=n+ zKgF1vW#w~hmK93AU-O1isp5=Zn$0Jt+)66%lnQnsHO+$Yb;0PX^>6c~cV6Zm^UQ%h zHC@^IlBBR7`*;;cd6_2ICn=w2TTdQR`Ldf&Rcz09>Z$$vhDWm#qe*|BlW(n}iM zX+Vu5`u$#m!juU}{_9!j!W(jUJmC4#Zs1$p8N77*OJ_5iewzjKORN73&B}oVmL5Bu zpzP-F5Xjf!80@9E5yP(>g8$I0w&V0%b6nM%b%S}JH%%V_8{X1kXo~;Nk5B44ez&u- z&aY>M|84%>4CwC$UL%tDlLXPZ>IK&8tVszzufm(I@_wN^GnO6UxMi@{d{vTZR%ldz Ky&}?jb$ Date: Thu, 25 Oct 2018 16:35:36 -0700 Subject: [PATCH 006/255] [set] Make array access more explicit Follow up on 94e421abbfc7ede9aaf3c8d86bb0ff9992ea3123 --- src/hb-set.hh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hb-set.hh b/src/hb-set.hh index 5fdad2b71..7ba4c04da 100644 --- a/src/hb-set.hh +++ b/src/hb-set.hh @@ -669,7 +669,9 @@ struct hb_set_t return nullptr; pages[map.index].init0 (); - memmove (&page_map[i] + 1, &page_map[i], (page_map.len - 1 - i) * sizeof (page_map[0])); + memmove (page_map.arrayZ() + i + 1, + page_map.arrayZ() + i, + (page_map.len - 1 - i) * sizeof (page_map[0])); page_map[i] = map; } return &pages[page_map[i].index]; From 8d55e2adef9a376a5cf83c20aff2dba27dd64da8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 25 Oct 2018 16:37:53 -0700 Subject: [PATCH 007/255] [set] Minor --- src/hb-set.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-set.hh b/src/hb-set.hh index 7ba4c04da..4a7e74b66 100644 --- a/src/hb-set.hh +++ b/src/hb-set.hh @@ -368,8 +368,8 @@ struct hb_set_t if (!resize (count)) return; population = other->population; - memcpy (pages.arrayZ(), other->pages.arrayZ(), count * sizeof (pages.arrayZ()[0])); - memcpy (page_map.arrayZ(), other->page_map.arrayZ(), count * sizeof (page_map.arrayZ()[0])); + memcpy (pages.arrayZ(), other->pages.arrayZ(), count * sizeof (pages[0])); + memcpy (page_map.arrayZ(), other->page_map.arrayZ(), count * sizeof (page_map[0])); } inline bool is_equal (const hb_set_t *other) const From 955aa56b11e4fa14bc6d5b1b56cb810e28fab6cd Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 25 Oct 2018 16:50:38 -0700 Subject: [PATCH 008/255] [vector] Make it act more like pointer Add pointer cast operator and plus operator. --- src/hb-coretext.cc | 2 +- src/hb-machinery.hh | 2 +- src/hb-ot-cmap-table.hh | 2 +- src/hb-set.hh | 8 ++++---- src/hb-subset.cc | 2 +- src/hb-uniscribe.cc | 12 ++++++------ src/hb-vector.hh | 6 ++++++ 7 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/hb-coretext.cc b/src/hb-coretext.cc index 9f7745dbf..54e3f9ccc 100644 --- a/src/hb-coretext.cc +++ b/src/hb-coretext.cc @@ -586,7 +586,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, } else { active_feature_t *feature = active_features.find (&event->feature); if (feature) - active_features.remove (feature - active_features.arrayZ()); + active_features.remove (feature - active_features); } } } diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index 19245e89b..35cbc155f 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -612,7 +612,7 @@ struct Supplier } inline Supplier (const hb_vector_t *v) { - head = v->arrayZ(); + head = *v; len = v->len; stride = sizeof (Type); } diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 9978d1b02..d5b4fde34 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -495,7 +495,7 @@ struct CmapSubtableLongSegmented { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); - Supplier supplier (group_data.arrayZ(), group_data.len); + Supplier supplier (group_data, group_data.len); if (unlikely (!groups.serialize (c, supplier, group_data.len))) return_trace (false); return true; } diff --git a/src/hb-set.hh b/src/hb-set.hh index 4a7e74b66..2071196bc 100644 --- a/src/hb-set.hh +++ b/src/hb-set.hh @@ -368,8 +368,8 @@ struct hb_set_t if (!resize (count)) return; population = other->population; - memcpy (pages.arrayZ(), other->pages.arrayZ(), count * sizeof (pages[0])); - memcpy (page_map.arrayZ(), other->page_map.arrayZ(), count * sizeof (page_map[0])); + memcpy (pages, other->pages, count * sizeof (pages[0])); + memcpy (page_map, other->page_map, count * sizeof (page_map[0])); } inline bool is_equal (const hb_set_t *other) const @@ -669,8 +669,8 @@ struct hb_set_t return nullptr; pages[map.index].init0 (); - memmove (page_map.arrayZ() + i + 1, - page_map.arrayZ() + i, + memmove (page_map + i + 1, + page_map + i, (page_map.len - 1 - i) * sizeof (page_map[0])); page_map[i] = map; } diff --git a/src/hb-subset.cc b/src/hb-subset.cc index 9f14b89ba..294fd8460 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -77,7 +77,7 @@ _subset2 (hb_subset_plan_t *plan) return false; } retry: - hb_serialize_context_t serializer (buf.arrayZ(), buf_size); + hb_serialize_context_t serializer (buf, buf_size); hb_subset_context_t c (plan, &serializer); result = table->subset (&c); if (serializer.ran_out_of_room) diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc index 44a67ae4c..c3949c989 100644 --- a/src/hb-uniscribe.cc +++ b/src/hb-uniscribe.cc @@ -717,7 +717,7 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan, { active_feature_t *feature = active_features.find (&event->feature); if (feature) - active_features.remove (feature - active_features.arrayZ()); + active_features.remove (feature - active_features); } } @@ -728,7 +728,7 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan, for (unsigned int i = 0; i < range_records.len; i++) { range_record_t *range = &range_records[i]; - range->props.potfRecords = feature_records.arrayZ() + reinterpret_cast (range->props.potfRecords); + range->props.potfRecords = feature_records + reinterpret_cast (range->props.potfRecords); } } @@ -902,8 +902,8 @@ retry: &items[i].a, script_tags[i], language_tag, - range_char_counts.arrayZ(), - range_properties.arrayZ(), + range_char_counts, + range_properties, range_properties.len, pchars + chars_offset, item_chars_len, @@ -943,8 +943,8 @@ retry: &items[i].a, script_tags[i], language_tag, - range_char_counts.arrayZ(), - range_properties.arrayZ(), + range_char_counts, + range_properties, range_properties.len, pchars + chars_offset, log_clusters + chars_offset, diff --git a/src/hb-vector.hh b/src/hb-vector.hh index eed4507ff..8995ae104 100644 --- a/src/hb-vector.hh +++ b/src/hb-vector.hh @@ -66,6 +66,12 @@ struct hb_vector_t return arrayZ()[i]; } + template inline operator T * (void) { return arrayZ(); } + template inline operator const T * (void) const { return arrayZ(); } + + inline Type * operator + (unsigned int i) { return arrayZ() + i; } + inline const Type * operator + (unsigned int i) const { return arrayZ() + i; } + inline Type *push (void) { if (unlikely (!resize (len + 1))) From 102af615f15d04da20c17d80eb38f5948020f9ac Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 25 Oct 2018 17:29:32 -0700 Subject: [PATCH 009/255] [aat] Start adding support for DELETED-GLYPH https://github.com/harfbuzz/harfbuzz/issues/1302 --- src/hb-aat-layout-common.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index a99ccaf9f..da4b37fb2 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -362,6 +362,7 @@ template <> } namespace AAT { +enum { DELETED_GLYPH = 0xFFFF }; /* * Extended State Table @@ -424,6 +425,7 @@ struct StateTable inline unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs) const { + if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH; const HBUINT16 *v = (this+classTable).get_value (glyph_id, num_glyphs); return v ? (unsigned) *v : (unsigned) CLASS_OUT_OF_BOUNDS; } From 1bb8ed86d6cfec0fc87c8e1930d9a86426b42001 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 25 Oct 2018 17:33:48 -0700 Subject: [PATCH 010/255] [aat] Minor --- src/hb-aat-layout-common.hh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index da4b37fb2..406a36d8c 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -532,7 +532,7 @@ struct StateTableDriver unsigned int state = StateTable::STATE_START_OF_TEXT; bool last_was_dont_advance = false; - for (buffer->idx = 0;;) + for (buffer->idx = 0; buffer->successful;) { unsigned int klass = buffer->idx < buffer->len ? machine.get_class (buffer->info[buffer->idx].codepoint, num_glyphs) : @@ -566,8 +566,6 @@ struct StateTableDriver if (unlikely (!c->transition (this, entry))) break; - if (unlikely (!buffer->successful)) return; - last_was_dont_advance = (entry->flags & context_t::DontAdvance) && buffer->max_ops-- > 0; state = entry->newState; From 5c272e3613667ca532f32764824784c63d797f57 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 25 Oct 2018 17:36:33 -0700 Subject: [PATCH 011/255] [morx] Remove deleted-glyph at the end of processing --- src/hb-aat-layout-morx-table.hh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index c663fcc84..a3077e574 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -998,6 +998,22 @@ struct morx } } + inline static void remove_deleted_glyphs (hb_buffer_t *buffer) + { + if (unlikely (!buffer->successful)) return; + + buffer->clear_output (); + for (buffer->idx = 0; buffer->idx < buffer->len && buffer->successful;) + { + if (unlikely (buffer->cur().codepoint == DELETED_GLYPH)) + buffer->skip_glyph (); + else + buffer->next_glyph (); + } + if (likely (buffer->successful)) + buffer->swap_buffers (); + } + inline void apply (hb_aat_apply_context_t *c) const { if (unlikely (!c->buffer->successful)) return; @@ -1010,6 +1026,7 @@ struct morx if (unlikely (!c->buffer->successful)) return; chain = &StructAfter (*chain); } + remove_deleted_glyphs (c->buffer); } inline bool sanitize (hb_sanitize_context_t *c) const From ba5ca6a762cb46a17f41673b14996a12e6cfe3d1 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 25 Oct 2018 17:41:26 -0700 Subject: [PATCH 012/255] [morx] Use deleted-glyph, instead of actual deletion, in Ligation Closer to what CoreText does. Fixes https://github.com/harfbuzz/harfbuzz/issues/1302 --- src/hb-aat-layout-morx-table.hh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index a3077e574..84e321edc 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -447,8 +447,7 @@ struct LigatureSubtable { DEBUG_MSG (APPLY, nullptr, "Skipping ligature component"); buffer->move_to (match_positions[--match_length]); - buffer->skip_glyph (); - end--; + buffer->replace_glyph (DELETED_GLYPH); } buffer->move_to (end + 1); From 73449cd213c3a12468e99b9c3d840fc60a334902 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 25 Oct 2018 20:32:05 -0700 Subject: [PATCH 013/255] [layout] Fold one function inline Preparation for fixing https://github.com/harfbuzz/harfbuzz/pull/1317 --- src/hb-ot-layout.cc | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 128253da9..7e08c2a09 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -555,19 +555,6 @@ hb_ot_layout_language_get_required_feature (hb_face_t *face, return l.has_required_feature (); } -static void -_hb_ot_layout_language_add_feature_indexes_to (hb_face_t *face, - hb_tag_t table_tag, - unsigned int script_index, - unsigned int language_index, - hb_set_t *feature_indexes /* OUT */) -{ - const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); - const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index); - l.add_feature_indexes_to (feature_indexes); -} - - unsigned int hb_ot_layout_language_get_feature_indexes (hb_face_t *face, hb_tag_t table_tag, @@ -724,12 +711,9 @@ _hb_ot_layout_collect_features_features (hb_face_t *face, nullptr)) feature_indexes->add (required_feature_index); - /* All features */ - _hb_ot_layout_language_add_feature_indexes_to (face, - table_tag, - script_index, - language_index, - feature_indexes); + const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); + const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index); + l.add_feature_indexes_to (feature_indexes); } else { From 96828b97a8fc2c50721ce040bdde63c462908791 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 25 Oct 2018 20:34:29 -0700 Subject: [PATCH 014/255] [layout] Minor We were returning the accelerator's lookup count. Returns table's. They are the same except for OOM cases. Just shorter code. --- src/hb-ot-layout.cc | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 7e08c2a09..338ca6493 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -652,19 +652,7 @@ unsigned int hb_ot_layout_table_get_lookup_count (hb_face_t *face, hb_tag_t table_tag) { - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return 0; - switch (table_tag) - { - case HB_OT_TAG_GSUB: - { - return hb_ot_face_data (face)->GSUB->lookup_count; - } - case HB_OT_TAG_GPOS: - { - return hb_ot_face_data (face)->GPOS->lookup_count; - } - } - return 0; + return get_gsubgpos_table (face, table_tag).get_lookup_count (); } static void From e8e67503ff0a50eb10ad410d6a76a282ea494cf4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 25 Oct 2018 20:48:20 -0700 Subject: [PATCH 015/255] [lookup] More prep work for memoizing collect_features https://github.com/harfbuzz/harfbuzz/pull/1317 --- src/hb-ot-layout-common.hh | 2 + src/hb-ot-layout.cc | 81 +++++++++++++++++--------------------- 2 files changed, 39 insertions(+), 44 deletions(-) diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 98f6a079f..c9a87ce8f 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -277,6 +277,8 @@ struct Script { return langSys.find_index (tag, index); } inline bool has_default_lang_sys (void) const { return defaultLangSys != 0; } + inline const LangSys& get_default_lang_sys (unsigned int i) const + { return get_default_lang_sys (); } inline const LangSys& get_default_lang_sys (void) const { return this+defaultLangSys; } inline bool subset (hb_subset_context_t *c) const diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 338ca6493..d4bb280f2 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -681,40 +681,38 @@ _hb_ot_layout_collect_lookups_lookups (hb_face_t *face, } static void -_hb_ot_layout_collect_features_features (hb_face_t *face, - hb_tag_t table_tag, - unsigned int script_index, - unsigned int language_index, - const hb_tag_t *features, - hb_set_t *feature_indexes /* OUT */) +langsys_collect_features (const OT::GSUBGPOS &g, + const OT::LangSys &l, + const hb_tag_t *features, + hb_set_t *feature_indexes /* OUT */) { if (!features) { - unsigned int required_feature_index; - if (hb_ot_layout_language_get_required_feature (face, - table_tag, - script_index, - language_index, - &required_feature_index, - nullptr)) - feature_indexes->add (required_feature_index); + /* All features. */ + unsigned int index = l.get_required_feature_index (); + if (index != HB_OT_LAYOUT_NO_FEATURE_INDEX) + feature_indexes->add (index); - const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); - const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index); l.add_feature_indexes_to (feature_indexes); } else { + /* Ugh. Any faster way? */ for (; *features; features++) { + hb_tag_t feature_tag = *features; unsigned int feature_index; - if (hb_ot_layout_language_find_feature (face, - table_tag, - script_index, - language_index, - *features, - &feature_index)) - feature_indexes->add (feature_index); + unsigned int num_features = l.get_feature_count (); + for (unsigned int i = 0; i < num_features; i++) + { + unsigned int feature_index = l.get_feature_index (i); + + if (feature_tag == g.get_feature_tag (feature_index)) + { + feature_indexes->add (feature_index); + break; + } + } } } } @@ -727,27 +725,24 @@ _hb_ot_layout_collect_features_languages (hb_face_t *face, const hb_tag_t *features, hb_set_t *feature_indexes /* OUT */) { - _hb_ot_layout_collect_features_features (face, - table_tag, - script_index, - HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, - features, - feature_indexes); - + const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); if (!languages) { - /* All languages */ + /* All languages. */ + langsys_collect_features (g, + g.get_script (script_index).get_default_lang_sys (), + features, + feature_indexes); + unsigned int count = hb_ot_layout_script_get_language_tags (face, table_tag, script_index, 0, nullptr, nullptr); for (unsigned int language_index = 0; language_index < count; language_index++) - _hb_ot_layout_collect_features_features (face, - table_tag, - script_index, - language_index, - features, - feature_indexes); + langsys_collect_features (g, + g.get_script (script_index).get_lang_sys (language_index), + features, + feature_indexes); } else { @@ -760,12 +755,10 @@ _hb_ot_layout_collect_features_languages (hb_face_t *face, 1, languages, &language_index)) - _hb_ot_layout_collect_features_features (face, - table_tag, - script_index, - language_index, - features, - feature_indexes); + langsys_collect_features (g, + g.get_script (script_index).get_lang_sys (language_index), + features, + feature_indexes); } } } @@ -785,7 +778,7 @@ hb_ot_layout_collect_features (hb_face_t *face, { if (!scripts) { - /* All scripts */ + /* All scripts. */ unsigned int count = hb_ot_layout_table_get_script_tags (face, table_tag, 0, nullptr, nullptr); From fe5520ddea3941f7a72888d908fd2b895e2f388e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 25 Oct 2018 20:58:34 -0700 Subject: [PATCH 016/255] [layout] More prep work to memoize collect_features() work --- src/hb-ot-layout.cc | 62 +++++++++++++++++---------------------------- 1 file changed, 23 insertions(+), 39 deletions(-) diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index d4bb280f2..787ef13b1 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -718,29 +718,24 @@ langsys_collect_features (const OT::GSUBGPOS &g, } static void -_hb_ot_layout_collect_features_languages (hb_face_t *face, - hb_tag_t table_tag, - unsigned int script_index, - const hb_tag_t *languages, - const hb_tag_t *features, - hb_set_t *feature_indexes /* OUT */) +script_collect_features (const OT::GSUBGPOS &g, + const OT::Script &s, + const hb_tag_t *languages, + const hb_tag_t *features, + hb_set_t *feature_indexes /* OUT */) { - const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); if (!languages) { /* All languages. */ langsys_collect_features (g, - g.get_script (script_index).get_default_lang_sys (), + s.get_default_lang_sys (), features, feature_indexes); - unsigned int count = hb_ot_layout_script_get_language_tags (face, - table_tag, - script_index, - 0, nullptr, nullptr); + unsigned int count = s.get_lang_sys_count (); for (unsigned int language_index = 0; language_index < count; language_index++) langsys_collect_features (g, - g.get_script (script_index).get_lang_sys (language_index), + s.get_lang_sys (language_index), features, feature_indexes); } @@ -749,14 +744,9 @@ _hb_ot_layout_collect_features_languages (hb_face_t *face, for (; *languages; languages++) { unsigned int language_index; - if (hb_ot_layout_script_select_language (face, - table_tag, - script_index, - 1, - languages, - &language_index)) + if (s.find_lang_sys_index (*languages, &language_index)) langsys_collect_features (g, - g.get_script (script_index).get_lang_sys (language_index), + s.get_lang_sys (language_index), features, feature_indexes); } @@ -776,35 +766,29 @@ hb_ot_layout_collect_features (hb_face_t *face, const hb_tag_t *features, hb_set_t *feature_indexes /* OUT */) { + const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); if (!scripts) { /* All scripts. */ - unsigned int count = hb_ot_layout_table_get_script_tags (face, - table_tag, - 0, nullptr, nullptr); + unsigned int count = g.get_script_count (); for (unsigned int script_index = 0; script_index < count; script_index++) - _hb_ot_layout_collect_features_languages (face, - table_tag, - script_index, - languages, - features, - feature_indexes); + script_collect_features (g, + g.get_script (script_index), + languages, + features, + feature_indexes); } else { for (; *scripts; scripts++) { unsigned int script_index; - if (hb_ot_layout_table_find_script (face, - table_tag, - *scripts, - &script_index)) - _hb_ot_layout_collect_features_languages (face, - table_tag, - script_index, - languages, - features, - feature_indexes); + if (g.find_script_index (*scripts, &script_index)) + script_collect_features (g, + g.get_script (script_index), + languages, + features, + feature_indexes); } } } From c237cdfcc74d33f77b2399b4d08228c2fcf50df5 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 25 Oct 2018 21:17:30 -0700 Subject: [PATCH 017/255] [lookup] Fold another function inline --- src/hb-ot-layout.cc | 48 ++++++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 787ef13b1..ece7f89da 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -655,31 +655,6 @@ hb_ot_layout_table_get_lookup_count (hb_face_t *face, return get_gsubgpos_table (face, table_tag).get_lookup_count (); } -static void -_hb_ot_layout_collect_lookups_lookups (hb_face_t *face, - hb_tag_t table_tag, - unsigned int feature_index, - hb_set_t *lookup_indexes /* OUT */) -{ - unsigned int lookup_indices[32]; - unsigned int offset, len; - - offset = 0; - do { - len = ARRAY_LENGTH (lookup_indices); - hb_ot_layout_feature_get_lookups (face, - table_tag, - feature_index, - offset, &len, - lookup_indices); - - for (unsigned int i = 0; i < len; i++) - lookup_indexes->add (lookup_indices[i]); - - offset += len; - } while (len == ARRAY_LENGTH (lookup_indices)); -} - static void langsys_collect_features (const OT::GSUBGPOS &g, const OT::LangSys &l, @@ -808,8 +783,27 @@ hb_ot_layout_collect_lookups (hb_face_t *face, { hb_auto_t feature_indexes; hb_ot_layout_collect_features (face, table_tag, scripts, languages, features, &feature_indexes); - for (hb_codepoint_t feature_index = HB_SET_VALUE_INVALID; hb_set_next (&feature_indexes, &feature_index);) - _hb_ot_layout_collect_lookups_lookups (face, table_tag, feature_index, lookup_indexes); + for (hb_codepoint_t feature_index = HB_SET_VALUE_INVALID; + hb_set_next (&feature_indexes, &feature_index);) + { + unsigned int lookup_indices[32]; + unsigned int offset, len; + + offset = 0; + do { + len = ARRAY_LENGTH (lookup_indices); + hb_ot_layout_feature_get_lookups (face, + table_tag, + feature_index, + offset, &len, + lookup_indices); + + for (unsigned int i = 0; i < len; i++) + lookup_indexes->add (lookup_indices[i]); + + offset += len; + } while (len == ARRAY_LENGTH (lookup_indices)); + } } /** From 941600a9e06309f148d51403fa07dc56ce542572 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 25 Oct 2018 21:26:08 -0700 Subject: [PATCH 018/255] [layout] Add hb_collect_features_context_t Towards https://github.com/harfbuzz/harfbuzz/pull/1317 --- src/hb-ot-layout.cc | 66 ++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index ece7f89da..aa1a35702 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -655,20 +655,32 @@ hb_ot_layout_table_get_lookup_count (hb_face_t *face, return get_gsubgpos_table (face, table_tag).get_lookup_count (); } + +struct hb_collect_features_context_t +{ + hb_collect_features_context_t (hb_face_t *face, + hb_tag_t table_tag, + hb_set_t *feature_indexes_) + : g (get_gsubgpos_table (face, table_tag)), + feature_indexes (feature_indexes_) {} + + const OT::GSUBGPOS &g; + hb_set_t *feature_indexes; +}; + static void -langsys_collect_features (const OT::GSUBGPOS &g, +langsys_collect_features (hb_collect_features_context_t *c, const OT::LangSys &l, - const hb_tag_t *features, - hb_set_t *feature_indexes /* OUT */) + const hb_tag_t *features) { if (!features) { /* All features. */ unsigned int index = l.get_required_feature_index (); if (index != HB_OT_LAYOUT_NO_FEATURE_INDEX) - feature_indexes->add (index); + c->feature_indexes->add (index); - l.add_feature_indexes_to (feature_indexes); + l.add_feature_indexes_to (c->feature_indexes); } else { @@ -682,9 +694,9 @@ langsys_collect_features (const OT::GSUBGPOS &g, { unsigned int feature_index = l.get_feature_index (i); - if (feature_tag == g.get_feature_tag (feature_index)) + if (feature_tag == c->g.get_feature_tag (feature_index)) { - feature_indexes->add (feature_index); + c->feature_indexes->add (feature_index); break; } } @@ -693,26 +705,23 @@ langsys_collect_features (const OT::GSUBGPOS &g, } static void -script_collect_features (const OT::GSUBGPOS &g, +script_collect_features (hb_collect_features_context_t *c, const OT::Script &s, const hb_tag_t *languages, - const hb_tag_t *features, - hb_set_t *feature_indexes /* OUT */) + const hb_tag_t *features) { if (!languages) { /* All languages. */ - langsys_collect_features (g, + langsys_collect_features (c, s.get_default_lang_sys (), - features, - feature_indexes); + features); unsigned int count = s.get_lang_sys_count (); for (unsigned int language_index = 0; language_index < count; language_index++) - langsys_collect_features (g, + langsys_collect_features (c, s.get_lang_sys (language_index), - features, - feature_indexes); + features); } else { @@ -720,10 +729,9 @@ script_collect_features (const OT::GSUBGPOS &g, { unsigned int language_index; if (s.find_lang_sys_index (*languages, &language_index)) - langsys_collect_features (g, + langsys_collect_features (c, s.get_lang_sys (language_index), - features, - feature_indexes); + features); } } } @@ -741,29 +749,27 @@ hb_ot_layout_collect_features (hb_face_t *face, const hb_tag_t *features, hb_set_t *feature_indexes /* OUT */) { - const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); + hb_collect_features_context_t c (face, table_tag, feature_indexes); if (!scripts) { /* All scripts. */ - unsigned int count = g.get_script_count (); + unsigned int count = c.g.get_script_count (); for (unsigned int script_index = 0; script_index < count; script_index++) - script_collect_features (g, - g.get_script (script_index), + script_collect_features (&c, + c.g.get_script (script_index), languages, - features, - feature_indexes); + features); } else { for (; *scripts; scripts++) { unsigned int script_index; - if (g.find_script_index (*scripts, &script_index)) - script_collect_features (g, - g.get_script (script_index), + if (c.g.find_script_index (*scripts, &script_index)) + script_collect_features (&c, + c.g.get_script (script_index), languages, - features, - feature_indexes); + features); } } } From 84098b1639775aea5bf3f5d91fa6e657b612ce3a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 25 Oct 2018 21:33:12 -0700 Subject: [PATCH 019/255] [layout] Remove unintentionally added code --- src/hb-ot-layout-common.hh | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index c9a87ce8f..98f6a079f 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -277,8 +277,6 @@ struct Script { return langSys.find_index (tag, index); } inline bool has_default_lang_sys (void) const { return defaultLangSys != 0; } - inline const LangSys& get_default_lang_sys (unsigned int i) const - { return get_default_lang_sys (); } inline const LangSys& get_default_lang_sys (void) const { return this+defaultLangSys; } inline bool subset (hb_subset_context_t *c) const From eb44bfc864f91c0c833c3156475d191ac1b79c72 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 25 Oct 2018 21:42:19 -0700 Subject: [PATCH 020/255] [layout] Memoize collect_features Fixes https://github.com/harfbuzz/harfbuzz/pull/1317 Fixes https://oss-fuzz.com/v2/testcase-detail/6543700493598720 --- src/hb-ot-layout.cc | 55 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index aa1a35702..c2803f3f0 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -664,8 +664,46 @@ struct hb_collect_features_context_t : g (get_gsubgpos_table (face, table_tag)), feature_indexes (feature_indexes_) {} + bool inline visited (const OT::Script &s) + { + /* We might have Null() object here. Don't want to involve + * that in the memoize. So, detect empty objects and return. */ + if (unlikely (!s.has_default_lang_sys () && + !s.get_lang_sys_count ())) + return true; + + return visited (s, visited_script); + } + bool inline visited (const OT::LangSys &l) + { + /* We might have Null() object here. Don't want to involve + * that in the memoize. So, detect empty objects and return. */ + if (unlikely (!l.has_required_feature () && + !l.get_feature_count ())) + return true; + + return visited (l, visited_langsys); + } + + private: + template + bool inline visited (const T &p, hb_set_t &visited_set) + { + hb_codepoint_t delta = (hb_codepoint_t) ((uintptr_t) &p - (uintptr_t) &g); + if (visited_set.has (delta)) + return true; + + visited_set.add (delta); + return false; + } + + public: const OT::GSUBGPOS &g; hb_set_t *feature_indexes; + + private: + hb_auto_t visited_script; + hb_auto_t visited_langsys; }; static void @@ -673,12 +711,13 @@ langsys_collect_features (hb_collect_features_context_t *c, const OT::LangSys &l, const hb_tag_t *features) { + if (c->visited (l)) return; + if (!features) { /* All features. */ - unsigned int index = l.get_required_feature_index (); - if (index != HB_OT_LAYOUT_NO_FEATURE_INDEX) - c->feature_indexes->add (index); + if (l.has_required_feature ()) + c->feature_indexes->add (l.get_required_feature_index ()); l.add_feature_indexes_to (c->feature_indexes); } @@ -688,7 +727,6 @@ langsys_collect_features (hb_collect_features_context_t *c, for (; *features; features++) { hb_tag_t feature_tag = *features; - unsigned int feature_index; unsigned int num_features = l.get_feature_count (); for (unsigned int i = 0; i < num_features; i++) { @@ -710,12 +748,15 @@ script_collect_features (hb_collect_features_context_t *c, const hb_tag_t *languages, const hb_tag_t *features) { + if (c->visited (s)) return; + if (!languages) { /* All languages. */ - langsys_collect_features (c, - s.get_default_lang_sys (), - features); + if (s.has_default_lang_sys ()) + langsys_collect_features (c, + s.get_default_lang_sys (), + features); unsigned int count = s.get_lang_sys_count (); for (unsigned int language_index = 0; language_index < count; language_index++) From e98af6d1eda33346f72de8a45fbd317fc0e15935 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 25 Oct 2018 22:25:29 -0700 Subject: [PATCH 021/255] [layout] Try to speed up collect_lookups some more Barely made a dent :(. --- src/hb-ot-layout-common.hh | 2 ++ src/hb-ot-layout.cc | 23 ++++------------------- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 98f6a079f..7bca2caec 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -555,6 +555,8 @@ struct Feature unsigned int *lookup_count /* IN/OUT */, unsigned int *lookup_tags /* OUT */) const { return lookupIndex.get_indexes (start_index, lookup_count, lookup_tags); } + inline void add_lookup_indexes_to (hb_set_t *lookup_indexes) const + { lookupIndex.add_indexes_to (lookup_indexes); } inline const FeatureParams &get_feature_params (void) const { return this+featureParams; } diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index c2803f3f0..096fda207 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -828,29 +828,14 @@ hb_ot_layout_collect_lookups (hb_face_t *face, const hb_tag_t *features, hb_set_t *lookup_indexes /* OUT */) { + const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); + hb_auto_t feature_indexes; hb_ot_layout_collect_features (face, table_tag, scripts, languages, features, &feature_indexes); + for (hb_codepoint_t feature_index = HB_SET_VALUE_INVALID; hb_set_next (&feature_indexes, &feature_index);) - { - unsigned int lookup_indices[32]; - unsigned int offset, len; - - offset = 0; - do { - len = ARRAY_LENGTH (lookup_indices); - hb_ot_layout_feature_get_lookups (face, - table_tag, - feature_index, - offset, &len, - lookup_indices); - - for (unsigned int i = 0; i < len; i++) - lookup_indexes->add (lookup_indices[i]); - - offset += len; - } while (len == ARRAY_LENGTH (lookup_indices)); - } + g.get_feature (feature_index).add_lookup_indexes_to (lookup_indexes); } /** From c7a4e3dfb5c8dd4f8faf08e327bb1900c0096cf6 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Tue, 23 Oct 2018 18:00:48 +0330 Subject: [PATCH 022/255] [svg] Add public API * hb_ot_color_has_svg * hb_ot_color_glyph_svg_create_blob --- src/dump-emoji.cc | 51 ++++++++++++-------- src/hb-open-type.hh | 1 - src/hb-ot-color-sbix-table.hh | 2 + src/hb-ot-color-svg-table.hh | 88 ++++++++++++++++++++++++++--------- src/hb-ot-color.cc | 53 ++++++++++++++++++--- src/hb-ot-color.h | 13 ++++++ src/hb-ot-face.cc | 2 + src/hb-ot-face.hh | 4 +- src/hb-ot-layout.cc | 4 -- test/api/test-ot-color.c | 43 +++++++++++++++-- 10 files changed, 200 insertions(+), 61 deletions(-) diff --git a/src/dump-emoji.cc b/src/dump-emoji.cc index 2f79fc69d..97aab0044 100644 --- a/src/dump-emoji.cc +++ b/src/dump-emoji.cc @@ -69,26 +69,40 @@ sbix_callback (const uint8_t* data, unsigned int length, } static void -svg_callback (const uint8_t* data, unsigned int length, - unsigned int start_glyph, unsigned int end_glyph) +svg_dump (hb_face_t *face) { - char output_path[255]; - if (start_glyph == end_glyph) - sprintf (output_path, "out/svg-%d.svg", start_glyph); - else - sprintf (output_path, "out/svg-%d-%d.svg", start_glyph, end_glyph); + unsigned glyph_count = hb_face_get_glyph_count (face); - // append "z" if the content is gzipped - if ((data[0] == 0x1F) && (data[1] == 0x8B)) - strcat (output_path, "z"); + for (unsigned int glyph_id = 0; glyph_id < glyph_count; glyph_id++) + { + hb_codepoint_t start_glyph_id, end_glyph_id; + hb_blob_t *blob = hb_ot_color_glyph_svg_create_blob (face, glyph_id, + &start_glyph_id, &end_glyph_id); - FILE *f = fopen (output_path, "wb"); - fwrite (data, 1, length, f); - fclose (f); + if (hb_blob_get_length (blob) == 0) continue; + + char output_path[255]; + if (start_glyph_id == end_glyph_id) + sprintf (output_path, "out/svg-%d.svg", start_glyph_id); + else + sprintf (output_path, "out/svg-%d-%d.svg", start_glyph_id, end_glyph_id); + + unsigned int length; + const char *data = hb_blob_get_data (blob, &length); + // append "z" if the content is gzipped, https://stackoverflow.com/a/6059405 + if (length > 2 && (data[0] == '\x1F') && (data[1] == '\x8B')) + strcat (output_path, "z"); + + FILE *f = fopen (output_path, "wb"); + fwrite (data, 1, length, f); + fclose (f); + + if (glyph_id < end_glyph_id) glyph_id = end_glyph_id; + } } static void -colr_cpal_rendering (hb_face_t *face, cairo_font_face_t *cairo_face) +colr_cpal_dump (hb_face_t *face, cairo_font_face_t *cairo_face) { unsigned int upem = hb_face_get_upem (face); @@ -268,10 +282,8 @@ main (int argc, char **argv) sbix.dump (sbix_callback); sbix.fini (); - OT::SVG::accelerator_t svg; - svg.init (face); - svg.dump (svg_callback); - svg.fini (); + if (hb_ot_color_has_svg (face)) + svg_dump (face); cairo_font_face_t *cairo_face; { @@ -281,7 +293,8 @@ main (int argc, char **argv) FT_New_Face (library, argv[1], 0, &ftface); cairo_face = cairo_ft_font_face_create_for_ft_face (ftface, 0); } - colr_cpal_rendering (face, cairo_face); + if (hb_ot_color_has_layers (face) && hb_ot_color_has_palettes (face)) + colr_cpal_dump (face, cairo_face); unsigned int num_glyphs = hb_face_get_glyph_count (face); unsigned int upem = hb_face_get_upem (face); diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 8b7ea0939..8d17f3ed1 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -523,7 +523,6 @@ struct ArrayOf ::qsort (arrayZ, len, sizeof (Type), Type::cmp); } - private: inline bool sanitize_shallow (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 1b643c77a..1dd0a5c6d 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -142,6 +142,8 @@ struct sbix DEFINE_SIZE_ARRAY (8, strikes); }; +struct sbix_accelerator_t : sbix::accelerator_t {}; + } /* namespace OT */ #endif /* HB_OT_COLOR_SBIX_TABLE_HH */ diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh index 53d466846..fc5b8662a 100644 --- a/src/hb-ot-color-svg-table.hh +++ b/src/hb-ot-color-svg-table.hh @@ -41,12 +41,22 @@ namespace OT { struct SVGDocumentIndexEntry { friend struct SVG; + friend struct SVGDocumentIndex; - inline bool sanitize (hb_sanitize_context_t *c, const void* base) const + inline int cmp (hb_codepoint_t g) const + { return g < startGlyphID ? -1 : g > endGlyphID ? 1 : 0; } + + static int cmp (const void *pa, const void *pb) + { + const hb_codepoint_t *a = (const hb_codepoint_t *) pa; + const SVGDocumentIndexEntry *b = (const SVGDocumentIndexEntry *) pb; + return b->cmp (*a); + } + + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - (base+svgDoc).sanitize (c, svgDocLength)); + return_trace (c->check_struct (this)); } protected: @@ -57,7 +67,7 @@ struct SVGDocumentIndexEntry LOffsetTo, false> svgDoc; /* Offset from the beginning of the SVG Document Index * to an SVG document. Must be non-zero. */ - HBUINT32 svgDocLength; /* Length of the SVG document. + HBUINT32 svgDocLength; /* Length of the SVG document. * Must be non-zero. */ public: DEFINE_SIZE_STATIC (12); @@ -67,11 +77,22 @@ struct SVGDocumentIndex { friend struct SVG; + inline const SVGDocumentIndexEntry &get_glyph_entry (hb_codepoint_t glyph_id) const + { + const SVGDocumentIndexEntry *rec; + rec = (SVGDocumentIndexEntry *) bsearch (&glyph_id, + &entries.arrayZ, + entries.len, + sizeof (SVGDocumentIndexEntry), + SVGDocumentIndexEntry::cmp); + return likely (rec && glyph_id <= rec->endGlyphID) ? *rec : Null(SVGDocumentIndexEntry); + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && - entries.sanitize (c, this)); + entries.sanitize_shallow (c)); } protected: @@ -85,13 +106,6 @@ struct SVG { static const hb_tag_t tableTag = HB_OT_TAG_SVG; - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && - (this+svgDocIndex).sanitize (c))); - } - struct accelerator_t { inline void init (hb_face_t *face) @@ -106,20 +120,39 @@ struct SVG hb_blob_destroy (svg_blob); } - inline void - dump (void (*callback) (const uint8_t* data, unsigned int length, - unsigned int start_glyph, unsigned int end_glyph)) const + inline hb_blob_t* + failed_create_blob (hb_codepoint_t glyph_id, + hb_codepoint_t *start_glyph_id, + hb_codepoint_t *end_glyph_id) const { - const SVGDocumentIndex &index = svg+svg->svgDocIndex; - const ArrayOf &entries = index.entries; - for (unsigned int i = 0; i < entries.len; ++i) - { - const SVGDocumentIndexEntry &entry = entries[i]; - callback ((const uint8_t*) &entry.svgDoc (&index), entry.svgDocLength, - entry.startGlyphID, entry.endGlyphID); - } + if (start_glyph_id) *start_glyph_id = 0; + if (end_glyph_id) *end_glyph_id = 0; + return hb_blob_get_empty (); } + inline hb_blob_t* + create_blob (hb_codepoint_t glyph_id, + hb_codepoint_t *start_glyph_id, + hb_codepoint_t *end_glyph_id) const + { + if (unlikely (svg_len == 0)) + return failed_create_blob (glyph_id, start_glyph_id, end_glyph_id); + const SVGDocumentIndex &index = svg+svg->svgDocIndex; + const SVGDocumentIndexEntry &entry = index.get_glyph_entry (glyph_id); + if (unlikely (entry.svgDocLength == 0)) + return failed_create_blob (glyph_id, start_glyph_id, end_glyph_id); + unsigned int blob_offset = entry.svgDoc; + blob_offset += svg->svgDocIndex; + if (unlikely (blob_offset > svg_len || blob_offset + entry.svgDocLength > svg_len)) + return failed_create_blob (glyph_id, start_glyph_id, end_glyph_id); + if (start_glyph_id) *start_glyph_id = entry.startGlyphID; + if (end_glyph_id) *end_glyph_id = entry.endGlyphID; + return hb_blob_create_sub_blob (svg_blob, blob_offset, entry.svgDocLength); + } + + inline bool has_data () const + { return svg_len; } + private: hb_blob_t *svg_blob; const SVG *svg; @@ -127,6 +160,13 @@ struct SVG unsigned int svg_len; }; + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + (this+svgDocIndex).sanitize (c))); + } + protected: HBUINT16 version; /* Table version (starting at 0). */ LOffsetTo @@ -137,6 +177,8 @@ struct SVG DEFINE_SIZE_STATIC (10); }; +struct SVG_accelerator_t : SVG::accelerator_t {}; + } /* namespace OT */ diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index 229b6e66f..e2f36ca37 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -54,6 +54,13 @@ _get_cpal (hb_face_t *face) return *(hb_ot_face_data (face)->CPAL.get ()); } +static inline const OT::SVG_accelerator_t& +_get_svg (hb_face_t *face) +{ + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::SVG_accelerator_t); + return *(hb_ot_face_data (face)->SVG.get ()); +} + #if 0 static inline const OT::CBDT_accelerator_t& _get_cbdt (hb_face_t *face) @@ -68,13 +75,6 @@ _get_sbix (hb_face_t *face) if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::sbix); return *(hb_ot_face_data (face)->sbix.get ()); } - -static inline const OT::SVG& -_get_svg (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::SVG); - return *(hb_ot_face_data (face)->SVG.get ()); -} #endif @@ -238,3 +238,42 @@ hb_ot_color_glyph_get_layers (hb_face_t *face, { return _get_colr (face).get_glyph_layers (glyph, start_offset, count, layers); } + + +/* + * SVG + */ + +/** + * hb_ot_color_has_svg: + * @face: a font face. + * + * Returns: whether SVG table is available. + * + * Since: REPLACEME + */ +hb_bool_t +hb_ot_color_has_svg (hb_face_t *face) +{ + return _get_svg (face).has_data (); +} + +/** + * hb_ot_color_glyph_svg_create_blob: + * @face: + * @glyph: + * @start_glyph: (out) (optional): Start of range this SVG supports + * @end_glyph: (out) (optional): End of range this SVG supports + * + * Returns: + * + * Since: REPLACEME + */ +hb_blob_t * +hb_ot_color_glyph_svg_create_blob (hb_face_t *face, + hb_codepoint_t glyph, + hb_codepoint_t *start_glyph, /* OUT. May be NULL. */ + hb_codepoint_t *end_glyph /* OUT. May be NULL. */) +{ + return _get_svg (face).create_blob (glyph, start_glyph, end_glyph); +} diff --git a/src/hb-ot-color.h b/src/hb-ot-color.h index 02b76bffc..8b31b687b 100644 --- a/src/hb-ot-color.h +++ b/src/hb-ot-color.h @@ -111,6 +111,19 @@ hb_ot_color_glyph_get_layers (hb_face_t *face, unsigned int *count, /* IN/OUT. May be NULL. */ hb_ot_color_layer_t *layers /* OUT. May be NULL. */); +/* + * SVG + */ + +HB_EXTERN hb_bool_t +hb_ot_color_has_svg (hb_face_t *face); + +HB_EXTERN hb_blob_t * +hb_ot_color_glyph_svg_create_blob (hb_face_t *face, + hb_codepoint_t glyph, + hb_codepoint_t *start_glyph, /* OUT. May be NULL. */ + hb_codepoint_t *end_glyph /* OUT. May be NULL. */); + HB_END_DECLS diff --git a/src/hb-ot-face.cc b/src/hb-ot-face.cc index 1bc68d366..0aba2a691 100644 --- a/src/hb-ot-face.cc +++ b/src/hb-ot-face.cc @@ -32,6 +32,8 @@ #include "hb-ot-kern-table.hh" #include "hb-ot-post-table.hh" #include "hb-ot-color-cbdt-table.hh" +#include "hb-ot-color-sbix-table.hh" +#include "hb-ot-color-svg-table.hh" #include "hb-ot-layout-gdef-table.hh" #include "hb-ot-layout-gsub-table.hh" #include "hb-ot-layout-gpos-table.hh" diff --git a/src/hb-ot-face.hh b/src/hb-ot-face.hh index a45a49361..cce2f1d8f 100644 --- a/src/hb-ot-face.hh +++ b/src/hb-ot-face.hh @@ -73,8 +73,8 @@ HB_OT_TABLE(OT, COLR) \ HB_OT_TABLE(OT, CPAL) \ HB_OT_ACCELERATOR(OT, CBDT) \ - HB_OT_TABLE(OT, sbix) \ - HB_OT_TABLE(OT, SVG) \ + HB_OT_ACCELERATOR(OT, sbix) \ + HB_OT_ACCELERATOR(OT, SVG) \ /* */ /* Declare tables. */ diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 096fda207..7f3e6c73d 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -41,10 +41,6 @@ // Just so we compile them; unused otherwise: #include "hb-ot-layout-base-table.hh" #include "hb-ot-layout-jstf-table.hh" -#include "hb-ot-color-colr-table.hh" -#include "hb-ot-color-cpal-table.hh" -#include "hb-ot-color-sbix-table.hh" -#include "hb-ot-color-svg-table.hh" #include "hb-ot-kern-table.hh" #include "hb-ot-name-table.hh" diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index a514c6aa9..f145a4ce6 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -103,6 +103,7 @@ static hb_face_t *cpal = NULL; static hb_face_t *cbdt = NULL; static hb_face_t *sbix = NULL; static hb_face_t *svg = NULL; +static hb_face_t *empty = NULL; #define assert_color_rgba(colors, i, r, g, b, a) G_STMT_START { \ const hb_color_t *_colors = (colors); \ @@ -203,7 +204,6 @@ test_hb_ot_color_palette_get_flags_v1 (void) static void test_hb_ot_color_palette_get_colors_empty (void) { - hb_face_t *empty = hb_face_get_empty (); g_assert_cmpint (hb_ot_color_palette_get_colors (empty, 0, 0, NULL, NULL), ==, 0); } @@ -302,8 +302,6 @@ test_hb_ot_color_palette_get_colors_v1 (void) static void test_hb_ot_color_palette_color_get_name_id (void) { - hb_face_t *empty = hb_face_get_empty (); - g_assert_cmpuint (hb_ot_color_palette_color_get_name_id (empty, 0), ==, HB_NAME_ID_INVALID); g_assert_cmpuint (hb_ot_color_palette_color_get_name_id (empty, 1), ==, HB_NAME_ID_INVALID); g_assert_cmpuint (hb_ot_color_palette_color_get_name_id (empty, 2), ==, HB_NAME_ID_INVALID); @@ -349,8 +347,6 @@ test_hb_ot_color_glyph_get_layers (void) static void test_hb_ot_color_has_data (void) { - hb_face_t *empty = hb_face_get_empty (); - g_assert (hb_ot_color_has_layers (empty) == FALSE); g_assert (hb_ot_color_has_layers (cpal_v0) == TRUE); g_assert (hb_ot_color_has_layers (cpal_v1) == TRUE); @@ -366,6 +362,41 @@ test_hb_ot_color_has_data (void) g_assert (hb_ot_color_has_palettes (cbdt) == FALSE); g_assert (hb_ot_color_has_palettes (sbix) == FALSE); g_assert (hb_ot_color_has_palettes (svg) == FALSE); + + g_assert (hb_ot_color_has_svg (empty) == FALSE); + g_assert (hb_ot_color_has_svg (cpal_v0) == FALSE); + g_assert (hb_ot_color_has_svg (cpal_v1) == FALSE); + g_assert (hb_ot_color_has_svg (cpal) == FALSE); + g_assert (hb_ot_color_has_svg (cbdt) == FALSE); + g_assert (hb_ot_color_has_svg (sbix) == FALSE); + g_assert (hb_ot_color_has_svg (svg) == TRUE); +} + +static void +test_hb_ot_color_svg (void) +{ + hb_codepoint_t start_glyph, end_glyph; + hb_blob_t *blob; + + blob = hb_ot_color_glyph_svg_create_blob (svg, 0, &start_glyph, &end_glyph); + g_assert (hb_blob_get_length (blob) == 0); + g_assert (start_glyph == 0); + g_assert (end_glyph == 0); + + blob = hb_ot_color_glyph_svg_create_blob (svg, 1, &start_glyph, &end_glyph); + unsigned int length; + const char *data = hb_blob_get_data (blob, &length); + g_assert_cmpuint (length, ==, 146); + g_assert_cmpuint (start_glyph, ==, 1); + g_assert_cmpuint (end_glyph, ==, 1); + g_assert (strncmp (data, "", 5) == 0); + hb_blob_destroy (blob); + + blob = hb_ot_color_glyph_svg_create_blob (empty, 0, &start_glyph, &end_glyph); + g_assert (hb_blob_get_length (blob) == 0); + g_assert (start_glyph == 0); + g_assert (end_glyph == 0); } int @@ -380,6 +411,7 @@ main (int argc, char **argv) cbdt = hb_test_open_font_file ("fonts/chromacheck-cbdt.ttf"); sbix = hb_test_open_font_file ("fonts/chromacheck-sbix.ttf"); svg = hb_test_open_font_file ("fonts/chromacheck-svg.ttf"); + empty = hb_face_get_empty (); hb_test_add (test_hb_ot_color_palette_get_count); hb_test_add (test_hb_ot_color_palette_get_name_id_empty); hb_test_add (test_hb_ot_color_palette_get_name_id_v0); @@ -393,6 +425,7 @@ main (int argc, char **argv) hb_test_add (test_hb_ot_color_palette_color_get_name_id); hb_test_add (test_hb_ot_color_glyph_get_layers); hb_test_add (test_hb_ot_color_has_data); + hb_test_add (test_hb_ot_color_svg); status = hb_test_run(); hb_face_destroy (cpal_v0); hb_face_destroy (cpal_v1); From 4ceabb8c2126fe365303b8d69e667005276c0241 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Thu, 25 Oct 2018 21:52:35 +0330 Subject: [PATCH 023/255] [svg] Hide start_glyph and end_glyph from API --- src/dump-emoji.cc | 21 +++++++----------- src/hb-ot-color-svg-table.hh | 42 +++++++++++------------------------- src/hb-ot-color.cc | 9 ++------ src/hb-ot-color.h | 5 +---- test/api/test-ot-color.c | 11 ++-------- 5 files changed, 25 insertions(+), 63 deletions(-) diff --git a/src/dump-emoji.cc b/src/dump-emoji.cc index 97aab0044..1603d2d98 100644 --- a/src/dump-emoji.cc +++ b/src/dump-emoji.cc @@ -75,29 +75,24 @@ svg_dump (hb_face_t *face) for (unsigned int glyph_id = 0; glyph_id < glyph_count; glyph_id++) { - hb_codepoint_t start_glyph_id, end_glyph_id; - hb_blob_t *blob = hb_ot_color_glyph_svg_create_blob (face, glyph_id, - &start_glyph_id, &end_glyph_id); + hb_blob_t *blob = hb_ot_color_glyph_svg_create_blob (face, glyph_id); if (hb_blob_get_length (blob) == 0) continue; - char output_path[255]; - if (start_glyph_id == end_glyph_id) - sprintf (output_path, "out/svg-%d.svg", start_glyph_id); - else - sprintf (output_path, "out/svg-%d-%d.svg", start_glyph_id, end_glyph_id); - unsigned int length; const char *data = hb_blob_get_data (blob, &length); - // append "z" if the content is gzipped, https://stackoverflow.com/a/6059405 - if (length > 2 && (data[0] == '\x1F') && (data[1] == '\x8B')) - strcat (output_path, "z"); + + char output_path[256]; + sprintf (output_path, "out/svg-%d.svg%s", + glyph_id, + // append "z" if the content is gzipped, https://stackoverflow.com/a/6059405 + (length > 2 && (data[0] == '\x1F') && (data[1] == '\x8B')) ? "z" : ""); FILE *f = fopen (output_path, "wb"); fwrite (data, 1, length, f); fclose (f); - if (glyph_id < end_glyph_id) glyph_id = end_glyph_id; + hb_blob_destroy (blob); } } diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh index fc5b8662a..9e03ef762 100644 --- a/src/hb-ot-color-svg-table.hh +++ b/src/hb-ot-color-svg-table.hh @@ -40,9 +40,6 @@ namespace OT { struct SVGDocumentIndexEntry { - friend struct SVG; - friend struct SVGDocumentIndex; - inline int cmp (hb_codepoint_t g) const { return g < startGlyphID ? -1 : g > endGlyphID ? 1 : 0; } @@ -53,6 +50,13 @@ struct SVGDocumentIndexEntry return b->cmp (*a); } + inline hb_blob_t* create_blob (hb_blob_t *svg_blob, unsigned int index_offset) const + { + if (svgDocLength == 0) return hb_blob_get_empty (); + return hb_blob_create_sub_blob (svg_blob, (unsigned int) svgDoc + index_offset, + svgDocLength); + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -85,7 +89,7 @@ struct SVGDocumentIndex entries.len, sizeof (SVGDocumentIndexEntry), SVGDocumentIndexEntry::cmp); - return likely (rec && glyph_id <= rec->endGlyphID) ? *rec : Null(SVGDocumentIndexEntry); + return likely (rec) ? *rec : Null(SVGDocumentIndexEntry); } inline bool sanitize (hb_sanitize_context_t *c) const @@ -120,34 +124,12 @@ struct SVG hb_blob_destroy (svg_blob); } - inline hb_blob_t* - failed_create_blob (hb_codepoint_t glyph_id, - hb_codepoint_t *start_glyph_id, - hb_codepoint_t *end_glyph_id) const - { - if (start_glyph_id) *start_glyph_id = 0; - if (end_glyph_id) *end_glyph_id = 0; - return hb_blob_get_empty (); - } - - inline hb_blob_t* - create_blob (hb_codepoint_t glyph_id, - hb_codepoint_t *start_glyph_id, - hb_codepoint_t *end_glyph_id) const + inline hb_blob_t* create_blob_for_glyph (hb_codepoint_t glyph_id) const { if (unlikely (svg_len == 0)) - return failed_create_blob (glyph_id, start_glyph_id, end_glyph_id); - const SVGDocumentIndex &index = svg+svg->svgDocIndex; - const SVGDocumentIndexEntry &entry = index.get_glyph_entry (glyph_id); - if (unlikely (entry.svgDocLength == 0)) - return failed_create_blob (glyph_id, start_glyph_id, end_glyph_id); - unsigned int blob_offset = entry.svgDoc; - blob_offset += svg->svgDocIndex; - if (unlikely (blob_offset > svg_len || blob_offset + entry.svgDocLength > svg_len)) - return failed_create_blob (glyph_id, start_glyph_id, end_glyph_id); - if (start_glyph_id) *start_glyph_id = entry.startGlyphID; - if (end_glyph_id) *end_glyph_id = entry.endGlyphID; - return hb_blob_create_sub_blob (svg_blob, blob_offset, entry.svgDocLength); + return hb_blob_get_empty (); + return (svg+svg->svgDocIndex).get_glyph_entry (glyph_id).create_blob (svg_blob, + svg->svgDocIndex); } inline bool has_data () const diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index e2f36ca37..cdfbaade1 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -262,18 +262,13 @@ hb_ot_color_has_svg (hb_face_t *face) * hb_ot_color_glyph_svg_create_blob: * @face: * @glyph: - * @start_glyph: (out) (optional): Start of range this SVG supports - * @end_glyph: (out) (optional): End of range this SVG supports * * Returns: * * Since: REPLACEME */ hb_blob_t * -hb_ot_color_glyph_svg_create_blob (hb_face_t *face, - hb_codepoint_t glyph, - hb_codepoint_t *start_glyph, /* OUT. May be NULL. */ - hb_codepoint_t *end_glyph /* OUT. May be NULL. */) +hb_ot_color_glyph_svg_create_blob (hb_face_t *face, hb_codepoint_t glyph) { - return _get_svg (face).create_blob (glyph, start_glyph, end_glyph); + return _get_svg (face).create_blob_for_glyph (glyph); } diff --git a/src/hb-ot-color.h b/src/hb-ot-color.h index 8b31b687b..259c84987 100644 --- a/src/hb-ot-color.h +++ b/src/hb-ot-color.h @@ -119,10 +119,7 @@ HB_EXTERN hb_bool_t hb_ot_color_has_svg (hb_face_t *face); HB_EXTERN hb_blob_t * -hb_ot_color_glyph_svg_create_blob (hb_face_t *face, - hb_codepoint_t glyph, - hb_codepoint_t *start_glyph, /* OUT. May be NULL. */ - hb_codepoint_t *end_glyph /* OUT. May be NULL. */); +hb_ot_color_glyph_svg_create_blob (hb_face_t *face, hb_codepoint_t glyph); HB_END_DECLS diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index f145a4ce6..8e4ec0a06 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -375,28 +375,21 @@ test_hb_ot_color_has_data (void) static void test_hb_ot_color_svg (void) { - hb_codepoint_t start_glyph, end_glyph; hb_blob_t *blob; - blob = hb_ot_color_glyph_svg_create_blob (svg, 0, &start_glyph, &end_glyph); + blob = hb_ot_color_glyph_svg_create_blob (svg, 0); g_assert (hb_blob_get_length (blob) == 0); - g_assert (start_glyph == 0); - g_assert (end_glyph == 0); - blob = hb_ot_color_glyph_svg_create_blob (svg, 1, &start_glyph, &end_glyph); + blob = hb_ot_color_glyph_svg_create_blob (svg, 1); unsigned int length; const char *data = hb_blob_get_data (blob, &length); g_assert_cmpuint (length, ==, 146); - g_assert_cmpuint (start_glyph, ==, 1); - g_assert_cmpuint (end_glyph, ==, 1); g_assert (strncmp (data, "", 5) == 0); hb_blob_destroy (blob); blob = hb_ot_color_glyph_svg_create_blob (empty, 0, &start_glyph, &end_glyph); g_assert (hb_blob_get_length (blob) == 0); - g_assert (start_glyph == 0); - g_assert (end_glyph == 0); } int From 5cb1ce868138a10c0663a18c3891bc717aa4bc64 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Thu, 25 Oct 2018 22:39:58 +0330 Subject: [PATCH 024/255] [svg] Collapse SVGDocumentIndex into SVG --- src/hb-ot-color-svg-table.hh | 54 ++++++++++++------------------------ src/hb-ot-color.cc | 2 +- test/api/test-ot-color.c | 2 +- 3 files changed, 20 insertions(+), 38 deletions(-) diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh index 9e03ef762..4ef380745 100644 --- a/src/hb-ot-color-svg-table.hh +++ b/src/hb-ot-color-svg-table.hh @@ -50,7 +50,7 @@ struct SVGDocumentIndexEntry return b->cmp (*a); } - inline hb_blob_t* create_blob (hb_blob_t *svg_blob, unsigned int index_offset) const + inline hb_blob_t* reference_blob (hb_blob_t *svg_blob, unsigned int index_offset) const { if (svgDocLength == 0) return hb_blob_get_empty (); return hb_blob_create_sub_blob (svg_blob, (unsigned int) svgDoc + index_offset, @@ -77,35 +77,6 @@ struct SVGDocumentIndexEntry DEFINE_SIZE_STATIC (12); }; -struct SVGDocumentIndex -{ - friend struct SVG; - - inline const SVGDocumentIndexEntry &get_glyph_entry (hb_codepoint_t glyph_id) const - { - const SVGDocumentIndexEntry *rec; - rec = (SVGDocumentIndexEntry *) bsearch (&glyph_id, - &entries.arrayZ, - entries.len, - sizeof (SVGDocumentIndexEntry), - SVGDocumentIndexEntry::cmp); - return likely (rec) ? *rec : Null(SVGDocumentIndexEntry); - } - - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - entries.sanitize_shallow (c)); - } - - protected: - ArrayOf - entries; /* Array of SVG Document Index Entries. */ - public: - DEFINE_SIZE_ARRAY (2, entries); -}; - struct SVG { static const hb_tag_t tableTag = HB_OT_TAG_SVG; @@ -124,12 +95,11 @@ struct SVG hb_blob_destroy (svg_blob); } - inline hb_blob_t* create_blob_for_glyph (hb_codepoint_t glyph_id) const + inline hb_blob_t* reference_blob_for_glyph (hb_codepoint_t glyph_id) const { if (unlikely (svg_len == 0)) return hb_blob_get_empty (); - return (svg+svg->svgDocIndex).get_glyph_entry (glyph_id).create_blob (svg_blob, - svg->svgDocIndex); + return svg->get_glyph_entry (glyph_id).reference_blob (svg_blob, svg->svgDocEntries); } inline bool has_data () const @@ -142,18 +112,30 @@ struct SVG unsigned int svg_len; }; + inline const SVGDocumentIndexEntry &get_glyph_entry (hb_codepoint_t glyph_id) const + { + const SVGDocumentIndexEntry *rec; + rec = (SVGDocumentIndexEntry *) bsearch (&glyph_id, + &(this+svgDocEntries).arrayZ, + (this+svgDocEntries).len, + sizeof (SVGDocumentIndexEntry), + SVGDocumentIndexEntry::cmp); + return likely (rec) ? *rec : Null(SVGDocumentIndexEntry); + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && - (this+svgDocIndex).sanitize (c))); + (this+svgDocEntries).sanitize_shallow (c))); } protected: HBUINT16 version; /* Table version (starting at 0). */ - LOffsetTo - svgDocIndex; /* Offset (relative to the start of the SVG table) to the + LOffsetTo > + svgDocEntries; /* Offset (relative to the start of the SVG table) to the * SVG Documents Index. Must be non-zero. */ + /* Array of SVG Document Index Entries. */ HBUINT32 reserved; /* Set to 0. */ public: DEFINE_SIZE_STATIC (10); diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index cdfbaade1..3d9f1c1ba 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -270,5 +270,5 @@ hb_ot_color_has_svg (hb_face_t *face) hb_blob_t * hb_ot_color_glyph_svg_create_blob (hb_face_t *face, hb_codepoint_t glyph) { - return _get_svg (face).create_blob_for_glyph (glyph); + return _get_svg (face).reference_blob_for_glyph (glyph); } diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index 8e4ec0a06..13a25b0b8 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -388,7 +388,7 @@ test_hb_ot_color_svg (void) g_assert (strncmp (data + 140, "", 5) == 0); hb_blob_destroy (blob); - blob = hb_ot_color_glyph_svg_create_blob (empty, 0, &start_glyph, &end_glyph); + blob = hb_ot_color_glyph_svg_create_blob (empty, 0); g_assert (hb_blob_get_length (blob) == 0); } From 30f18039b3c0e5748101f8934ae82aebfc5a83f7 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Fri, 26 Oct 2018 09:34:34 +0330 Subject: [PATCH 025/255] [svg] Rename _svg_create_blob to _glyph_reference_blob_svg --- docs/harfbuzz-sections.txt | 2 ++ src/dump-emoji.cc | 2 +- src/hb-ot-color.cc | 4 ++-- src/hb-ot-color.h | 2 +- test/api/test-ot-color.c | 6 +++--- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index 7bca7ca20..c385984a7 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -460,8 +460,10 @@ HB_OT_H_IN
hb-ot-color hb_ot_color_glyph_get_layers +hb_ot_color_glyph_reference_blob_svg hb_ot_color_has_layers hb_ot_color_has_palettes +hb_ot_color_has_svg hb_ot_color_layer_t hb_ot_color_palette_color_get_name_id hb_ot_color_palette_flags_t diff --git a/src/dump-emoji.cc b/src/dump-emoji.cc index 1603d2d98..c4710a629 100644 --- a/src/dump-emoji.cc +++ b/src/dump-emoji.cc @@ -75,7 +75,7 @@ svg_dump (hb_face_t *face) for (unsigned int glyph_id = 0; glyph_id < glyph_count; glyph_id++) { - hb_blob_t *blob = hb_ot_color_glyph_svg_create_blob (face, glyph_id); + hb_blob_t *blob = hb_ot_color_glyph_reference_blob_svg (face, glyph_id); if (hb_blob_get_length (blob) == 0) continue; diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index 3d9f1c1ba..283b3a1e5 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -259,7 +259,7 @@ hb_ot_color_has_svg (hb_face_t *face) } /** - * hb_ot_color_glyph_svg_create_blob: + * hb_ot_color_glyph_reference_blob_svg: * @face: * @glyph: * @@ -268,7 +268,7 @@ hb_ot_color_has_svg (hb_face_t *face) * Since: REPLACEME */ hb_blob_t * -hb_ot_color_glyph_svg_create_blob (hb_face_t *face, hb_codepoint_t glyph) +hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph) { return _get_svg (face).reference_blob_for_glyph (glyph); } diff --git a/src/hb-ot-color.h b/src/hb-ot-color.h index 259c84987..fb9a9e370 100644 --- a/src/hb-ot-color.h +++ b/src/hb-ot-color.h @@ -119,7 +119,7 @@ HB_EXTERN hb_bool_t hb_ot_color_has_svg (hb_face_t *face); HB_EXTERN hb_blob_t * -hb_ot_color_glyph_svg_create_blob (hb_face_t *face, hb_codepoint_t glyph); +hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph); HB_END_DECLS diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index 13a25b0b8..4ffadeec0 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -377,10 +377,10 @@ test_hb_ot_color_svg (void) { hb_blob_t *blob; - blob = hb_ot_color_glyph_svg_create_blob (svg, 0); + blob = hb_ot_color_glyph_reference_blob_svg (svg, 0); g_assert (hb_blob_get_length (blob) == 0); - blob = hb_ot_color_glyph_svg_create_blob (svg, 1); + blob = hb_ot_color_glyph_reference_blob_svg (svg, 1); unsigned int length; const char *data = hb_blob_get_data (blob, &length); g_assert_cmpuint (length, ==, 146); @@ -388,7 +388,7 @@ test_hb_ot_color_svg (void) g_assert (strncmp (data + 140, "", 5) == 0); hb_blob_destroy (blob); - blob = hb_ot_color_glyph_svg_create_blob (empty, 0); + blob = hb_ot_color_glyph_reference_blob_svg (empty, 0); g_assert (hb_blob_get_length (blob) == 0); } From 143ffe65aa7f20d6c53219905cbc2520d680b8dd Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Fri, 26 Oct 2018 12:14:30 +0330 Subject: [PATCH 026/255] [fuzz] Add a new testcase --- ...se-minimized-hb-shape-fuzzer-5658272078495744 | Bin 0 -> 2252 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 test/api/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5658272078495744 diff --git a/test/api/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5658272078495744 b/test/api/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5658272078495744 new file mode 100644 index 0000000000000000000000000000000000000000..f3fa938e5d52ec24f77c0a22d68d841595b577ba GIT binary patch literal 2252 zcmZQzWME)W7#NV7SWy77nSp^(0z~KL7ga#`94sIj2l$Ue9INpE{}AOs8ciQe9IG}3 z21cN}uuF}KqJ;o@z@mpVn(~3?(#ydJdj@@wV2KpWEQ3W6^@R|D1~;2xmy8BKJS+(@ zumnFLEyG2W)AH_8rTW|)_4m4fwTe;GXXJ(4+iMj4=6VSD8U4h1hUzI z*cym+fH(q(3xK!=h(XdQ0BkByf`Ji4AOVnV$bcDSF4!$#H!v_Y0L_6I=m2yZvY`w} F8~}&-JH7w_ literal 0 HcmV?d00001 From 982c2f4a65d127e56e09e7ab583f84099b8136bb Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 26 Oct 2018 15:40:12 -0700 Subject: [PATCH 027/255] [indic/khmer/myanmar/use] Clarify clear_syllable No logic change. --- src/hb-ot-shape-complex-indic.cc | 3 +- src/hb-ot-shape-complex-khmer.cc | 4 +-- src/hb-ot-shape-complex-myanmar.cc | 50 ++++++++++++++---------------- src/hb-ot-shape-complex-use.cc | 22 +++++++++---- 4 files changed, 43 insertions(+), 36 deletions(-) diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc index 3babbfec6..f145a34c3 100644 --- a/src/hb-ot-shape-complex-indic.cc +++ b/src/hb-ot-shape-complex-indic.cc @@ -116,7 +116,8 @@ indic_features[] = {HB_TAG('c','j','c','t'), F_GLOBAL_MANUAL_JOINERS}, /* * Other features. - * These features are applied all at once, after final_reordering. + * These features are applied all at once, after final_reordering + * but before clearing syllables. * Default Bengali font in Windows for example has intermixed * lookups for init,pres,abvs,blws features. */ diff --git a/src/hb-ot-shape-complex-khmer.cc b/src/hb-ot-shape-complex-khmer.cc index 88d16267b..21db351fc 100644 --- a/src/hb-ot-shape-complex-khmer.cc +++ b/src/hb-ot-shape-complex-khmer.cc @@ -46,7 +46,7 @@ khmer_features[] = {HB_TAG('c','f','a','r'), F_MANUAL_JOINERS}, /* * Other features. - * These features are applied all at once. + * These features are applied all at once after clearing syllables. */ {HB_TAG('p','r','e','s'), F_GLOBAL_MANUAL_JOINERS}, {HB_TAG('a','b','v','s'), F_GLOBAL_MANUAL_JOINERS}, @@ -438,8 +438,6 @@ clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) { - /* TODO: In USE, we clear syllables right after reorder. Figure out - * what Uniscribe does. */ hb_glyph_info_t *info = buffer->info; unsigned int count = buffer->len; for (unsigned int i = 0; i < count; i++) diff --git a/src/hb-ot-shape-complex-myanmar.cc b/src/hb-ot-shape-complex-myanmar.cc index e201a2309..30fa82579 100644 --- a/src/hb-ot-shape-complex-myanmar.cc +++ b/src/hb-ot-shape-complex-myanmar.cc @@ -36,7 +36,7 @@ basic_features[] = { /* * Basic features. - * These features are applied in order, one at a time, after initial_reordering. + * These features are applied in order, one at a time, after reordering. */ HB_TAG('r','p','h','f'), HB_TAG('p','r','e','f'), @@ -48,7 +48,7 @@ other_features[] = { /* * Other features. - * These features are applied all at once, after final_reordering. + * These features are applied all at once, after clearing syllables. */ HB_TAG('p','r','e','s'), HB_TAG('a','b','v','s'), @@ -80,13 +80,13 @@ setup_syllables (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); static void -initial_reordering (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer); +reorder (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); static void -final_reordering (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer); +clear_syllables (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); static void collect_features_myanmar (hb_ot_shape_planner_t *plan) @@ -102,7 +102,7 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan) map->enable_feature (HB_TAG('c','c','m','p')); - map->add_gsub_pause (initial_reordering); + map->add_gsub_pause (reorder); for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++) { @@ -110,7 +110,7 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan) map->add_gsub_pause (nullptr); } - map->add_gsub_pause (final_reordering); + map->add_gsub_pause (clear_syllables); for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++) map->enable_feature (other_features[i], F_MANUAL_ZWJ); @@ -348,32 +348,30 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, } static void -initial_reordering (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer) +reorder (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) { insert_dotted_circles (plan, font, buffer); foreach_syllable (buffer, start, end) initial_reordering_syllable (plan, font->face, buffer, start, end); -} - -static void -final_reordering (const hb_ot_shape_plan_t *plan, - hb_font_t *font HB_UNUSED, - hb_buffer_t *buffer) -{ - hb_glyph_info_t *info = buffer->info; - unsigned int count = buffer->len; - - /* Zero syllables now... */ - for (unsigned int i = 0; i < count; i++) - info[i].syllable() = 0; HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_category); HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_position); } +static void +clear_syllables (const hb_ot_shape_plan_t *plan, + hb_font_t *font HB_UNUSED, + hb_buffer_t *buffer) +{ + hb_glyph_info_t *info = buffer->info; + unsigned int count = buffer->len; + for (unsigned int i = 0; i < count; i++) + info[i].syllable() = 0; +} + const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar = { diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index addfb87ba..7814e2c67 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -80,7 +80,8 @@ other_features[] = { /* * Other features. - * These features are applied all at once, after reordering. + * These features are applied all at once, after reordering and + * clearing syllables. */ HB_TAG('a','b','v','s'), HB_TAG('b','l','w','s'), @@ -120,6 +121,10 @@ static void reorder (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); +static void +clear_syllables (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); static void collect_features_use (hb_ot_shape_planner_t *plan) @@ -148,6 +153,7 @@ collect_features_use (hb_ot_shape_planner_t *plan) map->enable_feature (basic_features[i], F_MANUAL_ZWJ); map->add_gsub_pause (reorder); + map->add_gsub_pause (clear_syllables); /* "Topographical features" */ for (unsigned int i = 0; i < ARRAY_LENGTH (arabic_features); i++) @@ -559,17 +565,21 @@ reorder (const hb_ot_shape_plan_t *plan, { insert_dotted_circles (plan, font, buffer); - hb_glyph_info_t *info = buffer->info; - foreach_syllable (buffer, start, end) reorder_syllable (buffer, start, end); - /* Zero syllables now... */ + HB_BUFFER_DEALLOCATE_VAR (buffer, use_category); +} + +static void +clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_font_t *font HB_UNUSED, + hb_buffer_t *buffer) +{ + hb_glyph_info_t *info = buffer->info; unsigned int count = buffer->len; for (unsigned int i = 0; i < count; i++) info[i].syllable() = 0; - - HB_BUFFER_DEALLOCATE_VAR (buffer, use_category); } From 0bf93ec0fb549d838b0a246de02a95559a9b2772 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 15 Oct 2018 21:34:10 -0700 Subject: [PATCH 028/255] [name] Add public API declarations --- src/hb-ot-name.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/hb-ot-name.h b/src/hb-ot-name.h index 49423e87c..1f643d53e 100644 --- a/src/hb-ot-name.h +++ b/src/hb-ot-name.h @@ -48,6 +48,40 @@ typedef unsigned int hb_name_id_t; **/ #define HB_NAME_ID_INVALID 0xFFFF + +HB_EXTERN hb_bool_t +hb_ot_name_get_utf8 (hb_face_t *face, + hb_name_id_t name_id, + hb_language_t language, + unsigned int *text_size /* IN/OUT */, + char *text /* OUT */); + +HB_EXTERN hb_bool_t +hb_ot_name_get_utf16 (hb_face_t *face, + hb_name_id_t name_id, + hb_language_t language, + unsigned int *text_size /* IN/OUT */, + uint16_t *text /* OUT */); + +HB_EXTERN hb_bool_t +hb_ot_name_get_utf32 (hb_face_t *face, + hb_name_id_t name_id, + hb_language_t language, + unsigned int *text_size /* IN/OUT */, + uint32_t *text /* OUT */); + + +typedef struct hb_ot_name_entry_t +{ + hb_name_id_t name_id; + hb_language_t language; +} hb_ot_name_entry_t; + +HB_EXTERN unsigned int +hb_ot_name_get_names (hb_face_t *face, + hb_ot_name_entry_t **entries /* OUT */); + + HB_END_DECLS #endif /* HB_OT_NAME_H */ From 2157e56b34e7b932dd144ee3563f5bd682bbed30 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 15 Oct 2018 22:22:50 -0700 Subject: [PATCH 029/255] [name] Start implementing public API infrastructure --- src/hb-ot-face.cc | 1 + src/hb-ot-face.hh | 7 ++--- src/hb-ot-name-table.hh | 60 +++++++++++++++++++++++++++++++++++++++++ src/hb-ot-name.h | 3 +++ 4 files changed, 68 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-face.cc b/src/hb-ot-face.cc index 1bc68d366..dd17faf6b 100644 --- a/src/hb-ot-face.cc +++ b/src/hb-ot-face.cc @@ -30,6 +30,7 @@ #include "hb-ot-glyf-table.hh" #include "hb-ot-hmtx-table.hh" #include "hb-ot-kern-table.hh" +#include "hb-ot-name-table.hh" #include "hb-ot-post-table.hh" #include "hb-ot-color-cbdt-table.hh" #include "hb-ot-layout-gdef-table.hh" diff --git a/src/hb-ot-face.hh b/src/hb-ot-face.hh index a45a49361..c810e9fb4 100644 --- a/src/hb-ot-face.hh +++ b/src/hb-ot-face.hh @@ -45,6 +45,9 @@ * This is as good as any place. */ #define HB_OT_TABLES \ /* OpenType shaping. */ \ + HB_OT_ACCELERATOR(OT, GDEF) \ + HB_OT_ACCELERATOR(OT, GSUB) \ + HB_OT_ACCELERATOR(OT, GPOS) \ HB_OT_TABLE(OT, JSTF) \ HB_OT_TABLE(OT, BASE) \ /* AAT shaping. */ \ @@ -59,13 +62,11 @@ /* OpenType math. */ \ HB_OT_TABLE(OT, MATH) \ /* OpenType fundamentals. */ \ - HB_OT_ACCELERATOR(OT, GDEF) \ - HB_OT_ACCELERATOR(OT, GSUB) \ - HB_OT_ACCELERATOR(OT, GPOS) \ HB_OT_ACCELERATOR(OT, cmap) \ HB_OT_ACCELERATOR(OT, hmtx) \ HB_OT_ACCELERATOR(OT, vmtx) \ HB_OT_ACCELERATOR(OT, post) \ + HB_OT_ACCELERATOR(OT, name) \ HB_OT_ACCELERATOR(OT, kern) \ HB_OT_ACCELERATOR(OT, glyf) \ HB_OT_TABLE(OT, VORG) \ diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index bb49c2cb0..45726ab54 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -58,6 +58,13 @@ struct NameRecord return 0; } + inline bool supported (void) const + { + return platformID == 0 || + platformID == 3; + /* TODO Add Apple MacRoman (0:1). */ + } + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -75,6 +82,18 @@ struct NameRecord DEFINE_SIZE_STATIC (12); }; +static int +_hb_ot_name_entry_cmp (const void *pa, const void *pb) +{ + const hb_ot_name_entry_t *a = (const hb_ot_name_entry_t *) pa; + const hb_ot_name_entry_t *b = (const hb_ot_name_entry_t *) pb; + if (a->name_id != b->name_id) + return a->name_id < b->name_id ? -1 : +1; + if (a->index != b->index) + return a->index < b->index ? -1 : +1; + return 0; +} + struct name { static const hb_tag_t tableTag = HB_OT_TAG_name; @@ -122,6 +141,46 @@ struct name sanitize_records (c)); } + struct accelerator_t + { + inline void init (hb_face_t *face) + { + this->blob = hb_sanitize_context_t().reference_table (face); + const name *table = this->blob->as (); + const hb_array_t &all_names = hb_array_t (table->nameRecordZ.arrayZ, table->count); + + this->names.init (); + + for (unsigned int i = 0; i < all_names.len; i++) + { + if (!all_names[i].supported ()) continue; + + unsigned int name_id = all_names[i].nameID; + hb_language_t language = HB_LANGUAGE_INVALID; /* XXX */ + + hb_ot_name_entry_t entry = {name_id, i, language}; + + this->names.push (entry); + } + + this->names.qsort (_hb_ot_name_entry_cmp); + + /* Walk and pick best... */ + } + + inline void fini (void) + { + this->names.fini (); + hb_blob_destroy (this->blob); + } + + private: + hb_blob_t *blob; + hb_vector_t names; + + unsigned int names_count; + }; + /* We only implement format 0 for now. */ HBUINT16 format; /* Format selector (=0/1). */ HBUINT16 count; /* Number of name records. */ @@ -132,6 +191,7 @@ struct name DEFINE_SIZE_ARRAY (6, nameRecordZ); }; +struct name_accelerator_t : name::accelerator_t {}; } /* namespace OT */ diff --git a/src/hb-ot-name.h b/src/hb-ot-name.h index 1f643d53e..8b2c02b68 100644 --- a/src/hb-ot-name.h +++ b/src/hb-ot-name.h @@ -74,6 +74,9 @@ hb_ot_name_get_utf32 (hb_face_t *face, typedef struct hb_ot_name_entry_t { hb_name_id_t name_id; + /*< private >*/ + unsigned int index; + /*< public >*/ hb_language_t language; } hb_ot_name_entry_t; From 9a6c87c17d51fd57e4225c776a0fabbfd313f4f4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 15 Oct 2018 22:42:04 -0700 Subject: [PATCH 030/255] [name] Finish accelerator sorting --- src/hb-ot-name-table.hh | 61 ++++++++++++++++++++++++++++++++++------- src/hb-ot-name.h | 3 +- 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 45726ab54..a6a1e5f30 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -39,6 +39,7 @@ namespace OT { */ #define HB_OT_TAG_name HB_TAG('n','a','m','e') +#define UNSUPPORTED 42 struct NameRecord { @@ -58,11 +59,30 @@ struct NameRecord return 0; } - inline bool supported (void) const + inline uint16_t score (void) const { - return platformID == 0 || - platformID == 3; - /* TODO Add Apple MacRoman (0:1). */ + /* Same order as in cmap::find_best_subtable(). */ + unsigned int p = platformID; + unsigned int e = encodingID; + + /* 32-bit. */ + if (p == 3 && e == 10) return 0; + if (p == 0 && e == 6) return 1; + if (p == 0 && e == 4) return 2; + + /* 16-bit. */ + if (p == 3 && e == 1) return 3; + if (p == 0 && e == 3) return 4; + if (p == 0 && e == 2) return 5; + if (p == 0 && e == 1) return 6; + if (p == 0 && e == 0) return 7; + + /* Symbol. */ + if (p == 3 && e == 0) return 8; + + /* TODO Apple MacRoman (0:1). */ + + return UNSUPPORTED; } inline bool sanitize (hb_sanitize_context_t *c, const void *base) const @@ -87,10 +107,23 @@ _hb_ot_name_entry_cmp (const void *pa, const void *pb) { const hb_ot_name_entry_t *a = (const hb_ot_name_entry_t *) pa; const hb_ot_name_entry_t *b = (const hb_ot_name_entry_t *) pb; + + /* Sort by name_id, then language, then score, then index. */ + if (a->name_id != b->name_id) return a->name_id < b->name_id ? -1 : +1; + + int e = strcmp (hb_language_to_string (a->language), + hb_language_to_string (b->language)); + if (e) + return e; + + if (a->score != b->score) + return a->score < b->score ? -1 : +1; + if (a->index != b->index) return a->index < b->index ? -1 : +1; + return 0; } @@ -151,23 +184,31 @@ struct name this->names.init (); - for (unsigned int i = 0; i < all_names.len; i++) + for (uint16_t i = 0; i < all_names.len; i++) { - if (!all_names[i].supported ()) continue; - unsigned int name_id = all_names[i].nameID; + uint16_t score = all_names[i].score (); hb_language_t language = HB_LANGUAGE_INVALID; /* XXX */ - hb_ot_name_entry_t entry = {name_id, i, language}; + hb_ot_name_entry_t entry = {name_id, score, i, language}; this->names.push (entry); } this->names.qsort (_hb_ot_name_entry_cmp); - - /* Walk and pick best... */ + /* Walk and pick best only for each name_id,language pair... */ + unsigned int j = 0; + for (unsigned int i = 1; i < this->names.len; i++) + { + if (this->names[i - 1].name_id == this->names[i].name_id && + this->names[i - 1].language == this->names[i].language) + continue; + this->names[j++] = this->names[i]; + } + this->names.resize (j); } + inline void fini (void) { this->names.fini (); diff --git a/src/hb-ot-name.h b/src/hb-ot-name.h index 8b2c02b68..257b346de 100644 --- a/src/hb-ot-name.h +++ b/src/hb-ot-name.h @@ -75,7 +75,8 @@ typedef struct hb_ot_name_entry_t { hb_name_id_t name_id; /*< private >*/ - unsigned int index; + uint16_t score; + uint16_t index; /*< public >*/ hb_language_t language; } hb_ot_name_entry_t; From 90420ed8cb297f1ceff75f5a75c8fa7b6ea6f65e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 15 Oct 2018 22:48:48 -0700 Subject: [PATCH 031/255] [name] Implement hb_ot_name_get_names() --- src/Makefile.sources | 1 + src/hb-ot-name-table.hh | 3 +-- src/hb-ot-name.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Makefile.sources b/src/Makefile.sources index e13bd4f09..0ee79a479 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -34,6 +34,7 @@ HB_BASE_sources = \ hb-ot-kern-table.hh \ hb-ot-maxp-table.hh \ hb-ot-name-table.hh \ + hb-ot-name.cc \ hb-ot-os2-table.hh \ hb-ot-os2-unicode-ranges.hh \ hb-ot-post-macroman.hh \ diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index a6a1e5f30..5625ab2c0 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -217,9 +217,8 @@ struct name private: hb_blob_t *blob; + public: hb_vector_t names; - - unsigned int names_count; }; /* We only implement format 0 for now. */ diff --git a/src/hb-ot-name.h b/src/hb-ot-name.h index 257b346de..4c0db0fcb 100644 --- a/src/hb-ot-name.h +++ b/src/hb-ot-name.h @@ -82,8 +82,8 @@ typedef struct hb_ot_name_entry_t } hb_ot_name_entry_t; HB_EXTERN unsigned int -hb_ot_name_get_names (hb_face_t *face, - hb_ot_name_entry_t **entries /* OUT */); +hb_ot_name_get_names (hb_face_t *face, + const hb_ot_name_entry_t **entries /* OUT */); HB_END_DECLS From c3425f2401dffb1f3b5bd6fdbc0c3e9aad0f4306 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 15 Oct 2018 22:53:40 -0700 Subject: [PATCH 032/255] [name] Add hb-ot-name.cc for realz --- src/hb-ot-name.cc | 50 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/hb-ot-name.cc diff --git a/src/hb-ot-name.cc b/src/hb-ot-name.cc new file mode 100644 index 000000000..85995f8c4 --- /dev/null +++ b/src/hb-ot-name.cc @@ -0,0 +1,50 @@ +/* + * Copyright © 2018 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#include "hb.hh" + +#include "hb-ot-name-table.hh" + +#include "hb-ot-face.hh" + + +static inline const OT::name_accelerator_t& +_get_name (hb_face_t *face) +{ + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::name_accelerator_t); + return *(hb_ot_face_data (face)->name.get ()); +} + + +unsigned int +hb_ot_name_get_names (hb_face_t *face, + const hb_ot_name_entry_t **entries /* OUT */) +{ + const OT::name_accelerator_t &name = _get_name (face); + if (entries) + *entries = name.names.arrayZ(); + return name.names.len; +} From 740cde8991283b8b4e1e77e022175251eb37d3d1 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 15 Oct 2018 23:00:27 -0700 Subject: [PATCH 033/255] [name] Implement hb_bytes_t get_name() --- src/hb-ot-name-table.hh | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 5625ab2c0..37a2d42f6 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -131,26 +131,11 @@ struct name { static const hb_tag_t tableTag = HB_OT_TAG_name; - inline unsigned int get_name (unsigned int platform_id, - unsigned int encoding_id, - unsigned int language_id, - unsigned int name_id, - void *buffer, - unsigned int buffer_length) const + inline hb_bytes_t get_name (unsigned int idx) const { - NameRecord key; - key.platformID.set (platform_id); - key.encodingID.set (encoding_id); - key.languageID.set (language_id); - key.nameID.set (name_id); - NameRecord *match = (NameRecord *) bsearch (&key, nameRecordZ.arrayZ, count, sizeof (nameRecordZ[0]), NameRecord::cmp); - - if (!match) - return 0; - - unsigned int length = MIN (buffer_length, (unsigned int) match->length); - memcpy (buffer, (char *) this + stringOffset + match->offset, length); - return length; + const hb_array_t &all_names = hb_array_t (nameRecordZ.arrayZ, count); + const NameRecord &record = all_names[idx]; + return hb_bytes_t ((char *) this + stringOffset + record.offset, record.length); } inline unsigned int get_size (void) const @@ -160,6 +145,7 @@ struct name TRACE_SANITIZE (this); char *string_pool = (char *) this + stringOffset; unsigned int _count = count; + /* Move to run-time?! */ for (unsigned int i = 0; i < _count; i++) if (!nameRecordZ[i].sanitize (c, string_pool)) return_trace (false); return_trace (true); From c2aa409537c3e8a7b8592ef90f8304bd6588561d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 15 Oct 2018 23:09:28 -0700 Subject: [PATCH 034/255] [name] Start implementing hb_ot_name_get_utf16() --- src/hb-ot-name-table.hh | 6 ++++-- src/hb-ot-name.cc | 22 ++++++++++++++++++++++ src/hb-ot-name.h | 8 ++++++-- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 37a2d42f6..3d7b73119 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -165,8 +165,9 @@ struct name inline void init (hb_face_t *face) { this->blob = hb_sanitize_context_t().reference_table (face); - const name *table = this->blob->as (); - const hb_array_t &all_names = hb_array_t (table->nameRecordZ.arrayZ, table->count); + this->table = this->blob->as (); + const hb_array_t &all_names = hb_array_t (this->table->nameRecordZ.arrayZ, + this->table->count); this->names.init (); @@ -204,6 +205,7 @@ struct name private: hb_blob_t *blob; public: + const name *table; hb_vector_t names; }; diff --git a/src/hb-ot-name.cc b/src/hb-ot-name.cc index 85995f8c4..b5143d3de 100644 --- a/src/hb-ot-name.cc +++ b/src/hb-ot-name.cc @@ -48,3 +48,25 @@ hb_ot_name_get_names (hb_face_t *face, *entries = name.names.arrayZ(); return name.names.len; } + + +hb_bool_t +hb_ot_name_get_utf16 (hb_face_t *face, + hb_name_id_t name_id, + hb_language_t language, + unsigned int *text_size /* IN/OUT */, + uint16_t *text /* OUT */) +{ + const OT::name_accelerator_t &name = _get_name (face); + unsigned int idx = 0; //XXX + hb_bytes_t bytes = name.table->get_name (idx); + if (*text_size) + { + /* TODO Switch to walking string and validating. */ + memcpy (text, bytes.arrayZ, MIN (*text_size * 2, bytes.len)); + } + /* XXX Null-terminate. */ + *text_size = bytes.len / 2; //TODO + /* TODO Fallback? */ + return true; //XXX +} diff --git a/src/hb-ot-name.h b/src/hb-ot-name.h index 4c0db0fcb..013ce8dd4 100644 --- a/src/hb-ot-name.h +++ b/src/hb-ot-name.h @@ -49,12 +49,14 @@ typedef unsigned int hb_name_id_t; #define HB_NAME_ID_INVALID 0xFFFF +#if 0 HB_EXTERN hb_bool_t -hb_ot_name_get_utf8 (hb_face_t *face, +Xhb_ot_name_get_utf8 (hb_face_t *face, hb_name_id_t name_id, hb_language_t language, unsigned int *text_size /* IN/OUT */, char *text /* OUT */); +#endif HB_EXTERN hb_bool_t hb_ot_name_get_utf16 (hb_face_t *face, @@ -63,12 +65,14 @@ hb_ot_name_get_utf16 (hb_face_t *face, unsigned int *text_size /* IN/OUT */, uint16_t *text /* OUT */); +#if 0 HB_EXTERN hb_bool_t -hb_ot_name_get_utf32 (hb_face_t *face, +Xhb_ot_name_get_utf32 (hb_face_t *face, hb_name_id_t name_id, hb_language_t language, unsigned int *text_size /* IN/OUT */, uint32_t *text /* OUT */); +#endif typedef struct hb_ot_name_entry_t From c783d36324dd1e2031d3387064afab1ce5d90b6f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 15 Oct 2018 23:28:49 -0700 Subject: [PATCH 035/255] [name] Pre-allocate array --- src/hb-ot-name-table.hh | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 3d7b73119..14ac4ef2c 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -170,6 +170,7 @@ struct name this->table->count); this->names.init (); + this->names.alloc (all_names.len); for (uint16_t i = 0; i < all_names.len; i++) { From 75cd8c86bd9b0973864bb92e0244bf038980765e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 15 Oct 2018 23:32:08 -0700 Subject: [PATCH 036/255] [name] Add hb_ot_name_get_utf() --- src/hb-ot-name.cc | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/hb-ot-name.cc b/src/hb-ot-name.cc index b5143d3de..22149e44f 100644 --- a/src/hb-ot-name.cc +++ b/src/hb-ot-name.cc @@ -29,6 +29,7 @@ #include "hb-ot-name-table.hh" #include "hb-ot-face.hh" +#include "hb-utf.hh" static inline const OT::name_accelerator_t& @@ -50,12 +51,13 @@ hb_ot_name_get_names (hb_face_t *face, } -hb_bool_t -hb_ot_name_get_utf16 (hb_face_t *face, - hb_name_id_t name_id, - hb_language_t language, - unsigned int *text_size /* IN/OUT */, - uint16_t *text /* OUT */) +template +static inline hb_bool_t +hb_ot_name_get_utf (hb_face_t *face, + hb_name_id_t name_id, + hb_language_t language, + unsigned int *text_size /* IN/OUT */, + typename utf_t::codepoint_t *text /* OUT */) { const OT::name_accelerator_t &name = _get_name (face); unsigned int idx = 0; //XXX @@ -70,3 +72,13 @@ hb_ot_name_get_utf16 (hb_face_t *face, /* TODO Fallback? */ return true; //XXX } + +hb_bool_t +hb_ot_name_get_utf16 (hb_face_t *face, + hb_name_id_t name_id, + hb_language_t language, + unsigned int *text_size /* IN/OUT */, + uint16_t *text /* OUT */) +{ + return hb_ot_name_get_utf (face, name_id, language, text_size, text); +} From e7c595a9f09ba1552b2de1f8d56cbdcf376b9cad Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 15 Oct 2018 23:34:54 -0700 Subject: [PATCH 037/255] [name] More --- src/hb-ot-name.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hb-ot-name.cc b/src/hb-ot-name.cc index 22149e44f..e6dbe0a4d 100644 --- a/src/hb-ot-name.cc +++ b/src/hb-ot-name.cc @@ -62,13 +62,14 @@ hb_ot_name_get_utf (hb_face_t *face, const OT::name_accelerator_t &name = _get_name (face); unsigned int idx = 0; //XXX hb_bytes_t bytes = name.table->get_name (idx); - if (*text_size) + if (text_size && *text_size) { /* TODO Switch to walking string and validating. */ memcpy (text, bytes.arrayZ, MIN (*text_size * 2, bytes.len)); } /* XXX Null-terminate. */ - *text_size = bytes.len / 2; //TODO + if (text_size) + *text_size = bytes.len / 2; //TODO /* TODO Fallback? */ return true; //XXX } From a826a8730f21ae996ae8f4d12c44dc18b9e8e933 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 16 Oct 2018 13:06:56 -0700 Subject: [PATCH 038/255] [name] Hide internal details from public API --- src/hb-ot-name-table.hh | 23 +++++++++++++---------- src/hb-ot-name.h | 3 +-- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 14ac4ef2c..f0b5a5e68 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -33,6 +33,10 @@ namespace OT { +#define entry_score var.u16[0] +#define entry_index var.u16[1] + + /* * name -- Naming * https://docs.microsoft.com/en-us/typography/opentype/spec/name @@ -118,11 +122,11 @@ _hb_ot_name_entry_cmp (const void *pa, const void *pb) if (e) return e; - if (a->score != b->score) - return a->score < b->score ? -1 : +1; + if (a->entry_score != b->entry_score) + return a->entry_score < b->entry_score ? -1 : +1; - if (a->index != b->index) - return a->index < b->index ? -1 : +1; + if (a->entry_index != b->entry_index) + return a->entry_index < b->entry_index ? -1 : +1; return 0; } @@ -174,13 +178,12 @@ struct name for (uint16_t i = 0; i < all_names.len; i++) { - unsigned int name_id = all_names[i].nameID; - uint16_t score = all_names[i].score (); - hb_language_t language = HB_LANGUAGE_INVALID; /* XXX */ + hb_ot_name_entry_t *entry = this->names.push (); - hb_ot_name_entry_t entry = {name_id, score, i, language}; - - this->names.push (entry); + entry->name_id = all_names[i].nameID; + entry->language = HB_LANGUAGE_INVALID; /* XXX */ + entry->entry_score = all_names[i].score (); + entry->entry_index = i; } this->names.qsort (_hb_ot_name_entry_cmp); diff --git a/src/hb-ot-name.h b/src/hb-ot-name.h index 013ce8dd4..fb4948021 100644 --- a/src/hb-ot-name.h +++ b/src/hb-ot-name.h @@ -79,8 +79,7 @@ typedef struct hb_ot_name_entry_t { hb_name_id_t name_id; /*< private >*/ - uint16_t score; - uint16_t index; + hb_var_int_t var; /*< public >*/ hb_language_t language; } hb_ot_name_entry_t; From 8d304ef7f9094a71fabc3efd87b37a030c437adf Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 16 Oct 2018 19:04:48 -0700 Subject: [PATCH 039/255] [utf] Add UTF16-BE and UTF32-BE --- src/hb-buffer.cc | 4 +-- src/hb-utf.hh | 80 ++++++++++++++++++++++++++++-------------------- 2 files changed, 48 insertions(+), 36 deletions(-) diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc index ce9b0530c..f905c63a9 100644 --- a/src/hb-buffer.cc +++ b/src/hb-buffer.cc @@ -1665,7 +1665,7 @@ hb_buffer_add_utf32 (hb_buffer_t *buffer, unsigned int item_offset, int item_length) { - hb_buffer_add_utf > (buffer, text, text_length, item_offset, item_length); + hb_buffer_add_utf (buffer, text, text_length, item_offset, item_length); } /** @@ -1726,7 +1726,7 @@ hb_buffer_add_codepoints (hb_buffer_t *buffer, unsigned int item_offset, int item_length) { - hb_buffer_add_utf > (buffer, text, text_length, item_offset, item_length); + hb_buffer_add_utf (buffer, text, text_length, item_offset, item_length); } diff --git a/src/hb-utf.hh b/src/hb-utf.hh index eccb632e4..d8b7114ac 100644 --- a/src/hb-utf.hh +++ b/src/hb-utf.hh @@ -29,14 +29,16 @@ #include "hb.hh" +#include "hb-open-type.hh" + struct hb_utf8_t { typedef uint8_t codepoint_t; - static inline const uint8_t * - next (const uint8_t *text, - const uint8_t *end, + static inline const codepoint_t * + next (const codepoint_t *text, + const codepoint_t *end, hb_codepoint_t *unicode, hb_codepoint_t replacement) { @@ -103,13 +105,13 @@ struct hb_utf8_t return text; } - static inline const uint8_t * - prev (const uint8_t *text, - const uint8_t *start, + static inline const codepoint_t * + prev (const codepoint_t *text, + const codepoint_t *start, hb_codepoint_t *unicode, hb_codepoint_t replacement) { - const uint8_t *end = text--; + const codepoint_t *end = text--; while (start < text && (*text & 0xc0) == 0x80 && end - text < 4) text--; @@ -121,20 +123,22 @@ struct hb_utf8_t } static inline unsigned int - strlen (const uint8_t *text) + strlen (const codepoint_t *text) { return ::strlen ((const char *) text); } }; -struct hb_utf16_t +template +struct hb_utf16_xe_t { - typedef uint16_t codepoint_t; + static_assert (sizeof (TCodepoint) == 2, ""); + typedef TCodepoint codepoint_t; - static inline const uint16_t * - next (const uint16_t *text, - const uint16_t *end, + static inline const codepoint_t * + next (const codepoint_t *text, + const codepoint_t *end, hb_codepoint_t *unicode, hb_codepoint_t replacement) { @@ -164,9 +168,9 @@ struct hb_utf16_t return text; } - static inline const uint16_t * - prev (const uint16_t *text, - const uint16_t *start, + static inline const codepoint_t * + prev (const codepoint_t *text, + const codepoint_t *start, hb_codepoint_t *unicode, hb_codepoint_t replacement) { @@ -198,7 +202,7 @@ struct hb_utf16_t static inline unsigned int - strlen (const uint16_t *text) + strlen (const codepoint_t *text) { unsigned int l = 0; while (*text++) l++; @@ -206,15 +210,19 @@ struct hb_utf16_t } }; +typedef hb_utf16_xe_t hb_utf16_t; +typedef hb_utf16_xe_t hb_utf16_be_t; -template -struct hb_utf32_t + +template +struct hb_utf32_xe_t { - typedef uint32_t codepoint_t; + static_assert (sizeof (TCodepoint) == 4, ""); + typedef TCodepoint codepoint_t; - static inline const uint32_t * - next (const uint32_t *text, - const uint32_t *end HB_UNUSED, + static inline const TCodepoint * + next (const TCodepoint *text, + const TCodepoint *end HB_UNUSED, hb_codepoint_t *unicode, hb_codepoint_t replacement) { @@ -224,9 +232,9 @@ struct hb_utf32_t return text; } - static inline const uint32_t * - prev (const uint32_t *text, - const uint32_t *start HB_UNUSED, + static inline const TCodepoint * + prev (const TCodepoint *text, + const TCodepoint *start HB_UNUSED, hb_codepoint_t *unicode, hb_codepoint_t replacement) { @@ -237,7 +245,7 @@ struct hb_utf32_t } static inline unsigned int - strlen (const uint32_t *text) + strlen (const TCodepoint *text) { unsigned int l = 0; while (*text++) l++; @@ -245,14 +253,18 @@ struct hb_utf32_t } }; +typedef hb_utf32_xe_t hb_utf32_t; +typedef hb_utf32_xe_t hb_utf32_novalidate_t; +typedef hb_utf32_xe_t hb_utf32_be_t; + struct hb_latin1_t { typedef uint8_t codepoint_t; - static inline const uint8_t * - next (const uint8_t *text, - const uint8_t *end HB_UNUSED, + static inline const codepoint_t * + next (const codepoint_t *text, + const codepoint_t *end HB_UNUSED, hb_codepoint_t *unicode, hb_codepoint_t replacement HB_UNUSED) { @@ -260,9 +272,9 @@ struct hb_latin1_t return text; } - static inline const uint8_t * - prev (const uint8_t *text, - const uint8_t *start HB_UNUSED, + static inline const codepoint_t * + prev (const codepoint_t *text, + const codepoint_t *start HB_UNUSED, hb_codepoint_t *unicode, hb_codepoint_t replacement) { @@ -271,7 +283,7 @@ struct hb_latin1_t } static inline unsigned int - strlen (const uint8_t *text) + strlen (const codepoint_t *text) { unsigned int l = 0; while (*text++) l++; From b4d4d1ea787c829dea023d99f974a38bdc3de0ae Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 16 Oct 2018 19:55:17 -0700 Subject: [PATCH 040/255] [name] Return full string length from API --- src/hb-ot-name.cc | 6 +++--- src/hb-ot-name.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hb-ot-name.cc b/src/hb-ot-name.cc index e6dbe0a4d..3494cb7fc 100644 --- a/src/hb-ot-name.cc +++ b/src/hb-ot-name.cc @@ -52,7 +52,7 @@ hb_ot_name_get_names (hb_face_t *face, template -static inline hb_bool_t +static inline unsigned int hb_ot_name_get_utf (hb_face_t *face, hb_name_id_t name_id, hb_language_t language, @@ -71,10 +71,10 @@ hb_ot_name_get_utf (hb_face_t *face, if (text_size) *text_size = bytes.len / 2; //TODO /* TODO Fallback? */ - return true; //XXX + return *text_size; //XXX } -hb_bool_t +unsigned int hb_ot_name_get_utf16 (hb_face_t *face, hb_name_id_t name_id, hb_language_t language, diff --git a/src/hb-ot-name.h b/src/hb-ot-name.h index fb4948021..0afcd3fca 100644 --- a/src/hb-ot-name.h +++ b/src/hb-ot-name.h @@ -50,7 +50,7 @@ typedef unsigned int hb_name_id_t; #if 0 -HB_EXTERN hb_bool_t +HB_EXTERN unsigned int Xhb_ot_name_get_utf8 (hb_face_t *face, hb_name_id_t name_id, hb_language_t language, @@ -58,7 +58,7 @@ Xhb_ot_name_get_utf8 (hb_face_t *face, char *text /* OUT */); #endif -HB_EXTERN hb_bool_t +HB_EXTERN unsigned int hb_ot_name_get_utf16 (hb_face_t *face, hb_name_id_t name_id, hb_language_t language, @@ -66,7 +66,7 @@ hb_ot_name_get_utf16 (hb_face_t *face, uint16_t *text /* OUT */); #if 0 -HB_EXTERN hb_bool_t +HB_EXTERN unsigned int Xhb_ot_name_get_utf32 (hb_face_t *face, hb_name_id_t name_id, hb_language_t language, From 1046b1938b16ab6be861b0828b446fa13cf0377b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 17 Oct 2018 05:42:23 -0700 Subject: [PATCH 041/255] [name] Some more --- src/hb-ot-name.cc | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/hb-ot-name.cc b/src/hb-ot-name.cc index 3494cb7fc..3cb4a9232 100644 --- a/src/hb-ot-name.cc +++ b/src/hb-ot-name.cc @@ -60,17 +60,24 @@ hb_ot_name_get_utf (hb_face_t *face, typename utf_t::codepoint_t *text /* OUT */) { const OT::name_accelerator_t &name = _get_name (face); - unsigned int idx = 0; //XXX + unsigned int idx = 0; // XXX bsearch and find hb_bytes_t bytes = name.table->get_name (idx); + + unsigned int full_length = 0; + const typename utf_t::codepoint_t *src = (const typename utf_t::codepoint_t *) bytes.arrayZ; + unsigned int src_len = bytes.len / sizeof (typename utf_t::codepoint_t); + if (text_size && *text_size) { + *text_size--; /* Leave room for nul-termination. */ /* TODO Switch to walking string and validating. */ - memcpy (text, bytes.arrayZ, MIN (*text_size * 2, bytes.len)); + memcpy (text, + src, + MIN (*text_size, src_len) * sizeof (typename utf_t::codepoint_t)); } - /* XXX Null-terminate. */ - if (text_size) - *text_size = bytes.len / 2; //TODO - /* TODO Fallback? */ + + /* Walk the rest, accumulate the full length. */ + return *text_size; //XXX } From 84811a06a26508effe9f4a9eaf1be15297ecf0cb Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 23 Oct 2018 03:16:03 -0700 Subject: [PATCH 042/255] [name] Fix for rebase changes to hb_array_t --- src/hb-ot-name-table.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index f0b5a5e68..8967fcbd8 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -137,7 +137,7 @@ struct name inline hb_bytes_t get_name (unsigned int idx) const { - const hb_array_t &all_names = hb_array_t (nameRecordZ.arrayZ, count); + const hb_array_t all_names (nameRecordZ.arrayZ, count); const NameRecord &record = all_names[idx]; return hb_bytes_t ((char *) this + stringOffset + record.offset, record.length); } @@ -170,8 +170,8 @@ struct name { this->blob = hb_sanitize_context_t().reference_table (face); this->table = this->blob->as (); - const hb_array_t &all_names = hb_array_t (this->table->nameRecordZ.arrayZ, - this->table->count); + const hb_array_t all_names (this->table->nameRecordZ.arrayZ, + this->table->count); this->names.init (); this->names.alloc (all_names.len); From 5531bd068e759a5acb3b8d301c0ff9c64844166e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 23 Oct 2018 20:04:05 -0700 Subject: [PATCH 043/255] [name] Flesh out UTF-X to UTF-X conversion routines --- src/hb-ot-name.cc | 84 ++++++++++++++++++++++++++++++------ src/hb-ot-name.h | 10 ++--- src/hb-utf.hh | 107 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 182 insertions(+), 19 deletions(-) diff --git a/src/hb-ot-name.cc b/src/hb-ot-name.cc index 3cb4a9232..fe1276c32 100644 --- a/src/hb-ot-name.cc +++ b/src/hb-ot-name.cc @@ -51,6 +51,51 @@ hb_ot_name_get_names (hb_face_t *face, } +template +static inline unsigned int +hb_ot_name_convert_utf (const hb_bytes_t *bytes, + unsigned int *text_size /* IN/OUT */, + typename out_utf_t::codepoint_t *text /* OUT */) +{ + unsigned int src_len = bytes->len / sizeof (typename in_utf_t::codepoint_t); + const typename in_utf_t::codepoint_t *src = (const typename in_utf_t::codepoint_t *) bytes->arrayZ; + const typename in_utf_t::codepoint_t *src_end = src + src_len; + + typename out_utf_t::codepoint_t *dst = text; + + hb_codepoint_t unicode; + const hb_codepoint_t replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT; + + if (text_size && *text_size) + { + (*text_size)--; /* Same room for NUL-termination. */ + const typename out_utf_t::codepoint_t *dst_end = text + *text_size; + + while (src < src_end && dst < dst_end) + { + const typename in_utf_t::codepoint_t *src_next = in_utf_t::next (src, src_end, &unicode, replacement); + typename out_utf_t::codepoint_t *dst_next = out_utf_t::encode (dst, dst_end, unicode); + if (dst_next == dst) + break; /* Out-of-room. */ + + dst = dst_next; + src = src_next; + }; + + *text_size = dst - text; + *text = 0; /* NUL-terminate. */ + } + + /* Accumulate length of rest. */ + unsigned int dst_len = dst - text; + while (src < src_end) + { + src = in_utf_t::next (src, src_end, &unicode, replacement); + dst_len += out_utf_t::encode_len (unicode); + }; + return dst_len; +} + template static inline unsigned int hb_ot_name_get_utf (hb_face_t *face, @@ -63,22 +108,27 @@ hb_ot_name_get_utf (hb_face_t *face, unsigned int idx = 0; // XXX bsearch and find hb_bytes_t bytes = name.table->get_name (idx); - unsigned int full_length = 0; - const typename utf_t::codepoint_t *src = (const typename utf_t::codepoint_t *) bytes.arrayZ; - unsigned int src_len = bytes.len / sizeof (typename utf_t::codepoint_t); + if (true /*UTF16-BE*/) + return hb_ot_name_convert_utf (&bytes, text_size, text); - if (text_size && *text_size) + if (text_size) { - *text_size--; /* Leave room for nul-termination. */ - /* TODO Switch to walking string and validating. */ - memcpy (text, - src, - MIN (*text_size, src_len) * sizeof (typename utf_t::codepoint_t)); + if (*text_size) + *text = 0; + *text_size = 0; } + return 0; +} - /* Walk the rest, accumulate the full length. */ - - return *text_size; //XXX +unsigned int +hb_ot_name_get_utf8 (hb_face_t *face, + hb_name_id_t name_id, + hb_language_t language, + unsigned int *text_size /* IN/OUT */, + char *text /* OUT */) +{ + return hb_ot_name_get_utf (face, name_id, language, text_size, + (hb_utf8_t::codepoint_t *) text); } unsigned int @@ -90,3 +140,13 @@ hb_ot_name_get_utf16 (hb_face_t *face, { return hb_ot_name_get_utf (face, name_id, language, text_size, text); } + +unsigned int +hb_ot_name_get_utf32 (hb_face_t *face, + hb_name_id_t name_id, + hb_language_t language, + unsigned int *text_size /* IN/OUT */, + uint32_t *text /* OUT */) +{ + return hb_ot_name_get_utf (face, name_id, language, text_size, text); +} diff --git a/src/hb-ot-name.h b/src/hb-ot-name.h index 0afcd3fca..f2d2e4a63 100644 --- a/src/hb-ot-name.h +++ b/src/hb-ot-name.h @@ -49,14 +49,12 @@ typedef unsigned int hb_name_id_t; #define HB_NAME_ID_INVALID 0xFFFF -#if 0 -HB_EXTERN unsigned int -Xhb_ot_name_get_utf8 (hb_face_t *face, +unsigned int +hb_ot_name_get_utf8 (hb_face_t *face, hb_name_id_t name_id, hb_language_t language, unsigned int *text_size /* IN/OUT */, char *text /* OUT */); -#endif HB_EXTERN unsigned int hb_ot_name_get_utf16 (hb_face_t *face, @@ -65,14 +63,12 @@ hb_ot_name_get_utf16 (hb_face_t *face, unsigned int *text_size /* IN/OUT */, uint16_t *text /* OUT */); -#if 0 HB_EXTERN unsigned int -Xhb_ot_name_get_utf32 (hb_face_t *face, +hb_ot_name_get_utf32 (hb_face_t *face, hb_name_id_t name_id, hb_language_t language, unsigned int *text_size /* IN/OUT */, uint32_t *text /* OUT */); -#endif typedef struct hb_ot_name_entry_t diff --git a/src/hb-utf.hh b/src/hb-utf.hh index d8b7114ac..5e2faebb5 100644 --- a/src/hb-utf.hh +++ b/src/hb-utf.hh @@ -127,6 +127,55 @@ struct hb_utf8_t { return ::strlen ((const char *) text); } + + static inline unsigned int + encode_len (hb_codepoint_t unicode) + { + if (unicode < 0x0080u) return 1; + if (unicode < 0x0800u) return 2; + if (unicode < 0x10000u) return 3; + if (unicode < 0x110000u) return 4; + return 3; + } + + static inline codepoint_t * + encode (codepoint_t *text, + const codepoint_t *end, + hb_codepoint_t unicode) + { + if (unlikely (unicode >= 0xD800u && (unicode <= 0xDFFFu || unicode > 0x10FFFFu))) + unicode = 0xFFFDu; + if (unicode < 0x0080u) + *text++ = unicode; + else if (unicode < 0x0800u) + { + if (end - text >= 2) + { + *text++ = 0xC0u + (0x1Fu & (unicode >> 6)); + *text++ = 0x80u + (0x3Fu & (unicode )); + } + } + else if (unicode < 0x10000u) + { + if (end - text >= 3) + { + *text++ = 0xE0u + (0x0Fu & (unicode >> 12)); + *text++ = 0x80u + (0x3Fu & (unicode >> 6)); + *text++ = 0x80u + (0x3Fu & (unicode )); + } + } + else + { + if (end - text >= 4) + { + *text++ = 0xF0u + (0x07u & (unicode >> 18)); + *text++ = 0x80u + (0x3Fu & (unicode >> 12)); + *text++ = 0x80u + (0x3Fu & (unicode >> 6)); + *text++ = 0x80u + (0x3Fu & (unicode )); + } + } + return text; + } }; @@ -208,6 +257,30 @@ struct hb_utf16_xe_t while (*text++) l++; return l; } + + static inline unsigned int + encode_len (hb_codepoint_t unicode) + { + return unicode < 0x10000 ? 1 : 2; + } + + static inline codepoint_t * + encode (codepoint_t *text, + const codepoint_t *end, + hb_codepoint_t unicode) + { + if (unlikely (unicode >= 0xD800u && (unicode <= 0xDFFFu || unicode > 0x10FFFFu))) + unicode = 0xFFFDu; + if (unicode < 0x10000u) + *text++ = unicode; + else if (end - text >= 2) + { + unicode -= 0x10000u; + *text++ = 0xD800u + (unicode >> 10); + *text++ = 0xDC00u + (unicode & 0x03FFu); + } + return text; + } }; typedef hb_utf16_xe_t hb_utf16_t; @@ -251,6 +324,23 @@ struct hb_utf32_xe_t while (*text++) l++; return l; } + + static inline unsigned int + encode_len (hb_codepoint_t unicode HB_UNUSED) + { + return 1; + } + + static inline codepoint_t * + encode (codepoint_t *text, + const codepoint_t *end HB_UNUSED, + hb_codepoint_t unicode) + { + if (validate && unlikely (unicode >= 0xD800u && (unicode <= 0xDFFFu || unicode > 0x10FFFFu))) + unicode = 0xFFFDu; + *text++ = unicode; + return text; + } }; typedef hb_utf32_xe_t hb_utf32_t; @@ -289,6 +379,23 @@ struct hb_latin1_t while (*text++) l++; return l; } + + static inline unsigned int + encode_len (hb_codepoint_t unicode HB_UNUSED) + { + return 1; + } + + static inline codepoint_t * + encode (codepoint_t *text, + const codepoint_t *end HB_UNUSED, + hb_codepoint_t unicode) + { + if (unlikely (unicode >= 0x0100u)) + unicode = '?'; + *text++ = unicode; + return text; + } }; #endif /* HB_UTF_HH */ From 64334aff8c2ea5aa066d77a95844bc6f84efe725 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 23 Oct 2018 20:15:53 -0700 Subject: [PATCH 044/255] [name] Fix check --- src/hb-ot-name.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-name.h b/src/hb-ot-name.h index f2d2e4a63..ff1ae24d8 100644 --- a/src/hb-ot-name.h +++ b/src/hb-ot-name.h @@ -49,7 +49,7 @@ typedef unsigned int hb_name_id_t; #define HB_NAME_ID_INVALID 0xFFFF -unsigned int +HB_EXTERN unsigned int hb_ot_name_get_utf8 (hb_face_t *face, hb_name_id_t name_id, hb_language_t language, From 69f5da0629f1e5a307fc49fe58490aa92d1bd0e2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 23 Oct 2018 20:30:40 -0700 Subject: [PATCH 045/255] [name] More It assumes all names are encoded in UTF16-BE. Other than that, and not listing languages correctly, it's *supposed* to work. --- src/hb-dsalgs.hh | 21 +++++++++++++++++++ src/hb-ot-name-table.hh | 37 ++++++++++++++++++++++++++------- src/hb-ot-name.cc | 12 +++++++---- src/hb-ot-os2-unicode-ranges.hh | 10 ++++----- src/hb-unicode.cc | 8 +++---- src/hb-unicode.hh | 2 +- 6 files changed, 69 insertions(+), 21 deletions(-) diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index d22e8809e..265651b7f 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -312,6 +312,27 @@ hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3) * Sort and search. */ +static inline void * +hb_bsearch (const void *key, const void *base, + size_t nmemb, size_t size, + int (*compar)(const void *_key, const void *_item)) +{ + int min = 0, max = (int) nmemb - 1; + while (min <= max) + { + int mid = (min + max) / 2; + const void *p = (const void *) (((const char *) base) + (mid * size)); + int c = compar (key, p); + if (c < 0) + max = mid - 1; + else if (c > 0) + min = mid + 1; + else + return (void *) p; + } + return nullptr; +} + static inline void * hb_bsearch_r (const void *key, const void *base, size_t nmemb, size_t size, diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 8967fcbd8..f2eb49681 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -107,20 +107,31 @@ struct NameRecord }; static int -_hb_ot_name_entry_cmp (const void *pa, const void *pb) +_hb_ot_name_entry_cmp_key (const void *pa, const void *pb) { const hb_ot_name_entry_t *a = (const hb_ot_name_entry_t *) pa; const hb_ot_name_entry_t *b = (const hb_ot_name_entry_t *) pb; - /* Sort by name_id, then language, then score, then index. */ + /* Compare by name_id, then language. */ if (a->name_id != b->name_id) return a->name_id < b->name_id ? -1 : +1; - int e = strcmp (hb_language_to_string (a->language), - hb_language_to_string (b->language)); - if (e) - return e; + return strcmp (hb_language_to_string (a->language), + hb_language_to_string (b->language)); +} + +static int +_hb_ot_name_entry_cmp (const void *pa, const void *pb) +{ + /* Compare by name_id, then language, then score, then index. */ + + int v = _hb_ot_name_entry_cmp_key (pa, pb); + if (v) + return v; + + const hb_ot_name_entry_t *a = (const hb_ot_name_entry_t *) pa; + const hb_ot_name_entry_t *b = (const hb_ot_name_entry_t *) pb; if (a->entry_score != b->entry_score) return a->entry_score < b->entry_score ? -1 : +1; @@ -199,13 +210,25 @@ struct name this->names.resize (j); } - inline void fini (void) { this->names.fini (); hb_blob_destroy (this->blob); } + inline int get_index (hb_name_id_t name_id, + hb_language_t language) const + { + const hb_ot_name_entry_t key = {name_id, {0}, language}; + const hb_ot_name_entry_t *entry = (const hb_ot_name_entry_t *) + hb_bsearch (&key, + this->names.arrayZ(), + this->names.len, + sizeof (key), + _hb_ot_name_entry_cmp_key); + return entry ? entry->entry_index : -1; + } + private: hb_blob_t *blob; public: diff --git a/src/hb-ot-name.cc b/src/hb-ot-name.cc index fe1276c32..626e0637a 100644 --- a/src/hb-ot-name.cc +++ b/src/hb-ot-name.cc @@ -105,11 +105,15 @@ hb_ot_name_get_utf (hb_face_t *face, typename utf_t::codepoint_t *text /* OUT */) { const OT::name_accelerator_t &name = _get_name (face); - unsigned int idx = 0; // XXX bsearch and find - hb_bytes_t bytes = name.table->get_name (idx); - if (true /*UTF16-BE*/) - return hb_ot_name_convert_utf (&bytes, text_size, text); + int idx = name.get_index (name_id, language); + if (idx != -1) + { + hb_bytes_t bytes = name.table->get_name (idx); + + if (true /*UTF16-BE*/) + return hb_ot_name_convert_utf (&bytes, text_size, text); + } if (text_size) { diff --git a/src/hb-ot-os2-unicode-ranges.hh b/src/hb-ot-os2-unicode-ranges.hh index 19780088a..b0ccd00d7 100644 --- a/src/hb-ot-os2-unicode-ranges.hh +++ b/src/hb-ot-os2-unicode-ranges.hh @@ -34,7 +34,7 @@ namespace OT { struct OS2Range { static int - cmp (const void *_key, const void *_item, void *_arg) + cmp (const void *_key, const void *_item) { hb_codepoint_t cp = *((hb_codepoint_t *) _key); const OS2Range *range = (OS2Range *) _item; @@ -233,10 +233,10 @@ static const OS2Range _hb_os2_unicode_ranges[] = static unsigned int _hb_ot_os2_get_unicode_range_bit (hb_codepoint_t cp) { - OS2Range *range = (OS2Range*) hb_bsearch_r (&cp, _hb_os2_unicode_ranges, - ARRAY_LENGTH (_hb_os2_unicode_ranges), - sizeof (OS2Range), - OS2Range::cmp, nullptr); + OS2Range *range = (OS2Range*) hb_bsearch (&cp, _hb_os2_unicode_ranges, + ARRAY_LENGTH (_hb_os2_unicode_ranges), + sizeof (OS2Range), + OS2Range::cmp); if (range != nullptr) return range->bit; return -1; diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc index 596e76d05..a08f88829 100644 --- a/src/hb-unicode.cc +++ b/src/hb-unicode.cc @@ -576,8 +576,8 @@ _hb_modified_combining_class[256] = bool _hb_unicode_is_emoji_Extended_Pictographic (hb_codepoint_t cp) { - return hb_bsearch_r (&cp, _hb_unicode_emoji_Extended_Pictographic_table, - ARRAY_LENGTH (_hb_unicode_emoji_Extended_Pictographic_table), - sizeof (hb_unicode_range_t), - hb_unicode_range_t::cmp, nullptr); + return hb_bsearch (&cp, _hb_unicode_emoji_Extended_Pictographic_table, + ARRAY_LENGTH (_hb_unicode_emoji_Extended_Pictographic_table), + sizeof (hb_unicode_range_t), + hb_unicode_range_t::cmp); } diff --git a/src/hb-unicode.hh b/src/hb-unicode.hh index 6d6a4fa0c..4326798df 100644 --- a/src/hb-unicode.hh +++ b/src/hb-unicode.hh @@ -369,7 +369,7 @@ DECLARE_NULL_INSTANCE (hb_unicode_funcs_t); struct hb_unicode_range_t { static int - cmp (const void *_key, const void *_item, void *_arg) + cmp (const void *_key, const void *_item) { hb_codepoint_t cp = *((hb_codepoint_t *) _key); const hb_unicode_range_t *range = (hb_unicode_range_t *) _item; From 4668a05006e6c4797df19651489b4589817e1e01 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 23 Oct 2018 20:51:53 -0700 Subject: [PATCH 046/255] [name] Hook things up Accept Mac Latin name entries as ASCII as well. --- src/hb-ot-name-table.hh | 24 +++++++++++++----- src/hb-ot-name.cc | 8 ++++-- src/hb-utf.hh | 55 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 8 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index f2eb49681..26906671d 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -84,7 +84,8 @@ struct NameRecord /* Symbol. */ if (p == 3 && e == 0) return 8; - /* TODO Apple MacRoman (0:1). */ + /* We treat all Mac Latin names as ASCII only. */ + if (p == 1 && e == 0) return 10; /* 10 is magic number :| */ return UNSUPPORTED; } @@ -198,11 +199,15 @@ struct name } this->names.qsort (_hb_ot_name_entry_cmp); - /* Walk and pick best only for each name_id,language pair... */ + /* Walk and pick best only for each name_id,language pair, + * while dropping unsupported encodings. */ unsigned int j = 0; - for (unsigned int i = 1; i < this->names.len; i++) + for (unsigned int i = 0; i < this->names.len; i++) { - if (this->names[i - 1].name_id == this->names[i].name_id && + if (this->names[i].entry_score == UNSUPPORTED) + continue; + if (i && + this->names[i - 1].name_id == this->names[i].name_id && this->names[i - 1].language == this->names[i].language) continue; this->names[j++] = this->names[i]; @@ -217,7 +222,8 @@ struct name } inline int get_index (hb_name_id_t name_id, - hb_language_t language) const + hb_language_t language, + unsigned int *width=nullptr) const { const hb_ot_name_entry_t key = {name_id, {0}, language}; const hb_ot_name_entry_t *entry = (const hb_ot_name_entry_t *) @@ -226,7 +232,13 @@ struct name this->names.len, sizeof (key), _hb_ot_name_entry_cmp_key); - return entry ? entry->entry_index : -1; + if (!entry) + return -1; + + if (width) + *width = entry->entry_score < 10 ? 2 : 1; + + return entry->entry_index; } private: diff --git a/src/hb-ot-name.cc b/src/hb-ot-name.cc index 626e0637a..56f89335b 100644 --- a/src/hb-ot-name.cc +++ b/src/hb-ot-name.cc @@ -106,13 +106,17 @@ hb_ot_name_get_utf (hb_face_t *face, { const OT::name_accelerator_t &name = _get_name (face); - int idx = name.get_index (name_id, language); + unsigned int width; + int idx = name.get_index (name_id, language, &width); if (idx != -1) { hb_bytes_t bytes = name.table->get_name (idx); - if (true /*UTF16-BE*/) + if (width == 2) /* UTF16-BE */ return hb_ot_name_convert_utf (&bytes, text_size, text); + + if (width == 1) /* ASCII */ + return hb_ot_name_convert_utf (&bytes, text_size, text); } if (text_size) diff --git a/src/hb-utf.hh b/src/hb-utf.hh index 5e2faebb5..f78d54995 100644 --- a/src/hb-utf.hh +++ b/src/hb-utf.hh @@ -398,4 +398,59 @@ struct hb_latin1_t } }; + +struct hb_ascii_t +{ + typedef uint8_t codepoint_t; + + static inline const codepoint_t * + next (const codepoint_t *text, + const codepoint_t *end HB_UNUSED, + hb_codepoint_t *unicode, + hb_codepoint_t replacement HB_UNUSED) + { + *unicode = *text++; + if (*unicode >= 0x100) + *unicode = replacement; + return text; + } + + static inline const codepoint_t * + prev (const codepoint_t *text, + const codepoint_t *start HB_UNUSED, + hb_codepoint_t *unicode, + hb_codepoint_t replacement) + { + *unicode = *--text; + if (*unicode >= 0x0080) + *unicode = replacement; + return text; + } + + static inline unsigned int + strlen (const codepoint_t *text) + { + unsigned int l = 0; + while (*text++) l++; + return l; + } + + static inline unsigned int + encode_len (hb_codepoint_t unicode HB_UNUSED) + { + return 1; + } + + static inline codepoint_t * + encode (codepoint_t *text, + const codepoint_t *end HB_UNUSED, + hb_codepoint_t unicode) + { + if (unlikely (unicode >= 0x0080u)) + unicode = '?'; + *text++ = unicode; + return text; + } +}; + #endif /* HB_UTF_HH */ From 6db6bbe64bd63554919647c5b527e03aedbaee4e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 23 Oct 2018 21:12:58 -0700 Subject: [PATCH 047/255] [name] Remove unused cmp function --- src/hb-ot-name-table.hh | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 26906671d..c1e89a997 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -47,22 +47,6 @@ namespace OT { struct NameRecord { - static int cmp (const void *pa, const void *pb) - { - const NameRecord *a = (const NameRecord *) pa; - const NameRecord *b = (const NameRecord *) pb; - int ret; - ret = b->platformID.cmp (a->platformID); - if (ret) return ret; - ret = b->encodingID.cmp (a->encodingID); - if (ret) return ret; - ret = b->languageID.cmp (a->languageID); - if (ret) return ret; - ret = b->nameID.cmp (a->nameID); - if (ret) return ret; - return 0; - } - inline uint16_t score (void) const { /* Same order as in cmap::find_best_subtable(). */ From e2f9b657758cda3708c0a9db971c467ca59d5c19 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 23 Oct 2018 21:19:56 -0700 Subject: [PATCH 048/255] [name] Start adding language support --- src/hb-ot-name-table.hh | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index c1e89a997..c6b7796e8 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -47,6 +47,29 @@ namespace OT { struct NameRecord { + inline hb_language_t language (void) const + { + unsigned int p = platformID; + unsigned int l = languageID; + + if (p == 3) + { + switch (l) + { + case 0x0409: return hb_language_from_string ("en", -1); + } + } + else if (p == 1) + { + switch (l) + { + case 0: return hb_language_from_string ("en", -1); + } + } + + return HB_LANGUAGE_INVALID; + } + inline uint16_t score (void) const { /* Same order as in cmap::find_best_subtable(). */ @@ -177,7 +200,7 @@ struct name hb_ot_name_entry_t *entry = this->names.push (); entry->name_id = all_names[i].nameID; - entry->language = HB_LANGUAGE_INVALID; /* XXX */ + entry->language = all_names[i].language (); entry->entry_score = all_names[i].score (); entry->entry_index = i; } From 9b532e2ed432611005b19c40cac7e626afcccd08 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 23 Oct 2018 22:00:19 -0700 Subject: [PATCH 049/255] [name] Add language mapping --- src/Makefile.sources | 2 + src/hb-ot-name-language.cc | 349 +++++++++++++++++++++++++++++++++++++ src/hb-ot-name-language.hh | 40 +++++ src/hb-ot-name-table.hh | 21 +-- 4 files changed, 399 insertions(+), 13 deletions(-) create mode 100644 src/hb-ot-name-language.cc create mode 100644 src/hb-ot-name-language.hh diff --git a/src/Makefile.sources b/src/Makefile.sources index 0ee79a479..fe140b044 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -33,6 +33,8 @@ HB_BASE_sources = \ hb-ot-hmtx-table.hh \ hb-ot-kern-table.hh \ hb-ot-maxp-table.hh \ + hb-ot-name-language.cc \ + hb-ot-name-language.hh \ hb-ot-name-table.hh \ hb-ot-name.cc \ hb-ot-os2-table.hh \ diff --git a/src/hb-ot-name-language.cc b/src/hb-ot-name-language.cc new file mode 100644 index 000000000..19ffc004a --- /dev/null +++ b/src/hb-ot-name-language.cc @@ -0,0 +1,349 @@ +/* + * Copyright © 2018 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#include "hb-ot-name-language.hh" + +struct hb_ot_language_map_t +{ + static int cmp (const void *key, const void *item) + { + unsigned int a = * (unsigned int *) key; + unsigned int b = ((const hb_ot_language_map_t *) item)->code; + return a < b ? -1 : a > b ? +1 : 0; + } + + uint16_t code; + char lang[6]; +}; + +static const hb_ot_language_map_t +hb_ms_language_map[] = +{ + {0x0401, "ar"}, /* Arabic (Saudi Arabia) */ + {0x0402, "bg"}, /* Bulgarian (Bulgaria) */ + {0x0404, "zh-tw"}, /* Chinese (Taiwan) */ + {0x0405, "cs"}, /* Czech (Czech Republic) */ + {0x0406, "da"}, /* Danish (Denmark) */ + {0x0407, "de"}, /* German (Germany) */ + {0x0408, "el"}, /* Greek (Greece) */ + {0x0409, "en"}, /* English (United States) */ + {0x040A, "es"}, /* Spanish (Traditional Sort) (Spain) */ + {0x040B, "fi"}, /* Finnish (Finland) */ + {0x040C, "fr"}, /* French (France) */ + {0x040D, "he"}, /* Hebrew (Israel) */ + {0x040E, "hu"}, /* Hungarian (Hungary) */ + {0x040F, "is"}, /* Icelandic (Iceland) */ + {0x0410, "it"}, /* Italian (Italy) */ + {0x0411, "ja"}, /* Japanese (Japan) */ + {0x0413, "nl"}, /* Dutch (Netherlands) */ + {0x0414, "no"}, /* Norwegian (Bokmal) (Norway) */ + {0x0415, "pl"}, /* Polish (Poland) */ + {0x0416, "pt"}, /* Portuguese (Brazil) */ + {0x0418, "ro"}, /* Romanian (Romania) */ + {0x0419, "ru"}, /* Russian (Russia) */ + {0x041A, "hr"}, /* Croatian (Croatia) */ + {0x041B, "sk"}, /* Slovak (Slovakia) */ + {0x041C, "sq"}, /* Albanian (Albania) */ + {0x041D, "sv"}, /* Swedish (Sweden) */ + {0x041E, "th"}, /* Thai (Thailand) */ + {0x041F, "tr"}, /* Turkish (Turkey) */ + {0x0420, "ur"}, /* Urdu (Islamic Republic of Pakistan) */ + {0x0421, "id"}, /* Indonesian (Indonesia) */ + {0x0422, "uk"}, /* Ukrainian (Ukraine) */ + {0x0423, "be"}, /* Belarusian (Belarus) */ + {0x0425, "et"}, /* Estonian (Estonia) */ + {0x0426, "lv"}, /* Latvian (Latvia) */ + {0x0427, "lt"}, /* Lithuanian (Lithuania) */ + {0x0428, "tg"}, /* Tajik (Cyrillic) (Tajikistan) */ + {0x042A, "vi"}, /* Vietnamese (Vietnam) */ + {0x042B, "hy"}, /* Armenian (Armenia) */ + {0x042C, "az"}, /* Azeri (Latin) (Azerbaijan) */ + {0x042F, "mk"}, /* Macedonian (FYROM) (Former Yugoslav Republic of Macedonia) */ + {0x0436, "af"}, /* Afrikaans (South Africa) */ + {0x0437, "ka"}, /* Georgian (Georgia) */ + {0x0438, "fo"}, /* Faroese (Faroe Islands) */ + {0x0439, "hi"}, /* Hindi (India) */ + {0x043A, "mt"}, /* Maltese (Malta) */ + {0x043E, "ms"}, /* Malay (Malaysia) */ + {0x0442, "tk"}, /* Turkmen (Turkmenistan) */ + {0x0443, "uz"}, /* Uzbek (Latin) (Uzbekistan) */ + {0x0445, "bn"}, /* Bengali (India) */ + {0x0446, "pa"}, /* Punjabi (India) */ + {0x0447, "gu"}, /* Gujarati (India) */ + {0x0449, "ta"}, /* Tamil (India) */ + {0x044A, "te"}, /* Telugu (India) */ + {0x044B, "kn"}, /* Kannada (India) */ + {0x044C, "ml"}, /* Malayalam (India) */ + {0x044D, "as"}, /* Assamese (India) */ + {0x044E, "mr"}, /* Marathi (India) */ + {0x044F, "sa"}, /* Sanskrit (India) */ + {0x0450, "mn"}, /* Mongolian (Cyrillic) (Mongolia) */ + {0x0453, "km"}, /* Khmer (Cambodia) */ + {0x0454, "lo"}, /* Lao (Lao P.D.R.) */ + {0x0457, "kok"}, /* Konkani (India) */ + {0x045A, "syr"}, /* Syriac (Syria) */ + {0x045D, "iu"}, /* Inuktitut (Canada) */ + {0x045E, "am"}, /* Amharic (Ethiopia) */ + {0x0461, "ne"}, /* Nepali (Nepal) */ + {0x0462, "fy"}, /* Frisian (Netherlands) */ + {0x0463, "ps"}, /* Pashto (Afghanistan) */ + {0x0464, "phi"}, /* Filipino (Philippines) */ + {0x0465, "div"}, /* Divehi (Maldives) */ + {0x0468, "ha"}, /* Hausa (Latin) (Nigeria) */ + {0x046A, "yo"}, /* Yoruba (Nigeria) */ + {0x0470, "ibo"}, /* Igbo (Nigeria) */ + {0x0481, "mi"}, /* Maori (New Zealand) */ + {0x0801, "ar"}, /* Arabic (Iraq) */ + {0x0804, "zh-cn"}, /* Chinese (People’s Republic of China) */ + {0x0807, "de"}, /* German (Switzerland) */ + {0x0809, "en"}, /* English (United Kingdom) */ + {0x080A, "es"}, /* Spanish (Mexico) */ + {0x080C, "fr"}, /* French (Belgium) */ + {0x0810, "it"}, /* Italian (Switzerland) */ + {0x0813, "nl"}, /* Dutch (Belgium) */ + {0x0814, "nn"}, /* Norwegian (Nynorsk) (Norway) */ + {0x0816, "pt"}, /* Portuguese (Portugal) */ + {0x081A, "sr"}, /* Serbian (Latin) (Serbia) */ + {0x081D, "sv"}, /* Sweden (Finland) */ + {0x082C, "az"}, /* Azeri (Cyrillic) (Azerbaijan) */ + {0x083E, "ms"}, /* Malay (Brunei Darussalam) */ + {0x0843, "uz"}, /* Uzbek (Cyrillic) (Uzbekistan) */ + {0x0845, "bn"}, /* Bengali (Bangladesh) */ + {0x0C01, "ar"}, /* Arabic (Egypt) */ + {0x0C04, "zh-hk"}, /* Chinese (Hong Kong S.A.R.) */ + {0x0C07, "de"}, /* German (Austria) */ + {0x0C09, "en"}, /* English (Australia) */ + {0x0C0C, "fr"}, /* French (Canada) */ + {0x0C1A, "sr"}, /* Serbian (Cyrillic) (Serbia) */ + {0x1001, "ar"}, /* Arabic (Libya) */ + {0x1004, "zh-sg"}, /* Chinese (Singapore) */ + {0x1007, "de"}, /* German (Luxembourg) */ + {0x1009, "en"}, /* English (Canada) */ + {0x100A, "es"}, /* Spanish (Guatemala) */ + {0x100C, "fr"}, /* French (Switzerland) */ + {0x1401, "ar"}, /* Arabic (Algeria) */ + {0x1409, "en"}, /* English (New Zealand) */ + {0x140A, "es"}, /* Spanish (Costa Rica) */ + {0x141A, "bs"}, /* Bosnian (Latin) (Bosnia and Herzegovina) */ + {0x1801, "ar"}, /* Arabic (Morocco) */ + {0x1809, "en"}, /* English (Ireland) */ + {0x180A, "es"}, /* Spanish (Panama) */ + {0x180C, "fr"}, /* French (Principality of Monaco) */ + {0x1C01, "ar"}, /* Arabic (Tunisia) */ + {0x1C09, "en"}, /* English (South Africa) */ + {0x1C0A, "es"}, /* Spanish (Dominican Republic) */ + {0x2001, "ar"}, /* Arabic (Oman) */ + {0x2009, "en"}, /* English (Jamaica) */ + {0x200A, "es"}, /* Spanish (Venezuela) */ + {0x2401, "ar"}, /* Arabic (Yemen) */ + {0x2409, "en"}, /* English (Caribbean) */ + {0x240A, "es"}, /* Spanish (Colombia) */ + {0x2801, "ar"}, /* Arabic (Syria) */ + {0x2809, "en"}, /* English (Belize) */ + {0x280A, "es"}, /* Spanish (Peru) */ + {0x2C01, "ar"}, /* Arabic (Jordan) */ + {0x2C09, "en"}, /* English (Trinidad and Tobago) */ + {0x2C0A, "es"}, /* Spanish (Argentina) */ + {0x3001, "ar"}, /* Arabic (Lebanon) */ + {0x3009, "en"}, /* English (Zimbabwe) */ + {0x300A, "es"}, /* Spanish (Ecuador) */ + {0x3401, "ar"}, /* Arabic (Kuwait) */ + {0x3409, "en"}, /* English (Republic of the Philippines) */ + {0x340A, "es"}, /* Spanish (Chile) */ + {0x3801, "ar"}, /* Arabic (U.A.E.) */ + {0x380A, "es"}, /* Spanish (Uruguay) */ + {0x3C01, "ar"}, /* Arabic (Bahrain) */ + {0x3C0A, "es"}, /* Spanish (Paraguay) */ + {0x4001, "ar"}, /* Arabic (Qatar) */ + {0x4009, "en"}, /* English (India) */ + {0x400A, "es"}, /* Spanish (Bolivia) */ + {0x4409, "en"}, /* English (Malaysia) */ + {0x440A, "es"}, /* Spanish (El Salvador) */ + {0x4809, "en"}, /* English (Singapore) */ + {0x480A, "es"}, /* Spanish (Honduras) */ + {0x4C0A, "es"}, /* Spanish (Nicaragua) */ + {0x500A, "es"}, /* Spanish (Puerto Rico) */ + {0x540A, "es"}, /* Spanish (United States) */ +}; + +static const hb_ot_language_map_t +hb_mac_language_map[] = +{ + {0, "en"}, /* English */ + {1, "fr"}, /* French */ + {2, "de"}, /* German */ + {3, "it"}, /* Italian */ + {4, "nl"}, /* Dutch */ + {5, "sv"}, /* Swedish */ + {6, "es"}, /* Spanish */ + {7, "da"}, /* Danish */ + {8, "pt"}, /* Portuguese */ + {9, "no"}, /* Norwegian */ + {10, "he"}, /* Hebrew */ + {11, "ja"}, /* Japanese */ + {12, "ar"}, /* Arabic */ + {13, "fi"}, /* Finnish */ + {14, "el"}, /* Greek */ + {15, "is"}, /* Icelandic */ + {16, "mt"}, /* Maltese */ + {17, "tr"}, /* Turkish */ + {18, "hr"}, /* Croatian */ + {19, "zh-tw"}, /* Chinese (Traditional) */ + {20, "ur"}, /* Urdu */ + {21, "hi"}, /* Hindi */ + {22, "th"}, /* Thai */ + {23, "ko"}, /* Korean */ + {24, "lt"}, /* Lithuanian */ + {25, "pl"}, /* Polish */ + {26, "hu"}, /* Hungarian */ + {27, "et"}, /* Estonian */ + {28, "lv"}, /* Latvian */ + {30, "fo"}, /* Faroese */ + {31, "fa"}, /* Farsi/Persian */ + {32, "ru"}, /* Russian */ + {33, "zh-cn"}, /* Chinese (Simplified) */ + {34, "nl"}, /* Flemish */ + {35, "ga"}, /* Irish Gaelic */ + {36, "sq"}, /* Albanian */ + {37, "ro"}, /* Romanian */ + {38, "cs"}, /* Czech */ + {39, "sk"}, /* Slovak */ + {40, "sl"}, /* Slovenian */ + {41, "yi"}, /* Yiddish */ + {42, "sr"}, /* Serbian */ + {43, "mk"}, /* Macedonian */ + {44, "bg"}, /* Bulgarian */ + {45, "uk"}, /* Ukrainian */ + {46, "be"}, /* Byelorussian */ + {47, "uz"}, /* Uzbek */ + {48, "kk"}, /* Kazakh */ + {49, "az"}, /* Azerbaijani (Cyrillic script) */ + {49, "az"}, /* Azerbaijani (Cyrillic script) */ + {50, "ar"}, /* Azerbaijani (Arabic script) */ + {51, "hy"}, /* Armenian */ + {52, "ka"}, /* Georgian */ + {53, "mo"}, /* Moldavian */ + {54, "ky"}, /* Kirghiz */ + {55, "tg"}, /* Tajiki */ + {56, "tk"}, /* Turkmen */ + {57, "mo"}, /* Mongolian (Mongolian script) */ + {57, "mo"}, /* Mongolian (Mongolian script) */ + {58, "mo"}, /* Mongolian (Cyrillic script) */ + {59, "ps"}, /* Pashto */ + {60, "ku"}, /* Kurdish */ + {61, "ks"}, /* Kashmiri */ + {62, "sd"}, /* Sindhi */ + {63, "bo"}, /* Tibetan */ + {64, "ne"}, /* Nepali */ + {65, "sa"}, /* Sanskrit */ + {66, "mr"}, /* Marathi */ + {67, "bn"}, /* Bengali */ + {68, "as"}, /* Assamese */ + {69, "gu"}, /* Gujarati */ + {70, "pa"}, /* Punjabi */ + {71, "or"}, /* Oriya */ + {72, "ml"}, /* Malayalam */ + {73, "kn"}, /* Kannada */ + {74, "ta"}, /* Tamil */ + {75, "te"}, /* Telugu */ + {76, "si"}, /* Sinhalese */ + {77, "my"}, /* Burmese */ + {78, "km"}, /* Khmer */ + {79, "lo"}, /* Lao */ + {80, "vi"}, /* Vietnamese */ + {81, "id"}, /* Indonesian */ + {82, "tl"}, /* Tagalog */ + {83, "ms"}, /* Malay (Roman script) */ + {84, "ms"}, /* Malay (Arabic script) */ + {85, "am"}, /* Amharic */ + {86, "ti"}, /* Tigrinya */ + {87, "om"}, /* Galla */ + {88, "so"}, /* Somali */ + {89, "sw"}, /* Swahili */ + {90, "rw"}, /* Kinyarwanda/Ruanda */ + {91, "rn"}, /* Rundi */ + {92, "ny"}, /* Nyanja/Chewa */ + {93, "mg"}, /* Malagasy */ + {94, "eo"}, /* Esperanto */ + {128, "cy"}, /* Welsh */ + {129, "eu"}, /* Basque */ + {130, "ca"}, /* Catalan */ + {131, "la"}, /* Latin */ + {132, "qu"}, /* Quechua */ + {133, "gn"}, /* Guarani */ + {134, "ay"}, /* Aymara */ + {135, "tt"}, /* Tatar */ + {136, "ug"}, /* Uighur */ + {137, "dz"}, /* Dzongkha */ + {138, "jw"}, /* Javanese (Roman script) */ + {139, "su"}, /* Sundanese (Roman script) */ + {140, "gl"}, /* Galician */ + {141, "af"}, /* Afrikaans */ + {142, "br"}, /* Breton */ + {143, "iu"}, /* Inuktitut */ + {144, "gd"}, /* Scottish Gaelic */ + {145, "gv"}, /* Manx Gaelic */ + {146, "ga"}, /* Irish Gaelic (with dot above) */ + {147, "to"}, /* Tongan */ + {148, "el"}, /* Greek (polytonic) */ + {149, "ik"}, /* Greenlandic */ + {150, "az"}, /* Azerbaijani (Roman script) */ +}; + + +static hb_language_t +_hb_ot_name_language_for (unsigned int code, + const hb_ot_language_map_t *array, + unsigned int len) +{ + const hb_ot_language_map_t *entry = (const hb_ot_language_map_t *) + hb_bsearch (&code, + array, + len, + sizeof (array[0]), + hb_ot_language_map_t::cmp); + + if (entry) + return hb_language_from_string (entry->lang, -1); + + return HB_LANGUAGE_INVALID; +} + +hb_language_t +_hb_ot_name_language_for_ms_code (unsigned int code) +{ + return _hb_ot_name_language_for (code, + hb_ms_language_map, + ARRAY_LENGTH (hb_ms_language_map)); +} + +hb_language_t +_hb_ot_name_language_for_mac_code (unsigned int code) +{ + return _hb_ot_name_language_for (code, + hb_mac_language_map, + ARRAY_LENGTH (hb_mac_language_map)); +} diff --git a/src/hb-ot-name-language.hh b/src/hb-ot-name-language.hh new file mode 100644 index 000000000..903076c0d --- /dev/null +++ b/src/hb-ot-name-language.hh @@ -0,0 +1,40 @@ +/* + * Copyright © 2018 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_NAME_LANGUAGE_HH +#define HB_OT_NAME_LANGUAGE_HH + +#include "hb.hh" + + +HB_INTERNAL hb_language_t +_hb_ot_name_language_for_ms_code (unsigned int code); + +HB_INTERNAL hb_language_t +_hb_ot_name_language_for_mac_code (unsigned int code); + + +#endif /* HB_OT_NAME_LANGUAGE_HH */ diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index c6b7796e8..14a8efab0 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -28,6 +28,7 @@ #define HB_OT_NAME_TABLE_HH #include "hb-open-type.hh" +#include "hb-ot-name-language.hh" namespace OT { @@ -53,19 +54,13 @@ struct NameRecord unsigned int l = languageID; if (p == 3) - { - switch (l) - { - case 0x0409: return hb_language_from_string ("en", -1); - } - } - else if (p == 1) - { - switch (l) - { - case 0: return hb_language_from_string ("en", -1); - } - } + return _hb_ot_name_language_for_ms_code (l); + + if (p == 1) + return _hb_ot_name_language_for_mac_code (l); + + //if (p == 0) + /* TODO use 'ltag' table? */ return HB_LANGUAGE_INVALID; } From 888a65615c7b11222749ae85c124aaa9a36fe863 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 23 Oct 2018 22:16:32 -0700 Subject: [PATCH 050/255] [name] Fix nul-termination bug --- src/hb-ot-name.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-name.cc b/src/hb-ot-name.cc index 56f89335b..7962d8b89 100644 --- a/src/hb-ot-name.cc +++ b/src/hb-ot-name.cc @@ -83,7 +83,7 @@ hb_ot_name_convert_utf (const hb_bytes_t *bytes, }; *text_size = dst - text; - *text = 0; /* NUL-terminate. */ + *dst = 0; /* NUL-terminate. */ } /* Accumulate length of rest. */ From 68f172101c1228a7d669d71da1d0eeb96a10565e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 23 Oct 2018 22:19:09 -0700 Subject: [PATCH 051/255] [name] Fix cmp for invalid language --- src/hb-ot-name-table.hh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 14a8efab0..be9c5e365 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -120,6 +120,9 @@ _hb_ot_name_entry_cmp_key (const void *pa, const void *pb) if (a->name_id != b->name_id) return a->name_id < b->name_id ? -1 : +1; + if (a->language == b->language) return 0; + if (!a->language) return -1; + if (!b->language) return +1; return strcmp (hb_language_to_string (a->language), hb_language_to_string (b->language)); } From 7007bd9dff9f8eef3263f1b39327552ff1ebae3f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 23 Oct 2018 22:44:36 -0700 Subject: [PATCH 052/255] [name] Rebuild language list, include missing entries --- src/hb-ot-name-language.cc | 634 ++++++++++++++++++++++--------------- 1 file changed, 370 insertions(+), 264 deletions(-) diff --git a/src/hb-ot-name-language.cc b/src/hb-ot-name-language.cc index 19ffc004a..8b79d4d6d 100644 --- a/src/hb-ot-name-language.cc +++ b/src/hb-ot-name-language.cc @@ -26,6 +26,9 @@ #include "hb-ot-name-language.hh" +/* Following two tables were generated by joining FreeType, FontConfig, + * and OpenType specification language lists. */ + struct hb_ot_language_map_t { static int cmp (const void *key, const void *item) @@ -42,275 +45,378 @@ struct hb_ot_language_map_t static const hb_ot_language_map_t hb_ms_language_map[] = { - {0x0401, "ar"}, /* Arabic (Saudi Arabia) */ - {0x0402, "bg"}, /* Bulgarian (Bulgaria) */ - {0x0404, "zh-tw"}, /* Chinese (Taiwan) */ - {0x0405, "cs"}, /* Czech (Czech Republic) */ - {0x0406, "da"}, /* Danish (Denmark) */ - {0x0407, "de"}, /* German (Germany) */ - {0x0408, "el"}, /* Greek (Greece) */ - {0x0409, "en"}, /* English (United States) */ - {0x040A, "es"}, /* Spanish (Traditional Sort) (Spain) */ - {0x040B, "fi"}, /* Finnish (Finland) */ - {0x040C, "fr"}, /* French (France) */ - {0x040D, "he"}, /* Hebrew (Israel) */ - {0x040E, "hu"}, /* Hungarian (Hungary) */ - {0x040F, "is"}, /* Icelandic (Iceland) */ - {0x0410, "it"}, /* Italian (Italy) */ - {0x0411, "ja"}, /* Japanese (Japan) */ - {0x0413, "nl"}, /* Dutch (Netherlands) */ - {0x0414, "no"}, /* Norwegian (Bokmal) (Norway) */ - {0x0415, "pl"}, /* Polish (Poland) */ - {0x0416, "pt"}, /* Portuguese (Brazil) */ - {0x0418, "ro"}, /* Romanian (Romania) */ - {0x0419, "ru"}, /* Russian (Russia) */ - {0x041A, "hr"}, /* Croatian (Croatia) */ - {0x041B, "sk"}, /* Slovak (Slovakia) */ - {0x041C, "sq"}, /* Albanian (Albania) */ - {0x041D, "sv"}, /* Swedish (Sweden) */ - {0x041E, "th"}, /* Thai (Thailand) */ - {0x041F, "tr"}, /* Turkish (Turkey) */ - {0x0420, "ur"}, /* Urdu (Islamic Republic of Pakistan) */ - {0x0421, "id"}, /* Indonesian (Indonesia) */ - {0x0422, "uk"}, /* Ukrainian (Ukraine) */ - {0x0423, "be"}, /* Belarusian (Belarus) */ - {0x0425, "et"}, /* Estonian (Estonia) */ - {0x0426, "lv"}, /* Latvian (Latvia) */ - {0x0427, "lt"}, /* Lithuanian (Lithuania) */ - {0x0428, "tg"}, /* Tajik (Cyrillic) (Tajikistan) */ - {0x042A, "vi"}, /* Vietnamese (Vietnam) */ - {0x042B, "hy"}, /* Armenian (Armenia) */ - {0x042C, "az"}, /* Azeri (Latin) (Azerbaijan) */ - {0x042F, "mk"}, /* Macedonian (FYROM) (Former Yugoslav Republic of Macedonia) */ - {0x0436, "af"}, /* Afrikaans (South Africa) */ - {0x0437, "ka"}, /* Georgian (Georgia) */ - {0x0438, "fo"}, /* Faroese (Faroe Islands) */ - {0x0439, "hi"}, /* Hindi (India) */ - {0x043A, "mt"}, /* Maltese (Malta) */ - {0x043E, "ms"}, /* Malay (Malaysia) */ - {0x0442, "tk"}, /* Turkmen (Turkmenistan) */ - {0x0443, "uz"}, /* Uzbek (Latin) (Uzbekistan) */ - {0x0445, "bn"}, /* Bengali (India) */ - {0x0446, "pa"}, /* Punjabi (India) */ - {0x0447, "gu"}, /* Gujarati (India) */ - {0x0449, "ta"}, /* Tamil (India) */ - {0x044A, "te"}, /* Telugu (India) */ - {0x044B, "kn"}, /* Kannada (India) */ - {0x044C, "ml"}, /* Malayalam (India) */ - {0x044D, "as"}, /* Assamese (India) */ - {0x044E, "mr"}, /* Marathi (India) */ - {0x044F, "sa"}, /* Sanskrit (India) */ - {0x0450, "mn"}, /* Mongolian (Cyrillic) (Mongolia) */ - {0x0453, "km"}, /* Khmer (Cambodia) */ - {0x0454, "lo"}, /* Lao (Lao P.D.R.) */ - {0x0457, "kok"}, /* Konkani (India) */ - {0x045A, "syr"}, /* Syriac (Syria) */ - {0x045D, "iu"}, /* Inuktitut (Canada) */ - {0x045E, "am"}, /* Amharic (Ethiopia) */ - {0x0461, "ne"}, /* Nepali (Nepal) */ - {0x0462, "fy"}, /* Frisian (Netherlands) */ - {0x0463, "ps"}, /* Pashto (Afghanistan) */ - {0x0464, "phi"}, /* Filipino (Philippines) */ - {0x0465, "div"}, /* Divehi (Maldives) */ - {0x0468, "ha"}, /* Hausa (Latin) (Nigeria) */ - {0x046A, "yo"}, /* Yoruba (Nigeria) */ - {0x0470, "ibo"}, /* Igbo (Nigeria) */ - {0x0481, "mi"}, /* Maori (New Zealand) */ - {0x0801, "ar"}, /* Arabic (Iraq) */ - {0x0804, "zh-cn"}, /* Chinese (People’s Republic of China) */ - {0x0807, "de"}, /* German (Switzerland) */ - {0x0809, "en"}, /* English (United Kingdom) */ - {0x080A, "es"}, /* Spanish (Mexico) */ - {0x080C, "fr"}, /* French (Belgium) */ - {0x0810, "it"}, /* Italian (Switzerland) */ - {0x0813, "nl"}, /* Dutch (Belgium) */ - {0x0814, "nn"}, /* Norwegian (Nynorsk) (Norway) */ - {0x0816, "pt"}, /* Portuguese (Portugal) */ - {0x081A, "sr"}, /* Serbian (Latin) (Serbia) */ - {0x081D, "sv"}, /* Sweden (Finland) */ - {0x082C, "az"}, /* Azeri (Cyrillic) (Azerbaijan) */ - {0x083E, "ms"}, /* Malay (Brunei Darussalam) */ - {0x0843, "uz"}, /* Uzbek (Cyrillic) (Uzbekistan) */ - {0x0845, "bn"}, /* Bengali (Bangladesh) */ - {0x0C01, "ar"}, /* Arabic (Egypt) */ - {0x0C04, "zh-hk"}, /* Chinese (Hong Kong S.A.R.) */ - {0x0C07, "de"}, /* German (Austria) */ - {0x0C09, "en"}, /* English (Australia) */ - {0x0C0C, "fr"}, /* French (Canada) */ - {0x0C1A, "sr"}, /* Serbian (Cyrillic) (Serbia) */ - {0x1001, "ar"}, /* Arabic (Libya) */ - {0x1004, "zh-sg"}, /* Chinese (Singapore) */ - {0x1007, "de"}, /* German (Luxembourg) */ - {0x1009, "en"}, /* English (Canada) */ - {0x100A, "es"}, /* Spanish (Guatemala) */ - {0x100C, "fr"}, /* French (Switzerland) */ - {0x1401, "ar"}, /* Arabic (Algeria) */ - {0x1409, "en"}, /* English (New Zealand) */ - {0x140A, "es"}, /* Spanish (Costa Rica) */ - {0x141A, "bs"}, /* Bosnian (Latin) (Bosnia and Herzegovina) */ - {0x1801, "ar"}, /* Arabic (Morocco) */ - {0x1809, "en"}, /* English (Ireland) */ - {0x180A, "es"}, /* Spanish (Panama) */ - {0x180C, "fr"}, /* French (Principality of Monaco) */ - {0x1C01, "ar"}, /* Arabic (Tunisia) */ - {0x1C09, "en"}, /* English (South Africa) */ - {0x1C0A, "es"}, /* Spanish (Dominican Republic) */ - {0x2001, "ar"}, /* Arabic (Oman) */ - {0x2009, "en"}, /* English (Jamaica) */ - {0x200A, "es"}, /* Spanish (Venezuela) */ - {0x2401, "ar"}, /* Arabic (Yemen) */ - {0x2409, "en"}, /* English (Caribbean) */ - {0x240A, "es"}, /* Spanish (Colombia) */ - {0x2801, "ar"}, /* Arabic (Syria) */ - {0x2809, "en"}, /* English (Belize) */ - {0x280A, "es"}, /* Spanish (Peru) */ - {0x2C01, "ar"}, /* Arabic (Jordan) */ - {0x2C09, "en"}, /* English (Trinidad and Tobago) */ - {0x2C0A, "es"}, /* Spanish (Argentina) */ - {0x3001, "ar"}, /* Arabic (Lebanon) */ - {0x3009, "en"}, /* English (Zimbabwe) */ - {0x300A, "es"}, /* Spanish (Ecuador) */ - {0x3401, "ar"}, /* Arabic (Kuwait) */ - {0x3409, "en"}, /* English (Republic of the Philippines) */ - {0x340A, "es"}, /* Spanish (Chile) */ - {0x3801, "ar"}, /* Arabic (U.A.E.) */ - {0x380A, "es"}, /* Spanish (Uruguay) */ - {0x3C01, "ar"}, /* Arabic (Bahrain) */ - {0x3C0A, "es"}, /* Spanish (Paraguay) */ - {0x4001, "ar"}, /* Arabic (Qatar) */ - {0x4009, "en"}, /* English (India) */ - {0x400A, "es"}, /* Spanish (Bolivia) */ - {0x4409, "en"}, /* English (Malaysia) */ - {0x440A, "es"}, /* Spanish (El Salvador) */ - {0x4809, "en"}, /* English (Singapore) */ - {0x480A, "es"}, /* Spanish (Honduras) */ - {0x4C0A, "es"}, /* Spanish (Nicaragua) */ - {0x500A, "es"}, /* Spanish (Puerto Rico) */ - {0x540A, "es"}, /* Spanish (United States) */ + {0x0001, "ar"}, /* ??? */ + {0x0004, "zh"}, /* ??? */ + {0x0009, "en"}, /* ??? */ + {0x0401, "ar"}, /* Arabic (Saudi Arabia) */ + {0x0402, "bg"}, /* Bulgarian (Bulgaria) */ +//{0x0403, ""}, /* Catalan (Catalan) */ + {0x0404, "zh-tw"}, /* Chinese (Taiwan) */ + {0x0405, "cs"}, /* Czech (Czech Republic) */ + {0x0406, "da"}, /* Danish (Denmark) */ + {0x0407, "de"}, /* German (Germany) */ + {0x0408, "el"}, /* Greek (Greece) */ + {0x0409, "en"}, /* English (United States) */ + {0x040A, "es"}, /* Spanish (Traditional Sort) (Spain) */ + {0x040B, "fi"}, /* Finnish (Finland) */ + {0x040C, "fr"}, /* French (France) */ + {0x040D, "he"}, /* Hebrew (Israel) */ + {0x040E, "hu"}, /* Hungarian (Hungary) */ + {0x040F, "is"}, /* Icelandic (Iceland) */ + {0x0410, "it"}, /* Italian (Italy) */ + {0x0411, "ja"}, /* Japanese (Japan) */ +//{0x0412, ""}, /* Korean (Korea) */ + {0x0413, "nl"}, /* Dutch (Netherlands) */ + {0x0414, "no"}, /* Norwegian (Bokmal) (Norway) */ + {0x0415, "pl"}, /* Polish (Poland) */ + {0x0416, "pt"}, /* Portuguese (Brazil) */ +//{0x0417, ""}, /* Romansh (Switzerland) */ + {0x0418, "ro"}, /* Romanian (Romania) */ + {0x0419, "ru"}, /* Russian (Russia) */ + {0x041A, "hr"}, /* Croatian (Croatia) */ + {0x041B, "sk"}, /* Slovak (Slovakia) */ + {0x041C, "sq"}, /* Albanian (Albania) */ + {0x041D, "sv"}, /* Swedish (Sweden) */ + {0x041E, "th"}, /* Thai (Thailand) */ + {0x041F, "tr"}, /* Turkish (Turkey) */ + {0x0420, "ur"}, /* Urdu (Islamic Republic of Pakistan) */ + {0x0421, "id"}, /* Indonesian (Indonesia) */ + {0x0422, "uk"}, /* Ukrainian (Ukraine) */ + {0x0423, "be"}, /* Belarusian (Belarus) */ +//{0x0424, ""}, /* Slovenian (Slovenia) */ + {0x0425, "et"}, /* Estonian (Estonia) */ + {0x0426, "lv"}, /* Latvian (Latvia) */ + {0x0427, "lt"}, /* Lithuanian (Lithuania) */ + {0x0428, "tg"}, /* Tajik (Cyrillic) (Tajikistan) */ + {0x0429, "fa"}, /* ??? */ + {0x042A, "vi"}, /* Vietnamese (Vietnam) */ + {0x042B, "hy"}, /* Armenian (Armenia) */ + {0x042C, "az"}, /* Azeri (Latin) (Azerbaijan) */ +//{0x042D, ""}, /* Basque (Basque) */ +//{0x042E, ""}, /* Upper Sorbian (Germany) */ + {0x042F, "mk"}, /* Macedonian (FYROM) (Former Yugoslav Republic of Macedonia) */ + {0x0430, "st"}, /* ??? */ + {0x0431, "ts"}, /* ??? */ +//{0x0432, ""}, /* Setswana (South Africa) */ + {0x0433, "ven"}, /* ??? */ +//{0x0434, ""}, /* isiXhosa (South Africa) */ +//{0x0435, ""}, /* isiZulu (South Africa) */ + {0x0436, "af"}, /* Afrikaans (South Africa) */ + {0x0437, "ka"}, /* Georgian (Georgia) */ + {0x0438, "fo"}, /* Faroese (Faroe Islands) */ + {0x0439, "hi"}, /* Hindi (India) */ + {0x043A, "mt"}, /* Maltese (Malta) */ + {0x043B, "se"}, /* Sami (Northern) (Norway) */ + {0x043C, "ga"}, /* ??? */ + {0x043D, "yi"}, /* ??? */ + {0x043E, "ms"}, /* Malay (Malaysia) */ +//{0x043F, ""}, /* Kazakh (Kazakhstan) */ +//{0x0440, ""}, /* Kyrgyz (Kyrgyzstan) */ +//{0x0441, ""}, /* Kiswahili (Kenya) */ + {0x0442, "tk"}, /* Turkmen (Turkmenistan) */ + {0x0443, "uz"}, /* Uzbek (Latin) (Uzbekistan) */ +//{0x0444, ""}, /* Tatar (Russia) */ + {0x0445, "bn"}, /* Bengali (India) */ + {0x0446, "pa"}, /* Punjabi (India) */ + {0x0447, "gu"}, /* Gujarati (India) */ +//{0x0448, ""}, /* Odia (formerly Oriya) (India) */ + {0x0449, "ta"}, /* Tamil (India) */ + {0x044A, "te"}, /* Telugu (India) */ + {0x044B, "kn"}, /* Kannada (India) */ + {0x044C, "ml"}, /* Malayalam (India) */ + {0x044D, "as"}, /* Assamese (India) */ + {0x044E, "mr"}, /* Marathi (India) */ + {0x044F, "sa"}, /* Sanskrit (India) */ + {0x0450, "mn"}, /* Mongolian (Cyrillic) (Mongolia) */ +//{0x0451, ""}, /* Tibetan (PRC) */ +//{0x0452, ""}, /* Welsh (United Kingdom) */ + {0x0453, "km"}, /* Khmer (Cambodia) */ + {0x0454, "lo"}, /* Lao (Lao P.D.R.) */ + {0x0455, "my"}, /* ??? */ +//{0x0456, ""}, /* Galician (Galician) */ + {0x0457, "kok"}, /* Konkani (India) */ + {0x0458, "mni"}, /* ??? */ + {0x0459, "sd"}, /* ??? */ + {0x045A, "syr"}, /* Syriac (Syria) */ +//{0x045B, ""}, /* Sinhala (Sri Lanka) */ + {0x045C, "chr"}, /* ??? */ + {0x045D, "iu"}, /* Inuktitut (Canada) */ + {0x045E, "am"}, /* Amharic (Ethiopia) */ + {0x0460, "ks"}, /* ??? */ + {0x0461, "ne"}, /* Nepali (Nepal) */ + {0x0462, "fy"}, /* Frisian (Netherlands) */ + {0x0463, "ps"}, /* Pashto (Afghanistan) */ + {0x0464, "phi"}, /* Filipino (Philippines) */ + {0x0465, "div"}, /* Divehi (Maldives) */ + {0x0468, "ha"}, /* Hausa (Latin) (Nigeria) */ + {0x046A, "yo"}, /* Yoruba (Nigeria) */ +//{0x046B, ""}, /* Quechua (Bolivia) */ +//{0x046C, ""}, /* Sesotho sa Leboa (South Africa) */ +//{0x046D, ""}, /* Bashkir (Russia) */ +//{0x046E, ""}, /* Luxembourgish (Luxembourg) */ +//{0x046F, ""}, /* Greenlandic (Greenland) */ + {0x0470, "ibo"}, /* Igbo (Nigeria) */ + {0x0471, "kau"}, /* ??? */ + {0x0472, "om"}, /* ??? */ + {0x0473, "ti"}, /* ??? */ + {0x0474, "gn"}, /* ??? */ + {0x0475, "haw"}, /* ??? */ + {0x0476, "la"}, /* ??? */ + {0x0477, "so"}, /* ??? */ +//{0x0478, ""}, /* Yi (PRC) */ + {0x0479, "pap"}, /* ??? */ +//{0x047A, ""}, /* Mapudungun (Chile) */ +//{0x047C, ""}, /* Mohawk (Mohawk) */ +//{0x047E, ""}, /* Breton (France) */ +//{0x0480, ""}, /* Uighur (PRC) */ + {0x0481, "mi"}, /* Maori (New Zealand) */ +//{0x0482, ""}, /* Occitan (France) */ +//{0x0483, ""}, /* Corsican (France) */ +//{0x0484, ""}, /* Alsatian (France) */ +//{0x0485, ""}, /* Yakut (Russia) */ +//{0x0486, ""}, /* K'iche (Guatemala) */ +//{0x0487, ""}, /* Kinyarwanda (Rwanda) */ +//{0x0488, ""}, /* Wolof (Senegal) */ +//{0x048C, ""}, /* Dari (Afghanistan) */ + {0x0801, "ar"}, /* Arabic (Iraq) */ + {0x0804, "zh-cn"}, /* Chinese (People’s Republic of China) */ + {0x0807, "de"}, /* German (Switzerland) */ + {0x0809, "en"}, /* English (United Kingdom) */ + {0x080A, "es"}, /* Spanish (Mexico) */ + {0x080C, "fr"}, /* French (Belgium) */ + {0x0810, "it"}, /* Italian (Switzerland) */ + {0x0812, "ko"}, /* ??? */ + {0x0813, "nl"}, /* Dutch (Belgium) */ + {0x0814, "nn"}, /* Norwegian (Nynorsk) (Norway) */ + {0x0816, "pt"}, /* Portuguese (Portugal) */ + {0x0818, "mo"}, /* ??? */ + {0x0819, "ru"}, /* ??? */ + {0x081A, "sr"}, /* Serbian (Latin) (Serbia) */ + {0x081D, "sv"}, /* Sweden (Finland) */ + {0x0820, "ur"}, /* ??? */ + {0x0827, "lt"}, /* ??? */ + {0x082C, "az"}, /* Azeri (Cyrillic) (Azerbaijan) */ +//{0x082E, ""}, /* Lower Sorbian (Germany) */ +//{0x083B, ""}, /* Sami (Northern) (Sweden) */ + {0x083C, "gd"}, /* Irish (Ireland) */ + {0x083E, "ms"}, /* Malay (Brunei Darussalam) */ + {0x0843, "uz"}, /* Uzbek (Cyrillic) (Uzbekistan) */ + {0x0845, "bn"}, /* Bengali (Bangladesh) */ + {0x0846, "ar"}, /* ??? */ +//{0x0850, ""}, /* Mongolian (Traditional) (People’s Republic of China) */ + {0x0851, "dz"}, /* ??? */ +//{0x085D, ""}, /* Inuktitut (Latin) (Canada) */ +//{0x085F, ""}, /* Tamazight (Latin) (Algeria) */ + {0x0861, "ne"}, /* ??? */ +//{0x086B, ""}, /* Quechua (Ecuador) */ + {0x0873, "ti"}, /* ??? */ + {0x0C01, "ar"}, /* Arabic (Egypt) */ + {0x0C04, "zh-hk"}, /* Chinese (Hong Kong S.A.R.) */ + {0x0C07, "de"}, /* German (Austria) */ + {0x0C09, "en"}, /* English (Australia) */ +//{0x0C0A, ""}, /* Spanish (Modern Sort) (Spain) */ + {0x0C0C, "fr"}, /* French (Canada) */ + {0x0C1A, "sr"}, /* Serbian (Cyrillic) (Serbia) */ +//{0x0C3B, ""}, /* Sami (Northern) (Finland) */ +//{0x0C6B, ""}, /* Quechua (Peru) */ + {0x1001, "ar"}, /* Arabic (Libya) */ + {0x1004, "zh-sg"}, /* Chinese (Singapore) */ + {0x1007, "de"}, /* German (Luxembourg) */ + {0x1009, "en"}, /* English (Canada) */ + {0x100A, "es"}, /* Spanish (Guatemala) */ + {0x100C, "fr"}, /* French (Switzerland) */ +//{0x101A, ""}, /* Croatian (Latin) (Bosnia and Herzegovina) */ +//{0x103B, ""}, /* Sami (Lule) (Norway) */ + {0x1401, "ar"}, /* Arabic (Algeria) */ +//{0x1404, ""}, /* Chinese (Macao S.A.R.) */ +//{0x1407, ""}, /* German (Liechtenstein) */ + {0x1409, "en"}, /* English (New Zealand) */ + {0x140A, "es"}, /* Spanish (Costa Rica) */ + {0x140C, "fr"}, /* ??? */ +//{0x140c, ""}, /* French (Luxembourg) */ + {0x141A, "bs"}, /* Bosnian (Latin) (Bosnia and Herzegovina) */ +//{0x143B, ""}, /* Sami (Lule) (Sweden) */ + {0x1801, "ar"}, /* Arabic (Morocco) */ + {0x1809, "en"}, /* English (Ireland) */ + {0x180A, "es"}, /* Spanish (Panama) */ + {0x180C, "fr"}, /* French (Principality of Monaco) */ +//{0x181A, ""}, /* Serbian (Latin) (Bosnia and Herzegovina) */ +//{0x183B, ""}, /* Sami (Southern) (Norway) */ + {0x1C01, "ar"}, /* Arabic (Tunisia) */ + {0x1C09, "en"}, /* English (South Africa) */ + {0x1C0A, "es"}, /* Spanish (Dominican Republic) */ + {0x1C0C, "fr"}, /* ??? */ +//{0x1C1A, ""}, /* Serbian (Cyrillic) (Bosnia and Herzegovina) */ +//{0x1C3B, ""}, /* Sami (Southern) (Sweden) */ + {0x2001, "ar"}, /* Arabic (Oman) */ + {0x2009, "en"}, /* English (Jamaica) */ + {0x200A, "es"}, /* Spanish (Venezuela) */ + {0x200C, "fr"}, /* ??? */ +//{0x201A, ""}, /* Bosnian (Cyrillic) (Bosnia and Herzegovina) */ +//{0x203B, ""}, /* Sami (Skolt) (Finland) */ + {0x2401, "ar"}, /* Arabic (Yemen) */ + {0x2409, "en"}, /* English (Caribbean) */ + {0x240A, "es"}, /* Spanish (Colombia) */ + {0x240C, "fr"}, /* ??? */ +//{0x243B, ""}, /* Sami (Inari) (Finland) */ + {0x2801, "ar"}, /* Arabic (Syria) */ + {0x2809, "en"}, /* English (Belize) */ + {0x280A, "es"}, /* Spanish (Peru) */ + {0x280C, "fr"}, /* ??? */ + {0x2C01, "ar"}, /* Arabic (Jordan) */ + {0x2C09, "en"}, /* English (Trinidad and Tobago) */ + {0x2C0A, "es"}, /* Spanish (Argentina) */ + {0x2C0C, "fr"}, /* ??? */ + {0x3001, "ar"}, /* Arabic (Lebanon) */ + {0x3009, "en"}, /* English (Zimbabwe) */ + {0x300A, "es"}, /* Spanish (Ecuador) */ + {0x300C, "fr"}, /* ??? */ + {0x3401, "ar"}, /* Arabic (Kuwait) */ + {0x3409, "en"}, /* English (Republic of the Philippines) */ + {0x340A, "es"}, /* Spanish (Chile) */ + {0x340C, "fr"}, /* ??? */ + {0x3801, "ar"}, /* Arabic (U.A.E.) */ + {0x380A, "es"}, /* Spanish (Uruguay) */ + {0x380C, "fr"}, /* ??? */ + {0x3C01, "ar"}, /* Arabic (Bahrain) */ + {0x3C09, "en"}, /* ??? */ + {0x3C0A, "es"}, /* Spanish (Paraguay) */ + {0x3C0C, "fr"}, /* ??? */ + {0x4001, "ar"}, /* Arabic (Qatar) */ + {0x4009, "en"}, /* English (India) */ + {0x400A, "es"}, /* Spanish (Bolivia) */ + {0x4409, "en"}, /* English (Malaysia) */ + {0x440A, "es"}, /* Spanish (El Salvador) */ + {0x4809, "en"}, /* English (Singapore) */ + {0x480A, "es"}, /* Spanish (Honduras) */ + {0x4C0A, "es"}, /* Spanish (Nicaragua) */ + {0x500A, "es"}, /* Spanish (Puerto Rico) */ + {0x540A, "es"}, /* Spanish (United States) */ + {0xE40A, "es"}, /* ??? */ + {0xE40C, "fr"}, /* ??? */ }; static const hb_ot_language_map_t hb_mac_language_map[] = { - {0, "en"}, /* English */ - {1, "fr"}, /* French */ - {2, "de"}, /* German */ - {3, "it"}, /* Italian */ - {4, "nl"}, /* Dutch */ - {5, "sv"}, /* Swedish */ - {6, "es"}, /* Spanish */ - {7, "da"}, /* Danish */ - {8, "pt"}, /* Portuguese */ - {9, "no"}, /* Norwegian */ - {10, "he"}, /* Hebrew */ - {11, "ja"}, /* Japanese */ - {12, "ar"}, /* Arabic */ - {13, "fi"}, /* Finnish */ - {14, "el"}, /* Greek */ - {15, "is"}, /* Icelandic */ - {16, "mt"}, /* Maltese */ - {17, "tr"}, /* Turkish */ - {18, "hr"}, /* Croatian */ - {19, "zh-tw"}, /* Chinese (Traditional) */ - {20, "ur"}, /* Urdu */ - {21, "hi"}, /* Hindi */ - {22, "th"}, /* Thai */ - {23, "ko"}, /* Korean */ - {24, "lt"}, /* Lithuanian */ - {25, "pl"}, /* Polish */ - {26, "hu"}, /* Hungarian */ - {27, "et"}, /* Estonian */ - {28, "lv"}, /* Latvian */ - {30, "fo"}, /* Faroese */ - {31, "fa"}, /* Farsi/Persian */ - {32, "ru"}, /* Russian */ - {33, "zh-cn"}, /* Chinese (Simplified) */ - {34, "nl"}, /* Flemish */ - {35, "ga"}, /* Irish Gaelic */ - {36, "sq"}, /* Albanian */ - {37, "ro"}, /* Romanian */ - {38, "cs"}, /* Czech */ - {39, "sk"}, /* Slovak */ - {40, "sl"}, /* Slovenian */ - {41, "yi"}, /* Yiddish */ - {42, "sr"}, /* Serbian */ - {43, "mk"}, /* Macedonian */ - {44, "bg"}, /* Bulgarian */ - {45, "uk"}, /* Ukrainian */ - {46, "be"}, /* Byelorussian */ - {47, "uz"}, /* Uzbek */ - {48, "kk"}, /* Kazakh */ - {49, "az"}, /* Azerbaijani (Cyrillic script) */ - {49, "az"}, /* Azerbaijani (Cyrillic script) */ - {50, "ar"}, /* Azerbaijani (Arabic script) */ - {51, "hy"}, /* Armenian */ - {52, "ka"}, /* Georgian */ - {53, "mo"}, /* Moldavian */ - {54, "ky"}, /* Kirghiz */ - {55, "tg"}, /* Tajiki */ - {56, "tk"}, /* Turkmen */ - {57, "mo"}, /* Mongolian (Mongolian script) */ - {57, "mo"}, /* Mongolian (Mongolian script) */ - {58, "mo"}, /* Mongolian (Cyrillic script) */ - {59, "ps"}, /* Pashto */ - {60, "ku"}, /* Kurdish */ - {61, "ks"}, /* Kashmiri */ - {62, "sd"}, /* Sindhi */ - {63, "bo"}, /* Tibetan */ - {64, "ne"}, /* Nepali */ - {65, "sa"}, /* Sanskrit */ - {66, "mr"}, /* Marathi */ - {67, "bn"}, /* Bengali */ - {68, "as"}, /* Assamese */ - {69, "gu"}, /* Gujarati */ - {70, "pa"}, /* Punjabi */ - {71, "or"}, /* Oriya */ - {72, "ml"}, /* Malayalam */ - {73, "kn"}, /* Kannada */ - {74, "ta"}, /* Tamil */ - {75, "te"}, /* Telugu */ - {76, "si"}, /* Sinhalese */ - {77, "my"}, /* Burmese */ - {78, "km"}, /* Khmer */ - {79, "lo"}, /* Lao */ - {80, "vi"}, /* Vietnamese */ - {81, "id"}, /* Indonesian */ - {82, "tl"}, /* Tagalog */ - {83, "ms"}, /* Malay (Roman script) */ - {84, "ms"}, /* Malay (Arabic script) */ - {85, "am"}, /* Amharic */ - {86, "ti"}, /* Tigrinya */ - {87, "om"}, /* Galla */ - {88, "so"}, /* Somali */ - {89, "sw"}, /* Swahili */ - {90, "rw"}, /* Kinyarwanda/Ruanda */ - {91, "rn"}, /* Rundi */ - {92, "ny"}, /* Nyanja/Chewa */ - {93, "mg"}, /* Malagasy */ - {94, "eo"}, /* Esperanto */ - {128, "cy"}, /* Welsh */ - {129, "eu"}, /* Basque */ - {130, "ca"}, /* Catalan */ - {131, "la"}, /* Latin */ - {132, "qu"}, /* Quechua */ - {133, "gn"}, /* Guarani */ - {134, "ay"}, /* Aymara */ - {135, "tt"}, /* Tatar */ - {136, "ug"}, /* Uighur */ - {137, "dz"}, /* Dzongkha */ - {138, "jw"}, /* Javanese (Roman script) */ - {139, "su"}, /* Sundanese (Roman script) */ - {140, "gl"}, /* Galician */ - {141, "af"}, /* Afrikaans */ - {142, "br"}, /* Breton */ - {143, "iu"}, /* Inuktitut */ - {144, "gd"}, /* Scottish Gaelic */ - {145, "gv"}, /* Manx Gaelic */ - {146, "ga"}, /* Irish Gaelic (with dot above) */ - {147, "to"}, /* Tongan */ - {148, "el"}, /* Greek (polytonic) */ - {149, "ik"}, /* Greenlandic */ - {150, "az"}, /* Azerbaijani (Roman script) */ + { 0, "en"}, /* English */ + { 1, "fr"}, /* French */ + { 2, "de"}, /* German */ + { 3, "it"}, /* Italian */ + { 4, "nl"}, /* Dutch */ + { 5, "sv"}, /* Swedish */ + { 6, "es"}, /* Spanish */ + { 7, "da"}, /* Danish */ + { 8, "pt"}, /* Portuguese */ + { 9, "no"}, /* Norwegian */ + { 10, "he"}, /* Hebrew */ + { 11, "ja"}, /* Japanese */ + { 12, "ar"}, /* Arabic */ + { 13, "fi"}, /* Finnish */ + { 14, "el"}, /* Greek */ + { 15, "is"}, /* Icelandic */ + { 16, "mt"}, /* Maltese */ + { 17, "tr"}, /* Turkish */ + { 18, "hr"}, /* Croatian */ + { 19, "zh-tw"}, /* Chinese (Traditional) */ + { 20, "ur"}, /* Urdu */ + { 21, "hi"}, /* Hindi */ + { 22, "th"}, /* Thai */ + { 23, "ko"}, /* Korean */ + { 24, "lt"}, /* Lithuanian */ + { 25, "pl"}, /* Polish */ + { 26, "hu"}, /* Hungarian */ + { 27, "et"}, /* Estonian */ + { 28, "lv"}, /* Latvian */ +//{ 29, ""}, /* Sami */ + { 30, "fo"}, /* Faroese */ + { 31, "fa"}, /* Farsi/Persian */ + { 32, "ru"}, /* Russian */ + { 33, "zh-cn"}, /* Chinese (Simplified) */ + { 34, "nl"}, /* Flemish */ + { 35, "ga"}, /* Irish Gaelic */ + { 36, "sq"}, /* Albanian */ + { 37, "ro"}, /* Romanian */ + { 38, "cs"}, /* Czech */ + { 39, "sk"}, /* Slovak */ + { 40, "sl"}, /* Slovenian */ + { 41, "yi"}, /* Yiddish */ + { 42, "sr"}, /* Serbian */ + { 43, "mk"}, /* Macedonian */ + { 44, "bg"}, /* Bulgarian */ + { 45, "uk"}, /* Ukrainian */ + { 46, "be"}, /* Byelorussian */ + { 47, "uz"}, /* Uzbek */ + { 48, "kk"}, /* Kazakh */ + { 49, "az"}, /* Azerbaijani (Cyrillic script) */ + { 50, "ar"}, /* Azerbaijani (Arabic script) */ + { 51, "hy"}, /* Armenian */ + { 52, "ka"}, /* Georgian */ + { 53, "mo"}, /* Moldavian */ + { 54, "ky"}, /* Kirghiz */ + { 55, "tg"}, /* Tajiki */ + { 56, "tk"}, /* Turkmen */ + { 57, "mo"}, /* Mongolian (Mongolian script) */ + { 58, "mo"}, /* Mongolian (Cyrillic script) */ + { 59, "ps"}, /* Pashto */ + { 60, "ku"}, /* Kurdish */ + { 61, "ks"}, /* Kashmiri */ + { 62, "sd"}, /* Sindhi */ + { 63, "bo"}, /* Tibetan */ + { 64, "ne"}, /* Nepali */ + { 65, "sa"}, /* Sanskrit */ + { 66, "mr"}, /* Marathi */ + { 67, "bn"}, /* Bengali */ + { 68, "as"}, /* Assamese */ + { 69, "gu"}, /* Gujarati */ + { 70, "pa"}, /* Punjabi */ + { 71, "or"}, /* Oriya */ + { 72, "ml"}, /* Malayalam */ + { 73, "kn"}, /* Kannada */ + { 74, "ta"}, /* Tamil */ + { 75, "te"}, /* Telugu */ + { 76, "si"}, /* Sinhalese */ + { 77, "my"}, /* Burmese */ + { 78, "km"}, /* Khmer */ + { 79, "lo"}, /* Lao */ + { 80, "vi"}, /* Vietnamese */ + { 81, "id"}, /* Indonesian */ + { 82, "tl"}, /* Tagalog */ + { 83, "ms"}, /* Malay (Roman script) */ + { 84, "ms"}, /* Malay (Arabic script) */ + { 85, "am"}, /* Amharic */ + { 86, "ti"}, /* Tigrinya */ + { 87, "om"}, /* Galla */ + { 88, "so"}, /* Somali */ + { 89, "sw"}, /* Swahili */ + { 90, "rw"}, /* Kinyarwanda/Ruanda */ + { 91, "rn"}, /* Rundi */ + { 92, "ny"}, /* Nyanja/Chewa */ + { 93, "mg"}, /* Malagasy */ + { 94, "eo"}, /* Esperanto */ + {128, "cy"}, /* Welsh */ + {129, "eu"}, /* Basque */ + {130, "ca"}, /* Catalan */ + {131, "la"}, /* Latin */ + {132, "qu"}, /* Quechua */ + {133, "gn"}, /* Guarani */ + {134, "ay"}, /* Aymara */ + {135, "tt"}, /* Tatar */ + {136, "ug"}, /* Uighur */ + {137, "dz"}, /* Dzongkha */ + {138, "jw"}, /* Javanese (Roman script) */ + {139, "su"}, /* Sundanese (Roman script) */ + {140, "gl"}, /* Galician */ + {141, "af"}, /* Afrikaans */ + {142, "br"}, /* Breton */ + {143, "iu"}, /* Inuktitut */ + {144, "gd"}, /* Scottish Gaelic */ + {145, "gv"}, /* Manx Gaelic */ + {146, "ga"}, /* Irish Gaelic (with dot above) */ + {147, "to"}, /* Tongan */ + {148, "el"}, /* Greek (polytonic) */ + {149, "ik"}, /* Greenlandic */ + {150, "az"}, /* Azerbaijani (Roman script) */ }; From c442fd9a10b3e91ab18720188afff08325adf6dc Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 23 Oct 2018 22:45:45 -0700 Subject: [PATCH 053/255] [name] Add src/test-name-table tool to show all font names --- src/Makefile.am | 17 +++++++---- src/test-name-table.cc | 67 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 src/test-name-table.cc diff --git a/src/Makefile.am b/src/Makefile.am index ac03890b3..fab703a11 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -348,6 +348,7 @@ noinst_PROGRAMS = \ main \ test \ test-buffer-serialize \ + test-name-table \ test-size-params \ test-would-substitute \ $(NULL) @@ -361,17 +362,21 @@ test_SOURCES = test.cc test_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS) test_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS) -test_would_substitute_SOURCES = test-would-substitute.cc -test_would_substitute_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS) -test_would_substitute_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS) +test_buffer_serialize_SOURCES = test-buffer-serialize.cc +test_buffer_serialize_CPPFLAGS = $(HBCFLAGS) +test_buffer_serialize_LDADD = libharfbuzz.la $(HBLIBS) + +test_name_table_SOURCES = test-name-table.cc +test_name_table_CPPFLAGS = $(HBCFLAGS) +test_name_table_LDADD = libharfbuzz.la $(HBLIBS) test_size_params_SOURCES = test-size-params.cc test_size_params_CPPFLAGS = $(HBCFLAGS) test_size_params_LDADD = libharfbuzz.la $(HBLIBS) -test_buffer_serialize_SOURCES = test-buffer-serialize.cc -test_buffer_serialize_CPPFLAGS = $(HBCFLAGS) -test_buffer_serialize_LDADD = libharfbuzz.la $(HBLIBS) +test_would_substitute_SOURCES = test-would-substitute.cc +test_would_substitute_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS) +test_would_substitute_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS) dist_check_SCRIPTS = \ check-c-linkage-decls.sh \ diff --git a/src/test-name-table.cc b/src/test-name-table.cc new file mode 100644 index 000000000..66596fe47 --- /dev/null +++ b/src/test-name-table.cc @@ -0,0 +1,67 @@ +/* + * Copyright © 2018 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#include "hb.h" +#include "hb-ot.h" + +#include +#include + +int +main (int argc, char **argv) +{ + if (argc != 2) { + fprintf (stderr, "usage: %s font-file\n", argv[0]); + exit (1); + } + + hb_blob_t *blob = hb_blob_create_from_file (argv[1]); + hb_face_t *face = hb_face_create (blob, 0 /* first face */); + hb_blob_destroy (blob); + blob = nullptr; + + const hb_ot_name_entry_t *entries; + unsigned int count = hb_ot_name_get_names (face, &entries); + + for (unsigned int i = 0; i < count; i++) + { + printf ("%d %s ", + entries[i].name_id, + hb_language_to_string (entries[i].language)); + + char buf[64]; + unsigned int buf_size = sizeof (buf); + hb_ot_name_get_utf8 (face, + entries[i].name_id, + entries[i].language, + &buf_size, + buf); + + printf ("%s\n", buf); + } + + return count ? 0 : 1; +} From a53d301b1c9f72cb42cc0fc321e2ad4dbac8e064 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 23 Oct 2018 23:05:55 -0700 Subject: [PATCH 054/255] [name] Minor --- src/hb-ot-name-table.hh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index be9c5e365..9b2835529 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -156,7 +156,7 @@ struct name { const hb_array_t all_names (nameRecordZ.arrayZ, count); const NameRecord &record = all_names[idx]; - return hb_bytes_t ((char *) this + stringOffset + record.offset, record.length); + return hb_bytes_t ((const char *) (this+stringOffset).arrayZ + record.offset, record.length); } inline unsigned int get_size (void) const @@ -164,7 +164,7 @@ struct name inline bool sanitize_records (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - char *string_pool = (char *) this + stringOffset; + const void *string_pool = (this+stringOffset).arrayZ; unsigned int _count = count; /* Move to run-time?! */ for (unsigned int i = 0; i < _count; i++) @@ -256,7 +256,8 @@ struct name /* We only implement format 0 for now. */ HBUINT16 format; /* Format selector (=0/1). */ HBUINT16 count; /* Number of name records. */ - Offset16 stringOffset; /* Offset to start of string storage (from start of table). */ + OffsetTo, HBUINT16, false> + stringOffset; /* Offset to start of string storage (from start of table). */ UnsizedArrayOf nameRecordZ; /* The name records where count is the number of records. */ public: From dc9a5f88b401fcad598946fcf735010c563741ac Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 23 Oct 2018 23:16:06 -0700 Subject: [PATCH 055/255] [name] Do record sanitization at run-time --- src/hb-dsalgs.hh | 66 ++++++++++++++++++++++------------------- src/hb-ot-name-table.hh | 22 +++++++++----- src/hb-ot-name.cc | 2 +- 3 files changed, 51 insertions(+), 39 deletions(-) diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index 265651b7f..837bb86bf 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -530,36 +530,6 @@ struct hb_auto_t : Type void fini (void) {} }; -template -struct hb_array_t -{ - inline hb_array_t (void) : arrayZ (nullptr), len (0) {} - inline hb_array_t (T *array_, unsigned int len_) : arrayZ (array_), len (len_) {} - - inline T& operator [] (unsigned int i) const - { - if (unlikely (i >= len)) return Null(T); - return arrayZ[i]; - } - - inline hb_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const - { - unsigned int count = len; - if (unlikely (start_offset > count)) - count = 0; - else - count -= start_offset; - count = MIN (count, seg_count); - return hb_array_t (arrayZ + start_offset, count); - } - - inline void free (void) { ::free ((void *) arrayZ); arrayZ = nullptr; len = 0; } - - T *arrayZ; - unsigned int len; -}; -template static inline -hb_array_t hb_array (T *array, unsigned int len) { return hb_array_t (array, len); } struct hb_bytes_t { @@ -589,6 +559,42 @@ struct hb_bytes_t unsigned int len; }; +template +struct hb_array_t +{ + inline hb_array_t (void) : arrayZ (nullptr), len (0) {} + inline hb_array_t (T *array_, unsigned int len_) : arrayZ (array_), len (len_) {} + + inline T& operator [] (unsigned int i) const + { + if (unlikely (i >= len)) return Null(T); + return arrayZ[i]; + } + + inline hb_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const + { + unsigned int count = len; + if (unlikely (start_offset > count)) + count = 0; + else + count -= start_offset; + count = MIN (count, seg_count); + return hb_array_t (arrayZ + start_offset, count); + } + + inline hb_bytes_t as_bytes (void) const + { + return hb_bytes_t (arrayZ, len * sizeof (T)); + } + + inline void free (void) { ::free ((void *) arrayZ); arrayZ = nullptr; len = 0; } + + T *arrayZ; + unsigned int len; +}; +template static inline +hb_array_t hb_array (T *array, unsigned int len) { return hb_array_t (array, len); } + struct HbOpOr { diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 9b2835529..f42c0db83 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -152,13 +152,6 @@ struct name { static const hb_tag_t tableTag = HB_OT_TAG_name; - inline hb_bytes_t get_name (unsigned int idx) const - { - const hb_array_t all_names (nameRecordZ.arrayZ, count); - const NameRecord &record = all_names[idx]; - return hb_bytes_t ((const char *) (this+stringOffset).arrayZ + record.offset, record.length); - } - inline unsigned int get_size (void) const { return min_size + count * nameRecordZ[0].min_size; } @@ -178,7 +171,7 @@ struct name return_trace (c->check_struct (this) && likely (format == 0 || format == 1) && c->check_array (nameRecordZ.arrayZ, count) && - sanitize_records (c)); + c->check_range (this, stringOffset)); } struct accelerator_t @@ -187,6 +180,9 @@ struct name { this->blob = hb_sanitize_context_t().reference_table (face); this->table = this->blob->as (); + assert (this->blob->length >= this->table->stringOffset); + this->pool = (this->table+this->table->stringOffset).arrayZ; + this->pool_len = this->blob->length - this->table->stringOffset; const hb_array_t all_names (this->table->nameRecordZ.arrayZ, this->table->count); @@ -246,8 +242,18 @@ struct name return entry->entry_index; } + inline hb_bytes_t get_name (unsigned int idx) const + { + const hb_array_t all_names (table->nameRecordZ.arrayZ, table->count); + const NameRecord &record = all_names[idx]; + const hb_array_t string_pool ((const char *) pool, pool_len); + return string_pool.sub_array (record.offset, record.length).as_bytes (); + } + private: hb_blob_t *blob; + const void *pool; + unsigned int pool_len; public: const name *table; hb_vector_t names; diff --git a/src/hb-ot-name.cc b/src/hb-ot-name.cc index 7962d8b89..ec3d87946 100644 --- a/src/hb-ot-name.cc +++ b/src/hb-ot-name.cc @@ -110,7 +110,7 @@ hb_ot_name_get_utf (hb_face_t *face, int idx = name.get_index (name_id, language, &width); if (idx != -1) { - hb_bytes_t bytes = name.table->get_name (idx); + hb_bytes_t bytes = name.get_name (idx); if (width == 2) /* UTF16-BE */ return hb_ot_name_convert_utf (&bytes, text_size, text); From 327546e633b590d6dedfb901810ccf490a0bf922 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 23 Oct 2018 23:33:44 -0700 Subject: [PATCH 056/255] [name] Hook up ltag table --- src/hb-aat-layout.cc | 15 ++++++++++++++- src/hb-aat-layout.hh | 5 +++++ src/hb-aat-ltag-table.hh | 17 +++++++++++++++-- src/hb-ot-face.hh | 3 ++- src/hb-ot-name-table.hh | 9 +++++---- 5 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index 1e1c7b4f4..ec053938f 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -34,7 +34,7 @@ #include "hb-aat-layout-kerx-table.hh" #include "hb-aat-layout-morx-table.hh" #include "hb-aat-layout-trak-table.hh" -#include "hb-aat-ltag-table.hh" // Just so we compile it; unused otherwise. +#include "hb-aat-ltag-table.hh" /* Table data courtesy of Apple. Converted from mnemonics to integers @@ -181,6 +181,12 @@ _get_trak (hb_face_t *face) if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(AAT::trak); return *(hb_ot_face_data (face)->trak.get ()); } +static inline const AAT::ltag& +_get_ltag (hb_face_t *face) +{ + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(AAT::ltag); + return *(hb_ot_face_data (face)->ltag.get ()); +} void @@ -248,3 +254,10 @@ hb_aat_layout_track (hb_ot_shape_plan_t *plan, AAT::hb_aat_apply_context_t c (plan, font, buffer); trak.apply (&c); } + +hb_language_t +_hb_aat_language_get (hb_face_t *face, + unsigned int i) +{ + return _get_ltag (face).get_language (i); +} diff --git a/src/hb-aat-layout.hh b/src/hb-aat-layout.hh index aea545689..8a558e6aa 100644 --- a/src/hb-aat-layout.hh +++ b/src/hb-aat-layout.hh @@ -80,4 +80,9 @@ hb_aat_layout_track (hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); +HB_INTERNAL hb_language_t +_hb_aat_language_get (hb_face_t *face, + unsigned int i); + + #endif /* HB_AAT_LAYOUT_HH */ diff --git a/src/hb-aat-ltag-table.hh b/src/hb-aat-ltag-table.hh index 08a1b51a9..8a42b3510 100644 --- a/src/hb-aat-ltag-table.hh +++ b/src/hb-aat-ltag-table.hh @@ -25,7 +25,7 @@ #ifndef HB_AAT_LTAG_TABLE_HH #define HB_AAT_LTAG_TABLE_HH -#include "hb-aat-layout-common.hh" +#include "hb-open-type.hh" /* * ltag -- Language Tag @@ -36,9 +36,13 @@ namespace AAT { +using namespace OT; + struct FTStringRange { + friend struct ltag; + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -58,10 +62,19 @@ struct ltag { static const hb_tag_t tableTag = HB_AAT_TAG_ltag; + inline hb_language_t get_language (unsigned int i) const + { + const FTStringRange &range = tagRanges[i]; + return hb_language_from_string ((const char *) (this+range.tag).arrayZ, + range.length); + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && tagRanges.sanitize (c, this))); + return_trace (likely (c->check_struct (this) && + version >= 1 && + tagRanges.sanitize (c, this))); } protected: diff --git a/src/hb-ot-face.hh b/src/hb-ot-face.hh index c810e9fb4..4c84f0a5f 100644 --- a/src/hb-ot-face.hh +++ b/src/hb-ot-face.hh @@ -66,10 +66,11 @@ HB_OT_ACCELERATOR(OT, hmtx) \ HB_OT_ACCELERATOR(OT, vmtx) \ HB_OT_ACCELERATOR(OT, post) \ - HB_OT_ACCELERATOR(OT, name) \ HB_OT_ACCELERATOR(OT, kern) \ HB_OT_ACCELERATOR(OT, glyf) \ HB_OT_TABLE(OT, VORG) \ + HB_OT_ACCELERATOR(OT, name) \ + HB_OT_TABLE(AAT, ltag) \ /* OpenType color fonts. */ \ HB_OT_TABLE(OT, COLR) \ HB_OT_TABLE(OT, CPAL) \ diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index f42c0db83..e58090848 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -29,6 +29,7 @@ #include "hb-open-type.hh" #include "hb-ot-name-language.hh" +#include "hb-aat-layout.hh" namespace OT { @@ -48,7 +49,7 @@ namespace OT { struct NameRecord { - inline hb_language_t language (void) const + inline hb_language_t language (hb_face_t *face) const { unsigned int p = platformID; unsigned int l = languageID; @@ -59,8 +60,8 @@ struct NameRecord if (p == 1) return _hb_ot_name_language_for_mac_code (l); - //if (p == 0) - /* TODO use 'ltag' table? */ + if (p == 0) + return _hb_aat_language_get (face, l); return HB_LANGUAGE_INVALID; } @@ -194,7 +195,7 @@ struct name hb_ot_name_entry_t *entry = this->names.push (); entry->name_id = all_names[i].nameID; - entry->language = all_names[i].language (); + entry->language = all_names[i].language (face); entry->entry_score = all_names[i].score (); entry->entry_index = i; } From ce81c7429810ad3902c37e50016ca54b9bae6f91 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Oct 2018 12:34:03 -0700 Subject: [PATCH 057/255] [utf] Fix ASCII --- src/hb-utf.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-utf.hh b/src/hb-utf.hh index f78d54995..52bc8b76a 100644 --- a/src/hb-utf.hh +++ b/src/hb-utf.hh @@ -410,7 +410,7 @@ struct hb_ascii_t hb_codepoint_t replacement HB_UNUSED) { *unicode = *text++; - if (*unicode >= 0x100) + if (*unicode >= 0x0080u) *unicode = replacement; return text; } @@ -422,7 +422,7 @@ struct hb_ascii_t hb_codepoint_t replacement) { *unicode = *--text; - if (*unicode >= 0x0080) + if (*unicode >= 0x0080u) *unicode = replacement; return text; } From 2c39f359e4a7312e3b518f76815d79e42ee96a32 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Oct 2018 12:34:30 -0700 Subject: [PATCH 058/255] [utf] Remove unused typedef --- src/hb-utf.hh | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hb-utf.hh b/src/hb-utf.hh index 52bc8b76a..b45bcd972 100644 --- a/src/hb-utf.hh +++ b/src/hb-utf.hh @@ -345,7 +345,6 @@ struct hb_utf32_xe_t typedef hb_utf32_xe_t hb_utf32_t; typedef hb_utf32_xe_t hb_utf32_novalidate_t; -typedef hb_utf32_xe_t hb_utf32_be_t; struct hb_latin1_t From 622b014faf7bbe7a97f9aff959c434d1664c10d0 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Oct 2018 12:40:15 -0700 Subject: [PATCH 059/255] [name] Skip enumerating names with unknown language --- src/hb-ot-name-table.hh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index e58090848..b84edd185 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -206,7 +206,8 @@ struct name unsigned int j = 0; for (unsigned int i = 0; i < this->names.len; i++) { - if (this->names[i].entry_score == UNSUPPORTED) + if (this->names[i].entry_score == UNSUPPORTED || + this->names[i].language == HB_LANGUAGE_INVALID) continue; if (i && this->names[i - 1].name_id == this->names[i].name_id && From 20d0171d20cf9f3f93bdd6878bbc1d7d8329e75f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Oct 2018 13:20:19 -0700 Subject: [PATCH 060/255] [name] Fill out most missing language codes --- src/hb-ot-name-language.cc | 114 +++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 56 deletions(-) diff --git a/src/hb-ot-name-language.cc b/src/hb-ot-name-language.cc index 8b79d4d6d..0e37e0acb 100644 --- a/src/hb-ot-name-language.cc +++ b/src/hb-ot-name-language.cc @@ -27,7 +27,10 @@ #include "hb-ot-name-language.hh" /* Following two tables were generated by joining FreeType, FontConfig, - * and OpenType specification language lists. */ + * and OpenType specification language lists, then filled in missing + * entries using: + * https://docs.microsoft.com/en-us/windows/desktop/intl/language-identifier-constants-and-strings + */ struct hb_ot_language_map_t { @@ -50,7 +53,7 @@ hb_ms_language_map[] = {0x0009, "en"}, /* ??? */ {0x0401, "ar"}, /* Arabic (Saudi Arabia) */ {0x0402, "bg"}, /* Bulgarian (Bulgaria) */ -//{0x0403, ""}, /* Catalan (Catalan) */ + {0x0403, "ca"}, /* Catalan (Catalan) */ {0x0404, "zh-tw"}, /* Chinese (Taiwan) */ {0x0405, "cs"}, /* Czech (Czech Republic) */ {0x0406, "da"}, /* Danish (Denmark) */ @@ -65,12 +68,12 @@ hb_ms_language_map[] = {0x040F, "is"}, /* Icelandic (Iceland) */ {0x0410, "it"}, /* Italian (Italy) */ {0x0411, "ja"}, /* Japanese (Japan) */ -//{0x0412, ""}, /* Korean (Korea) */ + {0x0412, "ko"}, /* Korean (Korea) */ {0x0413, "nl"}, /* Dutch (Netherlands) */ {0x0414, "no"}, /* Norwegian (Bokmal) (Norway) */ {0x0415, "pl"}, /* Polish (Poland) */ {0x0416, "pt"}, /* Portuguese (Brazil) */ -//{0x0417, ""}, /* Romansh (Switzerland) */ + {0x0417, "rm"}, /* Romansh (Switzerland) */ {0x0418, "ro"}, /* Romanian (Romania) */ {0x0419, "ru"}, /* Russian (Russia) */ {0x041A, "hr"}, /* Croatian (Croatia) */ @@ -83,24 +86,24 @@ hb_ms_language_map[] = {0x0421, "id"}, /* Indonesian (Indonesia) */ {0x0422, "uk"}, /* Ukrainian (Ukraine) */ {0x0423, "be"}, /* Belarusian (Belarus) */ -//{0x0424, ""}, /* Slovenian (Slovenia) */ + {0x0424, "sl"}, /* Slovenian (Slovenia) */ {0x0425, "et"}, /* Estonian (Estonia) */ {0x0426, "lv"}, /* Latvian (Latvia) */ {0x0427, "lt"}, /* Lithuanian (Lithuania) */ {0x0428, "tg"}, /* Tajik (Cyrillic) (Tajikistan) */ - {0x0429, "fa"}, /* ??? */ + {0x0429, "fa"}, /* Persian (Iran) */ {0x042A, "vi"}, /* Vietnamese (Vietnam) */ {0x042B, "hy"}, /* Armenian (Armenia) */ {0x042C, "az"}, /* Azeri (Latin) (Azerbaijan) */ -//{0x042D, ""}, /* Basque (Basque) */ -//{0x042E, ""}, /* Upper Sorbian (Germany) */ + {0x042D, "eu"}, /* Basque (Basque) */ + {0x042E, "hsb"}, /* Upper Sorbian (Germany) */ {0x042F, "mk"}, /* Macedonian (FYROM) (Former Yugoslav Republic of Macedonia) */ {0x0430, "st"}, /* ??? */ {0x0431, "ts"}, /* ??? */ -//{0x0432, ""}, /* Setswana (South Africa) */ + {0x0432, "tn"}, /* Setswana (South Africa) */ {0x0433, "ven"}, /* ??? */ -//{0x0434, ""}, /* isiXhosa (South Africa) */ -//{0x0435, ""}, /* isiZulu (South Africa) */ + {0x0434, "xh"}, /* isiXhosa (South Africa) */ + {0x0435, "zu"}, /* isiZulu (South Africa) */ {0x0436, "af"}, /* Afrikaans (South Africa) */ {0x0437, "ka"}, /* Georgian (Georgia) */ {0x0438, "fo"}, /* Faroese (Faroe Islands) */ @@ -110,16 +113,16 @@ hb_ms_language_map[] = {0x043C, "ga"}, /* ??? */ {0x043D, "yi"}, /* ??? */ {0x043E, "ms"}, /* Malay (Malaysia) */ -//{0x043F, ""}, /* Kazakh (Kazakhstan) */ -//{0x0440, ""}, /* Kyrgyz (Kyrgyzstan) */ -//{0x0441, ""}, /* Kiswahili (Kenya) */ + {0x043F, "kk"}, /* Kazakh (Kazakhstan) */ + {0x0440, "ky"}, /* Kyrgyz (Kyrgyzstan) */ + {0x0441, "sw"}, /* Kiswahili (Kenya) */ {0x0442, "tk"}, /* Turkmen (Turkmenistan) */ {0x0443, "uz"}, /* Uzbek (Latin) (Uzbekistan) */ -//{0x0444, ""}, /* Tatar (Russia) */ + {0x0444, "tt"}, /* Tatar (Russia) */ {0x0445, "bn"}, /* Bengali (India) */ {0x0446, "pa"}, /* Punjabi (India) */ {0x0447, "gu"}, /* Gujarati (India) */ -//{0x0448, ""}, /* Odia (formerly Oriya) (India) */ + {0x0448, "or"}, /* Odia (formerly Oriya) (India) */ {0x0449, "ta"}, /* Tamil (India) */ {0x044A, "te"}, /* Telugu (India) */ {0x044B, "kn"}, /* Kannada (India) */ @@ -128,17 +131,17 @@ hb_ms_language_map[] = {0x044E, "mr"}, /* Marathi (India) */ {0x044F, "sa"}, /* Sanskrit (India) */ {0x0450, "mn"}, /* Mongolian (Cyrillic) (Mongolia) */ -//{0x0451, ""}, /* Tibetan (PRC) */ -//{0x0452, ""}, /* Welsh (United Kingdom) */ + {0x0451, "bo"}, /* Tibetan (PRC) */ + {0x0452, "cy"}, /* Welsh (United Kingdom) */ {0x0453, "km"}, /* Khmer (Cambodia) */ {0x0454, "lo"}, /* Lao (Lao P.D.R.) */ {0x0455, "my"}, /* ??? */ -//{0x0456, ""}, /* Galician (Galician) */ + {0x0456, "gl"}, /* Galician (Galician) */ {0x0457, "kok"}, /* Konkani (India) */ {0x0458, "mni"}, /* ??? */ {0x0459, "sd"}, /* ??? */ {0x045A, "syr"}, /* Syriac (Syria) */ -//{0x045B, ""}, /* Sinhala (Sri Lanka) */ + {0x045B, "si"}, /* Sinhala (Sri Lanka) */ {0x045C, "chr"}, /* ??? */ {0x045D, "iu"}, /* Inuktitut (Canada) */ {0x045E, "am"}, /* Amharic (Ethiopia) */ @@ -150,11 +153,11 @@ hb_ms_language_map[] = {0x0465, "div"}, /* Divehi (Maldives) */ {0x0468, "ha"}, /* Hausa (Latin) (Nigeria) */ {0x046A, "yo"}, /* Yoruba (Nigeria) */ -//{0x046B, ""}, /* Quechua (Bolivia) */ -//{0x046C, ""}, /* Sesotho sa Leboa (South Africa) */ -//{0x046D, ""}, /* Bashkir (Russia) */ -//{0x046E, ""}, /* Luxembourgish (Luxembourg) */ -//{0x046F, ""}, /* Greenlandic (Greenland) */ + {0x046B, "quz"}, /* Quechua (Bolivia) */ + {0x046C, "nso"}, /* Sesotho sa Leboa (South Africa) */ + {0x046D, "ba"}, /* Bashkir (Russia) */ + {0x046E, "lb"}, /* Luxembourgish (Luxembourg) */ + {0x046F, "kl"}, /* Greenlandic (Greenland) */ {0x0470, "ibo"}, /* Igbo (Nigeria) */ {0x0471, "kau"}, /* ??? */ {0x0472, "om"}, /* ??? */ @@ -163,21 +166,21 @@ hb_ms_language_map[] = {0x0475, "haw"}, /* ??? */ {0x0476, "la"}, /* ??? */ {0x0477, "so"}, /* ??? */ -//{0x0478, ""}, /* Yi (PRC) */ + {0x0478, "ii"}, /* Yi (PRC) */ {0x0479, "pap"}, /* ??? */ -//{0x047A, ""}, /* Mapudungun (Chile) */ -//{0x047C, ""}, /* Mohawk (Mohawk) */ -//{0x047E, ""}, /* Breton (France) */ -//{0x0480, ""}, /* Uighur (PRC) */ + {0x047A, "arn"}, /* Mapudungun (Chile) */ + {0x047C, "moh"}, /* Mohawk (Mohawk) */ + {0x047E, "br"}, /* Breton (France) */ + {0x0480, "ug"}, /* Uighur (PRC) */ {0x0481, "mi"}, /* Maori (New Zealand) */ -//{0x0482, ""}, /* Occitan (France) */ -//{0x0483, ""}, /* Corsican (France) */ -//{0x0484, ""}, /* Alsatian (France) */ -//{0x0485, ""}, /* Yakut (Russia) */ -//{0x0486, ""}, /* K'iche (Guatemala) */ -//{0x0487, ""}, /* Kinyarwanda (Rwanda) */ -//{0x0488, ""}, /* Wolof (Senegal) */ -//{0x048C, ""}, /* Dari (Afghanistan) */ + {0x0482, "oc"}, /* Occitan (France) */ + {0x0483, "co"}, /* Corsican (France) */ + {0x0484, "gsw"}, /* Alsatian (France) */ + {0x0485, "sah"}, /* Yakut (Russia) */ + {0x0486, "qut"}, /* K'iche (Guatemala) */ + {0x0487, "rw"}, /* Kinyarwanda (Rwanda) */ + {0x0488, "wo"}, /* Wolof (Senegal) */ + {0x048C, "fa"}, /* Dari (Afghanistan) */ {0x0801, "ar"}, /* Arabic (Iraq) */ {0x0804, "zh-cn"}, /* Chinese (People’s Republic of China) */ {0x0807, "de"}, /* German (Switzerland) */ @@ -196,17 +199,17 @@ hb_ms_language_map[] = {0x0820, "ur"}, /* ??? */ {0x0827, "lt"}, /* ??? */ {0x082C, "az"}, /* Azeri (Cyrillic) (Azerbaijan) */ -//{0x082E, ""}, /* Lower Sorbian (Germany) */ + {0x082E, "dsb"}, /* Lower Sorbian (Germany) */ //{0x083B, ""}, /* Sami (Northern) (Sweden) */ {0x083C, "gd"}, /* Irish (Ireland) */ {0x083E, "ms"}, /* Malay (Brunei Darussalam) */ {0x0843, "uz"}, /* Uzbek (Cyrillic) (Uzbekistan) */ {0x0845, "bn"}, /* Bengali (Bangladesh) */ {0x0846, "ar"}, /* ??? */ -//{0x0850, ""}, /* Mongolian (Traditional) (People’s Republic of China) */ + {0x0850, "mn"}, /* Mongolian (Traditional) (People’s Republic of China) */ {0x0851, "dz"}, /* ??? */ -//{0x085D, ""}, /* Inuktitut (Latin) (Canada) */ -//{0x085F, ""}, /* Tamazight (Latin) (Algeria) */ + {0x085D, "iu"}, /* Inuktitut (Latin) (Canada) */ + {0x085F, "tzm"}, /* Tamazight (Latin) (Algeria) */ {0x0861, "ne"}, /* ??? */ //{0x086B, ""}, /* Quechua (Ecuador) */ {0x0873, "ti"}, /* ??? */ @@ -214,10 +217,10 @@ hb_ms_language_map[] = {0x0C04, "zh-hk"}, /* Chinese (Hong Kong S.A.R.) */ {0x0C07, "de"}, /* German (Austria) */ {0x0C09, "en"}, /* English (Australia) */ -//{0x0C0A, ""}, /* Spanish (Modern Sort) (Spain) */ + {0x0C0A, "es"}, /* Spanish (Modern Sort) (Spain) */ {0x0C0C, "fr"}, /* French (Canada) */ {0x0C1A, "sr"}, /* Serbian (Cyrillic) (Serbia) */ -//{0x0C3B, ""}, /* Sami (Northern) (Finland) */ + {0x0C3B, "se"}, /* Sami (Northern) (Finland) */ //{0x0C6B, ""}, /* Quechua (Peru) */ {0x1001, "ar"}, /* Arabic (Libya) */ {0x1004, "zh-sg"}, /* Chinese (Singapore) */ @@ -225,15 +228,14 @@ hb_ms_language_map[] = {0x1009, "en"}, /* English (Canada) */ {0x100A, "es"}, /* Spanish (Guatemala) */ {0x100C, "fr"}, /* French (Switzerland) */ -//{0x101A, ""}, /* Croatian (Latin) (Bosnia and Herzegovina) */ -//{0x103B, ""}, /* Sami (Lule) (Norway) */ + {0x101A, "hr"}, /* Croatian (Latin) (Bosnia and Herzegovina) */ + {0x103B, "smj"}, /* Sami (Lule) (Norway) */ {0x1401, "ar"}, /* Arabic (Algeria) */ //{0x1404, ""}, /* Chinese (Macao S.A.R.) */ -//{0x1407, ""}, /* German (Liechtenstein) */ + {0x1407, "de"}, /* German (Liechtenstein) */ {0x1409, "en"}, /* English (New Zealand) */ {0x140A, "es"}, /* Spanish (Costa Rica) */ - {0x140C, "fr"}, /* ??? */ -//{0x140c, ""}, /* French (Luxembourg) */ + {0x140C, "fr"}, /* French (Luxembourg) */ {0x141A, "bs"}, /* Bosnian (Latin) (Bosnia and Herzegovina) */ //{0x143B, ""}, /* Sami (Lule) (Sweden) */ {0x1801, "ar"}, /* Arabic (Morocco) */ @@ -241,7 +243,7 @@ hb_ms_language_map[] = {0x180A, "es"}, /* Spanish (Panama) */ {0x180C, "fr"}, /* French (Principality of Monaco) */ //{0x181A, ""}, /* Serbian (Latin) (Bosnia and Herzegovina) */ -//{0x183B, ""}, /* Sami (Southern) (Norway) */ + {0x183B, "sma"}, /* Sami (Southern) (Norway) */ {0x1C01, "ar"}, /* Arabic (Tunisia) */ {0x1C09, "en"}, /* English (South Africa) */ {0x1C0A, "es"}, /* Spanish (Dominican Republic) */ @@ -252,13 +254,13 @@ hb_ms_language_map[] = {0x2009, "en"}, /* English (Jamaica) */ {0x200A, "es"}, /* Spanish (Venezuela) */ {0x200C, "fr"}, /* ??? */ -//{0x201A, ""}, /* Bosnian (Cyrillic) (Bosnia and Herzegovina) */ -//{0x203B, ""}, /* Sami (Skolt) (Finland) */ + {0x201A, "bs"}, /* Bosnian (Cyrillic) (Bosnia and Herzegovina) */ + {0x203B, "sms"}, /* Sami (Skolt) (Finland) */ {0x2401, "ar"}, /* Arabic (Yemen) */ {0x2409, "en"}, /* English (Caribbean) */ {0x240A, "es"}, /* Spanish (Colombia) */ {0x240C, "fr"}, /* ??? */ -//{0x243B, ""}, /* Sami (Inari) (Finland) */ + {0x243B, "smn"}, /* Sami (Inari) (Finland) */ {0x2801, "ar"}, /* Arabic (Syria) */ {0x2809, "en"}, /* English (Belize) */ {0x280A, "es"}, /* Spanish (Peru) */ @@ -349,15 +351,15 @@ hb_mac_language_map[] = { 47, "uz"}, /* Uzbek */ { 48, "kk"}, /* Kazakh */ { 49, "az"}, /* Azerbaijani (Cyrillic script) */ - { 50, "ar"}, /* Azerbaijani (Arabic script) */ + { 50, "az"}, /* Azerbaijani (Arabic script) */ { 51, "hy"}, /* Armenian */ { 52, "ka"}, /* Georgian */ { 53, "mo"}, /* Moldavian */ { 54, "ky"}, /* Kirghiz */ { 55, "tg"}, /* Tajiki */ { 56, "tk"}, /* Turkmen */ - { 57, "mo"}, /* Mongolian (Mongolian script) */ - { 58, "mo"}, /* Mongolian (Cyrillic script) */ + { 57, "mn"}, /* Mongolian (Mongolian script) */ + { 58, "mn"}, /* Mongolian (Cyrillic script) */ { 59, "ps"}, /* Pashto */ { 60, "ku"}, /* Kurdish */ { 61, "ks"}, /* Kashmiri */ From 3fd6e5dbefe52a4a2e604c28a4edfbd40ed16027 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Oct 2018 13:42:38 -0700 Subject: [PATCH 061/255] [name] Add pre-defined nameIDs --- src/hb-ot-name.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/hb-ot-name.h b/src/hb-ot-name.h index ff1ae24d8..66af5b646 100644 --- a/src/hb-ot-name.h +++ b/src/hb-ot-name.h @@ -34,6 +34,35 @@ HB_BEGIN_DECLS +enum { + HB_NAME_ID_COPYRIGHT = 0, + HB_NAME_ID_FONT_FAMILY = 1, + HB_NAME_ID_FONT_SUBFAMILY = 2, + HB_NAME_ID_UNIQUE_ID = 3, + HB_NAME_ID_FULL_NAME = 4, + HB_NAME_ID_VERSION_STRING = 5, + HB_NAME_ID_POSTSCRIPT_NAME = 6, + HB_NAME_ID_TRADEMARK = 7, + HB_NAME_ID_MANUFACTURER = 8, + HB_NAME_ID_DESIGNER = 9, + HB_NAME_ID_DESCRIPTION = 10, + HB_NAME_ID_VENDOR_URL = 11, + HB_NAME_ID_DESIGNER_URL = 12, + HB_NAME_ID_LICENSE = 13, + HB_NAME_ID_LICENSE_URL = 14, +/*HB_NAME_ID_RESERVED = 15,*/ + HB_NAME_ID_TYPOGRAPHIC_FAMILY = 16, + HB_NAME_ID_TYPOGRAPHIC_SUBFAMILY = 17, + HB_NAME_ID_MAC_FULL_NAME = 18, + HB_NAME_ID_SAMPLE_TEXT = 19, + HB_NAME_ID_CID_FINDFONT_NAME = 20, + HB_NAME_ID_WWS_FAMILY = 21, + HB_NAME_ID_WWS_SUBFAMILY = 22, + HB_NAME_ID_LIGHT_BACKGROUND = 23, + HB_NAME_ID_DARK_BACKGROUND = 24, + HB_NAME_ID_VARIATIONS_PS_PREFIX = 25 +}; + /** * hb_name_id_t: * From c965eeadbc71943f2336a20dc16ac691c805b90e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 25 Oct 2018 13:43:25 -0700 Subject: [PATCH 062/255] [name] Default to "en" if language is not specified --- src/hb-ot-name.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hb-ot-name.cc b/src/hb-ot-name.cc index ec3d87946..f1c1f76e8 100644 --- a/src/hb-ot-name.cc +++ b/src/hb-ot-name.cc @@ -106,6 +106,9 @@ hb_ot_name_get_utf (hb_face_t *face, { const OT::name_accelerator_t &name = _get_name (face); + if (!language) + language = hb_language_from_string ("en", 2); + unsigned int width; int idx = name.get_index (name_id, language, &width); if (idx != -1) From 12058e44d100c28816f42c91c63a0f960a662181 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 26 Oct 2018 16:23:50 -0700 Subject: [PATCH 063/255] [fuzzing] Add more test --- ...se-minimized-harfbuzz_fuzzer-5659690013556736 | Bin 0 -> 2732 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 test/fuzzing/fonts/clusterfuzz-testcase-minimized-harfbuzz_fuzzer-5659690013556736 diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-harfbuzz_fuzzer-5659690013556736 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-harfbuzz_fuzzer-5659690013556736 new file mode 100644 index 0000000000000000000000000000000000000000..9293c46cfe5df32886163ce2626cbb698e477361 GIT binary patch literal 2732 zcmcgu3s6*582-<_ckiyjDlQ9JDe-bqe1Q8xCNnY~4HH6IjZ!nTAPed)?6h0J&!Z9ycg%k^{gqrILpPBi z7cNS()rdp&L~@j(swHJ!m(O_DHTyyPAwRdm<@b>uo%CA-qR0wQo%_)AFJ@xxCnBk| zvfQ=QFm+D~k?!HatI1gjM)ZuxYumwq03}y?1GVWr>TRI+f}Y{2E_3NVlGlOufu87f z)%qxoEdgBwI=;%~E!QO(^I^ai&D@!!9OX-@Ksr zWJ}|m>wjVq`D^Yj=}@2x-nOA#`B`{7|BYwc zl?zXdc}h8PE5a+ll`8~bg5Cn7OvyH@#QjK0v^eZ=G1{V;9c#8(oesNnz#8iQT2aoI zKhw3I%{u%svu*meZ+rhIuRZc`T76D!gTHF^gTnEqbwi&i{cS6kJQdB@=Gp7_D2Muj z%DKUv`%Wsub8lSR)bjYgo+!UES#G{p%G&?f1jH#WvB!v+`ulj3PS0?lF( zI!)vnacAwyU;5rw&P??;v~AzL@&0#~zRKpl&yrbQM@O(<*H~SsA(5`41$5;2NJzY% zIxn+>#|mz$WFI{JqPOIpDq^8dX&1H1k5UZwOhBsopk|643Ds=SsjBYXwn$G!g(tGj z+}qXFD?d7EW=3gQS!u@1NqJdqufN`wuc{m%1}q5{UIM_4WVnSW%$NNdU!d<*J%ywb zSZB(y&{6iaR7J@UhSCw=QZ$z{Y_c3~5>SuhzMF*S?LG6qr=3Gzq(* zE(!(3%;TXhV*(<~a~>^-!>ijfvrR?ipMHMt15#D!XT{O8HDX;P)2jpQTb4i)N*5h_ zjp@c*V*&gkV;Y|&93A>(X!p>zD5j$EYC#hy4kg2+F;Hv)Ei%GfzilxJ)JN0AV;bD-Ts``=l+tS z&YgRoM~cuma3ZJ|fnEy$aq3b-I5omeuh3~Wo=s-cSP5%jLBXo6VD(qWHwQ|_%{@mE z22Hfj(t9VL9O~{)KHnT1G#aH~G8vw`_tcogm?x3ChZh>&Fw9}Pij zY~;JSG2vEFxS)_wE{Yn~ArFf|tUv}z|SOZ^!7*q-* z<1|K*P;P0O&JTt5KA>fIKnGVHiC@b^&XshquayQMZ zbfvm!)(V%$P1!#G3cLsX0XKdl&IbIn7;`_BVmr5hzxkM;X?jlO8Q=^K?u`_Ww+LX( z0A4t66EI_>ai9P;nuXi*cDkS1(ND1{{|3f-4&T3lF|-;X@jafu!585V4*v5dQNmyF z#ei;x7&F9654nHB^p)~t)(VbWI|&c37@4-J!)k~Gg{#Jyf`Ccb3K}Ekq2&7pka7NZ Pc=-*-`D2I%jO70vq{Vu4 literal 0 HcmV?d00001 From 337ea0b7175793305e9d8935aecf385b707a5bc4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 26 Oct 2018 20:31:14 -0700 Subject: [PATCH 064/255] [fuzzing] Remove HB_NDEBUG Not sure why it ever was added. --- src/Makefile.am | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index fab703a11..0d614ee03 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -170,7 +170,6 @@ pkgconfig_DATA += harfbuzz-subset.pc EXTRA_DIST += harfbuzz-subset.pc.in FUZZING_CPPFLAGS = \ - -DHB_NDEBUG \ -DHB_MAX_NESTING_LEVEL=3 \ -DHB_SANITIZE_MAX_EDITS=3 \ -DHB_SANITIZE_MAX_OPS_FACTOR=3 \ From b2e1ec374cbd2a6e4d79419bd5601a4e2ecb9864 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 26 Oct 2018 20:45:28 -0700 Subject: [PATCH 065/255] [subset] Fix warning --- src/hb-subset.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-subset.hh b/src/hb-subset.hh index 9cdd388d7..e43c79f5e 100644 --- a/src/hb-subset.hh +++ b/src/hb-subset.hh @@ -43,7 +43,7 @@ struct hb_subset_context_t : template inline bool dispatch (const T &obj) { return obj.subset (this); } static bool default_return_value (void) { return true; } - bool stop_sublookup_iteration (bool r) const { return false; } + bool stop_sublookup_iteration (bool r HB_UNUSED) const { return false; } hb_subset_plan_t *plan; hb_serialize_context_t *serializer; From 39bd07aed5fe6ccddde53206bafceec32d56dcc1 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 26 Oct 2018 21:01:11 -0700 Subject: [PATCH 066/255] Fix bunch of unused parameter warnings Show up with gcc -O0. There's a few more but those are functions that need to be filled in. Maybe this is a lost battle... --- src/gen-vowel-constraints.py | 4 +-- src/hb-aat-layout-common.hh | 7 +++-- src/hb-aat-layout-kerx-table.hh | 4 +-- src/hb-aat-layout-morx-table.hh | 10 +++---- src/hb-face.cc | 2 +- src/hb-font.cc | 29 ++++++++++---------- src/hb-graphite2.cc | 9 ++++-- src/hb-machinery.hh | 4 +-- src/hb-ot-color-cbdt-table.hh | 2 +- src/hb-ot-glyf-table.hh | 4 +-- src/hb-ot-hmtx-table.hh | 2 +- src/hb-ot-layout-gpos-table.hh | 2 +- src/hb-ot-math-table.hh | 2 +- src/hb-ot-maxp-table.hh | 2 +- src/hb-ot-shape-complex-arabic-fallback.hh | 6 ++-- src/hb-ot-shape-complex-arabic.cc | 6 ++-- src/hb-ot-shape-complex-hangul.cc | 2 +- src/hb-ot-shape-complex-khmer.cc | 2 +- src/hb-ot-shape-complex-myanmar.cc | 6 ++-- src/hb-ot-shape-complex-use.cc | 8 +++--- src/hb-ot-shape-complex-vowel-constraints.cc | 4 +-- src/hb-ot-shape-fallback.cc | 4 +-- src/hb-ot-shape-normalize.cc | 4 ++- src/hb-ot-shape.cc | 2 +- src/hb-ot-tag.cc | 3 +- src/hb-ot-vorg-table.hh | 2 +- src/hb-set.cc | 2 +- src/hb-shape-plan.cc | 2 +- src/hb-utf.hh | 2 +- 29 files changed, 73 insertions(+), 65 deletions(-) diff --git a/src/gen-vowel-constraints.py b/src/gen-vowel-constraints.py index 02a338fa5..c4e75aa96 100755 --- a/src/gen-vowel-constraints.py +++ b/src/gen-vowel-constraints.py @@ -176,9 +176,9 @@ print ('}') print () print ('void') -print ('_hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan,') +print ('_hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,') print ('\t\t\t\t hb_buffer_t *buffer,') -print ('\t\t\t\t hb_font_t *font)') +print ('\t\t\t\t hb_font_t *font HB_UNUSED)') print ('{') print (' /* UGLY UGLY UGLY business of adding dotted-circle in the middle of') print (' * vowel-sequences that look like another vowel. Data for each script') diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 406a36d8c..ce40abd55 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -377,7 +377,10 @@ struct Entry /* Note, we don't recurse-sanitize data because we don't access it. * That said, in our DEFINE_SIZE_STATIC we access T::static_size, * which ensures that data has a simple sanitize(). To be determined - * if I need to remove that as well. */ + * if I need to remove that as well. + * + * XXX Because we are a template, our DEFINE_SIZE_STATIC assertion + * wouldn't be checked. */ return_trace (c->check_struct (this)); } @@ -394,7 +397,7 @@ struct Entry template <> struct Entry { - inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const + inline bool sanitize (hb_sanitize_context_t *c, unsigned int count /*XXX Unused?*/) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this)); diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 960c37e11..a88312501 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -163,7 +163,7 @@ struct KerxSubTableFormat1 kernAction (&table->machine + table->kernAction), depth (0) {} - inline bool is_actionable (StateTableDriver *driver, + inline bool is_actionable (StateTableDriver *driver HB_UNUSED, const Entry *entry) { return entry->data.kernActionIndex != 0xFFFF; @@ -365,7 +365,7 @@ struct KerxSubTableFormat4 mark_set (false), mark (0) {} - inline bool is_actionable (StateTableDriver *driver, + inline bool is_actionable (StateTableDriver *driver HB_UNUSED, const Entry *entry) { return entry->data.ankrActionIndex != 0xFFFF; diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 84e321edc..22a994431 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -65,11 +65,11 @@ struct RearrangementSubtable Verb = 0x000F, /* The type of rearrangement specified. */ }; - inline driver_context_t (const RearrangementSubtable *table) : + inline driver_context_t (const RearrangementSubtable *table HB_UNUSED) : ret (false), start (0), end (0) {} - inline bool is_actionable (StateTableDriver *driver, + inline bool is_actionable (StateTableDriver *driver HB_UNUSED, const Entry *entry) { return (entry->flags & Verb) && start < end; @@ -363,7 +363,7 @@ struct LigatureSubtable ligature (table+table->ligature), match_length (0) {} - inline bool is_actionable (StateTableDriver *driver, + inline bool is_actionable (StateTableDriver *driver HB_UNUSED, const Entry *entry) { return entry->flags & PerformAction; @@ -620,7 +620,7 @@ struct InsertionSubtable mark (0), insertionAction (table+table->insertionAction) {} - inline bool is_actionable (StateTableDriver *driver, + inline bool is_actionable (StateTableDriver *driver HB_UNUSED, const Entry *entry) { return (entry->flags & (CurrentInsertCount | MarkedInsertCount)) && @@ -937,7 +937,7 @@ struct Chain inline unsigned int get_size (void) const { return length; } - inline bool sanitize (hb_sanitize_context_t *c, unsigned int version) const + inline bool sanitize (hb_sanitize_context_t *c, unsigned int version HB_UNUSED) const { TRACE_SANITIZE (this); if (!length.sanitize (c) || diff --git a/src/hb-face.cc b/src/hb-face.cc index bba1ee3fa..74c77721f 100644 --- a/src/hb-face.cc +++ b/src/hb-face.cc @@ -666,7 +666,7 @@ _hb_face_builder_data_reference_blob (hb_face_builder_data_t *data) } static hb_blob_t * -_hb_face_builder_reference_table (hb_face_t *face, hb_tag_t tag, void *user_data) +_hb_face_builder_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) { hb_face_builder_data_t *data = (hb_face_builder_data_t *) user_data; diff --git a/src/hb-font.cc b/src/hb-font.cc index b6b668dd8..e38c2fbd3 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -89,7 +89,7 @@ hb_font_get_font_v_extents_default (hb_font_t *font, static hb_bool_t hb_font_get_nominal_glyph_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, - hb_codepoint_t unicode, + hb_codepoint_t unicode HB_UNUSED, hb_codepoint_t *glyph, void *user_data HB_UNUSED) { @@ -142,8 +142,8 @@ hb_font_get_nominal_glyphs_default (hb_font_t *font, static hb_bool_t hb_font_get_variation_glyph_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, - hb_codepoint_t unicode, - hb_codepoint_t variation_selector, + hb_codepoint_t unicode HB_UNUSED, + hb_codepoint_t variation_selector HB_UNUSED, hb_codepoint_t *glyph, void *user_data HB_UNUSED) { @@ -276,7 +276,7 @@ hb_font_get_glyph_v_advances_default (hb_font_t* font, static hb_bool_t hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, - hb_codepoint_t glyph, + hb_codepoint_t glyph HB_UNUSED, hb_position_t *x, hb_position_t *y, void *user_data HB_UNUSED) @@ -301,7 +301,7 @@ hb_font_get_glyph_h_origin_default (hb_font_t *font, static hb_bool_t hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, - hb_codepoint_t glyph, + hb_codepoint_t glyph HB_UNUSED, hb_position_t *x, hb_position_t *y, void *user_data HB_UNUSED) @@ -326,8 +326,8 @@ hb_font_get_glyph_v_origin_default (hb_font_t *font, static hb_position_t hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, - hb_codepoint_t left_glyph, - hb_codepoint_t right_glyph, + hb_codepoint_t left_glyph HB_UNUSED, + hb_codepoint_t right_glyph HB_UNUSED, void *user_data HB_UNUSED) { return 0; @@ -345,8 +345,8 @@ hb_font_get_glyph_h_kerning_default (hb_font_t *font, static hb_position_t hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, - hb_codepoint_t top_glyph, - hb_codepoint_t bottom_glyph, + hb_codepoint_t top_glyph HB_UNUSED, + hb_codepoint_t bottom_glyph HB_UNUSED, void *user_data HB_UNUSED) { return 0; @@ -364,7 +364,7 @@ hb_font_get_glyph_v_kerning_default (hb_font_t *font, static hb_bool_t hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, - hb_codepoint_t glyph, + hb_codepoint_t glyph HB_UNUSED, hb_glyph_extents_t *extents, void *user_data HB_UNUSED) { @@ -389,8 +389,8 @@ hb_font_get_glyph_extents_default (hb_font_t *font, static hb_bool_t hb_font_get_glyph_contour_point_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, - hb_codepoint_t glyph, - unsigned int point_index, + hb_codepoint_t glyph HB_UNUSED, + unsigned int point_index HB_UNUSED, hb_position_t *x, hb_position_t *y, void *user_data HB_UNUSED) @@ -416,7 +416,7 @@ hb_font_get_glyph_contour_point_default (hb_font_t *font, static hb_bool_t hb_font_get_glyph_name_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, - hb_codepoint_t glyph, + hb_codepoint_t glyph HB_UNUSED, char *name, unsigned int size, void *user_data HB_UNUSED) { @@ -436,7 +436,8 @@ hb_font_get_glyph_name_default (hb_font_t *font, static hb_bool_t hb_font_get_glyph_from_name_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, - const char *name, int len, /* -1 means nul-terminated */ + const char *name HB_UNUSED, + int len HB_UNUSED, /* -1 means nul-terminated */ hb_codepoint_t *glyph, void *user_data HB_UNUSED) { diff --git a/src/hb-graphite2.cc b/src/hb-graphite2.cc index 6b2b6f19d..1b73f9f4f 100644 --- a/src/hb-graphite2.cc +++ b/src/hb-graphite2.cc @@ -197,11 +197,14 @@ _hb_graphite2_shaper_font_data_destroy (hb_graphite2_font_data_t *data HB_UNUSED { } -/* +/** + * hb_graphite2_font_get_gr_font: + * * Since: 0.9.10 + * Deprecated: 1.4.2 */ gr_font * -hb_graphite2_font_get_gr_font (hb_font_t *font) +hb_graphite2_font_get_gr_font (hb_font_t *font HB_UNUSED) { return nullptr; } @@ -243,7 +246,7 @@ struct hb_graphite2_cluster_t { }; hb_bool_t -_hb_graphite2_shape (hb_shape_plan_t *shape_plan, +_hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED, hb_font_t *font, hb_buffer_t *buffer, const hb_feature_t *features, diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index 35cbc155f..2b238131a 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -136,7 +136,7 @@ struct hb_dispatch_context_t enum { max_debug_depth = MaxDebugDepth }; typedef Return return_t; template - inline bool may_dispatch (const T *obj, const F *format) { return true; } + inline bool may_dispatch (const T *obj HB_UNUSED, const F *format HB_UNUSED) { return true; } static return_t no_dispatch_return_value (void) { return Context::default_return_value (); } }; @@ -235,7 +235,7 @@ struct hb_sanitize_context_t : inline const char *get_name (void) { return "SANITIZE"; } template - inline bool may_dispatch (const T *obj, const F *format) + inline bool may_dispatch (const T *obj HB_UNUSED, const F *format) { return format->sanitize (this); } template inline return_t dispatch (const T &obj) { return obj.sanitize (this); } diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index 1e1fe0956..f807d6129 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -166,7 +166,7 @@ struct IndexSubtable } } - inline bool get_extents (hb_glyph_extents_t *extents) const + inline bool get_extents (hb_glyph_extents_t *extents HB_UNUSED) const { switch (u.header.indexFormat) { case 2: case 5: /* TODO */ diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh index 2145ac02b..9437a83d8 100644 --- a/src/hb-ot-glyf-table.hh +++ b/src/hb-ot-glyf-table.hh @@ -47,7 +47,7 @@ struct loca static const hb_tag_t tableTag = HB_OT_TAG_loca; - inline bool sanitize (hb_sanitize_context_t *c) const + inline bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const { TRACE_SANITIZE (this); return_trace (true); @@ -70,7 +70,7 @@ struct glyf { static const hb_tag_t tableTag = HB_OT_TAG_glyf; - inline bool sanitize (hb_sanitize_context_t *c) const + inline bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const { TRACE_SANITIZE (this); /* We don't check for anything specific here. The users of the diff --git a/src/hb-ot-hmtx-table.hh b/src/hb-ot-hmtx-table.hh index 935ddd720..607358584 100644 --- a/src/hb-ot-hmtx-table.hh +++ b/src/hb-ot-hmtx-table.hh @@ -56,7 +56,7 @@ struct LongMetric template struct hmtxvmtx { - inline bool sanitize (hb_sanitize_context_t *c) const + inline bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const { TRACE_SANITIZE (this); /* We don't check for anything specific here. The users of the diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index dd4e62792..8a6c0278f 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -1715,7 +1715,7 @@ GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) } void -GPOS::position_finish_advances (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) +GPOS::position_finish_advances (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer HB_UNUSED) { //_hb_buffer_assert_gsubgpos_vars (buffer); } diff --git a/src/hb-ot-math-table.hh b/src/hb-ot-math-table.hh index 2f871124c..e20935972 100644 --- a/src/hb-ot-math-table.hh +++ b/src/hb-ot-math-table.hh @@ -631,7 +631,7 @@ struct MathVariants inline const MathGlyphConstruction & get_glyph_construction (hb_codepoint_t glyph, hb_direction_t direction, - hb_font_t *font) const + hb_font_t *font HB_UNUSED) const { bool vertical = HB_DIRECTION_IS_VERTICAL (direction); unsigned int count = vertical ? vertGlyphCount : horizGlyphCount; diff --git a/src/hb-ot-maxp-table.hh b/src/hb-ot-maxp-table.hh index 2572ad288..648f232d9 100644 --- a/src/hb-ot-maxp-table.hh +++ b/src/hb-ot-maxp-table.hh @@ -117,7 +117,7 @@ struct maxp return result; } - static inline void drop_hint_fields (hb_subset_plan_t *plan, maxp *maxp_prime) + static inline void drop_hint_fields (hb_subset_plan_t *plan HB_UNUSED, maxp *maxp_prime) { if (maxp_prime->version.major == 1) { diff --git a/src/hb-ot-shape-complex-arabic-fallback.hh b/src/hb-ot-shape-complex-arabic-fallback.hh index 2aa036728..f64e2dd6e 100644 --- a/src/hb-ot-shape-complex-arabic-fallback.hh +++ b/src/hb-ot-shape-complex-arabic-fallback.hh @@ -220,9 +220,9 @@ struct ManifestLookup typedef OT::ArrayOf Manifest; static bool -arabic_fallback_plan_init_win1256 (arabic_fallback_plan_t *fallback_plan, - const hb_ot_shape_plan_t *plan, - hb_font_t *font) +arabic_fallback_plan_init_win1256 (arabic_fallback_plan_t *fallback_plan HB_UNUSED, + const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_font_t *font HB_UNUSED) { #ifdef HB_WITH_WIN1256 /* Does this font look like it's Windows-1256-encoded? */ diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc index b56443910..1fbd14a4c 100644 --- a/src/hb-ot-shape-complex-arabic.cc +++ b/src/hb-ot-shape-complex-arabic.cc @@ -416,7 +416,7 @@ retry: static void record_stch (const hb_ot_shape_plan_t *plan, - hb_font_t *font, + hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) { const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data; @@ -440,7 +440,7 @@ record_stch (const hb_ot_shape_plan_t *plan, } static void -apply_stch (const hb_ot_shape_plan_t *plan, +apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_buffer_t *buffer, hb_font_t *font) { @@ -626,7 +626,7 @@ info_is_mcm (const hb_glyph_info_t &info) } static void -reorder_marks_arabic (const hb_ot_shape_plan_t *plan, +reorder_marks_arabic (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_buffer_t *buffer, unsigned int start, unsigned int end) diff --git a/src/hb-ot-shape-complex-hangul.cc b/src/hb-ot-shape-complex-hangul.cc index 959540258..38e4dbba6 100644 --- a/src/hb-ot-shape-complex-hangul.cc +++ b/src/hb-ot-shape-complex-hangul.cc @@ -128,7 +128,7 @@ is_zero_width_char (hb_font_t *font, } static void -preprocess_text_hangul (const hb_ot_shape_plan_t *plan, +preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_buffer_t *buffer, hb_font_t *font) { diff --git a/src/hb-ot-shape-complex-khmer.cc b/src/hb-ot-shape-complex-khmer.cc index 21db351fc..ecb80195f 100644 --- a/src/hb-ot-shape-complex-khmer.cc +++ b/src/hb-ot-shape-complex-khmer.cc @@ -267,7 +267,7 @@ setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED, static void reorder_consonant_syllable (const hb_ot_shape_plan_t *plan, - hb_face_t *face, + hb_face_t *face HB_UNUSED, hb_buffer_t *buffer, unsigned int start, unsigned int end) { diff --git a/src/hb-ot-shape-complex-myanmar.cc b/src/hb-ot-shape-complex-myanmar.cc index 30fa82579..dcada261c 100644 --- a/src/hb-ot-shape-complex-myanmar.cc +++ b/src/hb-ot-shape-complex-myanmar.cc @@ -274,8 +274,8 @@ initial_reordering_consonant_syllable (hb_buffer_t *buffer, } static void -initial_reordering_syllable (const hb_ot_shape_plan_t *plan, - hb_face_t *face, +initial_reordering_syllable (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_face_t *face HB_UNUSED, hb_buffer_t *buffer, unsigned int start, unsigned int end) { @@ -362,7 +362,7 @@ reorder (const hb_ot_shape_plan_t *plan, } static void -clear_syllables (const hb_ot_shape_plan_t *plan, +clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) { diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index 7814e2c67..1bbf9805c 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -379,7 +379,7 @@ setup_syllables (const hb_ot_shape_plan_t *plan, } static void -clear_substitution_flags (const hb_ot_shape_plan_t *plan, +clear_substitution_flags (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) { @@ -391,7 +391,7 @@ clear_substitution_flags (const hb_ot_shape_plan_t *plan, static void record_rphf (const hb_ot_shape_plan_t *plan, - hb_font_t *font, + hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) { const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data; @@ -413,8 +413,8 @@ record_rphf (const hb_ot_shape_plan_t *plan, } static void -record_pref (const hb_ot_shape_plan_t *plan, - hb_font_t *font, +record_pref (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) { hb_glyph_info_t *info = buffer->info; diff --git a/src/hb-ot-shape-complex-vowel-constraints.cc b/src/hb-ot-shape-complex-vowel-constraints.cc index aae5936a2..20af8711e 100644 --- a/src/hb-ot-shape-complex-vowel-constraints.cc +++ b/src/hb-ot-shape-complex-vowel-constraints.cc @@ -30,9 +30,9 @@ _output_with_dotted_circle (hb_buffer_t *buffer) } void -_hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan, +_hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_buffer_t *buffer, - hb_font_t *font) + hb_font_t *font HB_UNUSED) { /* UGLY UGLY UGLY business of adding dotted-circle in the middle of * vowel-sequences that look like another vowel. Data for each script diff --git a/src/hb-ot-shape-fallback.cc b/src/hb-ot-shape-fallback.cc index 4c5ccc974..94bc4afb1 100644 --- a/src/hb-ot-shape-fallback.cc +++ b/src/hb-ot-shape-fallback.cc @@ -192,7 +192,7 @@ zero_mark_advances (hb_buffer_t *buffer, } static inline void -position_mark (const hb_ot_shape_plan_t *plan, +position_mark (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_font_t *font, hb_buffer_t *buffer, hb_glyph_extents_t &base_extents, @@ -472,7 +472,7 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan, /* Adjusts width of various spaces. */ void -_hb_ot_shape_fallback_spaces (const hb_ot_shape_plan_t *plan, +_hb_ot_shape_fallback_spaces (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_font_t *font, hb_buffer_t *buffer) { diff --git a/src/hb-ot-shape-normalize.cc b/src/hb-ot-shape-normalize.cc index a8229a98d..2164f7ad5 100644 --- a/src/hb-ot-shape-normalize.cc +++ b/src/hb-ot-shape-normalize.cc @@ -213,7 +213,9 @@ decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shor } static inline void -handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end, bool short_circuit) +handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, + unsigned int end, + bool short_circuit HB_UNUSED) { /* TODO Currently if there's a variation-selector we give-up, it's just too hard. */ hb_buffer_t * const buffer = c->buffer; diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 065b4d4bf..32c502048 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -276,7 +276,7 @@ _hb_ot_shaper_font_data_create (hb_font_t *font HB_UNUSED) } void -_hb_ot_shaper_font_data_destroy (hb_ot_font_data_t *data) +_hb_ot_shaper_font_data_destroy (hb_ot_font_data_t *data HB_UNUSED) { } diff --git a/src/hb-ot-tag.cc b/src/hb-ot-tag.cc index 4dba9c31a..a569b8c22 100644 --- a/src/hb-ot-tag.cc +++ b/src/hb-ot-tag.cc @@ -242,7 +242,6 @@ hb_ot_tag_from_language (hb_language_t language) static void hb_ot_tags_from_language (const char *lang_str, const char *limit, - const char *private_use_subtag, unsigned int *count, hb_tag_t *tags) { @@ -389,7 +388,7 @@ hb_ot_tags_from_script_and_language (hb_script_t script, needs_language = parse_private_use_subtag (private_use_subtag, language_count, language_tags, "-hbot", TOUPPER); if (needs_language && language_count && language_tags && *language_count) - hb_ot_tags_from_language (lang_str, limit, private_use_subtag, language_count, language_tags); + hb_ot_tags_from_language (lang_str, limit, language_count, language_tags); } if (needs_script && script_count && script_tags && *script_count) diff --git a/src/hb-ot-vorg-table.hh b/src/hb-ot-vorg-table.hh index b6494b51f..98af00e14 100644 --- a/src/hb-ot-vorg-table.hh +++ b/src/hb-ot-vorg-table.hh @@ -70,7 +70,7 @@ struct VORG return defaultVertOriginY; } - inline bool _subset (const hb_subset_plan_t *plan, + inline bool _subset (const hb_subset_plan_t *plan HB_UNUSED, const VORG *vorg_table, const hb_vector_t &subset_metrics, unsigned int dest_sz, diff --git a/src/hb-set.cc b/src/hb-set.cc index 09dc4b483..25c19147f 100644 --- a/src/hb-set.cc +++ b/src/hb-set.cc @@ -391,7 +391,7 @@ hb_set_symmetric_difference (hb_set_t *set, * Deprecated: 1.6.1 **/ void -hb_set_invert (hb_set_t *set) +hb_set_invert (hb_set_t *set HB_UNUSED) { } diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc index b2289f869..dea2c8c7b 100644 --- a/src/hb-shape-plan.cc +++ b/src/hb-shape-plan.cc @@ -441,7 +441,7 @@ hb_non_global_user_features_present (const hb_feature_t *user_features, } static inline hb_bool_t -hb_coords_present (const int *coords, +hb_coords_present (const int *coords HB_UNUSED, unsigned int num_coords) { return num_coords != 0; diff --git a/src/hb-utf.hh b/src/hb-utf.hh index b45bcd972..54ede3c16 100644 --- a/src/hb-utf.hh +++ b/src/hb-utf.hh @@ -365,7 +365,7 @@ struct hb_latin1_t prev (const codepoint_t *text, const codepoint_t *start HB_UNUSED, hb_codepoint_t *unicode, - hb_codepoint_t replacement) + hb_codepoint_t replacement HB_UNUSED) { *unicode = *--text; return text; From 79b2fa62ca7eb5a875778d3a2ecae63350083ba3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 26 Oct 2018 21:21:18 -0700 Subject: [PATCH 067/255] [indic] Fix infinite loop Fixes https://bugs.chromium.org/p/chromium/issues/detail?id=863044 --- src/hb-ot-shape-complex-indic.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc index f145a34c3..918e0d7e0 100644 --- a/src/hb-ot-shape-complex-indic.cc +++ b/src/hb-ot-shape-complex-indic.cc @@ -789,7 +789,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, * We could use buffer->sort() for this, if there was no special * reordering of pre-base stuff happening later... */ - if (indic_plan->is_old_spec || end - base > 127) + if (indic_plan->is_old_spec || end - start > 127) buffer->merge_clusters (base, end); else { From 30eab97a0072fbc22d353082249e0e6e546cd86b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 26 Oct 2018 21:54:07 -0700 Subject: [PATCH 068/255] Fix invalid memory read Buffer might be relocated inside replace_glyphs(). Fixes https://bugs.chromium.org/p/chromium/issues/detail?id=895117 --- src/hb-ot-shape-normalize.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-shape-normalize.cc b/src/hb-ot-shape-normalize.cc index 2164f7ad5..d5600f9f0 100644 --- a/src/hb-ot-shape-normalize.cc +++ b/src/hb-ot-shape-normalize.cc @@ -225,7 +225,8 @@ handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, /* The next two lines are some ugly lines... But work. */ if (font->get_variation_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index())) { - buffer->replace_glyphs (2, 1, &buffer->cur().codepoint); + hb_codepoint_t unicode = buffer->cur().codepoint; + buffer->replace_glyphs (2, 1, &unicode); } else { From 00ae4be6bf8b1d0800043167c5cf95187ac12515 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 26 Oct 2018 21:59:20 -0700 Subject: [PATCH 069/255] [morx] Fix bailing out ligation at end-of-text Check was after a move_to, which wouldn't work. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11147 --- src/hb-aat-layout-morx-table.hh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 22a994431..5b21358ec 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -399,6 +399,9 @@ struct LigatureSubtable if (unlikely (!match_length)) return true; + if (buffer->idx >= buffer->len) + return false; // TODO Work on previous instead? + unsigned int cursor = match_length; do { @@ -421,8 +424,6 @@ struct LigatureSubtable if (uoffset & 0x20000000) uoffset |= 0xC0000000; /* Sign-extend. */ int32_t offset = (int32_t) uoffset; - if (buffer->idx >= buffer->len) - return false; // TODO Work on previous instead? unsigned int component_idx = buffer->cur().codepoint + offset; const HBUINT16 &componentData = component[component_idx]; From 6aa019c4af6b64bb732205e6051f3e73e1b70721 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 26 Oct 2018 22:02:17 -0700 Subject: [PATCH 070/255] [morx] Fix merge_cluster to end at last ligature component Don't assume current position was a component in the ligature. --- src/hb-aat-layout-morx-table.hh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 5b21358ec..a56209104 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -443,6 +443,7 @@ struct LigatureSubtable DEBUG_MSG (APPLY, nullptr, "Produced ligature %d", lig); buffer->replace_glyph (lig); + unsigned int lig_end = match_positions[match_length - 1] + 1; /* Now go and delete all subsequent components. */ while (match_length - 1 > cursor) { @@ -451,7 +452,7 @@ struct LigatureSubtable buffer->replace_glyph (DELETED_GLYPH); } - buffer->move_to (end + 1); + buffer->move_to (lig_end); buffer->merge_out_clusters (match_positions[cursor], buffer->out_len); } From e7400c0275cad4f584eeaf21ce6d5c6adca29bbb Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 26 Oct 2018 22:09:17 -0700 Subject: [PATCH 071/255] [docs] Hook up new symbols --- docs/harfbuzz-docs.xml | 46 +++++++++++++++++++++++++++++++++----- docs/harfbuzz-sections.txt | 21 +++++++++++++++++ src/hb-ot-color.cc | 2 +- 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/docs/harfbuzz-docs.xml b/docs/harfbuzz-docs.xml index 9452a92af..3488ccb7f 100644 --- a/docs/harfbuzz-docs.xml +++ b/docs/harfbuzz-docs.xml @@ -104,8 +104,12 @@ API Index - - Index of new symbols in 0.9.2 + + Index of deprecated API + + + + Index of new symbols in 0.9.2 @@ -184,6 +188,10 @@ Index of new symbols in 1.3.3 + + Index of new symbols in 1.4.0 + + Index of new symbols in 1.4.2 @@ -200,9 +208,37 @@ Index of new symbols in 1.6.0 - - Index of deprecated API - + + Index of new symbols in 1.7.5 + + + + Index of new symbols in 1.7.7 + + + + Index of new symbols in 1.8.0 + + + + Index of new symbols in 1.8.1 + + + + Index of new symbols in 1.8.5 + + + + Index of new symbols in 1.8.6 + + + + Index of new symbols in 1.9.0 + + + + Index of new symbols in 2.0.0 + diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index 7bca7ca20..8229d4664 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -3,6 +3,8 @@ HB_H_IN HB_EXTERN +HB_DEPRECATED +HB_DEPRECATED_FOR
@@ -358,6 +360,7 @@ HB_GOBJECT_TYPE_FONT_FUNCS HB_GOBJECT_TYPE_GLYPH_FLAGS HB_GOBJECT_TYPE_MAP HB_GOBJECT_TYPE_MEMORY_MODE +HB_GOBJECT_TYPE_OT_COLOR_PALETTE_FLAGS HB_GOBJECT_TYPE_OT_LAYOUT_GLYPH_CLASS HB_GOBJECT_TYPE_OT_MATH_CONSTANT HB_GOBJECT_TYPE_OT_MATH_GLYPH_PART @@ -390,6 +393,7 @@ hb_gobject_font_get_type hb_gobject_glyph_flags_get_type hb_gobject_map_get_type hb_gobject_memory_mode_get_type +hb_gobject_ot_color_palette_flags_get_type hb_gobject_ot_layout_glyph_class_get_type hb_gobject_ot_math_constant_get_type hb_gobject_ot_math_glyph_part_get_type @@ -459,6 +463,12 @@ HB_OT_H_IN
hb-ot-color +hb_color_t +HB_COLOR +hb_color_get_alpha +hb_color_get_blue +hb_color_get_green +hb_color_get_red hb_ot_color_glyph_get_layers hb_ot_color_has_layers hb_ot_color_has_palettes @@ -476,6 +486,16 @@ hb_ot_color_palette_get_name_id hb_ot_font_set_funcs
+
+hb-ot-name +hb_name_id_t +HB_NAME_ID_INVALID +hb_ot_name_get_names +hb_ot_name_get_utf16 +hb_ot_name_get_utf32 +hb_ot_name_get_utf8 +
+
hb-ot-shape hb_ot_shape_glyphs_closure @@ -487,6 +507,7 @@ HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX HB_OT_LAYOUT_NO_FEATURE_INDEX HB_OT_LAYOUT_NO_SCRIPT_INDEX HB_OT_LAYOUT_NO_VARIATIONS_INDEX +HB_OT_TAG_BASE HB_OT_TAG_GDEF HB_OT_TAG_GPOS HB_OT_TAG_GSUB diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index 229b6e66f..3f492cc1f 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -115,7 +115,7 @@ hb_ot_color_palette_get_count (hb_face_t *face) /** * hb_ot_color_palette_get_name_id: * @face: a font face. - * @palette: the index of the color palette whose name is being requested. + * @palette_index: the index of the color palette whose name is being requested. * * Retrieves the name id of a color palette. For example, a color font can * have themed palettes like "Spring", "Summer", "Fall", and "Winter". From 7f5941e162bf7806299656edafd452a47b5a55b9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 27 Oct 2018 00:06:48 -0700 Subject: [PATCH 072/255] Remove stale comment Ugliness was fixed in 30eab97a0072fbc22d353082249e0e6e546cd86b But yeah, my smell detector was working. Ugliness was buggy. --- src/hb-ot-shape-normalize.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hb-ot-shape-normalize.cc b/src/hb-ot-shape-normalize.cc index d5600f9f0..82bb24b7d 100644 --- a/src/hb-ot-shape-normalize.cc +++ b/src/hb-ot-shape-normalize.cc @@ -222,7 +222,6 @@ handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, hb_font_t * const font = c->font; for (; buffer->idx < end - 1 && buffer->successful;) { if (unlikely (buffer->unicode->is_variation_selector (buffer->cur(+1).codepoint))) { - /* The next two lines are some ugly lines... But work. */ if (font->get_variation_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index())) { hb_codepoint_t unicode = buffer->cur().codepoint; From 265ad408ca41e9d0b5a1056a751d834d4eadc911 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Fri, 26 Oct 2018 23:55:11 +0330 Subject: [PATCH 073/255] [ot-color/png] Implement sbix part --- docs/harfbuzz-sections.txt | 2 + src/dump-emoji.cc | 5 +- src/hb-ot-color-cbdt-table.hh | 27 +++++++--- src/hb-ot-color-sbix-table.hh | 98 ++++++++++++++++++++++++++++++----- src/hb-ot-color.cc | 64 +++++++++++++++++++++++ src/hb-ot-color.h | 9 ++++ test/api/test-ot-color.c | 32 ++++++++++++ 7 files changed, 215 insertions(+), 22 deletions(-) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index c385984a7..67f9ae2c4 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -460,9 +460,11 @@ HB_OT_H_IN
hb-ot-color hb_ot_color_glyph_get_layers +hb_ot_color_glyph_reference_blob_png hb_ot_color_glyph_reference_blob_svg hb_ot_color_has_layers hb_ot_color_has_palettes +hb_ot_color_has_png hb_ot_color_has_svg hb_ot_color_layer_t hb_ot_color_palette_color_get_name_id diff --git a/src/dump-emoji.cc b/src/dump-emoji.cc index c4710a629..7c7392f20 100644 --- a/src/dump-emoji.cc +++ b/src/dump-emoji.cc @@ -58,12 +58,13 @@ cbdt_callback (const uint8_t* data, unsigned int length, } static void -sbix_callback (const uint8_t* data, unsigned int length, - unsigned int group, unsigned int gid) +sbix_callback (hb_blob_t *blob, unsigned int group, unsigned int gid) { char output_path[255]; sprintf (output_path, "out/sbix-%d-%d.png", group, gid); FILE *f = fopen (output_path, "wb"); + unsigned int length; + const char* data = hb_blob_get_data (blob, &length); fwrite (data, 1, length, f); fclose (f); } diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index 1e1fe0956..0f64577d3 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -376,13 +376,6 @@ struct CBDT { static const hb_tag_t tableTag = HB_OT_TAG_CBDT; - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - likely (version.major == 2 || version.major == 3)); - } - struct accelerator_t { inline void init (hb_face_t *face) @@ -511,6 +504,20 @@ struct CBDT } } + inline hb_blob_t* reference_blob_for_glyph (hb_codepoint_t glyph_id, + unsigned int requested_x_ppem, + unsigned int requested_y_ppem, + unsigned int *strike_x_ppem, + unsigned int *strike_y_ppem) const + { +// if (unlikely (cbdt_len == 0)) + return hb_blob_get_empty (); +// return svg->get_glyph_entry (glyph_id).reference_blob (svg_blob, svg->svgDocEntries); + } + + inline bool has_data () const + { return cbdt_len; } + private: hb_blob_t *cblc_blob; hb_blob_t *cbdt_blob; @@ -521,6 +528,12 @@ struct CBDT unsigned int upem; }; + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + likely (version.major == 2 || version.major == 3)); + } protected: FixedVersion<> version; diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 1dd0a5c6d..97eac9b58 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -62,8 +62,6 @@ struct SBIXGlyph struct SBIXStrike { - friend struct sbix; - inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -71,6 +69,48 @@ struct SBIXStrike imageOffsetsZ.sanitize_shallow (c, c->get_num_glyphs () + 1)); } + inline unsigned int get_ppem () const + { return ppem; } + + inline unsigned int get_resolution () const + { return resolution; } + + inline unsigned int blob_size (unsigned int glyph_id) const + { + return imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] - SBIXGlyph::min_size; + } + + inline hb_blob_t *get_glyph_blob (unsigned int glyph_id, + hb_blob_t *sbix_blob, + unsigned int strike_offset, + unsigned int *x_offset, + unsigned int *y_offset, + hb_tag_t requested_file_type, + unsigned int num_glyphs) const + { + if (imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] == 0) + return hb_blob_get_empty (); + + const SBIXGlyph *glyph = &(this+imageOffsetsZ[glyph_id]); + if (unlikely (glyph->graphicType == HB_TAG ('d','u','p','e') && + blob_size (glyph_id) >= 2)) + { + unsigned int new_glyph_id = *((HBUINT16 *) &glyph->data); + if (new_glyph_id < num_glyphs) + { + glyph = &(this+imageOffsetsZ[new_glyph_id]); + glyph_id = new_glyph_id; + } + } + if (unlikely (requested_file_type != glyph->graphicType)) + return hb_blob_get_empty (); + if (likely (x_offset)) *x_offset = glyph->xOffset; + if (likely (y_offset)) *y_offset = glyph->yOffset; + unsigned int offset = strike_offset + SBIXGlyph::min_size; + offset += imageOffsetsZ[glyph_id]; + return hb_blob_create_sub_blob (sbix_blob, offset, blob_size (glyph_id)); + } + protected: HBUINT16 ppem; /* The PPEM size for which this strike was designed. */ HBUINT16 resolution; /* The device pixel density (in PPI) for which this @@ -99,6 +139,7 @@ struct sbix sbix_blob = hb_sanitize_context_t().reference_table (face); sbix_len = hb_blob_get_length (sbix_blob); sbix_table = sbix_blob->as (); + num_glyphs = face->get_num_glyphs (); } inline void fini (void) @@ -106,29 +147,60 @@ struct sbix hb_blob_destroy (sbix_blob); } - inline void dump (void (*callback) (const uint8_t* data, unsigned int length, + inline void dump (void (*callback) (hb_blob_t *data, unsigned int group, unsigned int gid)) const { - for (unsigned group = 0; group < sbix_table->strikes.len; ++group) + for (unsigned group = 0; group < sbix_table->strikes.len; group++) { - const SBIXStrike &strike = sbix_table->strikes[group](sbix_table); - for (unsigned int glyph = 0; glyph < num_glyphs; ++glyph) - if (strike.imageOffsetsZ[glyph + 1] - strike.imageOffsetsZ[glyph] > 0) - { - const SBIXGlyph &sbixGlyph = strike.imageOffsetsZ[glyph]((const void *) &strike); - callback ((const uint8_t*) &sbixGlyph.data, - strike.imageOffsetsZ[glyph + 1] - strike.imageOffsetsZ[glyph] - 8, - group, glyph); - } + const SBIXStrike &strike = sbix_table+sbix_table->strikes[group]; + for (unsigned int glyph_id = 0; glyph_id < num_glyphs; glyph_id++) + { + unsigned int x_offset, y_offset; + hb_tag_t tag; + hb_blob_t *blob; + blob = strike.get_glyph_blob (glyph_id, sbix_blob, sbix_table->strikes[group], + &x_offset, &x_offset, + HB_TAG('p','n','g',' '), num_glyphs); + if (hb_blob_get_length (blob)) callback (blob, group, glyph_id); + } } } + inline hb_blob_t* reference_blob_for_glyph (hb_codepoint_t glyph_id, + unsigned int ptem HB_UNUSED, + unsigned int requested_ppem, + unsigned int requested_file_type, + unsigned int *available_x_ppem, + unsigned int *available_y_ppem) const + { + if (unlikely (sbix_len == 0 || sbix_table->strikes.len == 0)) + return hb_blob_get_empty (); + + /* TODO: Does spec guarantee strikes are ascended sorted? */ + unsigned int group = sbix_table->strikes.len - 1; + if (requested_ppem != 0) + /* TODO: Use bsearch maybe or doesn't worth it? */ + for (group = 0; group < sbix_table->strikes.len; group++) + if ((sbix_table+sbix_table->strikes[group]).get_ppem () >= requested_ppem) + break; + + const SBIXStrike &strike = sbix_table+sbix_table->strikes[group]; + if (available_x_ppem) *available_x_ppem = strike.get_ppem (); + if (available_y_ppem) *available_y_ppem = strike.get_ppem (); + return strike.get_glyph_blob (glyph_id, sbix_blob, sbix_table->strikes[group], + nullptr, nullptr, requested_file_type, num_glyphs); + } + + inline bool has_data () const + { return sbix_len; } + private: hb_blob_t *sbix_blob; const sbix *sbix_table; unsigned int sbix_len; unsigned int num_glyphs; + hb_vector_t > data_offsets; }; protected: diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index 283b3a1e5..8dd3b2a41 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -47,6 +47,13 @@ _get_colr (hb_face_t *face) return *(hb_ot_face_data (face)->COLR.get ()); } +static inline const OT::CBDT_accelerator_t& +_get_cbdt (hb_face_t *face) +{ + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::CBDT_accelerator_t); + return *(hb_ot_face_data (face)->CBDT.get ()); +} + static inline const OT::CPAL& _get_cpal (hb_face_t *face) { @@ -54,6 +61,13 @@ _get_cpal (hb_face_t *face) return *(hb_ot_face_data (face)->CPAL.get ()); } +static inline const OT::sbix_accelerator_t& +_get_sbix (hb_face_t *face) +{ + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::sbix_accelerator_t); + return *(hb_ot_face_data (face)->sbix.get ()); +} + static inline const OT::SVG_accelerator_t& _get_svg (hb_face_t *face) { @@ -272,3 +286,53 @@ hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph) { return _get_svg (face).reference_blob_for_glyph (glyph); } + + +/* + * PNG, CBDT or sbix + */ + +/** + * hb_ot_color_has_png: + * @face: a font face. + * + * Returns: whether SVG table is available. + * + * Since: REPLACEME + */ +hb_bool_t +hb_ot_color_has_png (hb_face_t *face) +{ + return _get_cbdt (face).has_data () || _get_sbix (face).has_data (); +} + +/** + * hb_ot_color_glyph_reference_blob_svg: + * @font: + * @glyph: + * @strike_x_ppem: (out): + * @strike_y_ppem: (out): + * + * Returns: + * + * Since: REPLACEME + */ +hb_blob_t * +hb_ot_color_glyph_reference_blob_png (hb_font_t *font, + hb_codepoint_t glyph, + unsigned int *strike_x_ppem /* OUT */, + unsigned int *strike_y_ppem /* OUT */) +{ + /* TODO: if (hb_options ().aat ()) then call sbix first */ + + if (_get_cbdt (font->face).has_data ()) + return _get_cbdt (font->face).reference_blob_for_glyph (glyph, font->x_ppem, font->y_ppem, + strike_x_ppem, strike_y_ppem); + + if (_get_sbix (font->face).has_data ()) + return _get_sbix (font->face).reference_blob_for_glyph (glyph, font->ptem, + MAX (font->x_ppem, font->y_ppem), + HB_TAG('p','n','g',' '), + strike_x_ppem, strike_y_ppem); + +} diff --git a/src/hb-ot-color.h b/src/hb-ot-color.h index fb9a9e370..7901a3598 100644 --- a/src/hb-ot-color.h +++ b/src/hb-ot-color.h @@ -121,6 +121,15 @@ hb_ot_color_has_svg (hb_face_t *face); HB_EXTERN hb_blob_t * hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph); +HB_EXTERN hb_bool_t +hb_ot_color_has_png (hb_face_t *face); + +HB_EXTERN hb_blob_t * +hb_ot_color_glyph_reference_blob_png (hb_font_t *font, + hb_codepoint_t glyph, + unsigned int *strike_x_ppem, + unsigned int *strike_y_ppem); + HB_END_DECLS diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index 4ffadeec0..767a3d61a 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -370,6 +370,14 @@ test_hb_ot_color_has_data (void) g_assert (hb_ot_color_has_svg (cbdt) == FALSE); g_assert (hb_ot_color_has_svg (sbix) == FALSE); g_assert (hb_ot_color_has_svg (svg) == TRUE); + + g_assert (hb_ot_color_has_png (empty) == FALSE); + g_assert (hb_ot_color_has_png (cpal_v0) == FALSE); + g_assert (hb_ot_color_has_png (cpal_v1) == FALSE); + g_assert (hb_ot_color_has_png (cpal) == FALSE); + g_assert (hb_ot_color_has_png (cbdt) == TRUE); + g_assert (hb_ot_color_has_png (sbix) == TRUE); + g_assert (hb_ot_color_has_png (svg) == FALSE); } static void @@ -392,6 +400,29 @@ test_hb_ot_color_svg (void) g_assert (hb_blob_get_length (blob) == 0); } + +static void +test_hb_ot_color_png (void) +{ + hb_blob_t *blob; + + hb_font_t *sbix_font; + sbix_font = hb_font_create (sbix); + blob = hb_ot_color_glyph_reference_blob_png (sbix_font, 0, NULL, NULL); + g_assert (hb_blob_get_length (blob) == 0); + + unsigned int strike_x_ppem, strike_y_ppem; + blob = hb_ot_color_glyph_reference_blob_png (sbix_font, 1, + &strike_x_ppem, &strike_y_ppem); + unsigned int length; + const char *data = hb_blob_get_data (blob, &length); + g_assert_cmpuint (length, ==, 224); + g_assert_cmpuint (strike_x_ppem, ==, 300); + g_assert_cmpuint (strike_y_ppem, ==, 300); + g_assert (strncmp (data + 1, "PNG", 3) == 0); + hb_blob_destroy (blob); +} + int main (int argc, char **argv) { @@ -418,6 +449,7 @@ main (int argc, char **argv) hb_test_add (test_hb_ot_color_palette_color_get_name_id); hb_test_add (test_hb_ot_color_glyph_get_layers); hb_test_add (test_hb_ot_color_has_data); + hb_test_add (test_hb_ot_color_png); hb_test_add (test_hb_ot_color_svg); status = hb_test_run(); hb_face_destroy (cpal_v0); From ca645accb97841e01846e45cda32e6bd2ad15940 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 27 Oct 2018 00:39:31 -0700 Subject: [PATCH 074/255] Comment --- src/hb-ot-shape-complex-indic.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc index 918e0d7e0..dfb67cfb9 100644 --- a/src/hb-ot-shape-complex-indic.cc +++ b/src/hb-ot-shape-complex-indic.cc @@ -788,6 +788,8 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, * * We could use buffer->sort() for this, if there was no special * reordering of pre-base stuff happening later... + * We don't want to merge_clusters all of that, which buffer->sort() + * would. */ if (indic_plan->is_old_spec || end - start > 127) buffer->merge_clusters (base, end); From 6a38fd68a8f4e66d9248e0c943ae3a1cf45c521b Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sat, 27 Oct 2018 10:50:53 +0330 Subject: [PATCH 075/255] [ot-color/png] sbix runtime memory check --- src/hb-ot-color-cbdt-table.hh | 16 +++++++--------- src/hb-ot-color-sbix-table.hh | 18 ++++++++++++------ src/hb-ot-color-svg-table.hh | 4 ++-- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index 0f64577d3..770fe3eb9 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -452,7 +452,7 @@ struct CBDT } inline void dump (void (*callback) (const uint8_t* data, unsigned int length, - unsigned int group, unsigned int gid)) const + unsigned int group, unsigned int gid)) const { if (!cblc) return; // Not a color bitmap font. @@ -504,15 +504,13 @@ struct CBDT } } - inline hb_blob_t* reference_blob_for_glyph (hb_codepoint_t glyph_id, - unsigned int requested_x_ppem, - unsigned int requested_y_ppem, - unsigned int *strike_x_ppem, - unsigned int *strike_y_ppem) const + inline hb_blob_t* reference_blob_for_glyph (hb_codepoint_t glyph_id HB_UNUSED, + unsigned int requested_x_ppem HB_UNUSED, + unsigned int requested_y_ppem HB_UNUSED, + unsigned int *strike_x_ppem HB_UNUSED, + unsigned int *strike_y_ppem HB_UNUSED) const { -// if (unlikely (cbdt_len == 0)) - return hb_blob_get_empty (); -// return svg->get_glyph_entry (glyph_id).reference_blob (svg_blob, svg->svgDocEntries); + return hb_blob_get_empty (); } inline bool has_data () const diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 97eac9b58..cba62f0cf 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -82,6 +82,7 @@ struct SBIXStrike inline hb_blob_t *get_glyph_blob (unsigned int glyph_id, hb_blob_t *sbix_blob, + unsigned int sbix_len, unsigned int strike_offset, unsigned int *x_offset, unsigned int *y_offset, @@ -91,6 +92,9 @@ struct SBIXStrike if (imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] == 0) return hb_blob_get_empty (); + if (strike_offset + (unsigned int) imageOffsetsZ[glyph_id] + SBIXGlyph::min_size > sbix_len) + return hb_blob_get_empty (); + const SBIXGlyph *glyph = &(this+imageOffsetsZ[glyph_id]); if (unlikely (glyph->graphicType == HB_TAG ('d','u','p','e') && blob_size (glyph_id) >= 2)) @@ -100,6 +104,8 @@ struct SBIXStrike { glyph = &(this+imageOffsetsZ[new_glyph_id]); glyph_id = new_glyph_id; + if (strike_offset + (unsigned int) imageOffsetsZ[glyph_id] + SBIXGlyph::min_size > sbix_len) + return hb_blob_get_empty (); } } if (unlikely (requested_file_type != glyph->graphicType)) @@ -155,18 +161,18 @@ struct sbix const SBIXStrike &strike = sbix_table+sbix_table->strikes[group]; for (unsigned int glyph_id = 0; glyph_id < num_glyphs; glyph_id++) { - unsigned int x_offset, y_offset; hb_tag_t tag; hb_blob_t *blob; - blob = strike.get_glyph_blob (glyph_id, sbix_blob, sbix_table->strikes[group], - &x_offset, &x_offset, + blob = strike.get_glyph_blob (glyph_id, sbix_blob, sbix_len, + sbix_table->strikes[group], + nullptr, nullptr, HB_TAG('p','n','g',' '), num_glyphs); if (hb_blob_get_length (blob)) callback (blob, group, glyph_id); } } } - inline hb_blob_t* reference_blob_for_glyph (hb_codepoint_t glyph_id, + inline hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id, unsigned int ptem HB_UNUSED, unsigned int requested_ppem, unsigned int requested_file_type, @@ -187,7 +193,8 @@ struct sbix const SBIXStrike &strike = sbix_table+sbix_table->strikes[group]; if (available_x_ppem) *available_x_ppem = strike.get_ppem (); if (available_y_ppem) *available_y_ppem = strike.get_ppem (); - return strike.get_glyph_blob (glyph_id, sbix_blob, sbix_table->strikes[group], + return strike.get_glyph_blob (glyph_id, sbix_blob, sbix_len, + sbix_table->strikes[group], nullptr, nullptr, requested_file_type, num_glyphs); } @@ -200,7 +207,6 @@ struct sbix unsigned int sbix_len; unsigned int num_glyphs; - hb_vector_t > data_offsets; }; protected: diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh index 4ef380745..5238ad458 100644 --- a/src/hb-ot-color-svg-table.hh +++ b/src/hb-ot-color-svg-table.hh @@ -50,7 +50,7 @@ struct SVGDocumentIndexEntry return b->cmp (*a); } - inline hb_blob_t* reference_blob (hb_blob_t *svg_blob, unsigned int index_offset) const + inline hb_blob_t *reference_blob (hb_blob_t *svg_blob, unsigned int index_offset) const { if (svgDocLength == 0) return hb_blob_get_empty (); return hb_blob_create_sub_blob (svg_blob, (unsigned int) svgDoc + index_offset, @@ -95,7 +95,7 @@ struct SVG hb_blob_destroy (svg_blob); } - inline hb_blob_t* reference_blob_for_glyph (hb_codepoint_t glyph_id) const + inline hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id) const { if (unlikely (svg_len == 0)) return hb_blob_get_empty (); From dc11a38107ac1f0a2d3edacae33ff7f10f5e894c Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sat, 27 Oct 2018 12:15:25 +0330 Subject: [PATCH 076/255] [sbix] Set num_glyphs on accelerator dump-emoji was broken without it --- src/hb-ot-color-sbix-table.hh | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 1b643c77a..ec956a8de 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -99,6 +99,7 @@ struct sbix sbix_blob = hb_sanitize_context_t().reference_table (face); sbix_len = hb_blob_get_length (sbix_blob); sbix_table = sbix_blob->as (); + num_glyphs = face->get_num_glyphs (); } inline void fini (void) From 0353ac6cde47df8f5386733f5c12cc60732a5bf4 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sat, 27 Oct 2018 12:24:53 +0330 Subject: [PATCH 077/255] Fix test-name-table on older bots --- src/test-name-table.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test-name-table.cc b/src/test-name-table.cc index 66596fe47..ad6d493de 100644 --- a/src/test-name-table.cc +++ b/src/test-name-table.cc @@ -41,7 +41,7 @@ main (int argc, char **argv) hb_blob_t *blob = hb_blob_create_from_file (argv[1]); hb_face_t *face = hb_face_create (blob, 0 /* first face */); hb_blob_destroy (blob); - blob = nullptr; + blob = NULL; const hb_ot_name_entry_t *entries; unsigned int count = hb_ot_name_get_names (face, &entries); From 5e2a52f71a8d081441fbc1c57a3550e3a9573e46 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sat, 27 Oct 2018 12:44:33 +0330 Subject: [PATCH 078/255] [sbix] Remove dump method from sbix accelerator --- src/dump-emoji.cc | 36 +++++++++++++++++++++++------------ src/hb-ot-color-sbix-table.hh | 26 ++++++++++--------------- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/src/dump-emoji.cc b/src/dump-emoji.cc index 7c7392f20..73305aa77 100644 --- a/src/dump-emoji.cc +++ b/src/dump-emoji.cc @@ -58,15 +58,30 @@ cbdt_callback (const uint8_t* data, unsigned int length, } static void -sbix_callback (hb_blob_t *blob, unsigned int group, unsigned int gid) +sbix_dump (hb_face_t *face) { - char output_path[255]; - sprintf (output_path, "out/sbix-%d-%d.png", group, gid); - FILE *f = fopen (output_path, "wb"); - unsigned int length; - const char* data = hb_blob_get_data (blob, &length); - fwrite (data, 1, length, f); - fclose (f); + OT::sbix::accelerator_t sbix; + sbix.init (face); + unsigned int length = 0; + unsigned int *available_ppems = sbix.get_available_ppems (&length); + unsigned int num_glyphs = face->num_glyphs; + for (unsigned int group = 0; group < length; group++) + for (unsigned int glyph_id = 0; glyph_id < num_glyphs; glyph_id++) + { + hb_blob_t *blob; + blob = sbix.reference_blob_for_glyph (glyph_id, 0, available_ppems[group], + HB_TAG('p','n','g',' '), NULL, NULL); + if (hb_blob_get_length (blob) == 0) continue; + + char output_path[255]; + sprintf (output_path, "out/sbix-%d-%d.png", available_ppems[group], glyph_id); + FILE *f = fopen (output_path, "wb"); + unsigned int length; + const char* data = hb_blob_get_data (blob, &length); + fwrite (data, 1, length, f); + fclose (f); + } + sbix.fini (); } static void @@ -273,10 +288,7 @@ main (int argc, char **argv) cbdt.dump (cbdt_callback); cbdt.fini (); - OT::sbix::accelerator_t sbix; - sbix.init (face); - sbix.dump (sbix_callback); - sbix.fini (); + sbix_dump (face); if (hb_ot_color_has_svg (face)) svg_dump (face); diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index cba62f0cf..b48ea1715 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -153,23 +153,17 @@ struct sbix hb_blob_destroy (sbix_blob); } - inline void dump (void (*callback) (hb_blob_t *data, - unsigned int group, unsigned int gid)) const + /* only to support dump-emoji, don't use it anywhere else */ + inline unsigned int *get_available_ppems (unsigned int *length) { - for (unsigned group = 0; group < sbix_table->strikes.len; group++) - { - const SBIXStrike &strike = sbix_table+sbix_table->strikes[group]; - for (unsigned int glyph_id = 0; glyph_id < num_glyphs; glyph_id++) - { - hb_tag_t tag; - hb_blob_t *blob; - blob = strike.get_glyph_blob (glyph_id, sbix_blob, sbix_len, - sbix_table->strikes[group], - nullptr, nullptr, - HB_TAG('p','n','g',' '), num_glyphs); - if (hb_blob_get_length (blob)) callback (blob, group, glyph_id); - } - } + if (unlikely (sbix_len == 0 || sbix_table->strikes.len == 0)) + return nullptr; + *length = sbix_table->strikes.len; + unsigned int *result; + result = (unsigned int *) malloc (sizeof (unsigned int) * sbix_table->strikes.len); + for (unsigned int i = 0; i < sbix_table->strikes.len; i++) + result[i] = (sbix_table+sbix_table->strikes[i]).get_ppem (); + return result; } inline hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id, From 4025ad804383dc8d5ace9654ae21d4d726d0dbc4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 27 Oct 2018 02:35:06 -0700 Subject: [PATCH 079/255] Document new API --- src/hb-common.h | 30 +++++++++++++++++++++- src/hb-ot-color.cc | 16 ++++++------ src/hb-ot-layout.cc | 2 +- src/hb-ot-name.cc | 61 ++++++++++++++++++++++++++++++++++++++++++++- src/hb-ot-name.h | 15 +++++++++++ 5 files changed, 113 insertions(+), 11 deletions(-) diff --git a/src/hb-common.h b/src/hb-common.h index 0858c0e29..2532d69fe 100644 --- a/src/hb-common.h +++ b/src/hb-common.h @@ -449,15 +449,43 @@ hb_variation_to_string (hb_variation_t *variation, * * Data type for holding color values. * - * Since: REPLACEME + * Since: 2.1.0 */ typedef uint32_t hb_color_t; #define HB_COLOR(b,g,r,a) ((hb_color_t) HB_TAG ((b),(g),(r),(a))) +/** + * hb_color_get_alpha: + * + * + * + * Since: 2.1.0 + */ #define hb_color_get_alpha(color) ((color) & 0xFF) +/** + * hb_color_get_red: + * + * + * + * Since: 2.1.0 + */ #define hb_color_get_red(color) (((color) >> 8) & 0xFF) +/** + * hb_color_get_green: + * + * + * + * Since: 2.1.0 + */ #define hb_color_get_green(color) (((color) >> 16) & 0xFF) +/** + * hb_color_get_blue: + * + * + * + * Since: 2.1.0 + */ #define hb_color_get_blue(color) (((color) >> 24) & 0xFF) diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index 3f492cc1f..58f5a0709 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -89,7 +89,7 @@ _get_svg (hb_face_t *face) * * Returns: whether CPAL table is available. * - * Since: REPLACEME + * Since: 2.1.0 */ hb_bool_t hb_ot_color_has_palettes (hb_face_t *face) @@ -104,7 +104,7 @@ hb_ot_color_has_palettes (hb_face_t *face) * Returns: the number of color palettes in @face, or zero if @face has * no colors. * - * Since: REPLACEME + * Since: 2.1.0 */ unsigned int hb_ot_color_palette_get_count (hb_face_t *face) @@ -123,7 +123,7 @@ hb_ot_color_palette_get_count (hb_face_t *face) * Returns: an identifier within @face's `name` table. * If the requested palette has no name the result is #HB_NAME_ID_INVALID. * - * Since: REPLACEME + * Since: 2.1.0 */ hb_name_id_t hb_ot_color_palette_get_name_id (hb_face_t *face, @@ -139,7 +139,7 @@ hb_ot_color_palette_get_name_id (hb_face_t *face, * * Returns: Name ID associated with a palette entry, e.g. eye color * - * Since: REPLACEME + * Since: 2.1.0 */ hb_name_id_t hb_ot_color_palette_color_get_name_id (hb_face_t *face, @@ -155,7 +155,7 @@ hb_ot_color_palette_color_get_name_id (hb_face_t *face, * * Returns: the flags for the requested color palette. * - * Since: REPLACEME + * Since: 2.1.0 */ hb_ot_color_palette_flags_t hb_ot_color_palette_get_flags (hb_face_t *face, @@ -186,7 +186,7 @@ hb_ot_color_palette_get_flags (hb_face_t *face, * * Returns: the total number of colors in the palette. * - * Since: REPLACEME + * Since: 2.1.0 */ unsigned int hb_ot_color_palette_get_colors (hb_face_t *face, @@ -209,7 +209,7 @@ hb_ot_color_palette_get_colors (hb_face_t *face, * * Returns: whether COLR table is available. * - * Since: REPLACEME + * Since: 2.1.0 */ hb_bool_t hb_ot_color_has_layers (hb_face_t *face) @@ -227,7 +227,7 @@ hb_ot_color_has_layers (hb_face_t *face) * * Returns: * - * Since: REPLACEME + * Since: 2.1.0 */ unsigned int hb_ot_color_glyph_get_layers (hb_face_t *face, diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 096fda207..27c49df7d 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -1174,7 +1174,7 @@ hb_ot_layout_feature_get_name_ids (hb_face_t *face, * one shot copying). * @char_count: (inout) (allow-none): The count of characters for which this feature * provides glyph variants. (May be zero.) - * @characters: (out) (allow-none): A buffer pointer. The Unicode Scalar Value + * @characters: (out caller-allocates) (array length=char_count): A buffer pointer. The Unicode codepoints * of the characters for which this feature provides glyph variants. * * Fetches characters listed by designer under feature parameters for "Character diff --git a/src/hb-ot-name.cc b/src/hb-ot-name.cc index f1c1f76e8..650d99ab0 100644 --- a/src/hb-ot-name.cc +++ b/src/hb-ot-name.cc @@ -39,7 +39,18 @@ _get_name (hb_face_t *face) return *(hb_ot_face_data (face)->name.get ()); } - +/** + * hb_ot_name_get_names: + * @face: font face. + * @entries: (out) (transfer none) (array): + * + * Enumerates all available name IDs and language combinations. Returned + * array is owned by the @face and should not be modified. It can be + * used as long as @face is alive. + * + * Returns: Number of entries returned. + * Since: 2.1.0 + **/ unsigned int hb_ot_name_get_names (hb_face_t *face, const hb_ot_name_entry_t **entries /* OUT */) @@ -131,6 +142,22 @@ hb_ot_name_get_utf (hb_face_t *face, return 0; } +/** + * hb_ot_name_get_utf8: + * @face: font face. + * @name_id: OpenType name identifier to fetch. + * @language: language to fetch the name for. + * @text_size: (inout) (allow-none): input size of @text buffer, and output size of + * text written to buffer. + * @text: (out caller-allocates) (array length=text_size): buffer to write fetched name into. + * + * Fetches a font name from the OpenType 'name' table. + * If @language is #HB_LANGUAGE_INVALID, English ("en") is assumed. + * Returns string in UTF-8 encoding. + * + * Returns: full length of the requested string, or 0 if not found. + * Since: 2.1.0 + **/ unsigned int hb_ot_name_get_utf8 (hb_face_t *face, hb_name_id_t name_id, @@ -142,6 +169,22 @@ hb_ot_name_get_utf8 (hb_face_t *face, (hb_utf8_t::codepoint_t *) text); } +/** + * hb_ot_name_get_utf16: + * @face: font face. + * @name_id: OpenType name identifier to fetch. + * @language: language to fetch the name for. + * @text_size: (inout) (allow-none): input size of @text buffer, and output size of + * text written to buffer. + * @text: (out caller-allocates) (array length=text_size): buffer to write fetched name into. + * + * Fetches a font name from the OpenType 'name' table. + * If @language is #HB_LANGUAGE_INVALID, English ("en") is assumed. + * Returns string in UTF-16 encoding. + * + * Returns: full length of the requested string, or 0 if not found. + * Since: 2.1.0 + **/ unsigned int hb_ot_name_get_utf16 (hb_face_t *face, hb_name_id_t name_id, @@ -152,6 +195,22 @@ hb_ot_name_get_utf16 (hb_face_t *face, return hb_ot_name_get_utf (face, name_id, language, text_size, text); } +/** + * hb_ot_name_get_utf32: + * @face: font face. + * @name_id: OpenType name identifier to fetch. + * @language: language to fetch the name for. + * @text_size: (inout) (allow-none): input size of @text buffer, and output size of + * text written to buffer. + * @text: (out caller-allocates) (array length=text_size): buffer to write fetched name into. + * + * Fetches a font name from the OpenType 'name' table. + * If @language is #HB_LANGUAGE_INVALID, English ("en") is assumed. + * Returns string in UTF-32 encoding. + * + * Returns: full length of the requested string, or 0 if not found. + * Since: 2.1.0 + **/ unsigned int hb_ot_name_get_utf32 (hb_face_t *face, hb_name_id_t name_id, diff --git a/src/hb-ot-name.h b/src/hb-ot-name.h index 66af5b646..18476553b 100644 --- a/src/hb-ot-name.h +++ b/src/hb-ot-name.h @@ -66,6 +66,10 @@ enum { /** * hb_name_id_t: * + * An integral type representing an OpenType 'name' table name identifier. + * There are predefined name IDs, as well as name IDs return from other + * API. These can be used to fetch name strings from a font face. + * * Since: 2.0.0 */ typedef unsigned int hb_name_id_t; @@ -73,6 +77,8 @@ typedef unsigned int hb_name_id_t; /** * HB_NAME_ID_INVALID * + * Value to represent a nonexistent name ID. + * * Since: 2.0.0 **/ #define HB_NAME_ID_INVALID 0xFFFF @@ -100,6 +106,15 @@ hb_ot_name_get_utf32 (hb_face_t *face, uint32_t *text /* OUT */); +/** + * hb_ot_name_entry_t: + * @name_id: name ID + * @language: language + * + * Structure representing a name ID in a particular language. + * + * Since: 2.1.0 + **/ typedef struct hb_ot_name_entry_t { hb_name_id_t name_id; From 3b7e5f131383956e19642d28c938f1bc0d16295f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 27 Oct 2018 02:39:20 -0700 Subject: [PATCH 080/255] [name] Rename hb_ot_name_get_names() to hb_ot_name_list_names() And swap return value positions, so can be annotated for gobject-introspectin. --- docs/harfbuzz-sections.txt | 2 +- src/hb-ot-name.cc | 17 ++++++++--------- src/hb-ot-name.h | 6 +++--- src/test-name-table.cc | 4 ++-- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index 8229d4664..dcca4f6c9 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -490,7 +490,7 @@ hb_ot_font_set_funcs hb-ot-name hb_name_id_t HB_NAME_ID_INVALID -hb_ot_name_get_names +hb_ot_name_list_names hb_ot_name_get_utf16 hb_ot_name_get_utf32 hb_ot_name_get_utf8 diff --git a/src/hb-ot-name.cc b/src/hb-ot-name.cc index 650d99ab0..28a45f010 100644 --- a/src/hb-ot-name.cc +++ b/src/hb-ot-name.cc @@ -40,25 +40,24 @@ _get_name (hb_face_t *face) } /** - * hb_ot_name_get_names: + * hb_ot_name_list_names: * @face: font face. - * @entries: (out) (transfer none) (array): + * @num_entries: (out) number of returned entries. * * Enumerates all available name IDs and language combinations. Returned * array is owned by the @face and should not be modified. It can be * used as long as @face is alive. * - * Returns: Number of entries returned. + * Returns: (out) (transfer none) (array length=num_entries) Array of available name entries. * Since: 2.1.0 **/ -unsigned int -hb_ot_name_get_names (hb_face_t *face, - const hb_ot_name_entry_t **entries /* OUT */) +const hb_ot_name_entry_t * +hb_ot_name_list_names (hb_face_t *face, + unsigned int *num_entries /* OUT */) { const OT::name_accelerator_t &name = _get_name (face); - if (entries) - *entries = name.names.arrayZ(); - return name.names.len; + *num_entries = name.names.len; + return name.names.arrayZ(); } diff --git a/src/hb-ot-name.h b/src/hb-ot-name.h index 18476553b..076773946 100644 --- a/src/hb-ot-name.h +++ b/src/hb-ot-name.h @@ -124,9 +124,9 @@ typedef struct hb_ot_name_entry_t hb_language_t language; } hb_ot_name_entry_t; -HB_EXTERN unsigned int -hb_ot_name_get_names (hb_face_t *face, - const hb_ot_name_entry_t **entries /* OUT */); +HB_EXTERN const hb_ot_name_entry_t * +hb_ot_name_list_names (hb_face_t *face, + unsigned int *num_entries /* OUT */); HB_END_DECLS diff --git a/src/test-name-table.cc b/src/test-name-table.cc index ad6d493de..333052729 100644 --- a/src/test-name-table.cc +++ b/src/test-name-table.cc @@ -43,8 +43,8 @@ main (int argc, char **argv) hb_blob_destroy (blob); blob = NULL; - const hb_ot_name_entry_t *entries; - unsigned int count = hb_ot_name_get_names (face, &entries); + unsigned int count; + const hb_ot_name_entry_t *entries = hb_ot_name_list_names (face, &count); for (unsigned int i = 0; i < count; i++) { From a8a55b9f892a5e4f086b20bbe337dc29182210af Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 27 Oct 2018 02:45:57 -0700 Subject: [PATCH 081/255] [name] Move around --- src/hb-ot-name.h | 84 ++++++++++++++++++++++++------------------------ 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/src/hb-ot-name.h b/src/hb-ot-name.h index 076773946..9cb6f5a1b 100644 --- a/src/hb-ot-name.h +++ b/src/hb-ot-name.h @@ -34,6 +34,26 @@ HB_BEGIN_DECLS +/** + * hb_name_id_t: + * + * An integral type representing an OpenType 'name' table name identifier. + * There are predefined name IDs, as well as name IDs return from other + * API. These can be used to fetch name strings from a font face. + * + * Since: 2.0.0 + */ +typedef unsigned int hb_name_id_t; + +/** + * HB_NAME_ID_INVALID + * + * Value to represent a nonexistent name ID. + * + * Since: 2.0.0 + **/ +#define HB_NAME_ID_INVALID 0xFFFF + enum { HB_NAME_ID_COPYRIGHT = 0, HB_NAME_ID_FONT_FAMILY = 1, @@ -63,48 +83,6 @@ enum { HB_NAME_ID_VARIATIONS_PS_PREFIX = 25 }; -/** - * hb_name_id_t: - * - * An integral type representing an OpenType 'name' table name identifier. - * There are predefined name IDs, as well as name IDs return from other - * API. These can be used to fetch name strings from a font face. - * - * Since: 2.0.0 - */ -typedef unsigned int hb_name_id_t; - -/** - * HB_NAME_ID_INVALID - * - * Value to represent a nonexistent name ID. - * - * Since: 2.0.0 - **/ -#define HB_NAME_ID_INVALID 0xFFFF - - -HB_EXTERN unsigned int -hb_ot_name_get_utf8 (hb_face_t *face, - hb_name_id_t name_id, - hb_language_t language, - unsigned int *text_size /* IN/OUT */, - char *text /* OUT */); - -HB_EXTERN unsigned int -hb_ot_name_get_utf16 (hb_face_t *face, - hb_name_id_t name_id, - hb_language_t language, - unsigned int *text_size /* IN/OUT */, - uint16_t *text /* OUT */); - -HB_EXTERN unsigned int -hb_ot_name_get_utf32 (hb_face_t *face, - hb_name_id_t name_id, - hb_language_t language, - unsigned int *text_size /* IN/OUT */, - uint32_t *text /* OUT */); - /** * hb_ot_name_entry_t: @@ -129,6 +107,28 @@ hb_ot_name_list_names (hb_face_t *face, unsigned int *num_entries /* OUT */); +HB_EXTERN unsigned int +hb_ot_name_get_utf8 (hb_face_t *face, + hb_name_id_t name_id, + hb_language_t language, + unsigned int *text_size /* IN/OUT */, + char *text /* OUT */); + +HB_EXTERN unsigned int +hb_ot_name_get_utf16 (hb_face_t *face, + hb_name_id_t name_id, + hb_language_t language, + unsigned int *text_size /* IN/OUT */, + uint16_t *text /* OUT */); + +HB_EXTERN unsigned int +hb_ot_name_get_utf32 (hb_face_t *face, + hb_name_id_t name_id, + hb_language_t language, + unsigned int *text_size /* IN/OUT */, + uint32_t *text /* OUT */); + + HB_END_DECLS #endif /* HB_OT_NAME_H */ From 40496a54a03864c5e6a1224c18b4b93a1f578eed Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 27 Oct 2018 02:49:32 -0700 Subject: [PATCH 082/255] [name] Move HB_NAME_ID_INVALID into the enum Don't know how to document anonymous enum members. --- src/hb-ot-name.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-name.h b/src/hb-ot-name.h index 9cb6f5a1b..d39b70382 100644 --- a/src/hb-ot-name.h +++ b/src/hb-ot-name.h @@ -52,8 +52,6 @@ typedef unsigned int hb_name_id_t; * * Since: 2.0.0 **/ -#define HB_NAME_ID_INVALID 0xFFFF - enum { HB_NAME_ID_COPYRIGHT = 0, HB_NAME_ID_FONT_FAMILY = 1, @@ -80,7 +78,9 @@ enum { HB_NAME_ID_WWS_SUBFAMILY = 22, HB_NAME_ID_LIGHT_BACKGROUND = 23, HB_NAME_ID_DARK_BACKGROUND = 24, - HB_NAME_ID_VARIATIONS_PS_PREFIX = 25 + HB_NAME_ID_VARIATIONS_PS_PREFIX = 25, + + HB_NAME_ID_INVALID = 0xFFFF }; From d941f66c75fe26f909b1ba248535cc372bbde851 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 27 Oct 2018 02:55:52 -0700 Subject: [PATCH 083/255] [name] Make hb_name_id_t be the enum This is like hb_script_t. We had this exposed as unsigned int since 2.0.0 release in two APIs, as well as hb_ot_layout_get_size_params() from earlier. But since no one uses those (right?!), let's just fix this now. --- docs/harfbuzz-docs.xml | 6 ++++-- docs/harfbuzz-sections.txt | 4 +++- src/hb-ot-color-cpal-table.hh | 12 ++++++------ src/hb-ot-layout.cc | 16 ++++++++-------- src/hb-ot-name-table.hh | 2 +- src/hb-ot-name.h | 15 ++++----------- src/test-size-params.cc | 2 +- 7 files changed, 27 insertions(+), 30 deletions(-) diff --git a/docs/harfbuzz-docs.xml b/docs/harfbuzz-docs.xml index 3488ccb7f..859cc7098 100644 --- a/docs/harfbuzz-docs.xml +++ b/docs/harfbuzz-docs.xml @@ -76,11 +76,13 @@ + - - + + + diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index dcca4f6c9..7f2ff2d2f 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -360,6 +360,7 @@ HB_GOBJECT_TYPE_FONT_FUNCS HB_GOBJECT_TYPE_GLYPH_FLAGS HB_GOBJECT_TYPE_MAP HB_GOBJECT_TYPE_MEMORY_MODE +HB_GOBJECT_TYPE_NAME_ID HB_GOBJECT_TYPE_OT_COLOR_PALETTE_FLAGS HB_GOBJECT_TYPE_OT_LAYOUT_GLYPH_CLASS HB_GOBJECT_TYPE_OT_MATH_CONSTANT @@ -393,6 +394,7 @@ hb_gobject_font_get_type hb_gobject_glyph_flags_get_type hb_gobject_map_get_type hb_gobject_memory_mode_get_type +hb_gobject_name_id_get_type hb_gobject_ot_color_palette_flags_get_type hb_gobject_ot_layout_glyph_class_get_type hb_gobject_ot_math_constant_get_type @@ -489,7 +491,7 @@ hb_ot_font_set_funcs
hb-ot-name hb_name_id_t -HB_NAME_ID_INVALID +hb_ot_name_entry_t hb_ot_name_list_names hb_ot_name_get_utf16 hb_ot_name_get_utf32 diff --git a/src/hb-ot-color-cpal-table.hh b/src/hb-ot-color-cpal-table.hh index 7d3733d3f..0e13bece2 100644 --- a/src/hb-ot-color-cpal-table.hh +++ b/src/hb-ot-color-cpal-table.hh @@ -58,22 +58,22 @@ struct CPALV1Tail hb_array (base+paletteFlagsZ, palette_count)[palette_index]; } - inline unsigned int + inline hb_name_id_t get_palette_name_id (const void *base, unsigned int palette_index, unsigned int palette_count) const { if (!paletteLabelsZ) return HB_NAME_ID_INVALID; - return hb_array (base+paletteLabelsZ, palette_count)[palette_index]; + return (hb_name_id_t) (unsigned) hb_array (base+paletteLabelsZ, palette_count)[palette_index]; } - inline unsigned int + inline hb_name_id_t get_color_name_id (const void *base, unsigned int color_index, unsigned int color_count) const { if (!colorLabelsZ) return HB_NAME_ID_INVALID; - return hb_array (base+colorLabelsZ, color_count)[color_index]; + return (hb_name_id_t) (unsigned) hb_array (base+colorLabelsZ, color_count)[color_index]; } public: @@ -123,10 +123,10 @@ struct CPAL inline hb_ot_color_palette_flags_t get_palette_flags (unsigned int palette_index) const { return v1 ().get_palette_flags (this, palette_index, numPalettes); } - inline unsigned int get_palette_name_id (unsigned int palette_index) const + inline hb_name_id_t get_palette_name_id (unsigned int palette_index) const { return v1 ().get_palette_name_id (this, palette_index, numPalettes); } - inline unsigned int get_color_name_id (unsigned int color_index) const + inline hb_name_id_t get_color_name_id (unsigned int color_index) const { return v1 ().get_color_name_id (this, color_index, numColors); } inline unsigned int get_palette_colors (unsigned int palette_index, diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 27c49df7d..47230b63e 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -1050,7 +1050,7 @@ hb_bool_t hb_ot_layout_get_size_params (hb_face_t *face, unsigned int *design_size, /* OUT. May be NULL */ unsigned int *subfamily_id, /* OUT. May be NULL */ - unsigned int *subfamily_name_id, /* OUT. May be NULL */ + hb_name_id_t *subfamily_name_id, /* OUT. May be NULL */ unsigned int *range_start, /* OUT. May be NULL */ unsigned int *range_end /* OUT. May be NULL */) { @@ -1069,7 +1069,7 @@ hb_ot_layout_get_size_params (hb_face_t *face, { if (design_size) *design_size = params.designSize; if (subfamily_id) *subfamily_id = params.subfamilyID; - if (subfamily_name_id) *subfamily_name_id = params.subfamilyNameID; + if (subfamily_name_id) *subfamily_name_id = (hb_name_id_t) (unsigned) params.subfamilyNameID; if (range_start) *range_start = params.rangeStart; if (range_end) *range_end = params.rangeEnd; @@ -1080,7 +1080,7 @@ hb_ot_layout_get_size_params (hb_face_t *face, if (design_size) *design_size = 0; if (subfamily_id) *subfamily_id = 0; - if (subfamily_name_id) *subfamily_name_id = 0; + if (subfamily_name_id) *subfamily_name_id = HB_NAME_ID_INVALID; if (range_start) *range_start = 0; if (range_end) *range_end = 0; @@ -1133,7 +1133,7 @@ hb_ot_layout_feature_get_name_ids (hb_face_t *face, feature_params.get_stylistic_set_params (feature_tag); if (&ss_params != &Null (OT::FeatureParamsStylisticSet)) /* ssXX */ { - if (label_id) *label_id = ss_params.uiNameID; + if (label_id) *label_id = (hb_name_id_t) (unsigned) ss_params.uiNameID; // ssXX features don't have the rest if (tooltip_id) *tooltip_id = HB_NAME_ID_INVALID; if (sample_id) *sample_id = HB_NAME_ID_INVALID; @@ -1145,11 +1145,11 @@ hb_ot_layout_feature_get_name_ids (hb_face_t *face, feature_params.get_character_variants_params (feature_tag); if (&cv_params != &Null (OT::FeatureParamsCharacterVariants)) /* cvXX */ { - if (label_id) *label_id = cv_params.featUILableNameID; - if (tooltip_id) *tooltip_id = cv_params.featUITooltipTextNameID; - if (sample_id) *sample_id = cv_params.sampleTextNameID; + if (label_id) *label_id = (hb_name_id_t) (unsigned) cv_params.featUILableNameID; + if (tooltip_id) *tooltip_id = (hb_name_id_t) (unsigned) cv_params.featUITooltipTextNameID; + if (sample_id) *sample_id = (hb_name_id_t) (unsigned) cv_params.sampleTextNameID; if (num_named_parameters) *num_named_parameters = cv_params.numNamedParameters; - if (first_param_id) *first_param_id = cv_params.firstParamUILabelNameID; + if (first_param_id) *first_param_id = (hb_name_id_t) (unsigned) cv_params.firstParamUILabelNameID; return true; } } diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index b84edd185..daf78c89c 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -194,7 +194,7 @@ struct name { hb_ot_name_entry_t *entry = this->names.push (); - entry->name_id = all_names[i].nameID; + entry->name_id = (hb_name_id_t) (unsigned) all_names[i].nameID; entry->language = all_names[i].language (face); entry->entry_score = all_names[i].score (); entry->entry_index = i; diff --git a/src/hb-ot-name.h b/src/hb-ot-name.h index d39b70382..002270a55 100644 --- a/src/hb-ot-name.h +++ b/src/hb-ot-name.h @@ -36,23 +36,16 @@ HB_BEGIN_DECLS /** * hb_name_id_t: + * @HB_NAME_ID_INVALID: Value to represent a nonexistent name ID. * * An integral type representing an OpenType 'name' table name identifier. * There are predefined name IDs, as well as name IDs return from other * API. These can be used to fetch name strings from a font face. * * Since: 2.0.0 - */ -typedef unsigned int hb_name_id_t; - -/** - * HB_NAME_ID_INVALID - * - * Value to represent a nonexistent name ID. - * - * Since: 2.0.0 **/ -enum { +typedef enum +{ HB_NAME_ID_COPYRIGHT = 0, HB_NAME_ID_FONT_FAMILY = 1, HB_NAME_ID_FONT_SUBFAMILY = 2, @@ -81,7 +74,7 @@ enum { HB_NAME_ID_VARIATIONS_PS_PREFIX = 25, HB_NAME_ID_INVALID = 0xFFFF -}; +} hb_name_id_t ; /** diff --git a/src/test-size-params.cc b/src/test-size-params.cc index e53a47d8d..b0905d5ad 100644 --- a/src/test-size-params.cc +++ b/src/test-size-params.cc @@ -46,7 +46,7 @@ main (int argc, char **argv) blob = nullptr; unsigned int p[5]; - bool ret = hb_ot_layout_get_size_params (face, p, p+1, p+2, p+3, p+4); + bool ret = hb_ot_layout_get_size_params (face, p, p+1, (hb_name_id_t *) (p+2), p+3, p+4); printf ("%g %u %u %g %g\n", p[0]/10., p[1], p[2], p[3]/10., p[4]/10.); From 9457cfd7bcc9c2fff38194f2bb82ab7be881bfeb Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 27 Oct 2018 03:15:34 -0700 Subject: [PATCH 084/255] [docs] Hook up hb-map --- docs/harfbuzz-docs.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/harfbuzz-docs.xml b/docs/harfbuzz-docs.xml index 859cc7098..0057a2a9d 100644 --- a/docs/harfbuzz-docs.xml +++ b/docs/harfbuzz-docs.xml @@ -74,6 +74,7 @@ + From 9435fb24daadf08add9a701816da01bd54c0cd78 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sat, 27 Oct 2018 13:32:14 +0330 Subject: [PATCH 085/255] [ot-color/png] Implement CBDT part --- src/hb-ot-color-cbdt-table.hh | 56 +++++++++++++++++++++++++++++++---- src/hb-ot-color.cc | 19 ++---------- src/hb-ot-color.h | 4 +++ test/api/test-ot-color.c | 25 ++++++++++++++-- 4 files changed, 79 insertions(+), 25 deletions(-) diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index 770fe3eb9..a9518b774 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -504,12 +504,58 @@ struct CBDT } } - inline hb_blob_t* reference_blob_for_glyph (hb_codepoint_t glyph_id HB_UNUSED, - unsigned int requested_x_ppem HB_UNUSED, - unsigned int requested_y_ppem HB_UNUSED, - unsigned int *strike_x_ppem HB_UNUSED, - unsigned int *strike_y_ppem HB_UNUSED) const + inline hb_blob_t* reference_blob_for_glyph (hb_codepoint_t glyph_id, + unsigned int requested_x_ppem, + unsigned int requested_y_ppem, + unsigned int *strike_x_ppem, + unsigned int *strike_y_ppem) const { + if (!cblc) + return hb_blob_get_empty (); // Not a color bitmap font. + + if (requested_x_ppem == 0) requested_x_ppem = upem; + if (requested_y_ppem == 0) requested_y_ppem = upem; + unsigned int x_ppem = requested_x_ppem, y_ppem = requested_y_ppem; + + const void *base; + const IndexSubtableRecord *subtable_record = this->cblc->find_table (glyph_id, &x_ppem, &y_ppem, &base); + if (!subtable_record || !x_ppem || !y_ppem) + return hb_blob_get_empty (); + + unsigned int image_offset = 0, image_length = 0, image_format = 0; + if (!subtable_record->get_image_data (glyph_id, base, &image_offset, &image_length, &image_format)) + return hb_blob_get_empty (); + + switch (image_format) + { + case 17: { + if (strike_x_ppem) *strike_x_ppem = x_ppem; + if (strike_x_ppem) *strike_y_ppem = y_ppem; + const GlyphBitmapDataFormat17& glyphFormat17 = + StructAtOffset (this->cbdt, image_offset); + return hb_blob_create_sub_blob (cbdt_blob, + image_offset + GlyphBitmapDataFormat17::min_size, + glyphFormat17.data.len); + } + case 18: { + if (strike_x_ppem) *strike_x_ppem = x_ppem; + if (strike_x_ppem) *strike_y_ppem = y_ppem; + const GlyphBitmapDataFormat18& glyphFormat18 = + StructAtOffset (this->cbdt, image_offset); + return hb_blob_create_sub_blob (cbdt_blob, + image_offset + GlyphBitmapDataFormat18::min_size, + glyphFormat18.data.len); + } + case 19: { + if (strike_x_ppem) *strike_x_ppem = x_ppem; + if (strike_x_ppem) *strike_y_ppem = y_ppem; + const GlyphBitmapDataFormat19& glyphFormat19 = + StructAtOffset (this->cbdt, image_offset); + return hb_blob_create_sub_blob (cbdt_blob, + image_offset + GlyphBitmapDataFormat19::min_size, + glyphFormat19.data.len); + } + } return hb_blob_get_empty (); } diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index 8dd3b2a41..9de2f9ac6 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -75,22 +75,6 @@ _get_svg (hb_face_t *face) return *(hb_ot_face_data (face)->SVG.get ()); } -#if 0 -static inline const OT::CBDT_accelerator_t& -_get_cbdt (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::CBDT_accelerator_t); - return *(hb_ot_face_data (face)->CBDT.get ()); -} - -static inline const OT::sbix& -_get_sbix (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::sbix); - return *(hb_ot_face_data (face)->sbix.get ()); -} -#endif - /* * CPAL @@ -289,7 +273,7 @@ hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph) /* - * PNG, CBDT or sbix + * PNG: CBDT or sbix */ /** @@ -335,4 +319,5 @@ hb_ot_color_glyph_reference_blob_png (hb_font_t *font, HB_TAG('p','n','g',' '), strike_x_ppem, strike_y_ppem); + return hb_blob_get_empty (); } diff --git a/src/hb-ot-color.h b/src/hb-ot-color.h index 7901a3598..1810cd63b 100644 --- a/src/hb-ot-color.h +++ b/src/hb-ot-color.h @@ -121,6 +121,10 @@ hb_ot_color_has_svg (hb_face_t *face); HB_EXTERN hb_blob_t * hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph); +/* + * PNG: CBDT or sbix + */ + HB_EXTERN hb_bool_t hb_ot_color_has_png (hb_face_t *face); diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index 767a3d61a..51b901d25 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -405,22 +405,41 @@ static void test_hb_ot_color_png (void) { hb_blob_t *blob; + unsigned int length; + const char *data; + unsigned int strike_x_ppem, strike_y_ppem; + /* sbix */ hb_font_t *sbix_font; sbix_font = hb_font_create (sbix); blob = hb_ot_color_glyph_reference_blob_png (sbix_font, 0, NULL, NULL); g_assert (hb_blob_get_length (blob) == 0); - unsigned int strike_x_ppem, strike_y_ppem; blob = hb_ot_color_glyph_reference_blob_png (sbix_font, 1, &strike_x_ppem, &strike_y_ppem); - unsigned int length; - const char *data = hb_blob_get_data (blob, &length); + data = hb_blob_get_data (blob, &length); g_assert_cmpuint (length, ==, 224); g_assert_cmpuint (strike_x_ppem, ==, 300); g_assert_cmpuint (strike_y_ppem, ==, 300); g_assert (strncmp (data + 1, "PNG", 3) == 0); hb_blob_destroy (blob); + hb_font_destroy (sbix_font); + + /* cbdt */ + hb_font_t *cbdt_font; + cbdt_font = hb_font_create (cbdt); + blob = hb_ot_color_glyph_reference_blob_png (cbdt_font, 0, NULL, NULL); + g_assert (hb_blob_get_length (blob) == 0); + + blob = hb_ot_color_glyph_reference_blob_png (cbdt_font, 1, + &strike_x_ppem, &strike_y_ppem); + data = hb_blob_get_data (blob, &length); + g_assert_cmpuint (length, ==, 88); + g_assert_cmpuint (strike_x_ppem, ==, 80); + g_assert_cmpuint (strike_y_ppem, ==, 80); + g_assert (strncmp (data + 1, "PNG", 3) == 0); + hb_blob_destroy (blob); + hb_font_destroy (cbdt_font); } int From 4ee3c8272c31736980218cba95f97fed53d24e14 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 27 Oct 2018 03:18:45 -0700 Subject: [PATCH 086/255] [docs] Fix hb_name_id_t Yep, was not recognized without this patch! --- src/hb-ot-name.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-name.h b/src/hb-ot-name.h index 002270a55..35146ac06 100644 --- a/src/hb-ot-name.h +++ b/src/hb-ot-name.h @@ -74,7 +74,7 @@ typedef enum HB_NAME_ID_VARIATIONS_PS_PREFIX = 25, HB_NAME_ID_INVALID = 0xFFFF -} hb_name_id_t ; +} hb_name_id_t; /** From b42661ee91ea92309e827a970f370cacc62c73aa Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sat, 27 Oct 2018 14:15:38 +0330 Subject: [PATCH 087/255] [ot-color] Add some documentation --- src/hb-ot-color.cc | 37 +++++++++++++++++++------------------ src/hb-ot-color.h | 2 +- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index 9de2f9ac6..84035069c 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -132,8 +132,8 @@ hb_ot_color_palette_get_name_id (hb_face_t *face, /** * hb_ot_color_palette_color_get_name_id: - * @face: a font face. - * @color_index: + * @face: a font face. + * @color_index: palette entry index. * * Returns: Name ID associated with a palette entry, e.g. eye color * @@ -148,7 +148,7 @@ hb_ot_color_palette_color_get_name_id (hb_face_t *face, /** * hb_ot_color_palette_get_flags: - * @face: a font face + * @face: a font face * @palette_index: the index of the color palette whose flags are being requested * * Returns: the flags for the requested color palette. @@ -217,13 +217,14 @@ hb_ot_color_has_layers (hb_face_t *face) /** * hb_ot_color_glyph_get_layers: - * @face: a font face. - * @glyph: - * @start_offset: - * @count: (inout) (optional): - * @layers: (array length=count) (out) (optional): + * @face: a font face. + * @glyph: a layered color glyph id. + * @start_offset: starting offset of layers. + * @count: (inout) (optional): gets number of layers available to be written on buffer + * and returns number of written layers. + * @layers: (array length=count) (out) (optional): layers buffer to buffer. * - * Returns: + * Returns: Total number of layers a layered color glyph have. * * Since: REPLACEME */ @@ -258,10 +259,10 @@ hb_ot_color_has_svg (hb_face_t *face) /** * hb_ot_color_glyph_reference_blob_svg: - * @face: - * @glyph: + * @face: a font face. + * @glyph: a svg glyph index. * - * Returns: + * Returns: respective svg blob of the glyph, if available. * * Since: REPLACEME */ @@ -280,7 +281,7 @@ hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph) * hb_ot_color_has_png: * @face: a font face. * - * Returns: whether SVG table is available. + * Returns: whether either of CBDT or sbix tables is available. * * Since: REPLACEME */ @@ -292,12 +293,14 @@ hb_ot_color_has_png (hb_face_t *face) /** * hb_ot_color_glyph_reference_blob_svg: - * @font: - * @glyph: + * @font: a font object, not face. upem should be set on + * that font object if one wants to get optimal png blob, otherwise + * return the biggest one + * @glyph: a glyph index. * @strike_x_ppem: (out): * @strike_y_ppem: (out): * - * Returns: + * Returns: respective png blob of the glyph, if available. * * Since: REPLACEME */ @@ -307,8 +310,6 @@ hb_ot_color_glyph_reference_blob_png (hb_font_t *font, unsigned int *strike_x_ppem /* OUT */, unsigned int *strike_y_ppem /* OUT */) { - /* TODO: if (hb_options ().aat ()) then call sbix first */ - if (_get_cbdt (font->face).has_data ()) return _get_cbdt (font->face).reference_blob_for_glyph (glyph, font->x_ppem, font->y_ppem, strike_x_ppem, strike_y_ppem); diff --git a/src/hb-ot-color.h b/src/hb-ot-color.h index 1810cd63b..a8eae8618 100644 --- a/src/hb-ot-color.h +++ b/src/hb-ot-color.h @@ -94,7 +94,7 @@ HB_EXTERN hb_bool_t hb_ot_color_has_layers (hb_face_t *face); /** - * hb_ot_color_layer_t: + * hb_ot_color_layer_t: Pairs of glyph and color index. * * Since: REPLACEME **/ From 9aa6279a2d64ab8057b0d7acbcc77044442c6d0e Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sat, 27 Oct 2018 14:24:58 +0330 Subject: [PATCH 088/255] [ot-color/png] Try to get image blob from sbix first options.aat is set --- src/hb-ot-color.cc | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index 84035069c..a2b753833 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -310,15 +310,21 @@ hb_ot_color_glyph_reference_blob_png (hb_font_t *font, unsigned int *strike_x_ppem /* OUT */, unsigned int *strike_y_ppem /* OUT */) { - if (_get_cbdt (font->face).has_data ()) - return _get_cbdt (font->face).reference_blob_for_glyph (glyph, font->x_ppem, font->y_ppem, + hb_blob_t *blob = hb_blob_get_empty (); + /* don't run cbdt first if aat is set */ + if (!hb_options ().aat && _get_cbdt (font->face).has_data ()) + blob = _get_cbdt (font->face).reference_blob_for_glyph (glyph, font->x_ppem, font->y_ppem, strike_x_ppem, strike_y_ppem); - if (_get_sbix (font->face).has_data ()) - return _get_sbix (font->face).reference_blob_for_glyph (glyph, font->ptem, + if (_get_sbix (font->face).has_data () && !hb_blob_get_length (blob)) + blob = _get_sbix (font->face).reference_blob_for_glyph (glyph, font->ptem, MAX (font->x_ppem, font->y_ppem), HB_TAG('p','n','g',' '), strike_x_ppem, strike_y_ppem); - return hb_blob_get_empty (); + if (hb_options ().aat && _get_cbdt (font->face).has_data () && !hb_blob_get_length (blob)) + blob = _get_cbdt (font->face).reference_blob_for_glyph (glyph, font->x_ppem, font->y_ppem, + strike_x_ppem, strike_y_ppem); + + return blob; } From 8180c37df0a856dbc3564c0aefd8b2acab8baf8a Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sat, 27 Oct 2018 14:45:00 +0330 Subject: [PATCH 089/255] [ot-color] Remove _png and _svg public APIs --- docs/harfbuzz-sections.txt | 4 ---- src/dump-emoji.cc | 11 ++++++++--- src/hb-ot-color.cc | 39 ++++++++++++++++++++++++++++++++++---- src/hb-ot-color.h | 24 ----------------------- test/api/test-ot-color.c | 8 ++++++-- 5 files changed, 49 insertions(+), 37 deletions(-) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index 67f9ae2c4..7bca7ca20 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -460,12 +460,8 @@ HB_OT_H_IN
hb-ot-color hb_ot_color_glyph_get_layers -hb_ot_color_glyph_reference_blob_png -hb_ot_color_glyph_reference_blob_svg hb_ot_color_has_layers hb_ot_color_has_palettes -hb_ot_color_has_png -hb_ot_color_has_svg hb_ot_color_layer_t hb_ot_color_palette_color_get_name_id hb_ot_color_palette_flags_t diff --git a/src/dump-emoji.cc b/src/dump-emoji.cc index 73305aa77..63fb5885f 100644 --- a/src/dump-emoji.cc +++ b/src/dump-emoji.cc @@ -89,9 +89,12 @@ svg_dump (hb_face_t *face) { unsigned glyph_count = hb_face_get_glyph_count (face); + OT::SVG::accelerator_t svg; + svg.init (face); + for (unsigned int glyph_id = 0; glyph_id < glyph_count; glyph_id++) { - hb_blob_t *blob = hb_ot_color_glyph_reference_blob_svg (face, glyph_id); + hb_blob_t *blob = svg.reference_blob_for_glyph (glyph_id); if (hb_blob_get_length (blob) == 0) continue; @@ -110,6 +113,8 @@ svg_dump (hb_face_t *face) hb_blob_destroy (blob); } + + svg.fini (); } static void @@ -290,8 +295,8 @@ main (int argc, char **argv) sbix_dump (face); - if (hb_ot_color_has_svg (face)) - svg_dump (face); +// if (hb_ot_color_has_svg (face)) + svg_dump (face); cairo_font_face_t *cairo_face; { diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index a2b753833..7ffc3d88b 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -47,12 +47,14 @@ _get_colr (hb_face_t *face) return *(hb_ot_face_data (face)->COLR.get ()); } +#if 0 static inline const OT::CBDT_accelerator_t& _get_cbdt (hb_face_t *face) { if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::CBDT_accelerator_t); return *(hb_ot_face_data (face)->CBDT.get ()); } +#endif static inline const OT::CPAL& _get_cpal (hb_face_t *face) @@ -61,6 +63,7 @@ _get_cpal (hb_face_t *face) return *(hb_ot_face_data (face)->CPAL.get ()); } +#if 0 static inline const OT::sbix_accelerator_t& _get_sbix (hb_face_t *face) { @@ -74,6 +77,7 @@ _get_svg (hb_face_t *face) if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::SVG_accelerator_t); return *(hb_ot_face_data (face)->SVG.get ()); } +#endif /* @@ -239,6 +243,7 @@ hb_ot_color_glyph_get_layers (hb_face_t *face, } +#if 0 /* * SVG */ @@ -249,7 +254,7 @@ hb_ot_color_glyph_get_layers (hb_face_t *face, * * Returns: whether SVG table is available. * - * Since: REPLACEME + * Since: DONTREPLACEME */ hb_bool_t hb_ot_color_has_svg (hb_face_t *face) @@ -264,7 +269,7 @@ hb_ot_color_has_svg (hb_face_t *face) * * Returns: respective svg blob of the glyph, if available. * - * Since: REPLACEME + * Since: DONTREPLACEME */ hb_blob_t * hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph) @@ -283,7 +288,7 @@ hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph) * * Returns: whether either of CBDT or sbix tables is available. * - * Since: REPLACEME + * Since: DONTREPLACEME */ hb_bool_t hb_ot_color_has_png (hb_face_t *face) @@ -302,7 +307,7 @@ hb_ot_color_has_png (hb_face_t *face) * * Returns: respective png blob of the glyph, if available. * - * Since: REPLACEME + * Since: DONTREPLACEME */ hb_blob_t * hb_ot_color_glyph_reference_blob_png (hb_font_t *font, @@ -328,3 +333,29 @@ hb_ot_color_glyph_reference_blob_png (hb_font_t *font, return blob; } + +/* To be moved to public header */ + +/* + * SVG + */ + +HB_EXTERN hb_bool_t +hb_ot_color_has_svg (hb_face_t *face); + +HB_EXTERN hb_blob_t * +hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph); + +/* + * PNG: CBDT or sbix + */ + +HB_EXTERN hb_bool_t +hb_ot_color_has_png (hb_face_t *face); + +HB_EXTERN hb_blob_t * +hb_ot_color_glyph_reference_blob_png (hb_font_t *font, + hb_codepoint_t glyph, + unsigned int *strike_x_ppem, + unsigned int *strike_y_ppem); +#endif diff --git a/src/hb-ot-color.h b/src/hb-ot-color.h index a8eae8618..6e4c1777e 100644 --- a/src/hb-ot-color.h +++ b/src/hb-ot-color.h @@ -111,30 +111,6 @@ hb_ot_color_glyph_get_layers (hb_face_t *face, unsigned int *count, /* IN/OUT. May be NULL. */ hb_ot_color_layer_t *layers /* OUT. May be NULL. */); -/* - * SVG - */ - -HB_EXTERN hb_bool_t -hb_ot_color_has_svg (hb_face_t *face); - -HB_EXTERN hb_blob_t * -hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph); - -/* - * PNG: CBDT or sbix - */ - -HB_EXTERN hb_bool_t -hb_ot_color_has_png (hb_face_t *face); - -HB_EXTERN hb_blob_t * -hb_ot_color_glyph_reference_blob_png (hb_font_t *font, - hb_codepoint_t glyph, - unsigned int *strike_x_ppem, - unsigned int *strike_y_ppem); - - HB_END_DECLS #endif /* HB_OT_COLOR_H */ diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index 51b901d25..27409e10c 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -363,6 +363,7 @@ test_hb_ot_color_has_data (void) g_assert (hb_ot_color_has_palettes (sbix) == FALSE); g_assert (hb_ot_color_has_palettes (svg) == FALSE); +#if 0 g_assert (hb_ot_color_has_svg (empty) == FALSE); g_assert (hb_ot_color_has_svg (cpal_v0) == FALSE); g_assert (hb_ot_color_has_svg (cpal_v1) == FALSE); @@ -378,8 +379,10 @@ test_hb_ot_color_has_data (void) g_assert (hb_ot_color_has_png (cbdt) == TRUE); g_assert (hb_ot_color_has_png (sbix) == TRUE); g_assert (hb_ot_color_has_png (svg) == FALSE); +#endif } +#if 0 static void test_hb_ot_color_svg (void) { @@ -441,6 +444,7 @@ test_hb_ot_color_png (void) hb_blob_destroy (blob); hb_font_destroy (cbdt_font); } +#endif int main (int argc, char **argv) @@ -468,8 +472,8 @@ main (int argc, char **argv) hb_test_add (test_hb_ot_color_palette_color_get_name_id); hb_test_add (test_hb_ot_color_glyph_get_layers); hb_test_add (test_hb_ot_color_has_data); - hb_test_add (test_hb_ot_color_png); - hb_test_add (test_hb_ot_color_svg); +// hb_test_add (test_hb_ot_color_png); +// hb_test_add (test_hb_ot_color_svg); status = hb_test_run(); hb_face_destroy (cpal_v0); hb_face_destroy (cpal_v1); From 55a19d73b4d5e7ddd328263d241a442f16f005b2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 27 Oct 2018 04:01:19 -0700 Subject: [PATCH 090/255] Move HB_EXTERN --- src/hb-common.h | 4 ++++ src/hb.h | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hb-common.h b/src/hb-common.h index 2532d69fe..ae23698a5 100644 --- a/src/hb-common.h +++ b/src/hb-common.h @@ -33,6 +33,10 @@ #ifndef HB_COMMON_H #define HB_COMMON_H +#ifndef HB_EXTERN +#define HB_EXTERN extern +#endif + #ifndef HB_BEGIN_DECLS # ifdef __cplusplus # define HB_BEGIN_DECLS extern "C" { diff --git a/src/hb.h b/src/hb.h index fc75a6918..c5e7072fb 100644 --- a/src/hb.h +++ b/src/hb.h @@ -28,10 +28,6 @@ #define HB_H #define HB_H_IN -#ifndef HB_EXTERN -#define HB_EXTERN extern -#endif - #include "hb-blob.h" #include "hb-buffer.h" #include "hb-common.h" From 00cf4e5eb6dcb04406d5a519712da799277cec2e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 27 Oct 2018 04:07:33 -0700 Subject: [PATCH 091/255] [docs] Fill in some sections --- docs/harfbuzz-docs.xml | 20 +++++------- docs/harfbuzz-sections.txt | 65 ++++++++++++++++---------------------- src/hb-blob.cc | 13 ++++++++ src/hb-buffer.cc | 3 +- src/hb-common.cc | 23 ++++++++++++++ src/hb-face.cc | 13 ++++++++ src/hb-font.cc | 13 ++++++++ src/hb-shape-plan.cc | 13 ++++++++ src/hb-shape.cc | 4 ++- src/hb-unicode.cc | 14 ++++++++ 10 files changed, 129 insertions(+), 52 deletions(-) diff --git a/docs/harfbuzz-docs.xml b/docs/harfbuzz-docs.xml index 0057a2a9d..6e3000df4 100644 --- a/docs/harfbuzz-docs.xml +++ b/docs/harfbuzz-docs.xml @@ -61,22 +61,15 @@ Reference manual HarfBuzz API - - - + - + - - - - - @@ -87,16 +80,19 @@ - - + + + + + - + diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index 7f2ff2d2f..f20c7d9f7 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -1,10 +1,6 @@ -
-hb HB_H_IN -HB_EXTERN -HB_DEPRECATED -HB_DEPRECATED_FOR +HB_OT_H_IN
@@ -148,6 +144,10 @@ uint16_t uint32_t uint64_t uint8_t + +HB_EXTERN +HB_DEPRECATED +HB_DEPRECATED_FOR
@@ -418,11 +418,6 @@ hb_gobject_user_data_key_get_type HB_GOBJECT_H_IN
-
-hb-gobject - -
-
hb-graphite2 HB_GRAPHITE2_TAG_SILF @@ -457,12 +452,6 @@ hb_map_set_user_data hb_map_t
-
-hb-ot - -HB_OT_H_IN -
-
hb-ot-color hb_color_t @@ -498,11 +487,6 @@ hb_ot_name_get_utf32 hb_ot_name_get_utf8
-
-hb-ot-shape -hb_ot_shape_glyphs_closure -
-
hb-ot-layout HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX @@ -554,23 +538,6 @@ Xhb_ot_layout_lookup_position Xhb_ot_layout_lookup_substitute
-
-hb-ot-var -HB_OT_TAG_VAR_AXIS_ITALIC -HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE -HB_OT_TAG_VAR_AXIS_SLANT -HB_OT_TAG_VAR_AXIS_WEIGHT -HB_OT_TAG_VAR_AXIS_WIDTH -HB_OT_VAR_NO_AXIS_INDEX -hb_ot_var_axis_t -hb_ot_var_has_data -hb_ot_var_find_axis -hb_ot_var_get_axis_count -hb_ot_var_get_axes -hb_ot_var_normalize_variations -hb_ot_var_normalize_coords -
-
hb-ot-math HB_OT_TAG_MATH @@ -591,6 +558,11 @@ hb_ot_math_get_min_connector_overlap hb_ot_math_get_glyph_assembly
+
+hb-ot-shape +hb_ot_shape_glyphs_closure +
+
hb-ot-tag HB_OT_MAX_TAGS_PER_LANGUAGE @@ -603,6 +575,23 @@ hb_ot_tags_from_script_and_language hb_ot_tags_to_script_and_language
+
+hb-ot-var +HB_OT_TAG_VAR_AXIS_ITALIC +HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE +HB_OT_TAG_VAR_AXIS_SLANT +HB_OT_TAG_VAR_AXIS_WEIGHT +HB_OT_TAG_VAR_AXIS_WIDTH +HB_OT_VAR_NO_AXIS_INDEX +hb_ot_var_axis_t +hb_ot_var_has_data +hb_ot_var_find_axis +hb_ot_var_get_axis_count +hb_ot_var_get_axes +hb_ot_var_normalize_variations +hb_ot_var_normalize_coords +
+
hb-set HB_SET_VALUE_INVALID diff --git a/src/hb-blob.cc b/src/hb-blob.cc index 368491c05..4b741cae6 100644 --- a/src/hb-blob.cc +++ b/src/hb-blob.cc @@ -40,6 +40,19 @@ #include +/** + * SECTION: hb-blob + * @title: Blobs + * @short_description: Binary data containers + * @include: hb.h + * + * Blobs wrap a chunk of binary data to handle lifecycle management of data + * while it is passed between client and HarfBuzz. Blobs are primarily used + * to create font faces, but also to access font face tables, as well as + * pass around other binary data. + **/ + + DEFINE_NULL_INSTANCE (hb_blob_t) = { HB_OBJECT_HEADER_STATIC, diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc index f905c63a9..7286202a3 100644 --- a/src/hb-buffer.cc +++ b/src/hb-buffer.cc @@ -38,9 +38,10 @@ * @include: hb.h * * Buffers serve dual role in HarfBuzz; they hold the input characters that are - * passed hb_shape(), and after shaping they hold the output glyphs. + * passed to hb_shape(), and after shaping they hold the output glyphs. **/ + /** * hb_segment_properties_equal: * @a: first #hb_segment_properties_t to compare. diff --git a/src/hb-common.cc b/src/hb-common.cc index 86d07cf16..2a61fcc33 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -36,6 +36,16 @@ #endif +/** + * SECTION:hb-common + * @title: Common types + * @short_description: Common data types + * @include: hb.h + * + * Common data types used across HarfBuzz are defined here. + **/ + + /* hb_options_t */ hb_atomic_int_t _hb_options; @@ -615,6 +625,19 @@ hb_user_data_array_t::get (hb_user_data_key_t *key) /* hb_version */ + +/** + * SECTION:hb-version + * @title: Version + * @short_description: Information about the version of HarfBuzz in use + * @include: hb.h + * + * These functions and macros allow accessing version of the HarfBuzz + * library used at compile- as well as run-time, and to direct code + * conditionally based on those versions, again, at compile- or run-time. + **/ + + /** * hb_version: * @major: (out): Library major version component. diff --git a/src/hb-face.cc b/src/hb-face.cc index 74c77721f..4695267a3 100644 --- a/src/hb-face.cc +++ b/src/hb-face.cc @@ -35,6 +35,19 @@ #include "hb-ot-cmap-table.hh" +/** + * SECTION:hb-face + * @title: Face + * @short_description: Font face object + * @include: hb.h + * + * Font face is objects represent a single face in a font family. + * More exactly, a font face represents a single face in a binary font file. + * Font faces are typically built from a binary blob and a face index. + * Font faces are used to create fonts. + **/ + + /** * hb_face_count: * @blob: a blob. diff --git a/src/hb-font.cc b/src/hb-font.cc index e38c2fbd3..3c7b4a5b0 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -34,6 +34,19 @@ #include "hb-ot.h" +/** + * SECTION:hb-font + * @title: Font + * @short_description: Font object + * @include: hb.h + * + * Font objects represent a font face at a certain size and other + * parameters (pixels per EM, points per EM, variation settings.) + * Fonts are created from font faces, and are used as input to + * hb_shape() among other things. + **/ + + /* * hb_font_funcs_t */ diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc index dea2c8c7b..3eacd587b 100644 --- a/src/hb-shape-plan.cc +++ b/src/hb-shape-plan.cc @@ -31,6 +31,19 @@ #include "hb-buffer.hh" +/** + * SECTION:hb-shape-plan + * @title: Shape plan + * @short_description: Object representing a shaping plan + * @include: hb.h + * + * Shape plans are not used for shaping directly, but can be access to query + * certain information about how shaping will perform given a set of input + * parameters (script, language, direction, features, etc.) + * Most client would not need to deal with shape plans directly. + **/ + + static void hb_shape_plan_plan (hb_shape_plan_t *shape_plan, const hb_feature_t *user_features, diff --git a/src/hb-shape.cc b/src/hb-shape.cc index e8eeff5b3..00c61397e 100644 --- a/src/hb-shape.cc +++ b/src/hb-shape.cc @@ -34,6 +34,7 @@ #include "hb-font.hh" #include "hb-machinery.hh" + /** * SECTION:hb-shape * @title: Shaping @@ -42,10 +43,11 @@ * * Shaping is the central operation of HarfBuzz. Shaping operates on buffers, * which are sequences of Unicode characters that use the same font and have - * the same text direction, script and language. After shaping the buffer + * the same text direction, script, and language. After shaping the buffer * contains the output glyphs and their positions. **/ + #ifdef HB_USE_ATEXIT static void free_static_shaper_list (void); #endif diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc index a08f88829..bfa4ca2bc 100644 --- a/src/hb-unicode.cc +++ b/src/hb-unicode.cc @@ -33,6 +33,20 @@ #include "hb-unicode.hh" +/** + * SECTION: hb-unicode + * @title: Unicode functions + * @short_description: Unicode character property access + * @include: hb.h + * + * Unicode functions are used to access Unicode character properties. + * Client can pass its own Unicode functions to HarfBuzz, or access + * the built-in Unicode functions that come with HarfBuzz. + * + * With the Unicode functions, one can query variour Unicode character + * properties, such as General Category, Script, Combining Class, etc. + **/ + /* * hb_unicode_funcs_t From 46072b7cb55bfeb8c46a78cbdb335dfdcce48298 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 27 Oct 2018 04:21:20 -0700 Subject: [PATCH 092/255] [ot] Fold hb-ot-tag.h into hb-ot-layout.h --- docs/harfbuzz-docs.xml | 1 - docs/harfbuzz-sections.txt | 20 ++++------ src/Makefile.sources | 1 - src/hb-graphite2.cc | 2 +- src/hb-ot-layout.h | 42 +++++++++++++++++++- src/hb-ot-tag.h | 78 -------------------------------------- src/hb-ot.h | 1 - src/hb-uniscribe.cc | 2 +- 8 files changed, 51 insertions(+), 96 deletions(-) delete mode 100644 src/hb-ot-tag.h diff --git a/docs/harfbuzz-docs.xml b/docs/harfbuzz-docs.xml index 6e3000df4..140184af4 100644 --- a/docs/harfbuzz-docs.xml +++ b/docs/harfbuzz-docs.xml @@ -72,7 +72,6 @@ - diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index f20c7d9f7..3ba5b8ce4 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -489,6 +489,14 @@ hb_ot_name_get_utf8
hb-ot-layout +HB_OT_MAX_TAGS_PER_LANGUAGE +HB_OT_MAX_TAGS_PER_SCRIPT +HB_OT_TAG_DEFAULT_LANGUAGE +HB_OT_TAG_DEFAULT_SCRIPT +hb_ot_tag_to_language +hb_ot_tag_to_script +hb_ot_tags_from_script_and_language +hb_ot_tags_to_script_and_language HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX HB_OT_LAYOUT_NO_FEATURE_INDEX HB_OT_LAYOUT_NO_SCRIPT_INDEX @@ -563,18 +571,6 @@ hb_ot_math_get_glyph_assembly hb_ot_shape_glyphs_closure
-
-hb-ot-tag -HB_OT_MAX_TAGS_PER_LANGUAGE -HB_OT_MAX_TAGS_PER_SCRIPT -HB_OT_TAG_DEFAULT_LANGUAGE -HB_OT_TAG_DEFAULT_SCRIPT -hb_ot_tag_to_language -hb_ot_tag_to_script -hb_ot_tags_from_script_and_language -hb_ot_tags_to_script_and_language -
-
hb-ot-var HB_OT_TAG_VAR_AXIS_ITALIC diff --git a/src/Makefile.sources b/src/Makefile.sources index fe140b044..561fbed6d 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -184,7 +184,6 @@ HB_OT_headers = \ hb-ot-math.h \ hb-ot-name.h \ hb-ot-shape.h \ - hb-ot-tag.h \ hb-ot-var.h \ $(NULL) diff --git a/src/hb-graphite2.cc b/src/hb-graphite2.cc index 1b73f9f4f..022e8814a 100644 --- a/src/hb-graphite2.cc +++ b/src/hb-graphite2.cc @@ -33,7 +33,7 @@ #include -#include "hb-ot-tag.h" +#include "hb-ot-layout.h" HB_SHAPER_DATA_ENSURE_DEFINE(graphite2, face) diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index 9bd18c8af..287d02217 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -33,7 +33,6 @@ #include "hb.h" -#include "hb-ot-tag.h" #include "hb-ot-name.h" HB_BEGIN_DECLS @@ -46,6 +45,47 @@ HB_BEGIN_DECLS #define HB_OT_TAG_JSTF HB_TAG('J','S','T','F') +/* + * Script & Language tags. + */ + +#define HB_OT_TAG_DEFAULT_SCRIPT HB_TAG ('D', 'F', 'L', 'T') +#define HB_OT_TAG_DEFAULT_LANGUAGE HB_TAG ('d', 'f', 'l', 't') + +/** + * HB_OT_MAX_TAGS_PER_SCRIPT: + * + * Since: 2.0.0 + **/ +#define HB_OT_MAX_TAGS_PER_SCRIPT 3u +/** + * HB_OT_MAX_TAGS_PER_LANGUAGE: + * + * Since: 2.0.0 + **/ +#define HB_OT_MAX_TAGS_PER_LANGUAGE 3u + +HB_EXTERN void +hb_ot_tags_from_script_and_language (hb_script_t script, + hb_language_t language, + unsigned int *script_count /* IN/OUT */, + hb_tag_t *script_tags /* OUT */, + unsigned int *language_count /* IN/OUT */, + hb_tag_t *language_tags /* OUT */); + +HB_EXTERN hb_script_t +hb_ot_tag_to_script (hb_tag_t tag); + +HB_EXTERN hb_language_t +hb_ot_tag_to_language (hb_tag_t tag); + +HB_EXTERN void +hb_ot_tags_to_script_and_language (hb_tag_t script_tag, + hb_tag_t language_tag, + hb_script_t *script /* OUT */, + hb_language_t *language /* OUT */); + + /* * GDEF */ diff --git a/src/hb-ot-tag.h b/src/hb-ot-tag.h deleted file mode 100644 index 33a4dbdbc..000000000 --- a/src/hb-ot-tag.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright © 2009 Red Hat, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Red Hat Author(s): Behdad Esfahbod - */ - -#ifndef HB_OT_H_IN -#error "Include instead." -#endif - -#ifndef HB_OT_TAG_H -#define HB_OT_TAG_H - -#include "hb.h" - -HB_BEGIN_DECLS - - -#define HB_OT_TAG_DEFAULT_SCRIPT HB_TAG ('D', 'F', 'L', 'T') -#define HB_OT_TAG_DEFAULT_LANGUAGE HB_TAG ('d', 'f', 'l', 't') - -/** - * HB_OT_MAX_TAGS_PER_SCRIPT: - * - * Since: 2.0.0 - **/ -#define HB_OT_MAX_TAGS_PER_SCRIPT 3u -/** - * HB_OT_MAX_TAGS_PER_LANGUAGE: - * - * Since: 2.0.0 - **/ -#define HB_OT_MAX_TAGS_PER_LANGUAGE 3u - -HB_EXTERN void -hb_ot_tags_from_script_and_language (hb_script_t script, - hb_language_t language, - unsigned int *script_count /* IN/OUT */, - hb_tag_t *script_tags /* OUT */, - unsigned int *language_count /* IN/OUT */, - hb_tag_t *language_tags /* OUT */); - -HB_EXTERN hb_script_t -hb_ot_tag_to_script (hb_tag_t tag); - -HB_EXTERN hb_language_t -hb_ot_tag_to_language (hb_tag_t tag); - -HB_EXTERN void -hb_ot_tags_to_script_and_language (hb_tag_t script_tag, - hb_tag_t language_tag, - hb_script_t *script /* OUT */, - hb_language_t *language /* OUT */); - - -HB_END_DECLS - -#endif /* HB_OT_TAG_H */ diff --git a/src/hb-ot.h b/src/hb-ot.h index 47508d67c..c168175ac 100644 --- a/src/hb-ot.h +++ b/src/hb-ot.h @@ -35,7 +35,6 @@ #include "hb-ot-layout.h" #include "hb-ot-math.h" #include "hb-ot-name.h" -#include "hb-ot-tag.h" #include "hb-ot-shape.h" #include "hb-ot-var.h" diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc index c3949c989..c6f60b99c 100644 --- a/src/hb-uniscribe.cc +++ b/src/hb-uniscribe.cc @@ -36,7 +36,7 @@ #include "hb-open-file.hh" #include "hb-ot-name-table.hh" -#include "hb-ot-tag.h" +#include "hb-ot-layout.h" static inline uint16_t hb_uint16_swap (const uint16_t v) From 524fb70216d7fec17f5327237faa4d092ae15a00 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 27 Oct 2018 04:27:36 -0700 Subject: [PATCH 093/255] [docs] More --- src/hb-map.cc | 11 ++++++++++- src/hb-set.cc | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/hb-map.cc b/src/hb-map.cc index 225f37bc6..57d17ba1e 100644 --- a/src/hb-map.cc +++ b/src/hb-map.cc @@ -27,7 +27,16 @@ #include "hb-map.hh" -/* Public API */ +/** + * SECTION:hb-map + * @title: Map + * @short_description: Object representing integer to integer mapping + * @include: hb.h + * + * Map objects are integer-to-integer hash-maps. Currently they are + * not used in the HarfBuzz public API, but are provided for client's + * use if desired. + **/ /** diff --git a/src/hb-set.cc b/src/hb-set.cc index 25c19147f..8b1a359c5 100644 --- a/src/hb-set.cc +++ b/src/hb-set.cc @@ -27,7 +27,16 @@ #include "hb-set.hh" -/* Public API */ +/** + * SECTION:hb-set + * @title: Set + * @short_description: Object representing a set of integers + * @include: hb.h + * + * Set objects represent a mathematical set of integer values. They are + * used in non-shaping API to query certain set of characters or glyphs, + * or other integer values. + **/ /** From 5dd86aa33b4e52a0de4fcd96b2ea7bafcae8dd34 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 27 Oct 2018 04:28:40 -0700 Subject: [PATCH 094/255] [docs] Rename section titles to object names More useful. --- src/hb-blob.cc | 2 +- src/hb-buffer.cc | 2 +- src/hb-face.cc | 4 ++-- src/hb-font.cc | 4 ++-- src/hb-map.cc | 2 +- src/hb-set.cc | 2 +- src/hb-shape-plan.cc | 2 +- src/hb-unicode.cc | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/hb-blob.cc b/src/hb-blob.cc index 4b741cae6..521e8b693 100644 --- a/src/hb-blob.cc +++ b/src/hb-blob.cc @@ -42,7 +42,7 @@ /** * SECTION: hb-blob - * @title: Blobs + * @title: hb_blob_t * @short_description: Binary data containers * @include: hb.h * diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc index 7286202a3..d773dd84a 100644 --- a/src/hb-buffer.cc +++ b/src/hb-buffer.cc @@ -33,7 +33,7 @@ /** * SECTION: hb-buffer - * @title: Buffers + * @title: hb_buffer_t * @short_description: Input and output buffers * @include: hb.h * diff --git a/src/hb-face.cc b/src/hb-face.cc index 4695267a3..2f6ccea31 100644 --- a/src/hb-face.cc +++ b/src/hb-face.cc @@ -37,8 +37,8 @@ /** * SECTION:hb-face - * @title: Face - * @short_description: Font face object + * @title: hb_face_t + * @short_description: Font face objects * @include: hb.h * * Font face is objects represent a single face in a font family. diff --git a/src/hb-font.cc b/src/hb-font.cc index 3c7b4a5b0..2ef0ff854 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -36,8 +36,8 @@ /** * SECTION:hb-font - * @title: Font - * @short_description: Font object + * @title: hb_font_t + * @short_description: Font objects * @include: hb.h * * Font objects represent a font face at a certain size and other diff --git a/src/hb-map.cc b/src/hb-map.cc index 57d17ba1e..e83396492 100644 --- a/src/hb-map.cc +++ b/src/hb-map.cc @@ -29,7 +29,7 @@ /** * SECTION:hb-map - * @title: Map + * @title: hb_map_t * @short_description: Object representing integer to integer mapping * @include: hb.h * diff --git a/src/hb-set.cc b/src/hb-set.cc index 8b1a359c5..2a4b356c7 100644 --- a/src/hb-set.cc +++ b/src/hb-set.cc @@ -29,7 +29,7 @@ /** * SECTION:hb-set - * @title: Set + * @title: hb_set_t * @short_description: Object representing a set of integers * @include: hb.h * diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc index 3eacd587b..abffd40d7 100644 --- a/src/hb-shape-plan.cc +++ b/src/hb-shape-plan.cc @@ -33,7 +33,7 @@ /** * SECTION:hb-shape-plan - * @title: Shape plan + * @title: hb_shape_plan_t * @short_description: Object representing a shaping plan * @include: hb.h * diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc index bfa4ca2bc..ca555a8df 100644 --- a/src/hb-unicode.cc +++ b/src/hb-unicode.cc @@ -35,7 +35,7 @@ /** * SECTION: hb-unicode - * @title: Unicode functions + * @title: hb_unicode_funcs_t * @short_description: Unicode character property access * @include: hb.h * From 04981ee05d83ed30c9f818106589a4de9c3e9b7f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 27 Oct 2018 04:40:43 -0700 Subject: [PATCH 095/255] [docs] More --- src/hb-coretext.cc | 10 ++++++++++ src/hb-ft.cc | 11 +++++++++++ src/hb-glib.cc | 10 ++++++++++ src/hb-gobject-structs.cc | 12 ++++++++++++ src/hb-graphite2.cc | 10 ++++++++++ src/hb-icu.cc | 10 ++++++++++ src/hb-uniscribe.cc | 10 ++++++++++ 7 files changed, 73 insertions(+) diff --git a/src/hb-coretext.cc b/src/hb-coretext.cc index 54e3f9ccc..8b4f7e6a3 100644 --- a/src/hb-coretext.cc +++ b/src/hb-coretext.cc @@ -35,6 +35,16 @@ #include "hb-aat-layout.hh" #include + +/** + * SECTION:hb-coretext + * @title: hb-coretext + * @short_description: CoreText integration + * @include: hb-coretext.h + * + * Functions for using HarfBuzz with the CoreText fonts. + **/ + /* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */ #define HB_CORETEXT_DEFAULT_FONT_SIZE 12.f diff --git a/src/hb-ft.cc b/src/hb-ft.cc index fbf362688..5e0511052 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -40,6 +40,17 @@ #include FT_TRUETYPE_TABLES_H +/** + * SECTION:hb-ft + * @title: hb-ft + * @short_description: FreeType integration + * @include: hb-ft.h + * + * Functions for using HarfBuzz with the FreeType library to provide face and + * font data. + **/ + + /* TODO: * * In general, this file does a fine job of what it's supposed to do. diff --git a/src/hb-glib.cc b/src/hb-glib.cc index a34acbba1..23a0d89c8 100644 --- a/src/hb-glib.cc +++ b/src/hb-glib.cc @@ -33,6 +33,16 @@ #include "hb-machinery.hh" +/** + * SECTION:hb-glib + * @title: hb-glib + * @short_description: GLib integration + * @include: hb-glib.h + * + * Functions for using HarfBuzz with the GLib library to provide Unicode data. + **/ + + #if !GLIB_CHECK_VERSION(2,29,14) static const hb_script_t glib_script_to_script[] = diff --git a/src/hb-gobject-structs.cc b/src/hb-gobject-structs.cc index 1b8758583..23ca43656 100644 --- a/src/hb-gobject-structs.cc +++ b/src/hb-gobject-structs.cc @@ -26,6 +26,18 @@ #include "hb.hh" + +/** + * SECTION:hb-gobject + * @title: hb-gobject + * @short_description: GObject integration + * @include: hb-gobject.h + * + * Functions for using HarfBuzz with the GObject library to provide + * type data. + **/ + + /* g++ didn't like older gtype.h gcc-only code path. */ #include #if !GLIB_CHECK_VERSION(2,29,16) diff --git a/src/hb-graphite2.cc b/src/hb-graphite2.cc index 022e8814a..971241f92 100644 --- a/src/hb-graphite2.cc +++ b/src/hb-graphite2.cc @@ -36,6 +36,16 @@ #include "hb-ot-layout.h" +/** + * SECTION:hb-graphite2 + * @title: hb-graphite2 + * @short_description: Graphite2 integration + * @include: hb-graphite2.h + * + * Functions for using HarfBuzz with the Graphite2 fonts. + **/ + + HB_SHAPER_DATA_ENSURE_DEFINE(graphite2, face) HB_SHAPER_DATA_ENSURE_DEFINE(graphite2, font) diff --git a/src/hb-icu.cc b/src/hb-icu.cc index e012314b5..12864677c 100644 --- a/src/hb-icu.cc +++ b/src/hb-icu.cc @@ -40,6 +40,16 @@ #include +/** + * SECTION:hb-icu + * @title: hb-icu + * @short_description: ICU integration + * @include: hb-icu.h + * + * Functions for using HarfBuzz with the ICU library to provide Unicode data. + **/ + + hb_script_t hb_icu_script_to_script (UScriptCode script) { diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc index c6f60b99c..b12a0539d 100644 --- a/src/hb-uniscribe.cc +++ b/src/hb-uniscribe.cc @@ -39,6 +39,16 @@ #include "hb-ot-layout.h" +/** + * SECTION:hb-uniscribe + * @title: hb-uniscribe + * @short_description: Windows integration + * @include: hb-uniscribe.h + * + * Functions for using HarfBuzz with the Windows fonts. + **/ + + static inline uint16_t hb_uint16_swap (const uint16_t v) { return (v >> 8) | (v << 8); } static inline uint32_t hb_uint32_swap (const uint32_t v) From cf5fa57f00613d324b55732d9e21c779ba0d2de2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 27 Oct 2018 04:50:38 -0700 Subject: [PATCH 096/255] [docs] Change section titles again I think I like the uniform "hb-*" more. --- src/hb-blob.cc | 2 +- src/hb-buffer.cc | 2 +- src/hb-common.cc | 4 ++-- src/hb-deprecated.h | 12 ++++++++++++ src/hb-face.cc | 2 +- src/hb-font.cc | 2 +- src/hb-shape.cc | 2 +- src/hb-unicode.cc | 2 +- 8 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/hb-blob.cc b/src/hb-blob.cc index 521e8b693..51f22ce4d 100644 --- a/src/hb-blob.cc +++ b/src/hb-blob.cc @@ -42,7 +42,7 @@ /** * SECTION: hb-blob - * @title: hb_blob_t + * @title: hb-blob * @short_description: Binary data containers * @include: hb.h * diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc index d773dd84a..5a8152ed4 100644 --- a/src/hb-buffer.cc +++ b/src/hb-buffer.cc @@ -33,7 +33,7 @@ /** * SECTION: hb-buffer - * @title: hb_buffer_t + * @title: hb-buffer * @short_description: Input and output buffers * @include: hb.h * diff --git a/src/hb-common.cc b/src/hb-common.cc index 2a61fcc33..d7c1921f3 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -38,7 +38,7 @@ /** * SECTION:hb-common - * @title: Common types + * @title: hb-common * @short_description: Common data types * @include: hb.h * @@ -628,7 +628,7 @@ hb_user_data_array_t::get (hb_user_data_key_t *key) /** * SECTION:hb-version - * @title: Version + * @title: hb-version * @short_description: Information about the version of HarfBuzz in use * @include: hb.h * diff --git a/src/hb-deprecated.h b/src/hb-deprecated.h index 369d07361..e39b79f74 100644 --- a/src/hb-deprecated.h +++ b/src/hb-deprecated.h @@ -36,6 +36,18 @@ #include "hb-font.h" #include "hb-set.h" + +/** + * SECTION:hb-deprecated + * @title: hb-deprecated + * @short_description: Deprecated API + * @include: hb.h + * + * These API have been deprecated in favor of newer API, or because they + * were deemed unnecessary. + **/ + + HB_BEGIN_DECLS #ifndef HB_DISABLE_DEPRECATED diff --git a/src/hb-face.cc b/src/hb-face.cc index 2f6ccea31..7ca4b1ba2 100644 --- a/src/hb-face.cc +++ b/src/hb-face.cc @@ -37,7 +37,7 @@ /** * SECTION:hb-face - * @title: hb_face_t + * @title: hb-face * @short_description: Font face objects * @include: hb.h * diff --git a/src/hb-font.cc b/src/hb-font.cc index 2ef0ff854..135d310ca 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -36,7 +36,7 @@ /** * SECTION:hb-font - * @title: hb_font_t + * @title: hb-font * @short_description: Font objects * @include: hb.h * diff --git a/src/hb-shape.cc b/src/hb-shape.cc index 00c61397e..f98bc6e51 100644 --- a/src/hb-shape.cc +++ b/src/hb-shape.cc @@ -37,7 +37,7 @@ /** * SECTION:hb-shape - * @title: Shaping + * @title: hb-shape * @short_description: Conversion of text strings into positioned glyphs * @include: hb.h * diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc index ca555a8df..cba18ab6a 100644 --- a/src/hb-unicode.cc +++ b/src/hb-unicode.cc @@ -35,7 +35,7 @@ /** * SECTION: hb-unicode - * @title: hb_unicode_funcs_t + * @title: hb-unicode * @short_description: Unicode character property access * @include: hb.h * From 80d9a427cf61f61512de13cd88bdc63d881019fe Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 27 Oct 2018 04:58:32 -0700 Subject: [PATCH 097/255] [docs] Document remaining sections --- src/hb-ot-color.cc | 10 ++++++++++ src/hb-ot-font.cc | 10 ++++++++++ src/hb-ot-layout.cc | 10 ++++++++++ src/hb-ot-math.cc | 11 +++++++++++ src/hb-ot-name.cc | 10 ++++++++++ src/hb-ot-shape.cc | 10 ++++++++++ 6 files changed, 61 insertions(+) diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index 78c462f0e..8150b5e79 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -40,6 +40,16 @@ #include "hb-ot-layout.hh" +/** + * SECTION:hb-ot-color + * @title: hb-ot-color + * @short_description: OpenType Color Fonts + * @include: hb-ot.h + * + * Functions for fetching color-font information from OpenType font faces. + **/ + + static inline const OT::COLR& _get_colr (hb_face_t *face) { diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index f0b620898..7a4516889 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -41,6 +41,16 @@ #include "hb-ot-color-cbdt-table.hh" +/** + * SECTION:hb-ot-font + * @title: hb-ot-font + * @short_description: OpenType font implementation + * @include: hb-ot.h + * + * Functions for using OpenType fonts with hb_shape(). + **/ + + static hb_bool_t hb_ot_get_nominal_glyph (hb_font_t *font HB_UNUSED, void *font_data, diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index befa838f3..6c5f0d401 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -45,6 +45,16 @@ #include "hb-ot-name-table.hh" +/** + * SECTION:hb-ot-layout + * @title: hb-ot-layout + * @short_description: OpenType Layout + * @include: hb-ot.h + * + * Functions for querying OpenType Layout features in the font face. + **/ + + static const OT::kern::accelerator_t& _get_kern (hb_face_t *face) { if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::kern::accelerator_t); diff --git a/src/hb-ot-math.cc b/src/hb-ot-math.cc index c693f4807..92c29480d 100644 --- a/src/hb-ot-math.cc +++ b/src/hb-ot-math.cc @@ -29,6 +29,17 @@ #include "hb-ot-face.hh" #include "hb-ot-math-table.hh" + +/** + * SECTION:hb-ot-math + * @title: hb-ot-math + * @short_description: OpenType Math information + * @include: hb-ot.h + * + * Functions for fetching mathematics layout data from OpenType fonts. + **/ + + static inline const OT::MATH& _get_math (hb_face_t *face) { diff --git a/src/hb-ot-name.cc b/src/hb-ot-name.cc index 28a45f010..2bf2ae58b 100644 --- a/src/hb-ot-name.cc +++ b/src/hb-ot-name.cc @@ -32,6 +32,16 @@ #include "hb-utf.hh" +/** + * SECTION:hb-ot-name + * @title: hb-ot-name + * @short_description: OpenType font name information + * @include: hb-ot.h + * + * Functions for fetching name strings from OpenType fonts. + **/ + + static inline const OT::name_accelerator_t& _get_name (hb_face_t *face) { diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 32c502048..c55d8dcb8 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -42,6 +42,16 @@ #include "hb-aat-layout.hh" +/** + * SECTION:hb-ot-shape + * @title: hb-ot-shape + * @short_description: OpenType shaping support + * @include: hb-ot.h + * + * Support functions for OpenType shaping related queries. + **/ + + static bool _hb_apply_morx (hb_face_t *face) { From 1d40d72f291ed5e11850f8bd51a8562b57de1997 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 27 Oct 2018 05:00:42 -0700 Subject: [PATCH 098/255] [docs] Hook up hb-var --- docs/harfbuzz-docs.xml | 1 + src/hb-ot-var.cc | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/docs/harfbuzz-docs.xml b/docs/harfbuzz-docs.xml index 140184af4..31aa4058b 100644 --- a/docs/harfbuzz-docs.xml +++ b/docs/harfbuzz-docs.xml @@ -76,6 +76,7 @@ + diff --git a/src/hb-ot-var.cc b/src/hb-ot-var.cc index 472ee8452..64087be81 100644 --- a/src/hb-ot-var.cc +++ b/src/hb-ot-var.cc @@ -32,6 +32,17 @@ #include "hb-ot-var-mvar-table.hh" #include "hb-ot-var.h" + +/** + * SECTION:hb-ot-var + * @title: hb-ot-var + * @short_description: OpenType Font Variations + * @include: hb-ot.h + * + * Functions for fetching information about OpenType Variable Fonts. + **/ + + /* * fvar/avar */ From 4740a3593d6bbb97758593b7d5cd1b86eccbed78 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 27 Oct 2018 05:07:54 -0700 Subject: [PATCH 099/255] [docs] Divide reference API into three chapters --- docs/harfbuzz-docs.xml | 213 +++++++++++------------------------------ 1 file changed, 56 insertions(+), 157 deletions(-) diff --git a/docs/harfbuzz-docs.xml b/docs/harfbuzz-docs.xml index 31aa4058b..21c251d0d 100644 --- a/docs/harfbuzz-docs.xml +++ b/docs/harfbuzz-docs.xml @@ -60,185 +60,84 @@ Reference manual - HarfBuzz API - + Core API + + + - + + + + + + OpenType API + - - + + - - - - - + + Integration API + - - + - - - - - + + - Index of new symbols in 0.9.2 - - - - Index of new symbols in 0.9.5 - - - - Index of new symbols in 0.9.7 - - - - Index of new symbols in 0.9.8 - - - - Index of new symbols in 0.9.10 - - - - Index of new symbols in 0.9.11 - - - - Index of new symbols in 0.9.20 - - - - Index of new symbols in 0.9.22 - - - - Index of new symbols in 0.9.28 - - - - Index of new symbols in 0.9.30 - - - - Index of new symbols in 0.9.31 - - - - Index of new symbols in 0.9.38 - - - - Index of new symbols in 0.9.39 - - - - Index of new symbols in 0.9.41 - - - - Index of new symbols in 0.9.42 - - - - Index of new symbols in 1.0.5 - - - - Index of new symbols in 1.1.2 - - - - Index of new symbols in 1.1.3 - - - - Index of new symbols in 1.2.3 - - - - Index of new symbols in 1.3.3 - - - - Index of new symbols in 1.4.0 - - - - Index of new symbols in 1.4.2 - - - - Index of new symbols in 1.4.3 - - - - Index of new symbols in 1.5.0 - - - - Index of new symbols in 1.6.0 - - - - Index of new symbols in 1.7.5 - - - - Index of new symbols in 1.7.7 - - - - Index of new symbols in 1.8.0 - - - - Index of new symbols in 1.8.1 - - - - Index of new symbols in 1.8.5 - - - - Index of new symbols in 1.8.6 - - - - Index of new symbols in 1.9.0 - - - - Index of new symbols in 2.0.0 - - + API Index + Index of deprecated API + + Index of new symbols in 2.0.0 + Index of new symbols in 1.9.0 + Index of new symbols in 1.8.6 + Index of new symbols in 1.8.5 + Index of new symbols in 1.8.1 + Index of new symbols in 1.8.0 + Index of new symbols in 1.7.7 + Index of new symbols in 1.7.5 + Index of new symbols in 1.6.0 + Index of new symbols in 1.5.0 + Index of new symbols in 1.4.3 + Index of new symbols in 1.4.2 + Index of new symbols in 1.4.0 + Index of new symbols in 1.3.3 + Index of new symbols in 1.2.3 + Index of new symbols in 1.1.3 + Index of new symbols in 1.1.2 + Index of new symbols in 1.0.5 + Index of new symbols in 0.9.42 + Index of new symbols in 0.9.41 + Index of new symbols in 0.9.39 + Index of new symbols in 0.9.38 + Index of new symbols in 0.9.31 + Index of new symbols in 0.9.30 + Index of new symbols in 0.9.28 + Index of new symbols in 0.9.22 + Index of new symbols in 0.9.20 + Index of new symbols in 0.9.11 + Index of new symbols in 0.9.10 + Index of new symbols in 0.9.8 + Index of new symbols in 0.9.7 + Index of new symbols in 0.9.5 + Index of new symbols in 0.9.2 From 213b6dd33564d0273b1db1c17a4e82548b727dfe Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 27 Oct 2018 18:36:24 -0700 Subject: [PATCH 100/255] [name] Make sure hb_name_id_t is int-sized https://github.com/harfbuzz/harfbuzz/commit/d941f66c75fe26f909b1ba248535cc372bbde851#commitcomment-31068905 --- src/hb-ot-name.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-name.h b/src/hb-ot-name.h index 35146ac06..b406c090b 100644 --- a/src/hb-ot-name.h +++ b/src/hb-ot-name.h @@ -73,7 +73,9 @@ typedef enum HB_NAME_ID_DARK_BACKGROUND = 24, HB_NAME_ID_VARIATIONS_PS_PREFIX = 25, - HB_NAME_ID_INVALID = 0xFFFF + HB_NAME_ID_INVALID = 0xFFFF, + + _HB_NAME_ID_MAX_VALUE_SIGNED = 0x7FFFFFFF /*< skip >*/ /* So we get int-sized. */ } hb_name_id_t; From a4f4f5ba5f64174dea931e02367aa4067d034383 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 08:23:36 -0700 Subject: [PATCH 101/255] [docs] Fix titles here as well --- src/hb-map.cc | 2 +- src/hb-set.cc | 2 +- src/hb-shape-plan.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hb-map.cc b/src/hb-map.cc index e83396492..067a2b371 100644 --- a/src/hb-map.cc +++ b/src/hb-map.cc @@ -29,7 +29,7 @@ /** * SECTION:hb-map - * @title: hb_map_t + * @title: hb-map * @short_description: Object representing integer to integer mapping * @include: hb.h * diff --git a/src/hb-set.cc b/src/hb-set.cc index 2a4b356c7..67ec56180 100644 --- a/src/hb-set.cc +++ b/src/hb-set.cc @@ -29,7 +29,7 @@ /** * SECTION:hb-set - * @title: hb_set_t + * @title: hb-set * @short_description: Object representing a set of integers * @include: hb.h * diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc index abffd40d7..4648cc757 100644 --- a/src/hb-shape-plan.cc +++ b/src/hb-shape-plan.cc @@ -33,7 +33,7 @@ /** * SECTION:hb-shape-plan - * @title: hb_shape_plan_t + * @title: hb-shape-plan * @short_description: Object representing a shaping plan * @include: hb.h * From 6ce49a921a80f1238ddc537f77a1fceea5274a21 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 08:26:30 -0700 Subject: [PATCH 102/255] [name] Change hb_name_id_t back to unsigned int https://github.com/harfbuzz/harfbuzz/commit/d941f66c75fe26f909b1ba248535cc372bbde851#commitcomment-31076011 --- docs/harfbuzz-sections.txt | 2 -- src/hb-ot-color-cpal-table.hh | 4 ++-- src/hb-ot-layout.cc | 12 ++++++------ src/hb-ot-name-table.hh | 2 +- src/hb-ot-name.h | 6 +++--- src/test-size-params.cc | 2 +- 6 files changed, 13 insertions(+), 15 deletions(-) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index 3ba5b8ce4..9d4edc267 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -360,7 +360,6 @@ HB_GOBJECT_TYPE_FONT_FUNCS HB_GOBJECT_TYPE_GLYPH_FLAGS HB_GOBJECT_TYPE_MAP HB_GOBJECT_TYPE_MEMORY_MODE -HB_GOBJECT_TYPE_NAME_ID HB_GOBJECT_TYPE_OT_COLOR_PALETTE_FLAGS HB_GOBJECT_TYPE_OT_LAYOUT_GLYPH_CLASS HB_GOBJECT_TYPE_OT_MATH_CONSTANT @@ -394,7 +393,6 @@ hb_gobject_font_get_type hb_gobject_glyph_flags_get_type hb_gobject_map_get_type hb_gobject_memory_mode_get_type -hb_gobject_name_id_get_type hb_gobject_ot_color_palette_flags_get_type hb_gobject_ot_layout_glyph_class_get_type hb_gobject_ot_math_constant_get_type diff --git a/src/hb-ot-color-cpal-table.hh b/src/hb-ot-color-cpal-table.hh index 0e13bece2..0b4bf377e 100644 --- a/src/hb-ot-color-cpal-table.hh +++ b/src/hb-ot-color-cpal-table.hh @@ -64,7 +64,7 @@ struct CPALV1Tail unsigned int palette_count) const { if (!paletteLabelsZ) return HB_NAME_ID_INVALID; - return (hb_name_id_t) (unsigned) hb_array (base+paletteLabelsZ, palette_count)[palette_index]; + return hb_array (base+paletteLabelsZ, palette_count)[palette_index]; } inline hb_name_id_t @@ -73,7 +73,7 @@ struct CPALV1Tail unsigned int color_count) const { if (!colorLabelsZ) return HB_NAME_ID_INVALID; - return (hb_name_id_t) (unsigned) hb_array (base+colorLabelsZ, color_count)[color_index]; + return hb_array (base+colorLabelsZ, color_count)[color_index]; } public: diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 6c5f0d401..19f800401 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -1075,7 +1075,7 @@ hb_ot_layout_get_size_params (hb_face_t *face, { if (design_size) *design_size = params.designSize; if (subfamily_id) *subfamily_id = params.subfamilyID; - if (subfamily_name_id) *subfamily_name_id = (hb_name_id_t) (unsigned) params.subfamilyNameID; + if (subfamily_name_id) *subfamily_name_id = params.subfamilyNameID; if (range_start) *range_start = params.rangeStart; if (range_end) *range_end = params.rangeEnd; @@ -1139,7 +1139,7 @@ hb_ot_layout_feature_get_name_ids (hb_face_t *face, feature_params.get_stylistic_set_params (feature_tag); if (&ss_params != &Null (OT::FeatureParamsStylisticSet)) /* ssXX */ { - if (label_id) *label_id = (hb_name_id_t) (unsigned) ss_params.uiNameID; + if (label_id) *label_id = ss_params.uiNameID; // ssXX features don't have the rest if (tooltip_id) *tooltip_id = HB_NAME_ID_INVALID; if (sample_id) *sample_id = HB_NAME_ID_INVALID; @@ -1151,11 +1151,11 @@ hb_ot_layout_feature_get_name_ids (hb_face_t *face, feature_params.get_character_variants_params (feature_tag); if (&cv_params != &Null (OT::FeatureParamsCharacterVariants)) /* cvXX */ { - if (label_id) *label_id = (hb_name_id_t) (unsigned) cv_params.featUILableNameID; - if (tooltip_id) *tooltip_id = (hb_name_id_t) (unsigned) cv_params.featUITooltipTextNameID; - if (sample_id) *sample_id = (hb_name_id_t) (unsigned) cv_params.sampleTextNameID; + if (label_id) *label_id = cv_params.featUILableNameID; + if (tooltip_id) *tooltip_id = cv_params.featUITooltipTextNameID; + if (sample_id) *sample_id = cv_params.sampleTextNameID; if (num_named_parameters) *num_named_parameters = cv_params.numNamedParameters; - if (first_param_id) *first_param_id = (hb_name_id_t) (unsigned) cv_params.firstParamUILabelNameID; + if (first_param_id) *first_param_id = cv_params.firstParamUILabelNameID; return true; } } diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index daf78c89c..b84edd185 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -194,7 +194,7 @@ struct name { hb_ot_name_entry_t *entry = this->names.push (); - entry->name_id = (hb_name_id_t) (unsigned) all_names[i].nameID; + entry->name_id = all_names[i].nameID; entry->language = all_names[i].language (face); entry->entry_score = all_names[i].score (); entry->entry_index = i; diff --git a/src/hb-ot-name.h b/src/hb-ot-name.h index b406c090b..e4ef5f07a 100644 --- a/src/hb-ot-name.h +++ b/src/hb-ot-name.h @@ -44,7 +44,7 @@ HB_BEGIN_DECLS * * Since: 2.0.0 **/ -typedef enum +enum { HB_NAME_ID_COPYRIGHT = 0, HB_NAME_ID_FONT_FAMILY = 1, @@ -74,9 +74,9 @@ typedef enum HB_NAME_ID_VARIATIONS_PS_PREFIX = 25, HB_NAME_ID_INVALID = 0xFFFF, +}; - _HB_NAME_ID_MAX_VALUE_SIGNED = 0x7FFFFFFF /*< skip >*/ /* So we get int-sized. */ -} hb_name_id_t; +typedef unsigned int hb_name_id_t; /** diff --git a/src/test-size-params.cc b/src/test-size-params.cc index b0905d5ad..12eec6188 100644 --- a/src/test-size-params.cc +++ b/src/test-size-params.cc @@ -46,7 +46,7 @@ main (int argc, char **argv) blob = nullptr; unsigned int p[5]; - bool ret = hb_ot_layout_get_size_params (face, p, p+1, (hb_name_id_t *) (p+2), p+3, p+4); + bool ret = hb_ot_layout_get_size_params (face, p, p+1, (p+2), p+3, p+4); printf ("%g %u %u %g %g\n", p[0]/10., p[1], p[2], p[3]/10., p[4]/10.); From dbd419bedef06a07c844b6a748a5e2868016000c Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sat, 27 Oct 2018 15:15:24 +0330 Subject: [PATCH 103/255] [ot-color] Add public API for CBDT/sbix/SVG color Emojis --- docs/harfbuzz-sections.txt | 4 ++++ src/dump-emoji.cc | 4 ++-- src/hb-ot-color.cc | 39 ++++---------------------------------- src/hb-ot-color.h | 24 +++++++++++++++++++++++ test/api/test-ot-color.c | 8 ++------ 5 files changed, 36 insertions(+), 43 deletions(-) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index 9d4edc267..ecce3c77f 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -459,8 +459,12 @@ hb_color_get_blue hb_color_get_green hb_color_get_red hb_ot_color_glyph_get_layers +hb_ot_color_glyph_reference_blob_png +hb_ot_color_glyph_reference_blob_svg hb_ot_color_has_layers hb_ot_color_has_palettes +hb_ot_color_has_png +hb_ot_color_has_svg hb_ot_color_layer_t hb_ot_color_palette_color_get_name_id hb_ot_color_palette_flags_t diff --git a/src/dump-emoji.cc b/src/dump-emoji.cc index 63fb5885f..b622da897 100644 --- a/src/dump-emoji.cc +++ b/src/dump-emoji.cc @@ -295,8 +295,8 @@ main (int argc, char **argv) sbix_dump (face); -// if (hb_ot_color_has_svg (face)) - svg_dump (face); + if (hb_ot_color_has_svg (face)) + svg_dump (face); cairo_font_face_t *cairo_face; { diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index 8150b5e79..fb6ca8660 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -57,14 +57,12 @@ _get_colr (hb_face_t *face) return *(hb_ot_face_data (face)->COLR.get ()); } -#if 0 static inline const OT::CBDT_accelerator_t& _get_cbdt (hb_face_t *face) { if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::CBDT_accelerator_t); return *(hb_ot_face_data (face)->CBDT.get ()); } -#endif static inline const OT::CPAL& _get_cpal (hb_face_t *face) @@ -73,7 +71,6 @@ _get_cpal (hb_face_t *face) return *(hb_ot_face_data (face)->CPAL.get ()); } -#if 0 static inline const OT::sbix_accelerator_t& _get_sbix (hb_face_t *face) { @@ -87,7 +84,6 @@ _get_svg (hb_face_t *face) if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::SVG_accelerator_t); return *(hb_ot_face_data (face)->SVG.get ()); } -#endif /* @@ -253,7 +249,6 @@ hb_ot_color_glyph_get_layers (hb_face_t *face, } -#if 0 /* * SVG */ @@ -264,7 +259,7 @@ hb_ot_color_glyph_get_layers (hb_face_t *face, * * Returns: whether SVG table is available. * - * Since: DONTREPLACEME + * Since: REPLACEME */ hb_bool_t hb_ot_color_has_svg (hb_face_t *face) @@ -279,7 +274,7 @@ hb_ot_color_has_svg (hb_face_t *face) * * Returns: respective svg blob of the glyph, if available. * - * Since: DONTREPLACEME + * Since: REPLACEME */ hb_blob_t * hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph) @@ -298,7 +293,7 @@ hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph) * * Returns: whether either of CBDT or sbix tables is available. * - * Since: DONTREPLACEME + * Since: REPLACEME */ hb_bool_t hb_ot_color_has_png (hb_face_t *face) @@ -317,7 +312,7 @@ hb_ot_color_has_png (hb_face_t *face) * * Returns: respective png blob of the glyph, if available. * - * Since: DONTREPLACEME + * Since: REPLACEME */ hb_blob_t * hb_ot_color_glyph_reference_blob_png (hb_font_t *font, @@ -343,29 +338,3 @@ hb_ot_color_glyph_reference_blob_png (hb_font_t *font, return blob; } - -/* To be moved to public header */ - -/* - * SVG - */ - -HB_EXTERN hb_bool_t -hb_ot_color_has_svg (hb_face_t *face); - -HB_EXTERN hb_blob_t * -hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph); - -/* - * PNG: CBDT or sbix - */ - -HB_EXTERN hb_bool_t -hb_ot_color_has_png (hb_face_t *face); - -HB_EXTERN hb_blob_t * -hb_ot_color_glyph_reference_blob_png (hb_font_t *font, - hb_codepoint_t glyph, - unsigned int *strike_x_ppem, - unsigned int *strike_y_ppem); -#endif diff --git a/src/hb-ot-color.h b/src/hb-ot-color.h index 6e4c1777e..a8eae8618 100644 --- a/src/hb-ot-color.h +++ b/src/hb-ot-color.h @@ -111,6 +111,30 @@ hb_ot_color_glyph_get_layers (hb_face_t *face, unsigned int *count, /* IN/OUT. May be NULL. */ hb_ot_color_layer_t *layers /* OUT. May be NULL. */); +/* + * SVG + */ + +HB_EXTERN hb_bool_t +hb_ot_color_has_svg (hb_face_t *face); + +HB_EXTERN hb_blob_t * +hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph); + +/* + * PNG: CBDT or sbix + */ + +HB_EXTERN hb_bool_t +hb_ot_color_has_png (hb_face_t *face); + +HB_EXTERN hb_blob_t * +hb_ot_color_glyph_reference_blob_png (hb_font_t *font, + hb_codepoint_t glyph, + unsigned int *strike_x_ppem, + unsigned int *strike_y_ppem); + + HB_END_DECLS #endif /* HB_OT_COLOR_H */ diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index 27409e10c..51b901d25 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -363,7 +363,6 @@ test_hb_ot_color_has_data (void) g_assert (hb_ot_color_has_palettes (sbix) == FALSE); g_assert (hb_ot_color_has_palettes (svg) == FALSE); -#if 0 g_assert (hb_ot_color_has_svg (empty) == FALSE); g_assert (hb_ot_color_has_svg (cpal_v0) == FALSE); g_assert (hb_ot_color_has_svg (cpal_v1) == FALSE); @@ -379,10 +378,8 @@ test_hb_ot_color_has_data (void) g_assert (hb_ot_color_has_png (cbdt) == TRUE); g_assert (hb_ot_color_has_png (sbix) == TRUE); g_assert (hb_ot_color_has_png (svg) == FALSE); -#endif } -#if 0 static void test_hb_ot_color_svg (void) { @@ -444,7 +441,6 @@ test_hb_ot_color_png (void) hb_blob_destroy (blob); hb_font_destroy (cbdt_font); } -#endif int main (int argc, char **argv) @@ -472,8 +468,8 @@ main (int argc, char **argv) hb_test_add (test_hb_ot_color_palette_color_get_name_id); hb_test_add (test_hb_ot_color_glyph_get_layers); hb_test_add (test_hb_ot_color_has_data); -// hb_test_add (test_hb_ot_color_png); -// hb_test_add (test_hb_ot_color_svg); + hb_test_add (test_hb_ot_color_png); + hb_test_add (test_hb_ot_color_svg); status = hb_test_run(); hb_face_destroy (cpal_v0); hb_face_destroy (cpal_v1); From 8ef0d2ef928ac47278d7c6db8c8040a47f076e85 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sun, 28 Oct 2018 20:09:40 +0330 Subject: [PATCH 104/255] [ot-color] Apply Behdad comment --- src/dump-emoji.cc | 2 +- src/hb-ot-color-cbdt-table.hh | 16 +++++++--------- src/hb-ot-color-sbix-table.hh | 14 ++++---------- src/hb-ot-color.cc | 22 +++++++--------------- src/hb-ot-color.h | 5 +---- test/api/test-ot-color.c | 15 ++++----------- 6 files changed, 24 insertions(+), 50 deletions(-) diff --git a/src/dump-emoji.cc b/src/dump-emoji.cc index b622da897..5cbf31abe 100644 --- a/src/dump-emoji.cc +++ b/src/dump-emoji.cc @@ -70,7 +70,7 @@ sbix_dump (hb_face_t *face) { hb_blob_t *blob; blob = sbix.reference_blob_for_glyph (glyph_id, 0, available_ppems[group], - HB_TAG('p','n','g',' '), NULL, NULL); + HB_TAG('p','n','g',' ')); if (hb_blob_get_length (blob) == 0) continue; char output_path[255]; diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index 5aa66ccb1..572fcec48 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -506,9 +506,7 @@ struct CBDT inline hb_blob_t* reference_blob_for_glyph (hb_codepoint_t glyph_id, unsigned int requested_x_ppem, - unsigned int requested_y_ppem, - unsigned int *strike_x_ppem, - unsigned int *strike_y_ppem) const + unsigned int requested_y_ppem) const { if (!cblc) return hb_blob_get_empty (); // Not a color bitmap font. @@ -529,8 +527,8 @@ struct CBDT switch (image_format) { case 17: { - if (strike_x_ppem) *strike_x_ppem = x_ppem; - if (strike_x_ppem) *strike_y_ppem = y_ppem; + // if (strike_x_ppem) *strike_x_ppem = x_ppem; + // if (strike_x_ppem) *strike_y_ppem = y_ppem; const GlyphBitmapDataFormat17& glyphFormat17 = StructAtOffset (this->cbdt, image_offset); return hb_blob_create_sub_blob (cbdt_blob, @@ -538,8 +536,8 @@ struct CBDT glyphFormat17.data.len); } case 18: { - if (strike_x_ppem) *strike_x_ppem = x_ppem; - if (strike_x_ppem) *strike_y_ppem = y_ppem; + // if (strike_x_ppem) *strike_x_ppem = x_ppem; + // if (strike_x_ppem) *strike_y_ppem = y_ppem; const GlyphBitmapDataFormat18& glyphFormat18 = StructAtOffset (this->cbdt, image_offset); return hb_blob_create_sub_blob (cbdt_blob, @@ -547,8 +545,8 @@ struct CBDT glyphFormat18.data.len); } case 19: { - if (strike_x_ppem) *strike_x_ppem = x_ppem; - if (strike_x_ppem) *strike_y_ppem = y_ppem; + // if (strike_x_ppem) *strike_x_ppem = x_ppem; + // if (strike_x_ppem) *strike_y_ppem = y_ppem; const GlyphBitmapDataFormat19& glyphFormat19 = StructAtOffset (this->cbdt, image_offset); return hb_blob_create_sub_blob (cbdt_blob, diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index b48ea1715..6dfc29d40 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -84,8 +84,6 @@ struct SBIXStrike hb_blob_t *sbix_blob, unsigned int sbix_len, unsigned int strike_offset, - unsigned int *x_offset, - unsigned int *y_offset, hb_tag_t requested_file_type, unsigned int num_glyphs) const { @@ -110,8 +108,8 @@ struct SBIXStrike } if (unlikely (requested_file_type != glyph->graphicType)) return hb_blob_get_empty (); - if (likely (x_offset)) *x_offset = glyph->xOffset; - if (likely (y_offset)) *y_offset = glyph->yOffset; + // if (x_offset) *x_offset = glyph->xOffset; + // if (y_offset) *y_offset = glyph->yOffset; unsigned int offset = strike_offset + SBIXGlyph::min_size; offset += imageOffsetsZ[glyph_id]; return hb_blob_create_sub_blob (sbix_blob, offset, blob_size (glyph_id)); @@ -169,9 +167,7 @@ struct sbix inline hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id, unsigned int ptem HB_UNUSED, unsigned int requested_ppem, - unsigned int requested_file_type, - unsigned int *available_x_ppem, - unsigned int *available_y_ppem) const + unsigned int requested_file_type) const { if (unlikely (sbix_len == 0 || sbix_table->strikes.len == 0)) return hb_blob_get_empty (); @@ -185,11 +181,9 @@ struct sbix break; const SBIXStrike &strike = sbix_table+sbix_table->strikes[group]; - if (available_x_ppem) *available_x_ppem = strike.get_ppem (); - if (available_y_ppem) *available_y_ppem = strike.get_ppem (); return strike.get_glyph_blob (glyph_id, sbix_blob, sbix_len, sbix_table->strikes[group], - nullptr, nullptr, requested_file_type, num_glyphs); + requested_file_type, num_glyphs); } inline bool has_data () const diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index fb6ca8660..4a460c8bd 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -272,7 +272,7 @@ hb_ot_color_has_svg (hb_face_t *face) * @face: a font face. * @glyph: a svg glyph index. * - * Returns: respective svg blob of the glyph, if available. + * Returns: (transfer full): respective svg blob of the glyph, if available. * * Since: REPLACEME */ @@ -302,39 +302,31 @@ hb_ot_color_has_png (hb_face_t *face) } /** - * hb_ot_color_glyph_reference_blob_svg: + * hb_ot_color_glyph_reference_blob_png: * @font: a font object, not face. upem should be set on * that font object if one wants to get optimal png blob, otherwise * return the biggest one * @glyph: a glyph index. - * @strike_x_ppem: (out): - * @strike_y_ppem: (out): * - * Returns: respective png blob of the glyph, if available. + * Returns: (transfer full): respective png blob of the glyph, if available. * * Since: REPLACEME */ hb_blob_t * -hb_ot_color_glyph_reference_blob_png (hb_font_t *font, - hb_codepoint_t glyph, - unsigned int *strike_x_ppem /* OUT */, - unsigned int *strike_y_ppem /* OUT */) +hb_ot_color_glyph_reference_blob_png (hb_font_t *font, hb_codepoint_t glyph) { hb_blob_t *blob = hb_blob_get_empty (); /* don't run cbdt first if aat is set */ if (!hb_options ().aat && _get_cbdt (font->face).has_data ()) - blob = _get_cbdt (font->face).reference_blob_for_glyph (glyph, font->x_ppem, font->y_ppem, - strike_x_ppem, strike_y_ppem); + blob = _get_cbdt (font->face).reference_blob_for_glyph (glyph, font->x_ppem, font->y_ppem); if (_get_sbix (font->face).has_data () && !hb_blob_get_length (blob)) blob = _get_sbix (font->face).reference_blob_for_glyph (glyph, font->ptem, MAX (font->x_ppem, font->y_ppem), - HB_TAG('p','n','g',' '), - strike_x_ppem, strike_y_ppem); + HB_TAG('p','n','g',' ')); if (hb_options ().aat && _get_cbdt (font->face).has_data () && !hb_blob_get_length (blob)) - blob = _get_cbdt (font->face).reference_blob_for_glyph (glyph, font->x_ppem, font->y_ppem, - strike_x_ppem, strike_y_ppem); + blob = _get_cbdt (font->face).reference_blob_for_glyph (glyph, font->x_ppem, font->y_ppem); return blob; } diff --git a/src/hb-ot-color.h b/src/hb-ot-color.h index a8eae8618..4b0d5b53f 100644 --- a/src/hb-ot-color.h +++ b/src/hb-ot-color.h @@ -129,10 +129,7 @@ HB_EXTERN hb_bool_t hb_ot_color_has_png (hb_face_t *face); HB_EXTERN hb_blob_t * -hb_ot_color_glyph_reference_blob_png (hb_font_t *font, - hb_codepoint_t glyph, - unsigned int *strike_x_ppem, - unsigned int *strike_y_ppem); +hb_ot_color_glyph_reference_blob_png (hb_font_t *font, hb_codepoint_t glyph); HB_END_DECLS diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index 51b901d25..c4c5610e2 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -407,20 +407,16 @@ test_hb_ot_color_png (void) hb_blob_t *blob; unsigned int length; const char *data; - unsigned int strike_x_ppem, strike_y_ppem; /* sbix */ hb_font_t *sbix_font; sbix_font = hb_font_create (sbix); - blob = hb_ot_color_glyph_reference_blob_png (sbix_font, 0, NULL, NULL); + blob = hb_ot_color_glyph_reference_blob_png (sbix_font, 0); g_assert (hb_blob_get_length (blob) == 0); - blob = hb_ot_color_glyph_reference_blob_png (sbix_font, 1, - &strike_x_ppem, &strike_y_ppem); + blob = hb_ot_color_glyph_reference_blob_png (sbix_font, 1); data = hb_blob_get_data (blob, &length); g_assert_cmpuint (length, ==, 224); - g_assert_cmpuint (strike_x_ppem, ==, 300); - g_assert_cmpuint (strike_y_ppem, ==, 300); g_assert (strncmp (data + 1, "PNG", 3) == 0); hb_blob_destroy (blob); hb_font_destroy (sbix_font); @@ -428,15 +424,12 @@ test_hb_ot_color_png (void) /* cbdt */ hb_font_t *cbdt_font; cbdt_font = hb_font_create (cbdt); - blob = hb_ot_color_glyph_reference_blob_png (cbdt_font, 0, NULL, NULL); + blob = hb_ot_color_glyph_reference_blob_png (cbdt_font, 0); g_assert (hb_blob_get_length (blob) == 0); - blob = hb_ot_color_glyph_reference_blob_png (cbdt_font, 1, - &strike_x_ppem, &strike_y_ppem); + blob = hb_ot_color_glyph_reference_blob_png (cbdt_font, 1); data = hb_blob_get_data (blob, &length); g_assert_cmpuint (length, ==, 88); - g_assert_cmpuint (strike_x_ppem, ==, 80); - g_assert_cmpuint (strike_y_ppem, ==, 80); g_assert (strncmp (data + 1, "PNG", 3) == 0); hb_blob_destroy (blob); hb_font_destroy (cbdt_font); From 3d4c1f6a41022ec99adefa2bdd2489622e2f9a66 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sun, 28 Oct 2018 21:38:56 +0330 Subject: [PATCH 105/255] [ot-color] Apply Behdad reviews --- docs/harfbuzz-sections.txt | 4 ++-- src/hb-ot-color-cbdt-table.hh | 15 ++++----------- src/hb-ot-color-sbix-table.hh | 6 ++---- src/hb-ot-color.cc | 8 ++++---- src/hb-ot-color.h | 4 ++-- test/api/test-ot-color.c | 14 +++++++------- 6 files changed, 21 insertions(+), 30 deletions(-) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index ecce3c77f..c33a1c125 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -459,8 +459,8 @@ hb_color_get_blue hb_color_get_green hb_color_get_red hb_ot_color_glyph_get_layers -hb_ot_color_glyph_reference_blob_png -hb_ot_color_glyph_reference_blob_svg +hb_ot_color_glyph_reference_png +hb_ot_color_glyph_reference_svg hb_ot_color_has_layers hb_ot_color_has_palettes hb_ot_color_has_png diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index 572fcec48..d07c73dbd 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -505,15 +505,14 @@ struct CBDT } inline hb_blob_t* reference_blob_for_glyph (hb_codepoint_t glyph_id, - unsigned int requested_x_ppem, - unsigned int requested_y_ppem) const + unsigned int x_ppem, + unsigned int y_ppem) const { if (!cblc) return hb_blob_get_empty (); // Not a color bitmap font. - if (requested_x_ppem == 0) requested_x_ppem = upem; - if (requested_y_ppem == 0) requested_y_ppem = upem; - unsigned int x_ppem = requested_x_ppem, y_ppem = requested_y_ppem; + if (x_ppem == 0) x_ppem = upem; + if (y_ppem == 0) y_ppem = upem; const void *base; const IndexSubtableRecord *subtable_record = this->cblc->find_table (glyph_id, &x_ppem, &y_ppem, &base); @@ -527,8 +526,6 @@ struct CBDT switch (image_format) { case 17: { - // if (strike_x_ppem) *strike_x_ppem = x_ppem; - // if (strike_x_ppem) *strike_y_ppem = y_ppem; const GlyphBitmapDataFormat17& glyphFormat17 = StructAtOffset (this->cbdt, image_offset); return hb_blob_create_sub_blob (cbdt_blob, @@ -536,8 +533,6 @@ struct CBDT glyphFormat17.data.len); } case 18: { - // if (strike_x_ppem) *strike_x_ppem = x_ppem; - // if (strike_x_ppem) *strike_y_ppem = y_ppem; const GlyphBitmapDataFormat18& glyphFormat18 = StructAtOffset (this->cbdt, image_offset); return hb_blob_create_sub_blob (cbdt_blob, @@ -545,8 +540,6 @@ struct CBDT glyphFormat18.data.len); } case 19: { - // if (strike_x_ppem) *strike_x_ppem = x_ppem; - // if (strike_x_ppem) *strike_y_ppem = y_ppem; const GlyphBitmapDataFormat19& glyphFormat19 = StructAtOffset (this->cbdt, image_offset); return hb_blob_create_sub_blob (cbdt_blob, diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 6dfc29d40..a5bfa281e 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -84,7 +84,7 @@ struct SBIXStrike hb_blob_t *sbix_blob, unsigned int sbix_len, unsigned int strike_offset, - hb_tag_t requested_file_type, + hb_tag_t file_type, unsigned int num_glyphs) const { if (imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] == 0) @@ -106,10 +106,8 @@ struct SBIXStrike return hb_blob_get_empty (); } } - if (unlikely (requested_file_type != glyph->graphicType)) + if (unlikely (file_type != glyph->graphicType)) return hb_blob_get_empty (); - // if (x_offset) *x_offset = glyph->xOffset; - // if (y_offset) *y_offset = glyph->yOffset; unsigned int offset = strike_offset + SBIXGlyph::min_size; offset += imageOffsetsZ[glyph_id]; return hb_blob_create_sub_blob (sbix_blob, offset, blob_size (glyph_id)); diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index 4a460c8bd..ed41a3b2b 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -268,7 +268,7 @@ hb_ot_color_has_svg (hb_face_t *face) } /** - * hb_ot_color_glyph_reference_blob_svg: + * hb_ot_color_glyph_reference_svg: * @face: a font face. * @glyph: a svg glyph index. * @@ -277,7 +277,7 @@ hb_ot_color_has_svg (hb_face_t *face) * Since: REPLACEME */ hb_blob_t * -hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph) +hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph) { return _get_svg (face).reference_blob_for_glyph (glyph); } @@ -302,7 +302,7 @@ hb_ot_color_has_png (hb_face_t *face) } /** - * hb_ot_color_glyph_reference_blob_png: + * hb_ot_color_glyph_reference_png: * @font: a font object, not face. upem should be set on * that font object if one wants to get optimal png blob, otherwise * return the biggest one @@ -313,7 +313,7 @@ hb_ot_color_has_png (hb_face_t *face) * Since: REPLACEME */ hb_blob_t * -hb_ot_color_glyph_reference_blob_png (hb_font_t *font, hb_codepoint_t glyph) +hb_ot_color_glyph_reference_png (hb_font_t *font, hb_codepoint_t glyph) { hb_blob_t *blob = hb_blob_get_empty (); /* don't run cbdt first if aat is set */ diff --git a/src/hb-ot-color.h b/src/hb-ot-color.h index 4b0d5b53f..89935143e 100644 --- a/src/hb-ot-color.h +++ b/src/hb-ot-color.h @@ -119,7 +119,7 @@ HB_EXTERN hb_bool_t hb_ot_color_has_svg (hb_face_t *face); HB_EXTERN hb_blob_t * -hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph); +hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph); /* * PNG: CBDT or sbix @@ -129,7 +129,7 @@ HB_EXTERN hb_bool_t hb_ot_color_has_png (hb_face_t *face); HB_EXTERN hb_blob_t * -hb_ot_color_glyph_reference_blob_png (hb_font_t *font, hb_codepoint_t glyph); +hb_ot_color_glyph_reference_png (hb_font_t *font, hb_codepoint_t glyph); HB_END_DECLS diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index c4c5610e2..f825c83ad 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -385,10 +385,10 @@ test_hb_ot_color_svg (void) { hb_blob_t *blob; - blob = hb_ot_color_glyph_reference_blob_svg (svg, 0); + blob = hb_ot_color_glyph_reference_svg (svg, 0); g_assert (hb_blob_get_length (blob) == 0); - blob = hb_ot_color_glyph_reference_blob_svg (svg, 1); + blob = hb_ot_color_glyph_reference_svg (svg, 1); unsigned int length; const char *data = hb_blob_get_data (blob, &length); g_assert_cmpuint (length, ==, 146); @@ -396,7 +396,7 @@ test_hb_ot_color_svg (void) g_assert (strncmp (data + 140, "", 5) == 0); hb_blob_destroy (blob); - blob = hb_ot_color_glyph_reference_blob_svg (empty, 0); + blob = hb_ot_color_glyph_reference_svg (empty, 0); g_assert (hb_blob_get_length (blob) == 0); } @@ -411,10 +411,10 @@ test_hb_ot_color_png (void) /* sbix */ hb_font_t *sbix_font; sbix_font = hb_font_create (sbix); - blob = hb_ot_color_glyph_reference_blob_png (sbix_font, 0); + blob = hb_ot_color_glyph_reference_png (sbix_font, 0); g_assert (hb_blob_get_length (blob) == 0); - blob = hb_ot_color_glyph_reference_blob_png (sbix_font, 1); + blob = hb_ot_color_glyph_reference_png (sbix_font, 1); data = hb_blob_get_data (blob, &length); g_assert_cmpuint (length, ==, 224); g_assert (strncmp (data + 1, "PNG", 3) == 0); @@ -424,10 +424,10 @@ test_hb_ot_color_png (void) /* cbdt */ hb_font_t *cbdt_font; cbdt_font = hb_font_create (cbdt); - blob = hb_ot_color_glyph_reference_blob_png (cbdt_font, 0); + blob = hb_ot_color_glyph_reference_png (cbdt_font, 0); g_assert (hb_blob_get_length (blob) == 0); - blob = hb_ot_color_glyph_reference_blob_png (cbdt_font, 1); + blob = hb_ot_color_glyph_reference_png (cbdt_font, 1); data = hb_blob_get_data (blob, &length); g_assert_cmpuint (length, ==, 88); g_assert (strncmp (data + 1, "PNG", 3) == 0); From d6d6f3bc225bab57c1ab29b41876c98ac4ec1e4d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 11:41:33 -0700 Subject: [PATCH 106/255] [docs] Add comment --- src/hb-ot-font.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 7a4516889..047c4eae5 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -47,7 +47,9 @@ * @short_description: OpenType font implementation * @include: hb-ot.h * - * Functions for using OpenType fonts with hb_shape(). + * Functions for using OpenType fonts with hb_shape(). Not that fonts returned + * by hb_font_create() default to using these functions, so most clients would + * never need to call these functions directly. **/ From 38706a0746822865008f810f9f577740c32580fa Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sun, 28 Oct 2018 23:19:04 +0330 Subject: [PATCH 107/255] [ot-color] Preparation for setting PNG width/height in extents --- src/dump-emoji.cc | 7 +++-- src/hb-ot-color-sbix-table.hh | 52 +++++++++++++++++++++++++++++------ src/hb-ot-color.cc | 14 ++++------ src/hb-ot-font.cc | 7 ++++- 4 files changed, 59 insertions(+), 21 deletions(-) diff --git a/src/dump-emoji.cc b/src/dump-emoji.cc index 5cbf31abe..e3cabc738 100644 --- a/src/dump-emoji.cc +++ b/src/dump-emoji.cc @@ -69,12 +69,13 @@ sbix_dump (hb_face_t *face) for (unsigned int glyph_id = 0; glyph_id < num_glyphs; glyph_id++) { hb_blob_t *blob; - blob = sbix.reference_blob_for_glyph (glyph_id, 0, available_ppems[group], - HB_TAG('p','n','g',' ')); + unsigned int ppem = available_ppems[group]; + blob = sbix.reference_blob_for_glyph (glyph_id, ppem, ppem, + HB_TAG('p','n','g',' '), nullptr, nullptr); if (hb_blob_get_length (blob) == 0) continue; char output_path[255]; - sprintf (output_path, "out/sbix-%d-%d.png", available_ppems[group], glyph_id); + sprintf (output_path, "out/sbix-%d-%d.png", ppem, glyph_id); FILE *f = fopen (output_path, "wb"); unsigned int length; const char* data = hb_blob_get_data (blob, &length); diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index a5bfa281e..bb2590240 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -75,7 +75,7 @@ struct SBIXStrike inline unsigned int get_resolution () const { return resolution; } - inline unsigned int blob_size (unsigned int glyph_id) const + inline unsigned int calculate_blob_size (unsigned int glyph_id) const { return imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] - SBIXGlyph::min_size; } @@ -84,6 +84,8 @@ struct SBIXStrike hb_blob_t *sbix_blob, unsigned int sbix_len, unsigned int strike_offset, + int *x_offset, + int *y_offset, hb_tag_t file_type, unsigned int num_glyphs) const { @@ -95,7 +97,7 @@ struct SBIXStrike const SBIXGlyph *glyph = &(this+imageOffsetsZ[glyph_id]); if (unlikely (glyph->graphicType == HB_TAG ('d','u','p','e') && - blob_size (glyph_id) >= 2)) + calculate_blob_size (glyph_id) >= 2)) { unsigned int new_glyph_id = *((HBUINT16 *) &glyph->data); if (new_glyph_id < num_glyphs) @@ -108,9 +110,15 @@ struct SBIXStrike } if (unlikely (file_type != glyph->graphicType)) return hb_blob_get_empty (); + unsigned int blob_size = calculate_blob_size (glyph_id); + if (unlikely (blob_size == 0)) + return hb_blob_get_empty (); + + if (x_offset) *x_offset = glyph->xOffset; + if (y_offset) *y_offset = glyph->yOffset; unsigned int offset = strike_offset + SBIXGlyph::min_size; offset += imageOffsetsZ[glyph_id]; - return hb_blob_create_sub_blob (sbix_blob, offset, blob_size (glyph_id)); + return hb_blob_create_sub_blob (sbix_blob, offset, blob_size); } protected: @@ -163,25 +171,51 @@ struct sbix } inline hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id, - unsigned int ptem HB_UNUSED, - unsigned int requested_ppem, - unsigned int requested_file_type) const + unsigned int x_ppem, + unsigned int y_ppem, + unsigned int file_type, + int *x_offset, + int *y_offset) const { if (unlikely (sbix_len == 0 || sbix_table->strikes.len == 0)) return hb_blob_get_empty (); /* TODO: Does spec guarantee strikes are ascended sorted? */ unsigned int group = sbix_table->strikes.len - 1; - if (requested_ppem != 0) + unsigned int ppem = MAX (x_ppem, y_ppem); + if (ppem != 0) /* TODO: Use bsearch maybe or doesn't worth it? */ for (group = 0; group < sbix_table->strikes.len; group++) - if ((sbix_table+sbix_table->strikes[group]).get_ppem () >= requested_ppem) + if ((sbix_table+sbix_table->strikes[group]).get_ppem () >= ppem) break; const SBIXStrike &strike = sbix_table+sbix_table->strikes[group]; return strike.get_glyph_blob (glyph_id, sbix_blob, sbix_len, sbix_table->strikes[group], - requested_file_type, num_glyphs); + x_offset, y_offset, + file_type, num_glyphs); + } + + inline bool get_png_extents (hb_codepoint_t glyph, + unsigned int x_ppem, + unsigned int y_ppem, + hb_glyph_extents_t *extents) const + { + int x_offset, y_offset; + hb_blob_t *blob = reference_blob_for_glyph (glyph, x_ppem, y_ppem, + HB_TAG ('P','N','G',' '), + &x_offset, &y_offset); + if (hb_blob_get_length (blob) == 0) + return false; + + extents->x_bearing = x_offset; + extents->y_bearing = y_offset; + /* XXX: Help me please! */ + extents->width = 0; + extents->height = 0; + hb_blob_destroy (blob); + + return true; } inline bool has_data () const diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index ed41a3b2b..82fa7e294 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -316,16 +316,14 @@ hb_blob_t * hb_ot_color_glyph_reference_png (hb_font_t *font, hb_codepoint_t glyph) { hb_blob_t *blob = hb_blob_get_empty (); - /* don't run cbdt first if aat is set */ - if (!hb_options ().aat && _get_cbdt (font->face).has_data ()) - blob = _get_cbdt (font->face).reference_blob_for_glyph (glyph, font->x_ppem, font->y_ppem); - if (_get_sbix (font->face).has_data () && !hb_blob_get_length (blob)) - blob = _get_sbix (font->face).reference_blob_for_glyph (glyph, font->ptem, - MAX (font->x_ppem, font->y_ppem), - HB_TAG('p','n','g',' ')); + if (_get_sbix (font->face).has_data ()) + blob = _get_sbix (font->face).reference_blob_for_glyph (glyph, + font->x_ppem, font->y_ppem, + HB_TAG('p','n','g',' '), + nullptr, nullptr); - if (hb_options ().aat && _get_cbdt (font->face).has_data () && !hb_blob_get_length (blob)) + if (hb_blob_get_length (blob) == 0 && _get_cbdt (font->face).has_data ()) blob = _get_cbdt (font->face).reference_blob_for_glyph (glyph, font->x_ppem, font->y_ppem); return blob; diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 047c4eae5..c8ad6f2f7 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -39,6 +39,7 @@ #include "hb-ot-glyf-table.hh" #include "hb-ot-vorg-table.hh" #include "hb-ot-color-cbdt-table.hh" +#include "hb-ot-color-sbix-table.hh" /** @@ -182,7 +183,11 @@ hb_ot_get_glyph_extents (hb_font_t *font, void *user_data HB_UNUSED) { const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; - bool ret = ot_face->glyf->get_extents (glyph, extents); + bool ret = false; + if (ot_face->sbix->has_data ()) + ret = ot_face->sbix->get_png_extents (glyph, font->x_ppem, font->y_ppem, extents); + if (!ret) + ret = ot_face->glyf->get_extents (glyph, extents); if (!ret) ret = ot_face->CBDT->get_extents (glyph, extents); // TODO Hook up side-bearings variations. From 632e9af862aba49ab31343c4fd07dffef6d2749f Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sun, 28 Oct 2018 23:43:50 +0330 Subject: [PATCH 108/255] [ot-color] Implement PNGHeader and test it, it doesn't work however --- src/hb-ot-color-sbix-table.hh | 20 +++++++++++++++----- src/hb-ot-font.cc | 4 +--- test/api/test-ot-color.c | 16 ++++++++++++++++ 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index bb2590240..95db7fe6e 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -196,23 +196,33 @@ struct sbix file_type, num_glyphs); } + struct PNGHeader + { + HBUINT8 header[9]; + HBUINT32 width; + HBUINT32 height; + }; + inline bool get_png_extents (hb_codepoint_t glyph, unsigned int x_ppem, unsigned int y_ppem, hb_glyph_extents_t *extents) const { + if (likely (sbix_len == 0)) + return hb_blob_get_empty (); + int x_offset, y_offset; hb_blob_t *blob = reference_blob_for_glyph (glyph, x_ppem, y_ppem, - HB_TAG ('P','N','G',' '), + HB_TAG ('p','n','g',' '), &x_offset, &y_offset); - if (hb_blob_get_length (blob) == 0) + if (hb_blob_get_length (blob) < sizeof (PNGHeader)) return false; extents->x_bearing = x_offset; extents->y_bearing = y_offset; - /* XXX: Help me please! */ - extents->width = 0; - extents->height = 0; + const PNGHeader &header = *blob->as(); + extents->width = header.width + 100; + extents->height = header.height; hb_blob_destroy (blob); return true; diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index c8ad6f2f7..fa6fda27a 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -183,9 +183,7 @@ hb_ot_get_glyph_extents (hb_font_t *font, void *user_data HB_UNUSED) { const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; - bool ret = false; - if (ot_face->sbix->has_data ()) - ret = ot_face->sbix->get_png_extents (glyph, font->x_ppem, font->y_ppem, extents); + bool ret = ot_face->sbix->get_png_extents (glyph, font->x_ppem, font->y_ppem, extents); if (!ret) ret = ot_face->glyf->get_extents (glyph, extents); if (!ret) diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index f825c83ad..bef52bfba 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -407,17 +407,28 @@ test_hb_ot_color_png (void) hb_blob_t *blob; unsigned int length; const char *data; + hb_glyph_extents_t extents; /* sbix */ hb_font_t *sbix_font; sbix_font = hb_font_create (sbix); blob = hb_ot_color_glyph_reference_png (sbix_font, 0); + hb_font_get_glyph_extents (sbix_font, 0, &extents); + g_assert_cmpint (extents.x_bearing, ==, 0); + g_assert_cmpint (extents.y_bearing, ==, 0); + g_assert_cmpint (extents.width, ==, 0); + g_assert_cmpint (extents.height, ==, 0); g_assert (hb_blob_get_length (blob) == 0); blob = hb_ot_color_glyph_reference_png (sbix_font, 1); data = hb_blob_get_data (blob, &length); g_assert_cmpuint (length, ==, 224); g_assert (strncmp (data + 1, "PNG", 3) == 0); + hb_font_get_glyph_extents (sbix_font, 1, &extents); + g_assert_cmpint (extents.x_bearing, ==, 0); + g_assert_cmpint (extents.y_bearing, ==, 0); + g_assert_cmpint (extents.width, ==, 3501); + g_assert_cmpint (extents.height, ==, 20992); hb_blob_destroy (blob); hb_font_destroy (sbix_font); @@ -431,6 +442,11 @@ test_hb_ot_color_png (void) data = hb_blob_get_data (blob, &length); g_assert_cmpuint (length, ==, 88); g_assert (strncmp (data + 1, "PNG", 3) == 0); + hb_font_get_glyph_extents (cbdt_font, 1, &extents); + g_assert_cmpint (extents.x_bearing, ==, 0); + g_assert_cmpint (extents.y_bearing, ==, 1024); + g_assert_cmpint (extents.width, ==, 1024); + g_assert_cmpint (extents.height, ==, -1024); hb_blob_destroy (blob); hb_font_destroy (cbdt_font); } From 307d61867a2b70073eecd1e0cb9b7d912e1c3f06 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Mon, 29 Oct 2018 00:03:01 +0330 Subject: [PATCH 109/255] [ot-color] Make PNGHeader reading actually work --- src/hb-ot-color-sbix-table.hh | 6 +++--- test/api/test-ot-color.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 95db7fe6e..79c86ed01 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -198,7 +198,7 @@ struct sbix struct PNGHeader { - HBUINT8 header[9]; + HBUINT8 header[16]; HBUINT32 width; HBUINT32 height; }; @@ -209,7 +209,7 @@ struct sbix hb_glyph_extents_t *extents) const { if (likely (sbix_len == 0)) - return hb_blob_get_empty (); + return false; int x_offset, y_offset; hb_blob_t *blob = reference_blob_for_glyph (glyph, x_ppem, y_ppem, @@ -221,7 +221,7 @@ struct sbix extents->x_bearing = x_offset; extents->y_bearing = y_offset; const PNGHeader &header = *blob->as(); - extents->width = header.width + 100; + extents->width = header.width; extents->height = header.height; hb_blob_destroy (blob); diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index bef52bfba..9cc353bad 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -427,8 +427,8 @@ test_hb_ot_color_png (void) hb_font_get_glyph_extents (sbix_font, 1, &extents); g_assert_cmpint (extents.x_bearing, ==, 0); g_assert_cmpint (extents.y_bearing, ==, 0); - g_assert_cmpint (extents.width, ==, 3501); - g_assert_cmpint (extents.height, ==, 20992); + g_assert_cmpint (extents.width, ==, 300); + g_assert_cmpint (extents.height, ==, 300); hb_blob_destroy (blob); hb_font_destroy (sbix_font); From 35fa3d326096639a33635e19f204a9cb31f20826 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Mon, 29 Oct 2018 00:07:26 +0330 Subject: [PATCH 110/255] [ot-color] Apply Behdad comment --- src/hb-ot-color-sbix-table.hh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 79c86ed01..5e49d7b2a 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -215,12 +215,13 @@ struct sbix hb_blob_t *blob = reference_blob_for_glyph (glyph, x_ppem, y_ppem, HB_TAG ('p','n','g',' '), &x_offset, &y_offset); - if (hb_blob_get_length (blob) < sizeof (PNGHeader)) + + const PNGHeader &header = *blob->as(); + if (header.width == 0 && header.width == 0) return false; extents->x_bearing = x_offset; extents->y_bearing = y_offset; - const PNGHeader &header = *blob->as(); extents->width = header.width; extents->height = header.height; hb_blob_destroy (blob); From d3ec31a57cb99048fb33bca65041da9dc884d8cb Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Mon, 29 Oct 2018 00:28:44 +0330 Subject: [PATCH 111/255] [ot-color] More on PNGHeader fields --- src/hb-ot-color-sbix-table.hh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 5e49d7b2a..bd298c62e 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -198,9 +198,15 @@ struct sbix struct PNGHeader { - HBUINT8 header[16]; - HBUINT32 width; - HBUINT32 height; + HBUINT8 signature[8]; + HBUINT8 chunkHeaderIHDR[8]; + HBUINT32 width; + HBUINT32 height; + HBUINT8 bitDepth; + HBUINT8 colorType; + HBUINT8 compressionMethod; + HBUINT8 filterMethod; + HBUINT8 interlaceMethod; }; inline bool get_png_extents (hb_codepoint_t glyph, From 48bc3039cb46d2b8cf672d86b63b4235a86252e6 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 14:16:52 -0700 Subject: [PATCH 112/255] [sbix] Check blob length against PNG header leangth --- src/hb-ot-color-sbix-table.hh | 37 ++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index bd298c62e..ad962e6ad 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -199,14 +199,24 @@ struct sbix struct PNGHeader { HBUINT8 signature[8]; - HBUINT8 chunkHeaderIHDR[8]; - HBUINT32 width; - HBUINT32 height; - HBUINT8 bitDepth; - HBUINT8 colorType; - HBUINT8 compressionMethod; - HBUINT8 filterMethod; - HBUINT8 interlaceMethod; + struct + { + struct + { + HBUINT32 length; + Tag type; + } header; + HBUINT32 width; + HBUINT32 height; + HBUINT8 bitDepth; + HBUINT8 colorType; + HBUINT8 compressionMethod; + HBUINT8 filterMethod; + HBUINT8 interlaceMethod; + } IHDR; + + public: + DEFINE_SIZE_STATIC (29); }; inline bool get_png_extents (hb_codepoint_t glyph, @@ -222,21 +232,20 @@ struct sbix HB_TAG ('p','n','g',' '), &x_offset, &y_offset); - const PNGHeader &header = *blob->as(); - if (header.width == 0 && header.width == 0) + const PNGHeader &png = *blob->as(); + if (unlikely (blob->length < sizeof (PNGHeader))) return false; extents->x_bearing = x_offset; extents->y_bearing = y_offset; - extents->width = header.width; - extents->height = header.height; + extents->width = png.IHDR.width; + extents->height = png.IHDR.height; hb_blob_destroy (blob); return true; } - inline bool has_data () const - { return sbix_len; } + inline bool has_data () const { return sbix_len; } private: hb_blob_t *sbix_blob; From f9f26bff4c79d65a92affd6b73e2b3de017f2d6d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 14:20:50 -0700 Subject: [PATCH 113/255] [sbix] Move code around. Add get_extents() --- src/hb-ot-color-sbix-table.hh | 15 +++++++++++++-- src/hb-ot-font.cc | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index ad962e6ad..8dc2aedb1 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -157,6 +157,8 @@ struct sbix hb_blob_destroy (sbix_blob); } + inline bool has_data () const { return sbix_len; } + /* only to support dump-emoji, don't use it anywhere else */ inline unsigned int *get_available_ppems (unsigned int *length) { @@ -170,6 +172,15 @@ struct sbix return result; } + inline bool get_extents (hb_codepoint_t glyph, + unsigned int x_ppem, + unsigned int y_ppem, + hb_glyph_extents_t *extents) const + { + /* We only support PNG right now, and following function checks type. */ + return get_png_extents (glyph, x_ppem, y_ppem, extents); + } + inline hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id, unsigned int x_ppem, unsigned int y_ppem, @@ -196,6 +207,8 @@ struct sbix file_type, num_glyphs); } + private: + struct PNGHeader { HBUINT8 signature[8]; @@ -245,8 +258,6 @@ struct sbix return true; } - inline bool has_data () const { return sbix_len; } - private: hb_blob_t *sbix_blob; const sbix *sbix_table; diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index fa6fda27a..7b31e025d 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -183,7 +183,7 @@ hb_ot_get_glyph_extents (hb_font_t *font, void *user_data HB_UNUSED) { const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; - bool ret = ot_face->sbix->get_png_extents (glyph, font->x_ppem, font->y_ppem, extents); + bool ret = ot_face->sbix->get_extents (glyph, font->x_ppem, font->y_ppem, extents); if (!ret) ret = ot_face->glyf->get_extents (glyph, extents); if (!ret) From 01c7d53fb739b547f3633972194893f68a4738bc Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 14:51:18 -0700 Subject: [PATCH 114/255] [sbix] Select best strike based on ppem --- src/hb-ot-color-sbix-table.hh | 50 ++++++++++++++++++++--------------- src/hb-ot-color.cc | 3 +-- src/hb-ot-font.cc | 2 +- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 8dc2aedb1..ce46f3fe8 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -172,37 +172,44 @@ struct sbix return result; } - inline bool get_extents (hb_codepoint_t glyph, - unsigned int x_ppem, - unsigned int y_ppem, + inline bool get_extents (hb_font_t *font, + hb_codepoint_t glyph, hb_glyph_extents_t *extents) const { /* We only support PNG right now, and following function checks type. */ - return get_png_extents (glyph, x_ppem, y_ppem, extents); + return get_png_extents (font, glyph, extents); } - inline hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id, - unsigned int x_ppem, - unsigned int y_ppem, + inline hb_blob_t *reference_blob_for_glyph (hb_font_t *font, + hb_codepoint_t glyph_id, unsigned int file_type, int *x_offset, int *y_offset) const { - if (unlikely (sbix_len == 0 || sbix_table->strikes.len == 0)) + if (unlikely (!sbix_len || !sbix_table->strikes.len)) return hb_blob_get_empty (); - /* TODO: Does spec guarantee strikes are ascended sorted? */ - unsigned int group = sbix_table->strikes.len - 1; - unsigned int ppem = MAX (x_ppem, y_ppem); - if (ppem != 0) - /* TODO: Use bsearch maybe or doesn't worth it? */ - for (group = 0; group < sbix_table->strikes.len; group++) - if ((sbix_table+sbix_table->strikes[group]).get_ppem () >= ppem) - break; + unsigned int requested_ppem = MAX (font->x_ppem, font->y_ppem); + if (!requested_ppem) + requested_ppem = 1<<30; /* Choose largest strike. */ + /* TODO Add DPI sensitivity as well? */ + unsigned int best_i = 0; + unsigned int best_ppem = (sbix_table+sbix_table->strikes[0]).get_ppem (); - const SBIXStrike &strike = sbix_table+sbix_table->strikes[group]; + for (unsigned int i = 1; i < sbix_table->strikes.len; i++) + { + unsigned int ppem = (sbix_table+sbix_table->strikes[i]).get_ppem (); + if ((requested_ppem <= ppem && ppem < best_ppem) || + (requested_ppem > best_ppem && ppem > best_ppem)) + { + best_i = i; + best_ppem = ppem; + } + } + + const SBIXStrike &strike = sbix_table+sbix_table->strikes[best_i]; return strike.get_glyph_blob (glyph_id, sbix_blob, sbix_len, - sbix_table->strikes[group], + sbix_table->strikes[best_i], x_offset, y_offset, file_type, num_glyphs); } @@ -232,16 +239,15 @@ struct sbix DEFINE_SIZE_STATIC (29); }; - inline bool get_png_extents (hb_codepoint_t glyph, - unsigned int x_ppem, - unsigned int y_ppem, + inline bool get_png_extents (hb_font_t *font, + hb_codepoint_t glyph, hb_glyph_extents_t *extents) const { if (likely (sbix_len == 0)) return false; int x_offset, y_offset; - hb_blob_t *blob = reference_blob_for_glyph (glyph, x_ppem, y_ppem, + hb_blob_t *blob = reference_blob_for_glyph (font, glyph, HB_TAG ('p','n','g',' '), &x_offset, &y_offset); diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index 82fa7e294..c61b2652c 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -318,8 +318,7 @@ hb_ot_color_glyph_reference_png (hb_font_t *font, hb_codepoint_t glyph) hb_blob_t *blob = hb_blob_get_empty (); if (_get_sbix (font->face).has_data ()) - blob = _get_sbix (font->face).reference_blob_for_glyph (glyph, - font->x_ppem, font->y_ppem, + blob = _get_sbix (font->face).reference_blob_for_glyph (font, glyph, HB_TAG('p','n','g',' '), nullptr, nullptr); diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 7b31e025d..e9619c54f 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -183,7 +183,7 @@ hb_ot_get_glyph_extents (hb_font_t *font, void *user_data HB_UNUSED) { const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; - bool ret = ot_face->sbix->get_extents (glyph, font->x_ppem, font->y_ppem, extents); + bool ret = ot_face->sbix->get_extents (font, glyph, extents); if (!ret) ret = ot_face->glyf->get_extents (glyph, extents); if (!ret) From 946b5344193183133bfc9799e26d3d0436d86404 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 14:52:25 -0700 Subject: [PATCH 115/255] [sbix] Fix uninitialized variables --- src/hb-ot-color-sbix-table.hh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index ce46f3fe8..5cff5b976 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -246,15 +246,16 @@ struct sbix if (likely (sbix_len == 0)) return false; - int x_offset, y_offset; + int x_offset = 0, y_offset = 0; hb_blob_t *blob = reference_blob_for_glyph (font, glyph, HB_TAG ('p','n','g',' '), &x_offset, &y_offset); - const PNGHeader &png = *blob->as(); if (unlikely (blob->length < sizeof (PNGHeader))) return false; + const PNGHeader &png = *blob->as(); + extents->x_bearing = x_offset; extents->y_bearing = y_offset; extents->width = png.IHDR.width; From 1f33b8525d578323d6c798c08fc23c56896f9de0 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 14:56:55 -0700 Subject: [PATCH 116/255] [sbix] Rename ugly reference_blob_for_glyph() to reference_png() --- src/hb-ot-color-sbix-table.hh | 16 +++++++--------- src/hb-ot-color.cc | 4 +--- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 5cff5b976..54cc62a6a 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -180,11 +180,10 @@ struct sbix return get_png_extents (font, glyph, extents); } - inline hb_blob_t *reference_blob_for_glyph (hb_font_t *font, - hb_codepoint_t glyph_id, - unsigned int file_type, - int *x_offset, - int *y_offset) const + inline hb_blob_t *reference_png (hb_font_t *font, + hb_codepoint_t glyph_id, + int *x_offset, + int *y_offset) const { if (unlikely (!sbix_len || !sbix_table->strikes.len)) return hb_blob_get_empty (); @@ -211,7 +210,8 @@ struct sbix return strike.get_glyph_blob (glyph_id, sbix_blob, sbix_len, sbix_table->strikes[best_i], x_offset, y_offset, - file_type, num_glyphs); + HB_TAG ('p','n','g',' '), + num_glyphs); } private: @@ -247,9 +247,7 @@ struct sbix return false; int x_offset = 0, y_offset = 0; - hb_blob_t *blob = reference_blob_for_glyph (font, glyph, - HB_TAG ('p','n','g',' '), - &x_offset, &y_offset); + hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset); if (unlikely (blob->length < sizeof (PNGHeader))) return false; diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index c61b2652c..c70549bc3 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -318,9 +318,7 @@ hb_ot_color_glyph_reference_png (hb_font_t *font, hb_codepoint_t glyph) hb_blob_t *blob = hb_blob_get_empty (); if (_get_sbix (font->face).has_data ()) - blob = _get_sbix (font->face).reference_blob_for_glyph (font, glyph, - HB_TAG('p','n','g',' '), - nullptr, nullptr); + blob = _get_sbix (font->face).reference_png (font, glyph, nullptr, nullptr); if (hb_blob_get_length (blob) == 0 && _get_cbdt (font->face).has_data ()) blob = _get_cbdt (font->face).reference_blob_for_glyph (glyph, font->x_ppem, font->y_ppem); From 7346841807ad96fc65bfc6ee9e78c3f190488f2a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 15:00:13 -0700 Subject: [PATCH 117/255] [cbdt] Rename reference_blob_for_glyph() to reference_png() --- src/hb-ot-color-cbdt-table.hh | 8 ++++---- src/hb-ot-color.cc | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index d07c73dbd..f744e1a6a 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -504,12 +504,12 @@ struct CBDT } } - inline hb_blob_t* reference_blob_for_glyph (hb_codepoint_t glyph_id, - unsigned int x_ppem, - unsigned int y_ppem) const + inline hb_blob_t* reference_png (hb_codepoint_t glyph_id, + unsigned int x_ppem, + unsigned int y_ppem) const { if (!cblc) - return hb_blob_get_empty (); // Not a color bitmap font. + return hb_blob_get_empty (); if (x_ppem == 0) x_ppem = upem; if (y_ppem == 0) y_ppem = upem; diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index c70549bc3..c89dc9e54 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -321,7 +321,7 @@ hb_ot_color_glyph_reference_png (hb_font_t *font, hb_codepoint_t glyph) blob = _get_sbix (font->face).reference_png (font, glyph, nullptr, nullptr); if (hb_blob_get_length (blob) == 0 && _get_cbdt (font->face).has_data ()) - blob = _get_cbdt (font->face).reference_blob_for_glyph (glyph, font->x_ppem, font->y_ppem); + blob = _get_cbdt (font->face).reference_png (glyph, font->x_ppem, font->y_ppem); return blob; } From 3770282c837aacbf49b16be1986c91a608faa7da Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 15:02:53 -0700 Subject: [PATCH 118/255] [sbix] Rename sbix_table to table in accelerator --- src/hb-ot-color-sbix-table.hh | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 54cc62a6a..5aee44e68 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -148,7 +148,7 @@ struct sbix { sbix_blob = hb_sanitize_context_t().reference_table (face); sbix_len = hb_blob_get_length (sbix_blob); - sbix_table = sbix_blob->as (); + table = sbix_blob->as (); num_glyphs = face->get_num_glyphs (); } @@ -162,13 +162,13 @@ struct sbix /* only to support dump-emoji, don't use it anywhere else */ inline unsigned int *get_available_ppems (unsigned int *length) { - if (unlikely (sbix_len == 0 || sbix_table->strikes.len == 0)) + if (unlikely (sbix_len == 0 || table->strikes.len == 0)) return nullptr; - *length = sbix_table->strikes.len; + *length = table->strikes.len; unsigned int *result; - result = (unsigned int *) malloc (sizeof (unsigned int) * sbix_table->strikes.len); - for (unsigned int i = 0; i < sbix_table->strikes.len; i++) - result[i] = (sbix_table+sbix_table->strikes[i]).get_ppem (); + result = (unsigned int *) malloc (sizeof (unsigned int) * table->strikes.len); + for (unsigned int i = 0; i < table->strikes.len; i++) + result[i] = (table+table->strikes[i]).get_ppem (); return result; } @@ -185,7 +185,7 @@ struct sbix int *x_offset, int *y_offset) const { - if (unlikely (!sbix_len || !sbix_table->strikes.len)) + if (unlikely (!sbix_len || !table->strikes.len)) return hb_blob_get_empty (); unsigned int requested_ppem = MAX (font->x_ppem, font->y_ppem); @@ -193,11 +193,11 @@ struct sbix requested_ppem = 1<<30; /* Choose largest strike. */ /* TODO Add DPI sensitivity as well? */ unsigned int best_i = 0; - unsigned int best_ppem = (sbix_table+sbix_table->strikes[0]).get_ppem (); + unsigned int best_ppem = (table+table->strikes[0]).get_ppem (); - for (unsigned int i = 1; i < sbix_table->strikes.len; i++) + for (unsigned int i = 1; i < table->strikes.len; i++) { - unsigned int ppem = (sbix_table+sbix_table->strikes[i]).get_ppem (); + unsigned int ppem = (table+table->strikes[i]).get_ppem (); if ((requested_ppem <= ppem && ppem < best_ppem) || (requested_ppem > best_ppem && ppem > best_ppem)) { @@ -206,9 +206,9 @@ struct sbix } } - const SBIXStrike &strike = sbix_table+sbix_table->strikes[best_i]; + const SBIXStrike &strike = table+table->strikes[best_i]; return strike.get_glyph_blob (glyph_id, sbix_blob, sbix_len, - sbix_table->strikes[best_i], + table->strikes[best_i], x_offset, y_offset, HB_TAG ('p','n','g',' '), num_glyphs); @@ -265,7 +265,7 @@ struct sbix private: hb_blob_t *sbix_blob; - const sbix *sbix_table; + const sbix *table; unsigned int sbix_len; unsigned int num_glyphs; From 400bc3f030b4ffebe24aa3562d8eb5fcc1cf4bdd Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 15:05:40 -0700 Subject: [PATCH 119/255] [sbix] Remove a couple of extra checks --- src/hb-ot-color-sbix-table.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 5aee44e68..2331a5f9a 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -162,7 +162,7 @@ struct sbix /* only to support dump-emoji, don't use it anywhere else */ inline unsigned int *get_available_ppems (unsigned int *length) { - if (unlikely (sbix_len == 0 || table->strikes.len == 0)) + if (unlikely (table->strikes.len == 0)) return nullptr; *length = table->strikes.len; unsigned int *result; @@ -185,7 +185,7 @@ struct sbix int *x_offset, int *y_offset) const { - if (unlikely (!sbix_len || !table->strikes.len)) + if (unlikely (!table->strikes.len)) return hb_blob_get_empty (); unsigned int requested_ppem = MAX (font->x_ppem, font->y_ppem); From c712005f55b2a1e5c782302d8a548cf1231c01f0 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 15:11:10 -0700 Subject: [PATCH 120/255] [sbix] Add get_strike() --- src/hb-ot-color-sbix-table.hh | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 2331a5f9a..f6b198ffc 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -83,12 +83,12 @@ struct SBIXStrike inline hb_blob_t *get_glyph_blob (unsigned int glyph_id, hb_blob_t *sbix_blob, unsigned int sbix_len, - unsigned int strike_offset, int *x_offset, int *y_offset, hb_tag_t file_type, unsigned int num_glyphs) const { + unsigned int strike_offset = (const char *) this - (const char *) sbix_blob->data; if (imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] == 0) return hb_blob_get_empty (); @@ -184,9 +184,19 @@ struct sbix hb_codepoint_t glyph_id, int *x_offset, int *y_offset) const + { + return get_strike (font).get_glyph_blob (glyph_id, sbix_blob, sbix_len, + x_offset, y_offset, + HB_TAG ('p','n','g',' '), + num_glyphs); + } + + private: + + inline const SBIXStrike &get_strike (hb_font_t *font) const { if (unlikely (!table->strikes.len)) - return hb_blob_get_empty (); + return Null(SBIXStrike); unsigned int requested_ppem = MAX (font->x_ppem, font->y_ppem); if (!requested_ppem) @@ -206,16 +216,9 @@ struct sbix } } - const SBIXStrike &strike = table+table->strikes[best_i]; - return strike.get_glyph_blob (glyph_id, sbix_blob, sbix_len, - table->strikes[best_i], - x_offset, y_offset, - HB_TAG ('p','n','g',' '), - num_glyphs); + return table+table->strikes[best_i]; } - private: - struct PNGHeader { HBUINT8 signature[8]; From a91cda72abdfc5e401510474c59dd14026e8b6cb Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 15:12:05 -0700 Subject: [PATCH 121/255] [sbix] Remove redundant parameter --- src/hb-ot-color-sbix-table.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index f6b198ffc..fc199da88 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -82,12 +82,12 @@ struct SBIXStrike inline hb_blob_t *get_glyph_blob (unsigned int glyph_id, hb_blob_t *sbix_blob, - unsigned int sbix_len, int *x_offset, int *y_offset, hb_tag_t file_type, unsigned int num_glyphs) const { + unsigned int sbix_len = sbix_blob->length; unsigned int strike_offset = (const char *) this - (const char *) sbix_blob->data; if (imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] == 0) return hb_blob_get_empty (); @@ -185,7 +185,7 @@ struct sbix int *x_offset, int *y_offset) const { - return get_strike (font).get_glyph_blob (glyph_id, sbix_blob, sbix_len, + return get_strike (font).get_glyph_blob (glyph_id, sbix_blob, x_offset, y_offset, HB_TAG ('p','n','g',' '), num_glyphs); From b46de42b3a4bdf110154f4f067656f153f5a7d1b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 15:13:45 -0700 Subject: [PATCH 122/255] [sbix] Fix order of parameters --- src/hb-ot-color-sbix-table.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index fc199da88..94b001205 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -82,9 +82,9 @@ struct SBIXStrike inline hb_blob_t *get_glyph_blob (unsigned int glyph_id, hb_blob_t *sbix_blob, + hb_tag_t file_type, int *x_offset, int *y_offset, - hb_tag_t file_type, unsigned int num_glyphs) const { unsigned int sbix_len = sbix_blob->length; @@ -186,8 +186,8 @@ struct sbix int *y_offset) const { return get_strike (font).get_glyph_blob (glyph_id, sbix_blob, - x_offset, y_offset, HB_TAG ('p','n','g',' '), + x_offset, y_offset, num_glyphs); } From 68f2c832c894d71715073d4748ad321a9d271a0e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 15:18:55 -0700 Subject: [PATCH 123/255] Remove dump-emoji --- src/Makefile.am | 9 - src/dump-emoji.cc | 322 ---------------------------------- src/hb-ot-color-sbix-table.hh | 4 +- 3 files changed, 3 insertions(+), 332 deletions(-) delete mode 100644 src/dump-emoji.cc diff --git a/src/Makefile.am b/src/Makefile.am index 0d614ee03..0b9ae9dc4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -412,15 +412,6 @@ dump_use_data_SOURCES = dump-use-data.cc hb-ot-shape-complex-use-table.cc dump_use_data_CPPFLAGS = $(HBCFLAGS) dump_use_data_LDADD = libharfbuzz.la $(HBLIBS) -if HAVE_FREETYPE -if HAVE_CAIRO_FT -check_PROGRAMS += dump-emoji -dump_emoji_SOURCES = dump-emoji.cc -dump_emoji_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS) $(CAIRO_FT_CFLAGS) -dump_emoji_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS) $(CAIRO_LIBS) $(CAIRO_FT_LIBS) -endif # HAVE_CAIRO_FT -endif # HAVE_FREETYPE - check_PROGRAMS += test-ot-tag test-unicode-ranges TESTS += test-ot-tag test-unicode-ranges diff --git a/src/dump-emoji.cc b/src/dump-emoji.cc deleted file mode 100644 index e3cabc738..000000000 --- a/src/dump-emoji.cc +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright © 2018 Ebrahim Byagowi - * Copyright © 2018 Khaled Hosny - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - */ - -#include "hb-static.cc" -#include "hb-ot-color-cbdt-table.hh" -#include "hb-ot-color-colr-table.hh" -#include "hb-ot-color-cpal-table.hh" -#include "hb-ot-color-sbix-table.hh" -#include "hb-ot-color-svg-table.hh" - -#include "hb-ft.h" - -#include -#include FT_FREETYPE_H -#include FT_GLYPH_H - -#include -#include -#include - -#ifdef HAVE_GLIB -#include -#endif -#include -#include - -static void -cbdt_callback (const uint8_t* data, unsigned int length, - unsigned int group, unsigned int gid) -{ - char output_path[255]; - sprintf (output_path, "out/cbdt-%d-%d.png", group, gid); - FILE *f = fopen (output_path, "wb"); - fwrite (data, 1, length, f); - fclose (f); -} - -static void -sbix_dump (hb_face_t *face) -{ - OT::sbix::accelerator_t sbix; - sbix.init (face); - unsigned int length = 0; - unsigned int *available_ppems = sbix.get_available_ppems (&length); - unsigned int num_glyphs = face->num_glyphs; - for (unsigned int group = 0; group < length; group++) - for (unsigned int glyph_id = 0; glyph_id < num_glyphs; glyph_id++) - { - hb_blob_t *blob; - unsigned int ppem = available_ppems[group]; - blob = sbix.reference_blob_for_glyph (glyph_id, ppem, ppem, - HB_TAG('p','n','g',' '), nullptr, nullptr); - if (hb_blob_get_length (blob) == 0) continue; - - char output_path[255]; - sprintf (output_path, "out/sbix-%d-%d.png", ppem, glyph_id); - FILE *f = fopen (output_path, "wb"); - unsigned int length; - const char* data = hb_blob_get_data (blob, &length); - fwrite (data, 1, length, f); - fclose (f); - } - sbix.fini (); -} - -static void -svg_dump (hb_face_t *face) -{ - unsigned glyph_count = hb_face_get_glyph_count (face); - - OT::SVG::accelerator_t svg; - svg.init (face); - - for (unsigned int glyph_id = 0; glyph_id < glyph_count; glyph_id++) - { - hb_blob_t *blob = svg.reference_blob_for_glyph (glyph_id); - - if (hb_blob_get_length (blob) == 0) continue; - - unsigned int length; - const char *data = hb_blob_get_data (blob, &length); - - char output_path[256]; - sprintf (output_path, "out/svg-%d.svg%s", - glyph_id, - // append "z" if the content is gzipped, https://stackoverflow.com/a/6059405 - (length > 2 && (data[0] == '\x1F') && (data[1] == '\x8B')) ? "z" : ""); - - FILE *f = fopen (output_path, "wb"); - fwrite (data, 1, length, f); - fclose (f); - - hb_blob_destroy (blob); - } - - svg.fini (); -} - -static void -colr_cpal_dump (hb_face_t *face, cairo_font_face_t *cairo_face) -{ - unsigned int upem = hb_face_get_upem (face); - - unsigned glyph_count = hb_face_get_glyph_count (face); - for (hb_codepoint_t gid = 0; gid < glyph_count; ++gid) - { - unsigned int num_layers = hb_ot_color_glyph_get_layers (face, gid, 0, nullptr, nullptr); - if (!num_layers) - continue; - - hb_ot_color_layer_t *layers = (hb_ot_color_layer_t*) malloc (num_layers * sizeof (hb_ot_color_layer_t)); - - hb_ot_color_glyph_get_layers (face, gid, 0, &num_layers, layers); - if (num_layers) - { - // Measure - cairo_text_extents_t extents; - { - cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1); - cairo_t *cr = cairo_create (surface); - cairo_set_font_face (cr, cairo_face); - cairo_set_font_size (cr, upem); - - cairo_glyph_t *glyphs = (cairo_glyph_t *) calloc (num_layers, sizeof (cairo_glyph_t)); - for (unsigned int j = 0; j < num_layers; ++j) - glyphs[j].index = layers[j].glyph; - cairo_glyph_extents (cr, glyphs, num_layers, &extents); - free (glyphs); - cairo_surface_destroy (surface); - cairo_destroy (cr); - } - - // Add a slight margin - extents.width += extents.width / 10; - extents.height += extents.height / 10; - extents.x_bearing -= extents.width / 20; - extents.y_bearing -= extents.height / 20; - - // Render - unsigned int palette_count = hb_ot_color_palette_get_count (face); - for (unsigned int palette = 0; palette < palette_count; palette++) { - char output_path[255]; - - unsigned int num_colors = hb_ot_color_palette_get_colors (face, palette, 0, nullptr, nullptr); - if (!num_colors) - continue; - - hb_color_t *colors = (hb_color_t*) calloc (num_colors, sizeof (hb_color_t)); - hb_ot_color_palette_get_colors (face, palette, 0, &num_colors, colors); - if (num_colors) - { - // If we have more than one palette, use a simpler naming - if (palette_count == 1) - sprintf (output_path, "out/colr-%d.svg", gid); - else - sprintf (output_path, "out/colr-%d-%d.svg", gid, palette); - - cairo_surface_t *surface = cairo_svg_surface_create (output_path, extents.width, extents.height); - cairo_t *cr = cairo_create (surface); - cairo_set_font_face (cr, cairo_face); - cairo_set_font_size (cr, upem); - - for (unsigned int layer = 0; layer < num_layers; ++layer) - { - hb_color_t color = 0x000000FF; - if (layers[layer].color_index != 0xFFFF) - color = colors[layers[layer].color_index]; - cairo_set_source_rgba (cr, - hb_color_get_red (color) / 255., - hb_color_get_green (color) / 255., - hb_color_get_blue (color) / 255., - hb_color_get_alpha (color) / 255.); - - cairo_glyph_t glyph; - glyph.index = layers[layer].glyph; - glyph.x = -extents.x_bearing; - glyph.y = -extents.y_bearing; - cairo_show_glyphs (cr, &glyph, 1); - } - - cairo_surface_destroy (surface); - cairo_destroy (cr); - } - free (colors); - } - } - - free (layers); - } -} - -static void -dump_glyphs (cairo_font_face_t *cairo_face, unsigned int upem, - unsigned int num_glyphs) -{ - // Dump every glyph available on the font - return; // disabled for now - for (unsigned int i = 0; i < num_glyphs; ++i) - { - cairo_text_extents_t extents; - cairo_glyph_t glyph = {0}; - glyph.index = i; - - // Measure - { - cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1); - cairo_t *cr = cairo_create (surface); - cairo_set_font_face (cr, cairo_face); - cairo_set_font_size (cr, upem); - - cairo_glyph_extents (cr, &glyph, 1, &extents); - cairo_surface_destroy (surface); - cairo_destroy (cr); - } - - // Add a slight margin - extents.width += extents.width / 10; - extents.height += extents.height / 10; - extents.x_bearing -= extents.width / 20; - extents.y_bearing -= extents.height / 20; - - // Render - { - char output_path[255]; - sprintf (output_path, "out/%d.svg", i); - cairo_surface_t *surface = cairo_svg_surface_create (output_path, extents.width, extents.height); - cairo_t *cr = cairo_create (surface); - cairo_set_font_face (cr, cairo_face); - cairo_set_font_size (cr, upem); - glyph.x = -extents.x_bearing; - glyph.y = -extents.y_bearing; - cairo_show_glyphs (cr, &glyph, 1); - cairo_surface_destroy (surface); - cairo_destroy (cr); - } - } -} - -int -main (int argc, char **argv) -{ - if (argc != 2) { - fprintf (stderr, "usage: %s font-file.ttf\n" - "run it like `rm -rf out && mkdir out && %s font-file.ttf`\n", - argv[0], argv[0]); - exit (1); - } - - - FILE *font_name_file = fopen ("out/_font_name_file.txt", "r"); - if (font_name_file != nullptr) - { - fprintf (stderr, "Purge or move ./out folder in order to run a new dump\n"); - exit (1); - } - - font_name_file = fopen ("out/_font_name_file.txt", "w"); - if (font_name_file == nullptr) - { - fprintf (stderr, "./out is not accessible as a folder, create it please\n"); - exit (1); - } - fwrite (argv[1], 1, strlen (argv[1]), font_name_file); - fclose (font_name_file); - - hb_blob_t *blob = hb_blob_create_from_file (argv[1]); - hb_face_t *face = hb_face_create (blob, 0); - hb_font_t *font = hb_font_create (face); - - OT::CBDT::accelerator_t cbdt; - cbdt.init (face); - cbdt.dump (cbdt_callback); - cbdt.fini (); - - sbix_dump (face); - - if (hb_ot_color_has_svg (face)) - svg_dump (face); - - cairo_font_face_t *cairo_face; - { - FT_Library library; - FT_Init_FreeType (&library); - FT_Face ftface; - FT_New_Face (library, argv[1], 0, &ftface); - cairo_face = cairo_ft_font_face_create_for_ft_face (ftface, 0); - } - if (hb_ot_color_has_layers (face) && hb_ot_color_has_palettes (face)) - colr_cpal_dump (face, cairo_face); - - unsigned int num_glyphs = hb_face_get_glyph_count (face); - unsigned int upem = hb_face_get_upem (face); - dump_glyphs (cairo_face, upem, num_glyphs); - - hb_font_destroy (font); - hb_face_destroy (face); - hb_blob_destroy (blob); - - return 0; -} diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 94b001205..2f33bf6c4 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -105,8 +105,10 @@ struct SBIXStrike glyph = &(this+imageOffsetsZ[new_glyph_id]); glyph_id = new_glyph_id; if (strike_offset + (unsigned int) imageOffsetsZ[glyph_id] + SBIXGlyph::min_size > sbix_len) - return hb_blob_get_empty (); + return hb_blob_get_empty (); } + else + return hb_blob_get_empty (); } if (unlikely (file_type != glyph->graphicType)) return hb_blob_get_empty (); From c8380bd3e4a2e51dfbe2e44e19738445be16ac75 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 15:20:33 -0700 Subject: [PATCH 124/255] [color] Remove more dump-emoji cruft --- src/hb-ot-color-cbdt-table.hh | 53 ----------------------------------- src/hb-ot-color-sbix-table.hh | 13 --------- 2 files changed, 66 deletions(-) diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index f744e1a6a..467159c7c 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -451,59 +451,6 @@ struct CBDT return true; } - inline void dump (void (*callback) (const uint8_t* data, unsigned int length, - unsigned int group, unsigned int gid)) const - { - if (!cblc) - return; // Not a color bitmap font. - - for (unsigned int i = 0; i < cblc->sizeTables.len; ++i) - { - const BitmapSizeTable &sizeTable = cblc->sizeTables[i]; - const IndexSubtableArray &subtable_array = cblc+sizeTable.indexSubtableArrayOffset; - for (unsigned int j = 0; j < sizeTable.numberOfIndexSubtables; ++j) - { - const IndexSubtableRecord &subtable_record = subtable_array.indexSubtablesZ[j]; - for (unsigned int gid = subtable_record.firstGlyphIndex; - gid <= subtable_record.lastGlyphIndex; ++gid) - { - unsigned int image_offset = 0, image_length = 0, image_format = 0; - - if (!subtable_record.get_image_data (gid, &subtable_array, - &image_offset, &image_length, &image_format)) - continue; - - switch (image_format) - { - case 17: { - const GlyphBitmapDataFormat17& glyphFormat17 = - StructAtOffset (this->cbdt, image_offset); - callback ((const uint8_t *) &glyphFormat17.data.arrayZ, - glyphFormat17.data.len, i, gid); - } - break; - case 18: { - const GlyphBitmapDataFormat18& glyphFormat18 = - StructAtOffset (this->cbdt, image_offset); - callback ((const uint8_t *) &glyphFormat18.data.arrayZ, - glyphFormat18.data.len, i, gid); - } - break; - case 19: { - const GlyphBitmapDataFormat19& glyphFormat19 = - StructAtOffset (this->cbdt, image_offset); - callback ((const uint8_t *) &glyphFormat19.data.arrayZ, - glyphFormat19.data.len, i, gid); - } - break; - default: - continue; - } - } - } - } - } - inline hb_blob_t* reference_png (hb_codepoint_t glyph_id, unsigned int x_ppem, unsigned int y_ppem) const diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 2f33bf6c4..79f79a5af 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -161,19 +161,6 @@ struct sbix inline bool has_data () const { return sbix_len; } - /* only to support dump-emoji, don't use it anywhere else */ - inline unsigned int *get_available_ppems (unsigned int *length) - { - if (unlikely (table->strikes.len == 0)) - return nullptr; - *length = table->strikes.len; - unsigned int *result; - result = (unsigned int *) malloc (sizeof (unsigned int) * table->strikes.len); - for (unsigned int i = 0; i < table->strikes.len; i++) - result[i] = (table+table->strikes[i]).get_ppem (); - return result; - } - inline bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const From d7eb534e59064633732959c3771b6557cc97005e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 15:27:04 -0700 Subject: [PATCH 125/255] [sbix] Check offsets before proceeding --- src/hb-ot-color-sbix-table.hh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 79f79a5af..91a9cb71a 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -89,7 +89,8 @@ struct SBIXStrike { unsigned int sbix_len = sbix_blob->length; unsigned int strike_offset = (const char *) this - (const char *) sbix_blob->data; - if (imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] == 0) + if (imageOffsetsZ[glyph_id + 1] < imageOffsetsZ[glyph_id] || + imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] <= SBIXGlyph::min_size) return hb_blob_get_empty (); if (strike_offset + (unsigned int) imageOffsetsZ[glyph_id] + SBIXGlyph::min_size > sbix_len) From a8cb9c73da29afa89b0253b6475ff220613e100a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 15:30:57 -0700 Subject: [PATCH 126/255] [sbix] Simplify 'dupe' handling logic --- src/hb-ot-color-sbix-table.hh | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 91a9cb71a..9a124a6e6 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -87,8 +87,11 @@ struct SBIXStrike int *y_offset, unsigned int num_glyphs) const { + unsigned int retry_count = 8; unsigned int sbix_len = sbix_blob->length; unsigned int strike_offset = (const char *) this - (const char *) sbix_blob->data; + + retry: if (imageOffsetsZ[glyph_id + 1] < imageOffsetsZ[glyph_id] || imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] <= SBIXGlyph::min_size) return hb_blob_get_empty (); @@ -97,20 +100,18 @@ struct SBIXStrike return hb_blob_get_empty (); const SBIXGlyph *glyph = &(this+imageOffsetsZ[glyph_id]); - if (unlikely (glyph->graphicType == HB_TAG ('d','u','p','e') && - calculate_blob_size (glyph_id) >= 2)) + + if (glyph->graphicType == HB_TAG ('d','u','p','e')) { - unsigned int new_glyph_id = *((HBUINT16 *) &glyph->data); - if (new_glyph_id < num_glyphs) + if (calculate_blob_size (glyph_id) >= 2) { - glyph = &(this+imageOffsetsZ[new_glyph_id]); - glyph_id = new_glyph_id; - if (strike_offset + (unsigned int) imageOffsetsZ[glyph_id] + SBIXGlyph::min_size > sbix_len) - return hb_blob_get_empty (); + glyph_id = *((HBUINT16 *) &glyph->data); + if (glyph_id < num_glyphs && retry_count--) + goto retry; } - else - return hb_blob_get_empty (); + return hb_blob_get_empty (); } + if (unlikely (file_type != glyph->graphicType)) return hb_blob_get_empty (); unsigned int blob_size = calculate_blob_size (glyph_id); From 50fb02a219dbf168d300c4ccf9f29aee38a78e6c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 15:33:12 -0700 Subject: [PATCH 127/255] [sbix] Check glyph id before looking into unsafe array That 'Z' at end of imageOffsetsZ is a reminder that you should check... --- src/hb-ot-color-sbix-table.hh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 9a124a6e6..49320785c 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -92,8 +92,9 @@ struct SBIXStrike unsigned int strike_offset = (const char *) this - (const char *) sbix_blob->data; retry: - if (imageOffsetsZ[glyph_id + 1] < imageOffsetsZ[glyph_id] || - imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] <= SBIXGlyph::min_size) + if (unlikely (glyph_id >= num_glyphs || + imageOffsetsZ[glyph_id + 1] < imageOffsetsZ[glyph_id] || + imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] <= SBIXGlyph::min_size)) return hb_blob_get_empty (); if (strike_offset + (unsigned int) imageOffsetsZ[glyph_id] + SBIXGlyph::min_size > sbix_len) @@ -106,7 +107,7 @@ struct SBIXStrike if (calculate_blob_size (glyph_id) >= 2) { glyph_id = *((HBUINT16 *) &glyph->data); - if (glyph_id < num_glyphs && retry_count--) + if (retry_count--) goto retry; } return hb_blob_get_empty (); From b76dc03108d04975335dbf3580f8d02321cb5d25 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 15:36:17 -0700 Subject: [PATCH 128/255] [sbix] Reduce code --- src/hb-ot-color-sbix-table.hh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 49320785c..d3b737792 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -97,7 +97,8 @@ struct SBIXStrike imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] <= SBIXGlyph::min_size)) return hb_blob_get_empty (); - if (strike_offset + (unsigned int) imageOffsetsZ[glyph_id] + SBIXGlyph::min_size > sbix_len) + unsigned int glyph_offset = strike_offset + (unsigned int) imageOffsetsZ[glyph_id] + SBIXGlyph::min_size; + if (glyph_offset > sbix_len) return hb_blob_get_empty (); const SBIXGlyph *glyph = &(this+imageOffsetsZ[glyph_id]); @@ -121,9 +122,7 @@ struct SBIXStrike if (x_offset) *x_offset = glyph->xOffset; if (y_offset) *y_offset = glyph->yOffset; - unsigned int offset = strike_offset + SBIXGlyph::min_size; - offset += imageOffsetsZ[glyph_id]; - return hb_blob_create_sub_blob (sbix_blob, offset, blob_size); + return hb_blob_create_sub_blob (sbix_blob, glyph_offset, blob_size); } protected: From 0730d623854dc17ce0c3f1f2755a90b656c8e52c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 15:38:42 -0700 Subject: [PATCH 129/255] [sbix] Check glyph data end is in range --- src/hb-ot-color-sbix-table.hh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index d3b737792..51e4a1666 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -90,11 +90,13 @@ struct SBIXStrike unsigned int retry_count = 8; unsigned int sbix_len = sbix_blob->length; unsigned int strike_offset = (const char *) this - (const char *) sbix_blob->data; + assert (strike_offset < sbix_len); retry: if (unlikely (glyph_id >= num_glyphs || imageOffsetsZ[glyph_id + 1] < imageOffsetsZ[glyph_id] || - imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] <= SBIXGlyph::min_size)) + imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] <= SBIXGlyph::min_size || + (unsigned int) imageOffsetsZ[glyph_id + 1] > sbix_len - strike_offset)) return hb_blob_get_empty (); unsigned int glyph_offset = strike_offset + (unsigned int) imageOffsetsZ[glyph_id] + SBIXGlyph::min_size; From 6ac9a4eaa3a47c9b9f2c7aa123255e82ccc53551 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 15:43:54 -0700 Subject: [PATCH 130/255] [sbix] Simplify glyph_length calc --- src/hb-ot-color-sbix-table.hh | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 51e4a1666..e37c29ad0 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -69,16 +69,8 @@ struct SBIXStrike imageOffsetsZ.sanitize_shallow (c, c->get_num_glyphs () + 1)); } - inline unsigned int get_ppem () const - { return ppem; } - - inline unsigned int get_resolution () const - { return resolution; } - - inline unsigned int calculate_blob_size (unsigned int glyph_id) const - { - return imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] - SBIXGlyph::min_size; - } + inline unsigned int get_ppem () const { return ppem; } + inline unsigned int get_resolution () const { return resolution; } inline hb_blob_t *get_glyph_blob (unsigned int glyph_id, hb_blob_t *sbix_blob, @@ -100,14 +92,13 @@ struct SBIXStrike return hb_blob_get_empty (); unsigned int glyph_offset = strike_offset + (unsigned int) imageOffsetsZ[glyph_id] + SBIXGlyph::min_size; - if (glyph_offset > sbix_len) - return hb_blob_get_empty (); + unsigned int glyph_length = imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] - SBIXGlyph::min_size; const SBIXGlyph *glyph = &(this+imageOffsetsZ[glyph_id]); if (glyph->graphicType == HB_TAG ('d','u','p','e')) { - if (calculate_blob_size (glyph_id) >= 2) + if (glyph_length >= 2) { glyph_id = *((HBUINT16 *) &glyph->data); if (retry_count--) @@ -118,13 +109,10 @@ struct SBIXStrike if (unlikely (file_type != glyph->graphicType)) return hb_blob_get_empty (); - unsigned int blob_size = calculate_blob_size (glyph_id); - if (unlikely (blob_size == 0)) - return hb_blob_get_empty (); if (x_offset) *x_offset = glyph->xOffset; if (y_offset) *y_offset = glyph->yOffset; - return hb_blob_create_sub_blob (sbix_blob, glyph_offset, blob_size); + return hb_blob_create_sub_blob (sbix_blob, glyph_offset, glyph_length); } protected: From 4e0ee2af091634198c4b9b17036d9391a4e6b084 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 15:44:40 -0700 Subject: [PATCH 131/255] [sbix] Simplify ppem access If struct members are simple and needed publicly, we make them public. --- src/hb-ot-color-sbix-table.hh | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index e37c29ad0..75d1cecc6 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -69,9 +69,6 @@ struct SBIXStrike imageOffsetsZ.sanitize_shallow (c, c->get_num_glyphs () + 1)); } - inline unsigned int get_ppem () const { return ppem; } - inline unsigned int get_resolution () const { return resolution; } - inline hb_blob_t *get_glyph_blob (unsigned int glyph_id, hb_blob_t *sbix_blob, hb_tag_t file_type, @@ -115,10 +112,11 @@ struct SBIXStrike return hb_blob_create_sub_blob (sbix_blob, glyph_offset, glyph_length); } - protected: + public: HBUINT16 ppem; /* The PPEM size for which this strike was designed. */ HBUINT16 resolution; /* The device pixel density (in PPI) for which this * strike was designed. (E.g., 96 PPI, 192 PPI.) */ + protected: UnsizedArrayOf > imageOffsetsZ; /* Offset from the beginning of the strike data header * to bitmap data for an individual glyph ID. */ @@ -184,11 +182,11 @@ struct sbix requested_ppem = 1<<30; /* Choose largest strike. */ /* TODO Add DPI sensitivity as well? */ unsigned int best_i = 0; - unsigned int best_ppem = (table+table->strikes[0]).get_ppem (); + unsigned int best_ppem = (table+table->strikes[0]).ppem; for (unsigned int i = 1; i < table->strikes.len; i++) { - unsigned int ppem = (table+table->strikes[i]).get_ppem (); + unsigned int ppem = (table+table->strikes[i]).ppem; if ((requested_ppem <= ppem && ppem < best_ppem) || (requested_ppem > best_ppem && ppem > best_ppem)) { From 69e9846452f829f82f6866a683845167b3d3d6e5 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 15:53:11 -0700 Subject: [PATCH 132/255] [sbix] Fix get_glyph_blob() on Null object --- src/hb-ot-color-sbix-table.hh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 75d1cecc6..bde66b77a 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -76,6 +76,8 @@ struct SBIXStrike int *y_offset, unsigned int num_glyphs) const { + if (unlikely (!ppem)) return hb_blob_get_empty (); /* To get Null() object out of the way. */ + unsigned int retry_count = 8; unsigned int sbix_len = sbix_blob->length; unsigned int strike_offset = (const char *) this - (const char *) sbix_blob->data; @@ -83,7 +85,7 @@ struct SBIXStrike retry: if (unlikely (glyph_id >= num_glyphs || - imageOffsetsZ[glyph_id + 1] < imageOffsetsZ[glyph_id] || + imageOffsetsZ[glyph_id + 1] <= imageOffsetsZ[glyph_id] || imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] <= SBIXGlyph::min_size || (unsigned int) imageOffsetsZ[glyph_id + 1] > sbix_len - strike_offset)) return hb_blob_get_empty (); @@ -225,9 +227,6 @@ struct sbix hb_codepoint_t glyph, hb_glyph_extents_t *extents) const { - if (likely (sbix_len == 0)) - return false; - int x_offset = 0, y_offset = 0; hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset); From 95524ed9bccdcd0d6a46c5dcc372e96a0c34b5f0 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 15:58:48 -0700 Subject: [PATCH 133/255] [sbix] Remove sbix_len --- src/hb-ot-color-sbix-table.hh | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index bde66b77a..b82a8847b 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -130,18 +130,13 @@ struct sbix { static const hb_tag_t tableTag = HB_OT_TAG_sbix; - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && strikes.sanitize (c, this))); - } + inline bool has_data (void) const { return version; } struct accelerator_t { inline void init (hb_face_t *face) { sbix_blob = hb_sanitize_context_t().reference_table (face); - sbix_len = hb_blob_get_length (sbix_blob); table = sbix_blob->as (); num_glyphs = face->get_num_glyphs (); } @@ -151,7 +146,13 @@ struct sbix hb_blob_destroy (sbix_blob); } - inline bool has_data () const { return sbix_len; } + inline bool has_data () const + { + /* XXX Fix somehow and remove next line. + * https://github.com/harfbuzz/harfbuzz/issues/1146 */ + if (!num_glyphs) return false; + return table->has_data (); + } inline bool get_extents (hb_font_t *font, hb_codepoint_t glyph, @@ -227,6 +228,11 @@ struct sbix hb_codepoint_t glyph, hb_glyph_extents_t *extents) const { + /* Following code is safe to call even without data, but faster to + * short-circuit. */ + if (!has_data ()) + return false; + int x_offset = 0, y_offset = 0; hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset); @@ -248,10 +254,17 @@ struct sbix hb_blob_t *sbix_blob; const sbix *table; - unsigned int sbix_len; unsigned int num_glyphs; }; + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + version >= 1 && + strikes.sanitize (c, this))); + } + protected: HBUINT16 version; /* Table version number — set to 1 */ HBUINT16 flags; /* Bit 0: Set to 1. Bit 1: Draw outlines. From a3ddd8067f266e49d9451c53a0fd40aff8551af7 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 16:26:03 -0700 Subject: [PATCH 134/255] [sbix] Add get_strike --- src/hb-ot-color-sbix-table.hh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index b82a8847b..13ed07835 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -132,6 +132,8 @@ struct sbix inline bool has_data (void) const { return version; } + inline const SBIXStrike &get_strike (unsigned int i) const { return this+strikes[i]; } + struct accelerator_t { inline void init (hb_face_t *face) @@ -185,11 +187,11 @@ struct sbix requested_ppem = 1<<30; /* Choose largest strike. */ /* TODO Add DPI sensitivity as well? */ unsigned int best_i = 0; - unsigned int best_ppem = (table+table->strikes[0]).ppem; + unsigned int best_ppem = table->get_strike (0).ppem; for (unsigned int i = 1; i < table->strikes.len; i++) { - unsigned int ppem = (table+table->strikes[i]).ppem; + unsigned int ppem = (table->get_strike (i)).ppem; if ((requested_ppem <= ppem && ppem < best_ppem) || (requested_ppem > best_ppem && ppem > best_ppem)) { @@ -198,7 +200,7 @@ struct sbix } } - return table+table->strikes[best_i]; + return table->get_strike (best_i); } struct PNGHeader From 65621723815138150e8a6354413ed14d53cf35b5 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 16:27:18 -0700 Subject: [PATCH 135/255] [sbix] Use LOffsetLArrayOf<> --- src/hb-open-type.hh | 2 ++ src/hb-ot-color-sbix-table.hh | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 8d17f3ed1..207f36b61 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -541,6 +541,8 @@ typedef ArrayOf PString; /* Array of Offset's */ template struct OffsetArrayOf : ArrayOf > {}; +template +struct LOffsetLArrayOf : ArrayOf, HBUINT32> {}; /* Array of offsets relative to the beginning of the array itself. */ template diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 13ed07835..9155db645 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -271,7 +271,7 @@ struct sbix HBUINT16 version; /* Table version number — set to 1 */ HBUINT16 flags; /* Bit 0: Set to 1. Bit 1: Draw outlines. * Bits 2 to 15: reserved (set to 0). */ - LArrayOf > + LOffsetLArrayOf strikes; /* Offsets from the beginning of the 'sbix' * table to data for each individual bitmap strike. */ public: From e8ff27c2082ffcf3bd213e7a77d823dc1809857e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 16:29:09 -0700 Subject: [PATCH 136/255] Minor --- src/hb-open-type.hh | 6 ++++-- src/hb-ot-layout-common.hh | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 207f36b61..6e545a6d3 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -539,8 +539,10 @@ template struct LArrayOf : ArrayOf {}; typedef ArrayOf PString; /* Array of Offset's */ -template -struct OffsetArrayOf : ArrayOf > {}; +template +struct OffsetArrayOf : ArrayOf > {}; +template +struct LOffsetArrayOf : ArrayOf > {}; template struct LOffsetLArrayOf : ArrayOf, HBUINT32> {}; diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 7bca2caec..11297a575 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -1605,7 +1605,7 @@ struct VariationStore protected: HBUINT16 format; LOffsetTo regions; - OffsetArrayOf dataSets; + LOffsetArrayOf dataSets; public: DEFINE_SIZE_ARRAY (8, dataSets); }; @@ -1687,7 +1687,7 @@ struct ConditionSet } protected: - OffsetArrayOf conditions; + LOffsetArrayOf conditions; public: DEFINE_SIZE_ARRAY (2, conditions); }; From 519fca101466283ca5c993dec2ec2c6891d8add5 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 16:32:20 -0700 Subject: [PATCH 137/255] [color] Minor --- src/hb-ot-color.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index c89dc9e54..b38e67c45 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -320,7 +320,7 @@ hb_ot_color_glyph_reference_png (hb_font_t *font, hb_codepoint_t glyph) if (_get_sbix (font->face).has_data ()) blob = _get_sbix (font->face).reference_png (font, glyph, nullptr, nullptr); - if (hb_blob_get_length (blob) == 0 && _get_cbdt (font->face).has_data ()) + if (!blob->length && _get_cbdt (font->face).has_data ()) blob = _get_cbdt (font->face).reference_png (glyph, font->x_ppem, font->y_ppem); return blob; From 4876c938a20af356988d566ba95472d3bcbb133d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 18:01:25 -0700 Subject: [PATCH 138/255] [sbix] Comment --- src/hb-ot-color-sbix-table.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 9155db645..40680ca22 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -230,8 +230,8 @@ struct sbix hb_codepoint_t glyph, hb_glyph_extents_t *extents) const { - /* Following code is safe to call even without data, but faster to - * short-circuit. */ + /* Following code is safe to call even without data (XXX currently + * isn't. See has_data()), but faster to short-circuit. */ if (!has_data ()) return false; From 18dd6363a5021cfd770b431a6320386f94447674 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 18:26:49 -0700 Subject: [PATCH 139/255] [svg] Minor --- src/hb-ot-color-svg-table.hh | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh index 5238ad458..3e6480cc2 100644 --- a/src/hb-ot-color-svg-table.hh +++ b/src/hb-ot-color-svg-table.hh @@ -87,7 +87,7 @@ struct SVG { svg_blob = hb_sanitize_context_t().reference_table (face); svg_len = hb_blob_get_length (svg_blob); - svg = svg_blob->as (); + table = svg_blob->as (); } inline void fini (void) @@ -97,29 +97,28 @@ struct SVG inline hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id) const { - if (unlikely (svg_len == 0)) + if (unlikely (!svg_len)) return hb_blob_get_empty (); - return svg->get_glyph_entry (glyph_id).reference_blob (svg_blob, svg->svgDocEntries); + return table->get_glyph_entry (glyph_id).reference_blob (svg_blob, table->svgDocEntries); } - inline bool has_data () const - { return svg_len; } + inline bool has_data () const { return svg_len; } private: hb_blob_t *svg_blob; - const SVG *svg; + const SVG *table; unsigned int svg_len; }; inline const SVGDocumentIndexEntry &get_glyph_entry (hb_codepoint_t glyph_id) const { - const SVGDocumentIndexEntry *rec; - rec = (SVGDocumentIndexEntry *) bsearch (&glyph_id, - &(this+svgDocEntries).arrayZ, - (this+svgDocEntries).len, - sizeof (SVGDocumentIndexEntry), - SVGDocumentIndexEntry::cmp); + const SVGDocumentIndexEntry *rec = (SVGDocumentIndexEntry *) + bsearch (&glyph_id, + &(this+svgDocEntries).arrayZ, + (this+svgDocEntries).len, + sizeof (SVGDocumentIndexEntry), + SVGDocumentIndexEntry::cmp); return likely (rec) ? *rec : Null(SVGDocumentIndexEntry); } From 9c1460e5685448ad4eac8faff9f05e456f87ed28 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 18:29:14 -0700 Subject: [PATCH 140/255] [svg] Use SortedArrayOf.bsearch --- src/hb-ot-color-svg-table.hh | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh index 3e6480cc2..35a364772 100644 --- a/src/hb-ot-color-svg-table.hh +++ b/src/hb-ot-color-svg-table.hh @@ -43,13 +43,6 @@ struct SVGDocumentIndexEntry inline int cmp (hb_codepoint_t g) const { return g < startGlyphID ? -1 : g > endGlyphID ? 1 : 0; } - static int cmp (const void *pa, const void *pb) - { - const hb_codepoint_t *a = (const hb_codepoint_t *) pa; - const SVGDocumentIndexEntry *b = (const SVGDocumentIndexEntry *) pb; - return b->cmp (*a); - } - inline hb_blob_t *reference_blob (hb_blob_t *svg_blob, unsigned int index_offset) const { if (svgDocLength == 0) return hb_blob_get_empty (); @@ -113,13 +106,8 @@ struct SVG inline const SVGDocumentIndexEntry &get_glyph_entry (hb_codepoint_t glyph_id) const { - const SVGDocumentIndexEntry *rec = (SVGDocumentIndexEntry *) - bsearch (&glyph_id, - &(this+svgDocEntries).arrayZ, - (this+svgDocEntries).len, - sizeof (SVGDocumentIndexEntry), - SVGDocumentIndexEntry::cmp); - return likely (rec) ? *rec : Null(SVGDocumentIndexEntry); + const SortedArrayOf docs = this+svgDocEntries; + return docs[docs.bsearch (glyph_id)]; } inline bool sanitize (hb_sanitize_context_t *c) const @@ -131,7 +119,7 @@ struct SVG protected: HBUINT16 version; /* Table version (starting at 0). */ - LOffsetTo > + LOffsetTo > svgDocEntries; /* Offset (relative to the start of the SVG table) to the * SVG Documents Index. Must be non-zero. */ /* Array of SVG Document Index Entries. */ From a8c9facf7a73cca39e3fed1f637db4858e64414a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 18:32:37 -0700 Subject: [PATCH 141/255] [svg] Cosmetic --- src/hb-ot-color-svg-table.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh index 35a364772..55629769a 100644 --- a/src/hb-ot-color-svg-table.hh +++ b/src/hb-ot-color-svg-table.hh @@ -45,8 +45,8 @@ struct SVGDocumentIndexEntry inline hb_blob_t *reference_blob (hb_blob_t *svg_blob, unsigned int index_offset) const { - if (svgDocLength == 0) return hb_blob_get_empty (); - return hb_blob_create_sub_blob (svg_blob, (unsigned int) svgDoc + index_offset, + return hb_blob_create_sub_blob (svg_blob, + index_offset + (unsigned int) svgDoc, svgDocLength); } From c929ccfcea18c5c35d6d41ae921845eeffba978a Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Mon, 29 Oct 2018 08:41:13 +0330 Subject: [PATCH 142/255] [ot-color/png] Consider strike ppem on scaling --- src/hb-ot-color-cbdt-table.hh | 5 +++-- src/hb-ot-color-sbix-table.hh | 23 +++++++++++++++++++---- src/hb-ot-color.cc | 2 +- src/hb-ot-font.cc | 2 +- test/api/test-ot-color.c | 4 ++-- 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index 467159c7c..cacabd075 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -402,9 +402,10 @@ struct CBDT hb_blob_destroy (this->cbdt_blob); } - inline bool get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const + inline bool get_extents (hb_font_t *font, hb_codepoint_t glyph, + hb_glyph_extents_t *extents) const { - unsigned int x_ppem = upem, y_ppem = upem; /* TODO Use font ppem if available. */ + unsigned int x_ppem = font->x_ppem, y_ppem = font->y_ppem; if (!cblc) return false; // Not a color bitmap font. diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 40680ca22..fbe48ec02 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -74,7 +74,8 @@ struct SBIXStrike hb_tag_t file_type, int *x_offset, int *y_offset, - unsigned int num_glyphs) const + unsigned int num_glyphs, + unsigned int *strike_ppem) const { if (unlikely (!ppem)) return hb_blob_get_empty (); /* To get Null() object out of the way. */ @@ -109,6 +110,7 @@ struct SBIXStrike if (unlikely (file_type != glyph->graphicType)) return hb_blob_get_empty (); + if (strike_ppem) *strike_ppem = ppem; if (x_offset) *x_offset = glyph->xOffset; if (y_offset) *y_offset = glyph->yOffset; return hb_blob_create_sub_blob (sbix_blob, glyph_offset, glyph_length); @@ -167,12 +169,13 @@ struct sbix inline hb_blob_t *reference_png (hb_font_t *font, hb_codepoint_t glyph_id, int *x_offset, - int *y_offset) const + int *y_offset, + unsigned int *available_ppem) const { return get_strike (font).get_glyph_blob (glyph_id, sbix_blob, HB_TAG ('p','n','g',' '), x_offset, y_offset, - num_glyphs); + num_glyphs, available_ppem); } private: @@ -236,7 +239,8 @@ struct sbix return false; int x_offset = 0, y_offset = 0; - hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset); + unsigned int strike_ppem = 0; + hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset, &strike_ppem); if (unlikely (blob->length < sizeof (PNGHeader))) return false; @@ -247,6 +251,17 @@ struct sbix extents->y_bearing = y_offset; extents->width = png.IHDR.width; extents->height = png.IHDR.height; + + /* Convert to the font units. */ + if (strike_ppem) + { + unsigned int upem = font->face->upem; + extents->x_bearing *= upem / (float) strike_ppem; + extents->y_bearing *= upem / (float) strike_ppem; + extents->width *= upem / (float) strike_ppem; + extents->height *= upem / (float) strike_ppem; + } + hb_blob_destroy (blob); return true; diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index b38e67c45..0cade5e76 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -318,7 +318,7 @@ hb_ot_color_glyph_reference_png (hb_font_t *font, hb_codepoint_t glyph) hb_blob_t *blob = hb_blob_get_empty (); if (_get_sbix (font->face).has_data ()) - blob = _get_sbix (font->face).reference_png (font, glyph, nullptr, nullptr); + blob = _get_sbix (font->face).reference_png (font, glyph, nullptr, nullptr, nullptr); if (!blob->length && _get_cbdt (font->face).has_data ()) blob = _get_cbdt (font->face).reference_png (glyph, font->x_ppem, font->y_ppem); diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index e9619c54f..33a4388ce 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -187,7 +187,7 @@ hb_ot_get_glyph_extents (hb_font_t *font, if (!ret) ret = ot_face->glyf->get_extents (glyph, extents); if (!ret) - ret = ot_face->CBDT->get_extents (glyph, extents); + ret = ot_face->CBDT->get_extents (font, glyph, extents); // TODO Hook up side-bearings variations. extents->x_bearing = font->em_scale_x (extents->x_bearing); extents->y_bearing = font->em_scale_y (extents->y_bearing); diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index 9cc353bad..ba3a0abcd 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -427,8 +427,8 @@ test_hb_ot_color_png (void) hb_font_get_glyph_extents (sbix_font, 1, &extents); g_assert_cmpint (extents.x_bearing, ==, 0); g_assert_cmpint (extents.y_bearing, ==, 0); - g_assert_cmpint (extents.width, ==, 300); - g_assert_cmpint (extents.height, ==, 300); + g_assert_cmpint (extents.width, ==, 800); + g_assert_cmpint (extents.height, ==, 800); hb_blob_destroy (blob); hb_font_destroy (sbix_font); From e998fb9fbfbd79b476d758238af60f6a4ddff20c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 22:45:53 -0700 Subject: [PATCH 143/255] [color] Round extents when scaling --- src/hb-ot-color-cbdt-table.hh | 12 +++++++----- src/hb-ot-color-sbix-table.hh | 12 ++++++------ 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index cacabd075..dab07a206 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -443,11 +443,13 @@ struct CBDT } } - /* Convert to the font units. */ - extents->x_bearing *= upem / (float) x_ppem; - extents->y_bearing *= upem / (float) y_ppem; - extents->width *= upem / (float) x_ppem; - extents->height *= upem / (float) y_ppem; + /* Convert to font units. */ + double x_scale = upem / (double) x_ppem; + double y_scale = upem / (double) y_ppem; + extents->x_bearing = round (extents->x_bearing * x_scale); + extents->y_bearing = round (extents->y_bearing * y_scale); + extents->width = round (extents->width * x_scale); + extents->height = round (extents->height * y_scale); return true; } diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index fbe48ec02..7bde38a6a 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -252,14 +252,14 @@ struct sbix extents->width = png.IHDR.width; extents->height = png.IHDR.height; - /* Convert to the font units. */ + /* Convert to font units. */ if (strike_ppem) { - unsigned int upem = font->face->upem; - extents->x_bearing *= upem / (float) strike_ppem; - extents->y_bearing *= upem / (float) strike_ppem; - extents->width *= upem / (float) strike_ppem; - extents->height *= upem / (float) strike_ppem; + double scale = font->face->upem / (double) strike_ppem; + extents->x_bearing = round (extents->x_bearing * scale); + extents->y_bearing = round (extents->y_bearing * scale); + extents->width = round (extents->width * scale); + extents->height = round (extents->height * scale); } hb_blob_destroy (blob); From 6983cca9c865752fe0a9a065f9b0278b686c3abc Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 22:46:18 -0700 Subject: [PATCH 144/255] [cbdt] Minor --- src/hb-ot-color-cbdt-table.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index dab07a206..a02bbba24 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -408,7 +408,7 @@ struct CBDT unsigned int x_ppem = font->x_ppem, y_ppem = font->y_ppem; if (!cblc) - return false; // Not a color bitmap font. + return false; const void *base; const IndexSubtableRecord *subtable_record = this->cblc->find_table (glyph, &x_ppem, &y_ppem, &base); From e2ba96da4c39ba5fe941bf2704c1e7cc5f98034f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 23:01:57 -0700 Subject: [PATCH 145/255] [cbdt] Refactor get_strike() --- src/hb-ot-color-cbdt-table.hh | 39 ++++++++++++++--------------------- src/hb-ot-color.cc | 2 +- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index a02bbba24..e6a78200a 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -343,26 +343,21 @@ struct CBLC } protected: - const IndexSubtableRecord *find_table (hb_codepoint_t glyph, - unsigned int *x_ppem, unsigned int *y_ppem, - const void **base) const + const BitmapSizeTable &get_strike (hb_font_t *font, + unsigned int *x_ppem, unsigned int *y_ppem) const { /* TODO: Make it possible to select strike. */ unsigned int count = sizeTables.len; for (uint32_t i = 0; i < count; ++i) { - unsigned int startGlyphIndex = sizeTables.arrayZ[i].startGlyphIndex; - unsigned int endGlyphIndex = sizeTables.arrayZ[i].endGlyphIndex; - if (startGlyphIndex <= glyph && glyph <= endGlyphIndex) - { - *x_ppem = sizeTables[i].ppemX; - *y_ppem = sizeTables[i].ppemY; - return sizeTables[i].find_table (glyph, this, base); - } + *x_ppem = sizeTables[i].ppemX; + *y_ppem = sizeTables[i].ppemY; + return sizeTables[i]; } - return nullptr; + *x_ppem = *y_ppem = 0; + return Null(BitmapSizeTable); } protected: @@ -405,13 +400,13 @@ struct CBDT inline bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const { - unsigned int x_ppem = font->x_ppem, y_ppem = font->y_ppem; - if (!cblc) return false; + unsigned int x_ppem, y_ppem; const void *base; - const IndexSubtableRecord *subtable_record = this->cblc->find_table (glyph, &x_ppem, &y_ppem, &base); + const BitmapSizeTable &strike = this->cblc->get_strike (font, &x_ppem, &y_ppem); + const IndexSubtableRecord *subtable_record = strike.find_table (glyph, cblc, &base); if (!subtable_record || !x_ppem || !y_ppem) return false; @@ -454,23 +449,21 @@ struct CBDT return true; } - inline hb_blob_t* reference_png (hb_codepoint_t glyph_id, - unsigned int x_ppem, - unsigned int y_ppem) const + inline hb_blob_t* reference_png (hb_font_t *font, + hb_codepoint_t glyph) const { if (!cblc) return hb_blob_get_empty (); - if (x_ppem == 0) x_ppem = upem; - if (y_ppem == 0) y_ppem = upem; - + unsigned int x_ppem, y_ppem; const void *base; - const IndexSubtableRecord *subtable_record = this->cblc->find_table (glyph_id, &x_ppem, &y_ppem, &base); + const BitmapSizeTable &strike = this->cblc->get_strike (font, &x_ppem, &y_ppem); + const IndexSubtableRecord *subtable_record = strike.find_table (glyph, cblc, &base); if (!subtable_record || !x_ppem || !y_ppem) return hb_blob_get_empty (); unsigned int image_offset = 0, image_length = 0, image_format = 0; - if (!subtable_record->get_image_data (glyph_id, base, &image_offset, &image_length, &image_format)) + if (!subtable_record->get_image_data (glyph, base, &image_offset, &image_length, &image_format)) return hb_blob_get_empty (); switch (image_format) diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index 0cade5e76..a3cd61905 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -321,7 +321,7 @@ hb_ot_color_glyph_reference_png (hb_font_t *font, hb_codepoint_t glyph) blob = _get_sbix (font->face).reference_png (font, glyph, nullptr, nullptr, nullptr); if (!blob->length && _get_cbdt (font->face).has_data ()) - blob = _get_cbdt (font->face).reference_png (glyph, font->x_ppem, font->y_ppem); + blob = _get_cbdt (font->face).reference_png (font, glyph); return blob; } From 0aa90271fdbb2b85389cd5af029b6d4468fb8146 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 23:03:20 -0700 Subject: [PATCH 146/255] [tests] Fix for recent rounding change in CBDT --- test/shaping/data/in-house/tests/color-fonts.tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/shaping/data/in-house/tests/color-fonts.tests b/test/shaping/data/in-house/tests/color-fonts.tests index e7311bc33..b325d78c1 100644 --- a/test/shaping/data/in-house/tests/color-fonts.tests +++ b/test/shaping/data/in-house/tests/color-fonts.tests @@ -1 +1 @@ -../fonts/ee39587d13b2afa5499cc79e45780aa79293bbd4.ttf:--font-funcs=ot --show-extents:U+1F42F:[gid1=0+2963<0,2178,2963,-2788>] +../fonts/ee39587d13b2afa5499cc79e45780aa79293bbd4.ttf:--font-funcs=ot --show-extents:U+1F42F:[gid1=0+2963<0,2179,2963,-2789>] From 574579d3766b7b42e62495cb9a98f3ffd91079e8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 23:04:37 -0700 Subject: [PATCH 147/255] [color] Rename get_strike() to choose_strike() --- src/hb-ot-color-cbdt-table.hh | 8 ++++---- src/hb-ot-color-sbix-table.hh | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index e6a78200a..c30f36c4d 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -343,8 +343,8 @@ struct CBLC } protected: - const BitmapSizeTable &get_strike (hb_font_t *font, - unsigned int *x_ppem, unsigned int *y_ppem) const + const BitmapSizeTable &choose_strike (hb_font_t *font, + unsigned int *x_ppem, unsigned int *y_ppem) const { /* TODO: Make it possible to select strike. */ @@ -405,7 +405,7 @@ struct CBDT unsigned int x_ppem, y_ppem; const void *base; - const BitmapSizeTable &strike = this->cblc->get_strike (font, &x_ppem, &y_ppem); + const BitmapSizeTable &strike = this->cblc->choose_strike (font, &x_ppem, &y_ppem); const IndexSubtableRecord *subtable_record = strike.find_table (glyph, cblc, &base); if (!subtable_record || !x_ppem || !y_ppem) return false; @@ -457,7 +457,7 @@ struct CBDT unsigned int x_ppem, y_ppem; const void *base; - const BitmapSizeTable &strike = this->cblc->get_strike (font, &x_ppem, &y_ppem); + const BitmapSizeTable &strike = this->cblc->choose_strike (font, &x_ppem, &y_ppem); const IndexSubtableRecord *subtable_record = strike.find_table (glyph, cblc, &base); if (!subtable_record || !x_ppem || !y_ppem) return hb_blob_get_empty (); diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 7bde38a6a..4a14a69d2 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -172,15 +172,15 @@ struct sbix int *y_offset, unsigned int *available_ppem) const { - return get_strike (font).get_glyph_blob (glyph_id, sbix_blob, - HB_TAG ('p','n','g',' '), - x_offset, y_offset, - num_glyphs, available_ppem); + return choose_strike (font).get_glyph_blob (glyph_id, sbix_blob, + HB_TAG ('p','n','g',' '), + x_offset, y_offset, + num_glyphs, available_ppem); } private: - inline const SBIXStrike &get_strike (hb_font_t *font) const + inline const SBIXStrike &choose_strike (hb_font_t *font) const { if (unlikely (!table->strikes.len)) return Null(SBIXStrike); From 8cffee0577284839a24d9fb863206886d2373974 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 23:07:59 -0700 Subject: [PATCH 148/255] [cbdt] Simplify more --- src/hb-ot-color-cbdt-table.hh | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index c30f36c4d..21d6c6c82 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -343,20 +343,14 @@ struct CBLC } protected: - const BitmapSizeTable &choose_strike (hb_font_t *font, - unsigned int *x_ppem, unsigned int *y_ppem) const + const BitmapSizeTable &choose_strike (hb_font_t *font) const { /* TODO: Make it possible to select strike. */ unsigned int count = sizeTables.len; for (uint32_t i = 0; i < count; ++i) - { - *x_ppem = sizeTables[i].ppemX; - *y_ppem = sizeTables[i].ppemY; return sizeTables[i]; - } - *x_ppem = *y_ppem = 0; return Null(BitmapSizeTable); } @@ -403,11 +397,10 @@ struct CBDT if (!cblc) return false; - unsigned int x_ppem, y_ppem; const void *base; - const BitmapSizeTable &strike = this->cblc->choose_strike (font, &x_ppem, &y_ppem); + const BitmapSizeTable &strike = this->cblc->choose_strike (font); const IndexSubtableRecord *subtable_record = strike.find_table (glyph, cblc, &base); - if (!subtable_record || !x_ppem || !y_ppem) + if (!subtable_record || !strike.ppemX || !strike.ppemY) return false; if (subtable_record->get_extents (extents, base)) @@ -439,8 +432,8 @@ struct CBDT } /* Convert to font units. */ - double x_scale = upem / (double) x_ppem; - double y_scale = upem / (double) y_ppem; + double x_scale = upem / (double) strike.ppemX; + double y_scale = upem / (double) strike.ppemY; extents->x_bearing = round (extents->x_bearing * x_scale); extents->y_bearing = round (extents->y_bearing * y_scale); extents->width = round (extents->width * x_scale); @@ -455,11 +448,10 @@ struct CBDT if (!cblc) return hb_blob_get_empty (); - unsigned int x_ppem, y_ppem; const void *base; - const BitmapSizeTable &strike = this->cblc->choose_strike (font, &x_ppem, &y_ppem); + const BitmapSizeTable &strike = this->cblc->choose_strike (font); const IndexSubtableRecord *subtable_record = strike.find_table (glyph, cblc, &base); - if (!subtable_record || !x_ppem || !y_ppem) + if (!subtable_record || !strike.ppemX || !strike.ppemY) return hb_blob_get_empty (); unsigned int image_offset = 0, image_length = 0, image_format = 0; From 98bddbc8ef3330bc5635f6255e6b9c16593a1934 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 23:14:15 -0700 Subject: [PATCH 149/255] [sbix] Minor --- src/hb-ot-color-sbix-table.hh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 4a14a69d2..39f85129a 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -182,7 +182,8 @@ struct sbix inline const SBIXStrike &choose_strike (hb_font_t *font) const { - if (unlikely (!table->strikes.len)) + unsigned count = table->strikes.len; + if (unlikely (!count)) return Null(SBIXStrike); unsigned int requested_ppem = MAX (font->x_ppem, font->y_ppem); @@ -192,7 +193,7 @@ struct sbix unsigned int best_i = 0; unsigned int best_ppem = table->get_strike (0).ppem; - for (unsigned int i = 1; i < table->strikes.len; i++) + for (unsigned int i = 1; i < count; i++) { unsigned int ppem = (table->get_strike (i)).ppem; if ((requested_ppem <= ppem && ppem < best_ppem) || From 5eb251aab041d89b06b0d3f65906ff6712608263 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 28 Oct 2018 23:16:13 -0700 Subject: [PATCH 150/255] [cbdt] Implement strike selection logic --- src/hb-ot-color-cbdt-table.hh | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index 21d6c6c82..ae6d3b5e6 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -345,13 +345,28 @@ struct CBLC protected: const BitmapSizeTable &choose_strike (hb_font_t *font) const { - /* TODO: Make it possible to select strike. */ + unsigned count = sizeTables.len; + if (unlikely (!count)) + return Null(BitmapSizeTable); - unsigned int count = sizeTables.len; - for (uint32_t i = 0; i < count; ++i) - return sizeTables[i]; + unsigned int requested_ppem = MAX (font->x_ppem, font->y_ppem); + if (!requested_ppem) + requested_ppem = 1<<30; /* Choose largest strike. */ + unsigned int best_i = 0; + unsigned int best_ppem = MAX (sizeTables[0].ppemX, sizeTables[0].ppemY); - return Null(BitmapSizeTable); + for (unsigned int i = 1; i < count; i++) + { + unsigned int ppem = MAX (sizeTables[i].ppemX, sizeTables[i].ppemY); + if ((requested_ppem <= ppem && ppem < best_ppem) || + (requested_ppem > best_ppem && ppem > best_ppem)) + { + best_i = i; + best_ppem = ppem; + } + } + + return sizeTables[best_i]; } protected: From f10252b4b637b4aa0b74bb75963ae1e1a41b5b9f Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Mon, 29 Oct 2018 10:29:58 +0330 Subject: [PATCH 151/255] [svg] Fix incorrect array referencing --- src/hb-ot-color-svg-table.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh index 55629769a..7c342d018 100644 --- a/src/hb-ot-color-svg-table.hh +++ b/src/hb-ot-color-svg-table.hh @@ -106,7 +106,7 @@ struct SVG inline const SVGDocumentIndexEntry &get_glyph_entry (hb_codepoint_t glyph_id) const { - const SortedArrayOf docs = this+svgDocEntries; + const SortedArrayOf &docs = this+svgDocEntries; return docs[docs.bsearch (glyph_id)]; } From 81bcf47e9ea7eb447ff95ce48ecbc5c4439cb53f Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Mon, 29 Oct 2018 09:40:39 +0330 Subject: [PATCH 152/255] Revive dump-emoji --- src/dump-emoji.cc | 322 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 322 insertions(+) create mode 100644 src/dump-emoji.cc diff --git a/src/dump-emoji.cc b/src/dump-emoji.cc new file mode 100644 index 000000000..e3cabc738 --- /dev/null +++ b/src/dump-emoji.cc @@ -0,0 +1,322 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * Copyright © 2018 Khaled Hosny + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#include "hb-static.cc" +#include "hb-ot-color-cbdt-table.hh" +#include "hb-ot-color-colr-table.hh" +#include "hb-ot-color-cpal-table.hh" +#include "hb-ot-color-sbix-table.hh" +#include "hb-ot-color-svg-table.hh" + +#include "hb-ft.h" + +#include +#include FT_FREETYPE_H +#include FT_GLYPH_H + +#include +#include +#include + +#ifdef HAVE_GLIB +#include +#endif +#include +#include + +static void +cbdt_callback (const uint8_t* data, unsigned int length, + unsigned int group, unsigned int gid) +{ + char output_path[255]; + sprintf (output_path, "out/cbdt-%d-%d.png", group, gid); + FILE *f = fopen (output_path, "wb"); + fwrite (data, 1, length, f); + fclose (f); +} + +static void +sbix_dump (hb_face_t *face) +{ + OT::sbix::accelerator_t sbix; + sbix.init (face); + unsigned int length = 0; + unsigned int *available_ppems = sbix.get_available_ppems (&length); + unsigned int num_glyphs = face->num_glyphs; + for (unsigned int group = 0; group < length; group++) + for (unsigned int glyph_id = 0; glyph_id < num_glyphs; glyph_id++) + { + hb_blob_t *blob; + unsigned int ppem = available_ppems[group]; + blob = sbix.reference_blob_for_glyph (glyph_id, ppem, ppem, + HB_TAG('p','n','g',' '), nullptr, nullptr); + if (hb_blob_get_length (blob) == 0) continue; + + char output_path[255]; + sprintf (output_path, "out/sbix-%d-%d.png", ppem, glyph_id); + FILE *f = fopen (output_path, "wb"); + unsigned int length; + const char* data = hb_blob_get_data (blob, &length); + fwrite (data, 1, length, f); + fclose (f); + } + sbix.fini (); +} + +static void +svg_dump (hb_face_t *face) +{ + unsigned glyph_count = hb_face_get_glyph_count (face); + + OT::SVG::accelerator_t svg; + svg.init (face); + + for (unsigned int glyph_id = 0; glyph_id < glyph_count; glyph_id++) + { + hb_blob_t *blob = svg.reference_blob_for_glyph (glyph_id); + + if (hb_blob_get_length (blob) == 0) continue; + + unsigned int length; + const char *data = hb_blob_get_data (blob, &length); + + char output_path[256]; + sprintf (output_path, "out/svg-%d.svg%s", + glyph_id, + // append "z" if the content is gzipped, https://stackoverflow.com/a/6059405 + (length > 2 && (data[0] == '\x1F') && (data[1] == '\x8B')) ? "z" : ""); + + FILE *f = fopen (output_path, "wb"); + fwrite (data, 1, length, f); + fclose (f); + + hb_blob_destroy (blob); + } + + svg.fini (); +} + +static void +colr_cpal_dump (hb_face_t *face, cairo_font_face_t *cairo_face) +{ + unsigned int upem = hb_face_get_upem (face); + + unsigned glyph_count = hb_face_get_glyph_count (face); + for (hb_codepoint_t gid = 0; gid < glyph_count; ++gid) + { + unsigned int num_layers = hb_ot_color_glyph_get_layers (face, gid, 0, nullptr, nullptr); + if (!num_layers) + continue; + + hb_ot_color_layer_t *layers = (hb_ot_color_layer_t*) malloc (num_layers * sizeof (hb_ot_color_layer_t)); + + hb_ot_color_glyph_get_layers (face, gid, 0, &num_layers, layers); + if (num_layers) + { + // Measure + cairo_text_extents_t extents; + { + cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1); + cairo_t *cr = cairo_create (surface); + cairo_set_font_face (cr, cairo_face); + cairo_set_font_size (cr, upem); + + cairo_glyph_t *glyphs = (cairo_glyph_t *) calloc (num_layers, sizeof (cairo_glyph_t)); + for (unsigned int j = 0; j < num_layers; ++j) + glyphs[j].index = layers[j].glyph; + cairo_glyph_extents (cr, glyphs, num_layers, &extents); + free (glyphs); + cairo_surface_destroy (surface); + cairo_destroy (cr); + } + + // Add a slight margin + extents.width += extents.width / 10; + extents.height += extents.height / 10; + extents.x_bearing -= extents.width / 20; + extents.y_bearing -= extents.height / 20; + + // Render + unsigned int palette_count = hb_ot_color_palette_get_count (face); + for (unsigned int palette = 0; palette < palette_count; palette++) { + char output_path[255]; + + unsigned int num_colors = hb_ot_color_palette_get_colors (face, palette, 0, nullptr, nullptr); + if (!num_colors) + continue; + + hb_color_t *colors = (hb_color_t*) calloc (num_colors, sizeof (hb_color_t)); + hb_ot_color_palette_get_colors (face, palette, 0, &num_colors, colors); + if (num_colors) + { + // If we have more than one palette, use a simpler naming + if (palette_count == 1) + sprintf (output_path, "out/colr-%d.svg", gid); + else + sprintf (output_path, "out/colr-%d-%d.svg", gid, palette); + + cairo_surface_t *surface = cairo_svg_surface_create (output_path, extents.width, extents.height); + cairo_t *cr = cairo_create (surface); + cairo_set_font_face (cr, cairo_face); + cairo_set_font_size (cr, upem); + + for (unsigned int layer = 0; layer < num_layers; ++layer) + { + hb_color_t color = 0x000000FF; + if (layers[layer].color_index != 0xFFFF) + color = colors[layers[layer].color_index]; + cairo_set_source_rgba (cr, + hb_color_get_red (color) / 255., + hb_color_get_green (color) / 255., + hb_color_get_blue (color) / 255., + hb_color_get_alpha (color) / 255.); + + cairo_glyph_t glyph; + glyph.index = layers[layer].glyph; + glyph.x = -extents.x_bearing; + glyph.y = -extents.y_bearing; + cairo_show_glyphs (cr, &glyph, 1); + } + + cairo_surface_destroy (surface); + cairo_destroy (cr); + } + free (colors); + } + } + + free (layers); + } +} + +static void +dump_glyphs (cairo_font_face_t *cairo_face, unsigned int upem, + unsigned int num_glyphs) +{ + // Dump every glyph available on the font + return; // disabled for now + for (unsigned int i = 0; i < num_glyphs; ++i) + { + cairo_text_extents_t extents; + cairo_glyph_t glyph = {0}; + glyph.index = i; + + // Measure + { + cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1); + cairo_t *cr = cairo_create (surface); + cairo_set_font_face (cr, cairo_face); + cairo_set_font_size (cr, upem); + + cairo_glyph_extents (cr, &glyph, 1, &extents); + cairo_surface_destroy (surface); + cairo_destroy (cr); + } + + // Add a slight margin + extents.width += extents.width / 10; + extents.height += extents.height / 10; + extents.x_bearing -= extents.width / 20; + extents.y_bearing -= extents.height / 20; + + // Render + { + char output_path[255]; + sprintf (output_path, "out/%d.svg", i); + cairo_surface_t *surface = cairo_svg_surface_create (output_path, extents.width, extents.height); + cairo_t *cr = cairo_create (surface); + cairo_set_font_face (cr, cairo_face); + cairo_set_font_size (cr, upem); + glyph.x = -extents.x_bearing; + glyph.y = -extents.y_bearing; + cairo_show_glyphs (cr, &glyph, 1); + cairo_surface_destroy (surface); + cairo_destroy (cr); + } + } +} + +int +main (int argc, char **argv) +{ + if (argc != 2) { + fprintf (stderr, "usage: %s font-file.ttf\n" + "run it like `rm -rf out && mkdir out && %s font-file.ttf`\n", + argv[0], argv[0]); + exit (1); + } + + + FILE *font_name_file = fopen ("out/_font_name_file.txt", "r"); + if (font_name_file != nullptr) + { + fprintf (stderr, "Purge or move ./out folder in order to run a new dump\n"); + exit (1); + } + + font_name_file = fopen ("out/_font_name_file.txt", "w"); + if (font_name_file == nullptr) + { + fprintf (stderr, "./out is not accessible as a folder, create it please\n"); + exit (1); + } + fwrite (argv[1], 1, strlen (argv[1]), font_name_file); + fclose (font_name_file); + + hb_blob_t *blob = hb_blob_create_from_file (argv[1]); + hb_face_t *face = hb_face_create (blob, 0); + hb_font_t *font = hb_font_create (face); + + OT::CBDT::accelerator_t cbdt; + cbdt.init (face); + cbdt.dump (cbdt_callback); + cbdt.fini (); + + sbix_dump (face); + + if (hb_ot_color_has_svg (face)) + svg_dump (face); + + cairo_font_face_t *cairo_face; + { + FT_Library library; + FT_Init_FreeType (&library); + FT_Face ftface; + FT_New_Face (library, argv[1], 0, &ftface); + cairo_face = cairo_ft_font_face_create_for_ft_face (ftface, 0); + } + if (hb_ot_color_has_layers (face) && hb_ot_color_has_palettes (face)) + colr_cpal_dump (face, cairo_face); + + unsigned int num_glyphs = hb_face_get_glyph_count (face); + unsigned int upem = hb_face_get_upem (face); + dump_glyphs (cairo_face, upem, num_glyphs); + + hb_font_destroy (font); + hb_face_destroy (face); + hb_blob_destroy (blob); + + return 0; +} From fb525f8943b43fe241424c93461bee2b94af28e3 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Mon, 29 Oct 2018 09:43:17 +0330 Subject: [PATCH 153/255] Rename dump-emoji to test-ot-color --- src/{dump-emoji.cc => test-ot-color.cc} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{dump-emoji.cc => test-ot-color.cc} (100%) diff --git a/src/dump-emoji.cc b/src/test-ot-color.cc similarity index 100% rename from src/dump-emoji.cc rename to src/test-ot-color.cc From 9c692e5b8d195d8e82538594d89865c609d708f3 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Mon, 29 Oct 2018 11:36:11 +0330 Subject: [PATCH 154/255] [test-ot-color] Use public APIs on the tool --- src/Makefile.am | 9 ++ src/test-ot-color.cc | 190 ++++++++++++++++++++++++------------------- 2 files changed, 116 insertions(+), 83 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 0b9ae9dc4..a51048b70 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -377,6 +377,15 @@ test_would_substitute_SOURCES = test-would-substitute.cc test_would_substitute_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS) test_would_substitute_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS) +if HAVE_FREETYPE +if HAVE_CAIRO_FT +noinst_PROGRAMS += test-ot-color +test_ot_color_SOURCES = test-ot-color.cc +test_ot_color_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS) $(CAIRO_FT_CFLAGS) +test_ot_color_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS) $(CAIRO_LIBS) $(CAIRO_FT_LIBS) +endif # HAVE_CAIRO_FT +endif # HAVE_FREETYPE + dist_check_SCRIPTS = \ check-c-linkage-decls.sh \ check-externs.sh \ diff --git a/src/test-ot-color.cc b/src/test-ot-color.cc index e3cabc738..5312554a5 100644 --- a/src/test-ot-color.cc +++ b/src/test-ot-color.cc @@ -23,12 +23,8 @@ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ -#include "hb-static.cc" -#include "hb-ot-color-cbdt-table.hh" -#include "hb-ot-color-colr-table.hh" -#include "hb-ot-color-cpal-table.hh" -#include "hb-ot-color-sbix-table.hh" -#include "hb-ot-color-svg-table.hh" +#include "hb.h" +#include "hb-ot.h" #include "hb-ft.h" @@ -40,71 +36,94 @@ #include #include -#ifdef HAVE_GLIB -#include -#endif #include #include static void -cbdt_callback (const uint8_t* data, unsigned int length, - unsigned int group, unsigned int gid) +png_dump (hb_face_t *face, unsigned int face_index) { - char output_path[255]; - sprintf (output_path, "out/cbdt-%d-%d.png", group, gid); - FILE *f = fopen (output_path, "wb"); - fwrite (data, 1, length, f); - fclose (f); -} + unsigned glyph_count = hb_face_get_glyph_count (face); + hb_font_t *font = hb_font_create (face); -static void -sbix_dump (hb_face_t *face) -{ - OT::sbix::accelerator_t sbix; - sbix.init (face); - unsigned int length = 0; - unsigned int *available_ppems = sbix.get_available_ppems (&length); - unsigned int num_glyphs = face->num_glyphs; - for (unsigned int group = 0; group < length; group++) - for (unsigned int glyph_id = 0; glyph_id < num_glyphs; glyph_id++) + /* ugly hack, scans the font for strikes, not needed for regular clients */ + #define STRIKES_MAX 20 + unsigned int strikes_count = 0; + unsigned int strikes[STRIKES_MAX] = {0}; + { + /* find a sample glyph */ + unsigned int sample_glyph_id; + /* we don't care much about different strikes for different glyphs */ + for (sample_glyph_id = 0; sample_glyph_id < glyph_count; sample_glyph_id++) { - hb_blob_t *blob; - unsigned int ppem = available_ppems[group]; - blob = sbix.reference_blob_for_glyph (glyph_id, ppem, ppem, - HB_TAG('p','n','g',' '), nullptr, nullptr); + hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, sample_glyph_id); + unsigned int blob_length = hb_blob_get_length (blob); + hb_blob_destroy (blob); + if (blob_length != 0) + break; + } + /* find strikes it has */ + unsigned int upem = hb_face_get_upem (face); + unsigned int blob_length = 0; + for (unsigned int ppem = 1; ppem <= upem && strikes_count < STRIKES_MAX; ppem++) + { + hb_font_set_ppem (font, ppem, ppem); + hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, sample_glyph_id); + unsigned int new_blob_length = hb_blob_get_length (blob); + if (blob_length != new_blob_length) + { + strikes_count++; + blob_length = new_blob_length; + } + strikes[strikes_count - 1] = ppem; + hb_blob_destroy (blob); + } + /* can't report the biggest strike correctly, and, we can't do anything about it */ + } + #undef STRIKES_MAX + + for (unsigned int strike = 0; strike < strikes_count; strike++) + for (unsigned int glyph_id = 0; glyph_id < glyph_count; glyph_id++) + { + unsigned int ppem = strikes[strike]; + hb_font_set_ppem (font, ppem, ppem); + hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, glyph_id); + if (hb_blob_get_length (blob) == 0) continue; - char output_path[255]; - sprintf (output_path, "out/sbix-%d-%d.png", ppem, glyph_id); - FILE *f = fopen (output_path, "wb"); unsigned int length; - const char* data = hb_blob_get_data (blob, &length); + const char *data = hb_blob_get_data (blob, &length); + + char output_path[255]; + sprintf (output_path, "out/png-%d-%d-%d.png", glyph_id, strike, face_index); + + FILE *f = fopen (output_path, "wb"); fwrite (data, 1, length, f); fclose (f); + + hb_blob_destroy (blob); } - sbix.fini (); + + hb_font_destroy (font); } static void -svg_dump (hb_face_t *face) +svg_dump (hb_face_t *face, unsigned int face_index) { unsigned glyph_count = hb_face_get_glyph_count (face); - OT::SVG::accelerator_t svg; - svg.init (face); - for (unsigned int glyph_id = 0; glyph_id < glyph_count; glyph_id++) { - hb_blob_t *blob = svg.reference_blob_for_glyph (glyph_id); + hb_blob_t *blob = hb_ot_color_glyph_reference_svg (face, glyph_id); if (hb_blob_get_length (blob) == 0) continue; unsigned int length; const char *data = hb_blob_get_data (blob, &length); - char output_path[256]; - sprintf (output_path, "out/svg-%d.svg%s", + char output_path[255]; + sprintf (output_path, "out/svg-%d-%d.svg%s", glyph_id, + face_index, // append "z" if the content is gzipped, https://stackoverflow.com/a/6059405 (length > 2 && (data[0] == '\x1F') && (data[1] == '\x8B')) ? "z" : ""); @@ -114,12 +133,10 @@ svg_dump (hb_face_t *face) hb_blob_destroy (blob); } - - svg.fini (); } static void -colr_cpal_dump (hb_face_t *face, cairo_font_face_t *cairo_face) +layered_glyph_dump (hb_face_t *face, cairo_font_face_t *cairo_face, unsigned int face_index) { unsigned int upem = hb_face_get_upem (face); @@ -171,11 +188,7 @@ colr_cpal_dump (hb_face_t *face, cairo_font_face_t *cairo_face) hb_ot_color_palette_get_colors (face, palette, 0, &num_colors, colors); if (num_colors) { - // If we have more than one palette, use a simpler naming - if (palette_count == 1) - sprintf (output_path, "out/colr-%d.svg", gid); - else - sprintf (output_path, "out/colr-%d-%d.svg", gid, palette); + sprintf (output_path, "out/colr-%d-%d-%d.svg", gid, palette, face_index); cairo_surface_t *surface = cairo_svg_surface_create (output_path, extents.width, extents.height); cairo_t *cr = cairo_create (surface); @@ -213,10 +226,8 @@ colr_cpal_dump (hb_face_t *face, cairo_font_face_t *cairo_face) static void dump_glyphs (cairo_font_face_t *cairo_face, unsigned int upem, - unsigned int num_glyphs) + unsigned int num_glyphs, unsigned int face_index) { - // Dump every glyph available on the font - return; // disabled for now for (unsigned int i = 0; i < num_glyphs; ++i) { cairo_text_extents_t extents; @@ -244,7 +255,7 @@ dump_glyphs (cairo_font_face_t *cairo_face, unsigned int upem, // Render { char output_path[255]; - sprintf (output_path, "out/%d.svg", i); + sprintf (output_path, "out/%d-%d.svg", face_index, i); cairo_surface_t *surface = cairo_svg_surface_create (output_path, extents.width, extents.height); cairo_t *cr = cairo_create (surface); cairo_set_font_face (cr, cairo_face); @@ -269,14 +280,14 @@ main (int argc, char **argv) } - FILE *font_name_file = fopen ("out/_font_name_file.txt", "r"); + FILE *font_name_file = fopen ("out/.dumped_font_name", "r"); if (font_name_file != nullptr) { fprintf (stderr, "Purge or move ./out folder in order to run a new dump\n"); exit (1); } - font_name_file = fopen ("out/_font_name_file.txt", "w"); + font_name_file = fopen ("out/.dumped_font_name", "w"); if (font_name_file == nullptr) { fprintf (stderr, "./out is not accessible as a folder, create it please\n"); @@ -286,36 +297,49 @@ main (int argc, char **argv) fclose (font_name_file); hb_blob_t *blob = hb_blob_create_from_file (argv[1]); - hb_face_t *face = hb_face_create (blob, 0); - hb_font_t *font = hb_font_create (face); - - OT::CBDT::accelerator_t cbdt; - cbdt.init (face); - cbdt.dump (cbdt_callback); - cbdt.fini (); - - sbix_dump (face); - - if (hb_ot_color_has_svg (face)) - svg_dump (face); - - cairo_font_face_t *cairo_face; + unsigned int num_faces = hb_face_count (blob); + if (num_faces == 0) { - FT_Library library; - FT_Init_FreeType (&library); - FT_Face ftface; - FT_New_Face (library, argv[1], 0, &ftface); - cairo_face = cairo_ft_font_face_create_for_ft_face (ftface, 0); + fprintf (stderr, "error: The file (%s) was corrupted, empty or not found", argv[1]); + exit (1); } - if (hb_ot_color_has_layers (face) && hb_ot_color_has_palettes (face)) - colr_cpal_dump (face, cairo_face); - unsigned int num_glyphs = hb_face_get_glyph_count (face); - unsigned int upem = hb_face_get_upem (face); - dump_glyphs (cairo_face, upem, num_glyphs); + for (unsigned int face_index = 0; face_index < hb_face_count (blob); face_index++) + { + hb_face_t *face = hb_face_create (blob, face_index); + hb_font_t *font = hb_font_create (face); + + if (hb_ot_color_has_png (face)) printf ("Dumping png (cbdt/sbix)...\n"); + png_dump (face, face_index); + + if (hb_ot_color_has_svg (face)) printf ("Dumping svg...\n"); + svg_dump (face, face_index); + + cairo_font_face_t *cairo_face; + { + FT_Library library; + FT_Init_FreeType (&library); + FT_Face ft_face; + FT_New_Face (library, argv[1], 0, &ft_face); + cairo_face = cairo_ft_font_face_create_for_ft_face (ft_face, 0); + } + if (hb_ot_color_has_layers (face) && hb_ot_color_has_palettes (face)) + printf ("Dumping layered color glyphs...\n"); + layered_glyph_dump (face, cairo_face, face_index); + + unsigned int num_glyphs = hb_face_get_glyph_count (face); + unsigned int upem = hb_face_get_upem (face); + + // disabled when color font as cairo rendering of NotoColorEmoji is soooo slow + if (!hb_ot_color_has_layers (face) && + !hb_ot_color_has_png (face) && + !hb_ot_color_has_svg (face)) + dump_glyphs (cairo_face, upem, num_glyphs, face_index); + + hb_font_destroy (font); + hb_face_destroy (face); + } - hb_font_destroy (font); - hb_face_destroy (face); hb_blob_destroy (blob); return 0; From 7170e35096f0afd084be1350d080695c70c65d40 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Mon, 29 Oct 2018 13:11:01 +0330 Subject: [PATCH 155/255] Rename deprecated symbols list file name and clean it up (#1328) --- src/Makefile.am | 6 +++--- src/gen-def.py | 9 ++++----- test/api/Makefile.am | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index a51048b70..fbd8f6023 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -268,7 +268,7 @@ EXTRA_DIST += \ CLEANFILES += $(pkgconfig_DATA) -DEF_FILES = harfbuzz.def harfbuzz-subset.def harfbuzz-icu.def harfbuzz-deprecated.def +DEF_FILES = harfbuzz.def harfbuzz-subset.def harfbuzz-icu.def harfbuzz-deprecated-symbols.txt if HAVE_GOBJECT DEF_FILES += harfbuzz-gobject.def endif @@ -282,8 +282,8 @@ harfbuzz-icu.def: $(HB_ICU_headers) $(AM_V_GEN) $(srcdir)/gen-def.py "$@" $^ harfbuzz-gobject.def: $(HB_GOBJECT_headers) $(AM_V_GEN) $(srcdir)/gen-def.py "$@" $^ -harfbuzz-deprecated.def: $(srcdir)/hb-deprecated.h - $(AM_V_GEN) $(srcdir)/gen-def.py "$@" $^ +harfbuzz-deprecated-symbols.txt: $(srcdir)/hb-deprecated.h + $(AM_V_GEN) PLAIN_LIST=1 $(srcdir)/gen-def.py "$@" $^ GENERATORS = \ diff --git a/src/gen-def.py b/src/gen-def.py index ba39eaae5..9111c698c 100755 --- a/src/gen-def.py +++ b/src/gen-def.py @@ -15,11 +15,10 @@ for h in header_paths: if h.endswith (".h"): with io.open (h, encoding='utf-8') as f: headers_content.append (f.read ()) -result = """EXPORTS +symbols = "\n".join (sorted (re.findall (r"^hb_\w+(?= \()", "\n".join (headers_content), re.M))) + +result = symbols if os.environ.get('PLAIN_LIST', '') else """EXPORTS %s -LIBRARY lib%s-0.dll""" % ( - "\n".join (sorted (re.findall (r"^hb_\w+(?= \()", "\n".join (headers_content), re.M))), - output_file.replace ('.def', '') -) +LIBRARY lib%s-0.dll""" % (symbols, output_file.replace ('.def', '')) with open (output_file, "w") as f: f.write (result) diff --git a/test/api/Makefile.am b/test/api/Makefile.am index 45a34e64d..c233a90ed 100644 --- a/test/api/Makefile.am +++ b/test/api/Makefile.am @@ -167,7 +167,7 @@ symbols-tested.txt: $(TEST_PROGS) $(AM_V_GEN)$(top_builddir)/libtool --mode=execute nm $^ \ | grep ' U hb_' | sed 's/.* U hb_/hb_/' \ | sort | uniq > $@.tmp && mv $@.tmp $@ -symbols-tested-or-deprecated.txt: symbols-tested.txt $(top_builddir)/src/harfbuzz-deprecated.def +symbols-tested-or-deprecated.txt: symbols-tested.txt $(top_builddir)/src/harfbuzz-deprecated-symbols.txt $(AM_V_GEN)cat $^ | sort | uniq > $@.tmp; mv $@.tmp $@ symbols-exported.txt: $(top_builddir)/src/.libs/libharfbuzz.so $(AM_V_GEN)$(top_builddir)/libtool --mode=execute nm $^ \ From ae802c2c6e001492f8f639e4c24546f0e21d86c7 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Mon, 29 Oct 2018 13:42:14 +0330 Subject: [PATCH 156/255] [test-ot-color] Minor --- src/test-ot-color.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test-ot-color.cc b/src/test-ot-color.cc index 5312554a5..2cb9b03b2 100644 --- a/src/test-ot-color.cc +++ b/src/test-ot-color.cc @@ -74,7 +74,8 @@ png_dump (hb_face_t *face, unsigned int face_index) strikes_count++; blob_length = new_blob_length; } - strikes[strikes_count - 1] = ppem; + if (strikes_count != 0) + strikes[strikes_count - 1] = ppem; hb_blob_destroy (blob); } /* can't report the biggest strike correctly, and, we can't do anything about it */ From 1366bb9760d0f171f8f655e5739e74dfd2537652 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Oct 2018 11:01:25 -0700 Subject: [PATCH 157/255] Fix g-i warnings --- src/hb-ot-color.h | 4 +++- src/hb-ot-name.cc | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-color.h b/src/hb-ot-color.h index 89935143e..1cc04d4f3 100644 --- a/src/hb-ot-color.h +++ b/src/hb-ot-color.h @@ -94,7 +94,9 @@ HB_EXTERN hb_bool_t hb_ot_color_has_layers (hb_face_t *face); /** - * hb_ot_color_layer_t: Pairs of glyph and color index. + * hb_ot_color_layer_t: + * + * Pairs of glyph and color index. * * Since: REPLACEME **/ diff --git a/src/hb-ot-name.cc b/src/hb-ot-name.cc index 2bf2ae58b..e8aa3d8e7 100644 --- a/src/hb-ot-name.cc +++ b/src/hb-ot-name.cc @@ -52,13 +52,13 @@ _get_name (hb_face_t *face) /** * hb_ot_name_list_names: * @face: font face. - * @num_entries: (out) number of returned entries. + * @num_entries: (out): number of returned entries. * * Enumerates all available name IDs and language combinations. Returned * array is owned by the @face and should not be modified. It can be * used as long as @face is alive. * - * Returns: (out) (transfer none) (array length=num_entries) Array of available name entries. + * Returns: (out) (transfer none) (array length=num_entries): Array of available name entries. * Since: 2.1.0 **/ const hb_ot_name_entry_t * From 31cc1f74b7028ef88fa0e93e7f12166c7e06de8e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Oct 2018 11:14:37 -0700 Subject: [PATCH 158/255] [svg] Minor --- src/hb-ot-color-svg-table.hh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh index 7c342d018..bb4c4f757 100644 --- a/src/hb-ot-color-svg-table.hh +++ b/src/hb-ot-color-svg-table.hh @@ -50,10 +50,11 @@ struct SVGDocumentIndexEntry svgDocLength); } - inline bool sanitize (hb_sanitize_context_t *c) const + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); + return_trace (c->check_struct (this) && + svgDoc.sanitize (c, base, svgDocLength)); } protected: From a256a92b3fbb72487cf073a63e646eab952b42ed Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Oct 2018 11:25:35 -0700 Subject: [PATCH 159/255] Make Array types uncopyable-unassignable Finally! Catches hard-to-find errors like this: - const SortedArrayOf docs = this+svgDocEntries; + const SortedArrayOf &docs = this+svgDocEntries; We implement this for our array types. This, in turn, trickles down into all types that embed the arrays. So, as long as we define all open-ended structs in terms of Array types (all can be done using UnsizedArrayOf), this achieves the goal of making uncopyable all structs that are variable-sized. Yay! --- src/hb-open-type.hh | 11 +++++++++++ src/hb.hh | 6 ++++++ 2 files changed, 17 insertions(+) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 6e545a6d3..ee452864d 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -335,6 +335,8 @@ static inline Type& operator + (Base &base, OffsetTo template struct UnsizedArrayOf { + HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE (UnsizedArrayOf, Type); + inline const Type& operator [] (unsigned int i) const { return arrayZ[i]; } inline Type& operator [] (unsigned int i) { return arrayZ[i]; } @@ -424,6 +426,8 @@ struct UnsizedOffsetListOf : UnsizedOffsetArrayOf template struct ArrayOf { + HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE2 (ArrayOf, Type, LenType); + inline const Type *sub_array (unsigned int start_offset, unsigned int *pcount /* IN/OUT */) const { unsigned int count = len; @@ -589,6 +593,8 @@ struct OffsetListOf : OffsetArrayOf template struct HeadlessArrayOf { + HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE2 (HeadlessArrayOf, Type, LenType); + inline const Type& operator [] (unsigned int i) const { if (unlikely (i >= lenP1 || !i)) return Null(Type); @@ -653,6 +659,8 @@ struct HeadlessArrayOf template struct ArrayOfM1 { + HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE2 (ArrayOfM1, Type, LenType); + inline const Type& operator [] (unsigned int i) const { if (unlikely (i > lenM1)) return Null(Type); @@ -757,6 +765,7 @@ struct BinSearchHeader template struct BinSearchArrayOf : SortedArrayOf > {}; + struct VarSizedBinSearchHeader { @@ -782,6 +791,8 @@ struct VarSizedBinSearchHeader template struct VarSizedBinSearchArrayOf { + HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE (VarSizedBinSearchArrayOf, Type); + inline const Type& operator [] (unsigned int i) const { if (unlikely (i >= header.nUnits)) return Null(Type); diff --git a/src/hb.hh b/src/hb.hh index ea474298f..e5bec5087 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -366,6 +366,12 @@ static_assert ((sizeof (hb_var_int_t) == 4), ""); #define HB_DISALLOW_COPY_AND_ASSIGN(TypeName) \ TypeName(const TypeName&); \ void operator=(const TypeName&) +#define HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE(TypeName, T) \ + TypeName(const TypeName&); \ + void operator=(const TypeName&) +#define HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE2(TypeName, T1, T2) \ + TypeName(const TypeName&); \ + void operator=(const TypeName&) /* From 6f0454e176efdb8b99c8aa59b5ad765ca455b8d6 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Oct 2018 13:51:15 -0700 Subject: [PATCH 160/255] Fix extra-semicolon warnings --- src/hb-machinery.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index 2b238131a..a624cf913 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -114,11 +114,11 @@ static inline Type& StructAfter(TObject &X) #define DEFINE_SIZE_ARRAY(size, array) \ DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + VAR * sizeof (array[0])); \ DEFINE_COMPILES_ASSERTION ((void) array[0].static_size) \ - enum { min_size = (size) }; \ + enum { min_size = (size) } \ #define DEFINE_SIZE_ARRAY_SIZED(size, array) \ - DEFINE_SIZE_ARRAY(size, array); \ - inline unsigned int get_size (void) const { return (size - array.min_size + array.get_size ()); } + inline unsigned int get_size (void) const { return (size - array.min_size + array.get_size ()); } \ + DEFINE_SIZE_ARRAY(size, array) #define DEFINE_SIZE_ARRAY2(size, array1, array2) \ DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (this->array1[0]) + sizeof (this->array2[0])); \ From 35d410f2bad62e98f3634c5ee156d0aea9031067 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Oct 2018 14:45:44 -0700 Subject: [PATCH 161/255] Remove ASSERT_POD Newer compilers / language allows structs with constructor in union. So, this was not actually testing anything. Indeed, the recent change in DISALLOW_COPY *is* making some of our types non-POD. That broke some bots. Just remove this since it wasn't doing much, and I'd rather have DISALLOW_COPY. --- src/hb-blob.hh | 1 - src/hb-buffer.hh | 1 - src/hb-face.hh | 1 - src/hb-font.hh | 2 -- src/hb-machinery.hh | 5 +---- src/hb-object.hh | 6 +---- src/hb-ot-shape-complex-arabic-fallback.hh | 2 -- src/hb-ot-shape-complex-arabic.cc | 2 -- src/hb-ot-shape-complex-hangul.cc | 2 -- src/hb-ot-shape-complex-indic.cc | 2 -- src/hb-ot-shape-complex-khmer.cc | 2 -- src/hb-ot-shape-complex-use.cc | 2 -- src/hb-set-digest.hh | 4 ---- src/hb-shape-plan.hh | 1 - src/hb-subset-input.hh | 1 - src/hb-subset-plan.hh | 1 - src/hb-unicode.hh | 1 - src/hb.hh | 26 ---------------------- 18 files changed, 2 insertions(+), 60 deletions(-) diff --git a/src/hb-blob.hh b/src/hb-blob.hh index bee8c9794..26e2dd70a 100644 --- a/src/hb-blob.hh +++ b/src/hb-blob.hh @@ -69,7 +69,6 @@ struct hb_blob_t public: hb_object_header_t header; - ASSERT_POD (); bool immutable; diff --git a/src/hb-buffer.hh b/src/hb-buffer.hh index 0d888e1e0..37adeb083 100644 --- a/src/hb-buffer.hh +++ b/src/hb-buffer.hh @@ -86,7 +86,6 @@ HB_MARK_AS_FLAG_T (hb_buffer_scratch_flags_t); struct hb_buffer_t { hb_object_header_t header; - ASSERT_POD (); /* Information about how the text in the buffer should be treated */ hb_unicode_funcs_t *unicode; /* Unicode functions */ diff --git a/src/hb-face.hh b/src/hb-face.hh index f90453dbd..89673ff84 100644 --- a/src/hb-face.hh +++ b/src/hb-face.hh @@ -42,7 +42,6 @@ struct hb_face_t { hb_object_header_t header; - ASSERT_POD (); hb_bool_t immutable; diff --git a/src/hb-font.hh b/src/hb-font.hh index 2df5e42ee..3dce233db 100644 --- a/src/hb-font.hh +++ b/src/hb-font.hh @@ -62,7 +62,6 @@ struct hb_font_funcs_t { hb_object_header_t header; - ASSERT_POD (); hb_bool_t immutable; @@ -102,7 +101,6 @@ DECLARE_NULL_INSTANCE (hb_font_funcs_t); struct hb_font_t { hb_object_header_t header; - ASSERT_POD (); hb_bool_t immutable; diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index a624cf913..0ff3a7681 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -82,10 +82,7 @@ static inline Type& StructAfter(TObject &X) /* Check _assertion in a method environment */ #define _DEFINE_INSTANCE_ASSERTION1(_line, _assertion) \ inline void _instance_assertion_on_line_##_line (void) const \ - { \ - static_assert ((_assertion), ""); \ - ASSERT_INSTANCE_POD (*this); /* Make sure it's POD. */ \ - } + { static_assert ((_assertion), ""); } # define _DEFINE_INSTANCE_ASSERTION0(_line, _assertion) _DEFINE_INSTANCE_ASSERTION1 (_line, _assertion) # define DEFINE_INSTANCE_ASSERTION(_assertion) _DEFINE_INSTANCE_ASSERTION0 (__LINE__, _assertion) diff --git a/src/hb-object.hh b/src/hb-object.hh index ca85af691..d347b5ffa 100644 --- a/src/hb-object.hh +++ b/src/hb-object.hh @@ -195,12 +195,8 @@ struct hb_object_header_t { hb_reference_count_t ref_count; hb_atomic_ptr_t user_data; - -#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INIT, HB_ATOMIC_PTR_INIT (nullptr)} - - private: - ASSERT_POD (); }; +#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INIT, HB_ATOMIC_PTR_INIT (nullptr)} /* diff --git a/src/hb-ot-shape-complex-arabic-fallback.hh b/src/hb-ot-shape-complex-arabic-fallback.hh index f64e2dd6e..eeb2da85f 100644 --- a/src/hb-ot-shape-complex-arabic-fallback.hh +++ b/src/hb-ot-shape-complex-arabic-fallback.hh @@ -194,8 +194,6 @@ arabic_fallback_synthesize_lookup (const hb_ot_shape_plan_t *plan, struct arabic_fallback_plan_t { - ASSERT_POD (); - unsigned int num_lookups; bool free_lookups; diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc index 1fbd14a4c..8e56dde3d 100644 --- a/src/hb-ot-shape-complex-arabic.cc +++ b/src/hb-ot-shape-complex-arabic.cc @@ -243,8 +243,6 @@ collect_features_arabic (hb_ot_shape_planner_t *plan) struct arabic_shape_plan_t { - ASSERT_POD (); - /* The "+ 1" in the next array is to accommodate for the "NONE" command, * which is not an OpenType feature, but this simplifies the code by not * having to do a "if (... < NONE) ..." and just rely on the fact that diff --git a/src/hb-ot-shape-complex-hangul.cc b/src/hb-ot-shape-complex-hangul.cc index 38e4dbba6..e143867e1 100644 --- a/src/hb-ot-shape-complex-hangul.cc +++ b/src/hb-ot-shape-complex-hangul.cc @@ -70,8 +70,6 @@ override_features_hangul (hb_ot_shape_planner_t *plan) struct hangul_shape_plan_t { - ASSERT_POD (); - hb_mask_t mask_array[HANGUL_FEATURE_COUNT]; }; diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc index dfb67cfb9..4f98f7480 100644 --- a/src/hb-ot-shape-complex-indic.cc +++ b/src/hb-ot-shape-complex-indic.cc @@ -252,8 +252,6 @@ struct would_substitute_feature_t struct indic_shape_plan_t { - ASSERT_POD (); - inline bool load_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const { hb_codepoint_t glyph = virama_glyph.get_relaxed (); diff --git a/src/hb-ot-shape-complex-khmer.cc b/src/hb-ot-shape-complex-khmer.cc index ecb80195f..1142da3ec 100644 --- a/src/hb-ot-shape-complex-khmer.cc +++ b/src/hb-ot-shape-complex-khmer.cc @@ -174,8 +174,6 @@ struct would_substitute_feature_t struct khmer_shape_plan_t { - ASSERT_POD (); - inline bool get_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const { hb_codepoint_t glyph = virama_glyph; diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index 1bbf9805c..3ab77fc58 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -171,8 +171,6 @@ collect_features_use (hb_ot_shape_planner_t *plan) struct use_shape_plan_t { - ASSERT_POD (); - hb_mask_t rphf_mask; arabic_shape_plan_t *arabic_plan; diff --git a/src/hb-set-digest.hh b/src/hb-set-digest.hh index 0f9329f62..4e99df0eb 100644 --- a/src/hb-set-digest.hh +++ b/src/hb-set-digest.hh @@ -48,8 +48,6 @@ template struct hb_set_digest_lowest_bits_t { - ASSERT_POD (); - enum { mask_bytes = sizeof (mask_t) }; enum { mask_bits = sizeof (mask_t) * 8 }; static const unsigned int num_bits = 0 @@ -117,8 +115,6 @@ struct hb_set_digest_lowest_bits_t template struct hb_set_digest_combiner_t { - ASSERT_POD (); - inline void init (void) { head.init (); tail.init (); diff --git a/src/hb-shape-plan.hh b/src/hb-shape-plan.hh index bf82b912b..403c3ebdf 100644 --- a/src/hb-shape-plan.hh +++ b/src/hb-shape-plan.hh @@ -34,7 +34,6 @@ struct hb_shape_plan_t { hb_object_header_t header; - ASSERT_POD (); hb_bool_t default_shaper_list; hb_face_t *face_unsafe; /* We don't carry a reference to face. */ diff --git a/src/hb-subset-input.hh b/src/hb-subset-input.hh index 9fc86154e..7f625f2e4 100644 --- a/src/hb-subset-input.hh +++ b/src/hb-subset-input.hh @@ -37,7 +37,6 @@ struct hb_subset_input_t { hb_object_header_t header; - ASSERT_POD (); hb_set_t *unicodes; hb_set_t *glyphs; diff --git a/src/hb-subset-plan.hh b/src/hb-subset-plan.hh index c2c484a5b..5ab32ad8f 100644 --- a/src/hb-subset-plan.hh +++ b/src/hb-subset-plan.hh @@ -37,7 +37,6 @@ struct hb_subset_plan_t { hb_object_header_t header; - ASSERT_POD (); bool drop_hints : 1; bool drop_layout : 1; diff --git a/src/hb-unicode.hh b/src/hb-unicode.hh index 4326798df..0b66ce8a1 100644 --- a/src/hb-unicode.hh +++ b/src/hb-unicode.hh @@ -63,7 +63,6 @@ extern HB_INTERNAL const uint8_t _hb_modified_combining_class[256]; struct hb_unicode_funcs_t { hb_object_header_t header; - ASSERT_POD (); hb_unicode_funcs_t *parent; diff --git a/src/hb.hh b/src/hb.hh index e5bec5087..18bccdbc2 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -337,32 +337,6 @@ static_assert ((sizeof (hb_mask_t) == 4), ""); static_assert ((sizeof (hb_var_int_t) == 4), ""); -/* We like our types POD */ - -#define _ASSERT_TYPE_POD1(_line, _type) union _type_##_type##_on_line_##_line##_is_not_POD { _type instance; } -#define _ASSERT_TYPE_POD0(_line, _type) _ASSERT_TYPE_POD1 (_line, _type) -#define ASSERT_TYPE_POD(_type) _ASSERT_TYPE_POD0 (__LINE__, _type) - -#ifdef __GNUC__ -# define _ASSERT_INSTANCE_POD1(_line, _instance) \ - HB_STMT_START { \ - typedef __typeof__(_instance) _type_##_line; \ - _ASSERT_TYPE_POD1 (_line, _type_##_line); \ - } HB_STMT_END -#else -# define _ASSERT_INSTANCE_POD1(_line, _instance) typedef int _assertion_on_line_##_line##_not_tested -#endif -# define _ASSERT_INSTANCE_POD0(_line, _instance) _ASSERT_INSTANCE_POD1 (_line, _instance) -# define ASSERT_INSTANCE_POD(_instance) _ASSERT_INSTANCE_POD0 (__LINE__, _instance) - -/* Check _assertion in a method environment */ -#define _ASSERT_POD1(_line) \ - HB_UNUSED inline void _static_assertion_on_line_##_line (void) const \ - { _ASSERT_INSTANCE_POD1 (_line, *this); /* Make sure it's POD. */ } -# define _ASSERT_POD0(_line) _ASSERT_POD1 (_line) -# define ASSERT_POD() _ASSERT_POD0 (__LINE__) - - #define HB_DISALLOW_COPY_AND_ASSIGN(TypeName) \ TypeName(const TypeName&); \ void operator=(const TypeName&) From be87959a67b8ccf2b21d3cfdb7d16202f18df670 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Oct 2018 15:16:38 -0700 Subject: [PATCH 162/255] [cmap] Minor --- src/hb-ot-cmap-table.hh | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index d5b4fde34..f0dbef69c 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -851,18 +851,6 @@ struct 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 @@ -872,9 +860,9 @@ struct cmap } // Format 4 - hb_vector_t format4_segments; + hb_auto_t > format4_segments; // Format 12 - hb_vector_t format12_groups; + hb_auto_t > format12_groups; }; inline bool sanitize (hb_sanitize_context_t *c) const From c7c5df9ffd4f7bcc84a9a02a565ccc1807cca529 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Oct 2018 15:16:52 -0700 Subject: [PATCH 163/255] Try fixing older bots Older C++ doesn't allow struct-with-constructor in union. --- src/hb.hh | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/hb.hh b/src/hb.hh index 18bccdbc2..8198d396b 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -337,6 +337,8 @@ static_assert ((sizeof (hb_mask_t) == 4), ""); static_assert ((sizeof (hb_var_int_t) == 4), ""); +#if __cplusplus >= 201103L + #define HB_DISALLOW_COPY_AND_ASSIGN(TypeName) \ TypeName(const TypeName&); \ void operator=(const TypeName&) @@ -344,8 +346,17 @@ static_assert ((sizeof (hb_var_int_t) == 4), ""); TypeName(const TypeName&); \ void operator=(const TypeName&) #define HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE2(TypeName, T1, T2) \ + inline TypeName() {} \ TypeName(const TypeName&); \ - void operator=(const TypeName&) + void operator=(const TypeName&); + +#else /* __cpluspplus >= 201103L */ + +#define HB_DISALLOW_COPY_AND_ASSIGN(TypeName) +#define HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE(TypeName, T) +#define HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE2(TypeName, T1, T2) + +#endif /* __cpluspplus >= 201103L */ /* From 14b353c1852be64db244f84bf5e95b4b7f3e65b6 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Oct 2018 15:29:13 -0700 Subject: [PATCH 164/255] One more iteration --- src/hb.hh | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hb.hh b/src/hb.hh index 8198d396b..d29baabfb 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -346,7 +346,6 @@ static_assert ((sizeof (hb_var_int_t) == 4), ""); TypeName(const TypeName&); \ void operator=(const TypeName&) #define HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE2(TypeName, T1, T2) \ - inline TypeName() {} \ TypeName(const TypeName&); \ void operator=(const TypeName&); From 5b563640b2df5b100130c9901b666713b2e1767e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Oct 2018 15:58:44 -0700 Subject: [PATCH 165/255] Remove HB_DISALLOW_COPY_AND_ASSIGN from hb_ot_shape_planner_t It was arbitrary that this struct had it and not dozens of others. --- src/hb-ot-shape.hh | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/hb-ot-shape.hh b/src/hb-ot-shape.hh index e7d6204a8..1cb9e24d7 100644 --- a/src/hb-ot-shape.hh +++ b/src/hb-ot-shape.hh @@ -102,9 +102,6 @@ struct hb_ot_shape_planner_t HB_INTERNAL void compile (hb_ot_shape_plan_t &plan, const int *coords, unsigned int num_coords); - - private: - HB_DISALLOW_COPY_AND_ASSIGN (hb_ot_shape_planner_t); }; From ea0e51d1b161245aaf5ad0f844bb5316b1cbcd5e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Oct 2018 16:00:23 -0700 Subject: [PATCH 166/255] Add HB_NO_CREATE_COPY_ASSIGN --- src/hb-open-type.hh | 10 +++++----- src/hb.hh | 15 +++++++++------ 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index ee452864d..e9f99b104 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -335,7 +335,7 @@ static inline Type& operator + (Base &base, OffsetTo template struct UnsizedArrayOf { - HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE (UnsizedArrayOf, Type); + HB_NO_CREATE_COPY_ASSIGN_TEMPLATE (UnsizedArrayOf, Type); inline const Type& operator [] (unsigned int i) const { return arrayZ[i]; } inline Type& operator [] (unsigned int i) { return arrayZ[i]; } @@ -426,7 +426,7 @@ struct UnsizedOffsetListOf : UnsizedOffsetArrayOf template struct ArrayOf { - HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE2 (ArrayOf, Type, LenType); + HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2 (ArrayOf, Type, LenType); inline const Type *sub_array (unsigned int start_offset, unsigned int *pcount /* IN/OUT */) const { @@ -593,7 +593,7 @@ struct OffsetListOf : OffsetArrayOf template struct HeadlessArrayOf { - HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE2 (HeadlessArrayOf, Type, LenType); + HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2 (HeadlessArrayOf, Type, LenType); inline const Type& operator [] (unsigned int i) const { @@ -659,7 +659,7 @@ struct HeadlessArrayOf template struct ArrayOfM1 { - HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE2 (ArrayOfM1, Type, LenType); + HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2 (ArrayOfM1, Type, LenType); inline const Type& operator [] (unsigned int i) const { @@ -791,7 +791,7 @@ struct VarSizedBinSearchHeader template struct VarSizedBinSearchArrayOf { - HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE (VarSizedBinSearchArrayOf, Type); + HB_NO_CREATE_COPY_ASSIGN_TEMPLATE (VarSizedBinSearchArrayOf, Type); inline const Type& operator [] (unsigned int i) const { diff --git a/src/hb.hh b/src/hb.hh index d29baabfb..74dd8ace0 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -339,21 +339,24 @@ static_assert ((sizeof (hb_var_int_t) == 4), ""); #if __cplusplus >= 201103L -#define HB_DISALLOW_COPY_AND_ASSIGN(TypeName) \ +#define HB_NO_CREATE_COPY_ASSIGN(TypeName) \ + TypeName(void); \ TypeName(const TypeName&); \ void operator=(const TypeName&) -#define HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE(TypeName, T) \ +#define HB_NO_CREATE_COPY_ASSIGN_TEMPLATE(TypeName, T) \ + TypeName(void); \ TypeName(const TypeName&); \ void operator=(const TypeName&) -#define HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE2(TypeName, T1, T2) \ +#define HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2(TypeName, T1, T2) \ + TypeName(void); \ TypeName(const TypeName&); \ void operator=(const TypeName&); #else /* __cpluspplus >= 201103L */ -#define HB_DISALLOW_COPY_AND_ASSIGN(TypeName) -#define HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE(TypeName, T) -#define HB_DISALLOW_COPY_AND_ASSIGN_TEMPLATE2(TypeName, T1, T2) +#define HB_NO_CREATE_COPY_ASSIGN(TypeName) +#define HB_NO_CREATE_COPY_ASSIGN_TEMPLATE(TypeName, T) +#define HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2(TypeName, T1, T2) #endif /* __cpluspplus >= 201103L */ From 67a22f377dee0dbd89f301f0a1fec6f787867b5e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Oct 2018 17:37:41 -0700 Subject: [PATCH 167/255] [set/map/vector] Make constructable, but not copy or assignable Disable copy/assign on them, as they shouldn't. Make constructor / destructor call init_shallow/fini_shallow, and make those idempotent. So, these three can be constructed on stack now and no init/fini call is needed. As such, hb_auto_t<> is not needed anymore. I'll remove that separately. --- src/hb-map.hh | 6 ++++++ src/hb-set.hh | 5 +++++ src/hb-vector.hh | 37 ++++++++++++++++++++----------------- src/hb.hh | 12 ++++++++++++ 4 files changed, 43 insertions(+), 17 deletions(-) diff --git a/src/hb-map.hh b/src/hb-map.hh index b55e3a954..e5ca3f515 100644 --- a/src/hb-map.hh +++ b/src/hb-map.hh @@ -44,6 +44,10 @@ inline uint32_t Hash (const T &v) struct hb_map_t { + HB_NO_COPY_ASSIGN (hb_map_t); + inline hb_map_t (void) { init_shallow (); } + inline ~hb_map_t (void) { fini_shallow (); } + struct item_t { hb_codepoint_t key; @@ -77,9 +81,11 @@ struct hb_map_t inline void fini_shallow (void) { free (items); + items = nullptr; } inline void fini (void) { + population = occupancy = 0; hb_object_fini (this); fini_shallow (); } diff --git a/src/hb-set.hh b/src/hb-set.hh index 2071196bc..97ff291eb 100644 --- a/src/hb-set.hh +++ b/src/hb-set.hh @@ -39,6 +39,10 @@ struct hb_set_t { + HB_NO_COPY_ASSIGN (hb_set_t); + inline hb_set_t (void) { init_shallow (); } + inline ~hb_set_t (void) { fini_shallow (); } + struct page_map_t { inline int cmp (const page_map_t *o) const { return (int) o->major - (int) major; } @@ -199,6 +203,7 @@ struct hb_set_t } inline void fini_shallow (void) { + population = 0; page_map.fini (); pages.fini (); } diff --git a/src/hb-vector.hh b/src/hb-vector.hh index 8995ae104..fe06addf7 100644 --- a/src/hb-vector.hh +++ b/src/hb-vector.hh @@ -34,6 +34,10 @@ template struct hb_vector_t { + HB_NO_COPY_ASSIGN_TEMPLATE2 (hb_vector_t, Type, StaticSize); + inline hb_vector_t (void) { init (); } + inline ~hb_vector_t (void) { fini (); } + unsigned int len; private: unsigned int allocated; /* == 0 means allocation failed. */ @@ -48,6 +52,22 @@ struct hb_vector_t arrayZ_ = nullptr; } + inline void fini (void) + { + if (arrayZ_) + free (arrayZ_); + arrayZ_ = nullptr; + allocated = len = 0; + } + inline void fini_deep (void) + { + Type *array = arrayZ(); + unsigned int count = len; + for (unsigned int i = 0; i < count; i++) + array[i].fini (); + fini (); + } + inline Type * arrayZ (void) { return arrayZ_ ? arrayZ_ : static_array; } inline const Type * arrayZ (void) const @@ -255,23 +275,6 @@ struct hb_vector_t *i = max; return false; } - - inline void fini_deep (void) - { - Type *array = arrayZ(); - unsigned int count = len; - for (unsigned int i = 0; i < count; i++) - array[i].fini (); - fini (); - } - - inline void fini (void) - { - if (arrayZ_) - free (arrayZ_); - arrayZ_ = nullptr; - allocated = len = 0; - } }; diff --git a/src/hb.hh b/src/hb.hh index 74dd8ace0..6f5d6aab2 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -339,6 +339,16 @@ static_assert ((sizeof (hb_var_int_t) == 4), ""); #if __cplusplus >= 201103L +/* We only enable these with C++11 or later, since earlier language + * does not allow structs with constructors in unions, and we need + * those. */ + +#define HB_NO_COPY_ASSIGN(TypeName) \ + TypeName(const TypeName&); \ + void operator=(const TypeName&) +#define HB_NO_COPY_ASSIGN_TEMPLATE2(TypeName, T1, T2) \ + TypeName(const TypeName&); \ + void operator=(const TypeName&) #define HB_NO_CREATE_COPY_ASSIGN(TypeName) \ TypeName(void); \ TypeName(const TypeName&); \ @@ -354,6 +364,8 @@ static_assert ((sizeof (hb_var_int_t) == 4), ""); #else /* __cpluspplus >= 201103L */ +#define HB_NO_COPY_ASSIGN(TypeName) +#define HB_NO_COPY_ASSIGN_TEMPLATE2(TypeName, T1, T2) #define HB_NO_CREATE_COPY_ASSIGN(TypeName) #define HB_NO_CREATE_COPY_ASSIGN_TEMPLATE(TypeName, T) #define HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2(TypeName, T1, T2) From 3a4e5dd425a2a37ff4c37db953943386c0b6e5d8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Oct 2018 18:05:25 -0700 Subject: [PATCH 168/255] Remove a few unnecessary hb_auto_t<>'s See a85641446c30247c4e948263f0f8c1147ed4efb9 --- src/hb-coretext.cc | 8 ++++---- src/hb-ot-cmap-table.hh | 6 ++---- src/hb-ot-layout-gsub-table.hh | 8 ++++---- src/hb-ot-layout-gsubgpos.hh | 2 +- src/hb-ot-layout.cc | 10 +++++----- src/hb-subset-plan.cc | 2 +- src/hb-subset.cc | 2 +- src/hb-uniscribe.cc | 12 ++++++------ 8 files changed, 24 insertions(+), 26 deletions(-) diff --git a/src/hb-coretext.cc b/src/hb-coretext.cc index 8b4f7e6a3..184db4944 100644 --- a/src/hb-coretext.cc +++ b/src/hb-coretext.cc @@ -474,8 +474,8 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, buffer->merge_clusters (i - 1, i + 1); } - hb_auto_t > feature_records; - hb_auto_t > range_records; + hb_vector_t feature_records; + hb_vector_t range_records; /* * Set up features. @@ -484,7 +484,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, if (num_features) { /* Sort features by start/end events. */ - hb_auto_t > feature_events; + hb_vector_t feature_events; for (unsigned int i = 0; i < num_features; i++) { const hb_aat_feature_mapping_t * mapping = hb_aat_layout_find_feature_mapping (features[i].tag); @@ -523,7 +523,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, } /* Scan events and save features for each range. */ - hb_auto_t > active_features; + hb_vector_t active_features; unsigned int last_index = 0; for (unsigned int i = 0; i < feature_events.len; i++) { diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index f0dbef69c..86f9d2ca5 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -859,10 +859,8 @@ struct cmap + CmapSubtableFormat12::get_sub_table_size (this->format12_groups); } - // Format 4 - hb_auto_t > format4_segments; - // Format 12 - hb_auto_t > format12_groups; + hb_vector_t format4_segments; + hb_vector_t format12_groups; }; inline bool sanitize (hb_sanitize_context_t *c) const diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 2ce52a1b4..10f4ca24a 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -110,8 +110,8 @@ struct SingleSubstFormat1 inline bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - hb_auto_t > from; - hb_auto_t > to; + hb_vector_t from; + hb_vector_t to; hb_codepoint_t delta = deltaGlyphID; for (hb_auto_t iter (this+coverage); iter.more (); iter.next ()) { @@ -216,8 +216,8 @@ struct SingleSubstFormat2 inline bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - hb_auto_t > from; - hb_auto_t > to; + hb_vector_t from; + hb_vector_t to; for (hb_auto_t iter (this+coverage); iter.more (); iter.next ()) { if (!c->plan->glyphset->has (iter.get_glyph ())) diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index a4066265c..09f642589 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -93,7 +93,7 @@ struct hb_closure_context_t : hb_face_t *face; hb_set_t *glyphs; - hb_auto_t out[1]; + hb_set_t out[1]; recurse_func_t recurse_func; unsigned int nesting_level_left; unsigned int debug_depth; diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 19f800401..ea59b8354 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -708,8 +708,8 @@ struct hb_collect_features_context_t hb_set_t *feature_indexes; private: - hb_auto_t visited_script; - hb_auto_t visited_langsys; + hb_set_t visited_script; + hb_set_t visited_langsys; }; static void @@ -836,7 +836,7 @@ hb_ot_layout_collect_lookups (hb_face_t *face, { const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); - hb_auto_t feature_indexes; + hb_set_t feature_indexes; hb_ot_layout_collect_features (face, table_tag, scripts, languages, features, &feature_indexes); for (hb_codepoint_t feature_index = HB_SET_VALUE_INVALID; @@ -974,7 +974,7 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t *face, unsigned int lookup_index, hb_set_t *glyphs) { - hb_auto_t done_lookups; + hb_map_t done_lookups; OT::hb_closure_context_t c (face, glyphs, &done_lookups); const OT::SubstLookup& l = _get_gsub (face).get_lookup (lookup_index); @@ -995,7 +995,7 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, const hb_set_t *lookups, hb_set_t *glyphs) { - hb_auto_t done_lookups; + hb_map_t done_lookups; OT::hb_closure_context_t c (face, glyphs, &done_lookups); const OT::GSUB& gsub = _get_gsub (face); diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index 057006039..64c8ad798 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -55,7 +55,7 @@ _add_gid_and_children (const OT::glyf::accelerator_t &glyf, static void _gsub_closure (hb_face_t *face, hb_set_t *gids_to_retain) { - hb_auto_t lookup_indices; + hb_set_t lookup_indices; hb_ot_layout_collect_lookups (face, HB_OT_TAG_GSUB, nullptr, diff --git a/src/hb-subset.cc b/src/hb-subset.cc index 294fd8460..ed61c628f 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -68,7 +68,7 @@ _subset2 (hb_subset_plan_t *plan) hb_bool_t result = false; if (source_blob->data) { - hb_auto_t > buf; + hb_vector_t buf; unsigned int buf_size = _plan_estimate_subset_table_size (plan, source_blob->length); DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG(tag), buf_size); if (unlikely (!buf.alloc (buf_size))) diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc index b12a0539d..26b99ed15 100644 --- a/src/hb-uniscribe.cc +++ b/src/hb-uniscribe.cc @@ -642,12 +642,12 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan, /* * Set up features. */ - hb_auto_t > feature_records; - hb_auto_t > range_records; + hb_vector_t feature_records; + hb_vector_t range_records; if (num_features) { /* Sort features by start/end events. */ - hb_auto_t > feature_events; + hb_vector_t feature_events; for (unsigned int i = 0; i < num_features; i++) { active_feature_t feature; @@ -682,7 +682,7 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan, } /* Scan events and save features for each range. */ - hb_auto_t > active_features; + hb_vector_t active_features; unsigned int last_index = 0; for (unsigned int i = 0; i < feature_events.len; i++) { @@ -854,8 +854,8 @@ retry: #undef MAX_ITEMS OPENTYPE_TAG language_tag = hb_uint32_swap (hb_ot_tag_from_language (buffer->props.language)); - hb_auto_t > range_properties; - hb_auto_t > range_char_counts; + hb_vector_t range_properties; + hb_vector_t range_char_counts; unsigned int glyphs_offset = 0; unsigned int glyphs_len; From ca5e5a4979fa4aca873ba986e60b3010aaf0b1de Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Oct 2018 22:30:21 -0700 Subject: [PATCH 169/255] Port Coverage::Iter off hb_auto_t<> --- src/hb-ot-layout-common.hh | 4 +--- src/hb-ot-layout-gpos-table.hh | 2 +- src/hb-ot-layout-gsub-table.hh | 26 +++++++++++++------------- src/hb-ot-layout-gsubgpos.hh | 8 ++++---- 4 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 11297a575..47731053d 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -1108,8 +1108,7 @@ struct Coverage struct Iter { - Iter (void) : format (0), u () {}; - inline void init (const Coverage &c_) + inline Iter (const Coverage &c_) { format = c_.u.format; switch (format) @@ -1119,7 +1118,6 @@ struct Coverage default: return; } } - inline void fini (void) {} inline bool more (void) { switch (format) diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index 8a6c0278f..399ede434 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -719,7 +719,7 @@ struct PairPosFormat1 inline bool intersects (const hb_set_t *glyphs) const { unsigned int count = pairSet.len; - for (hb_auto_t iter (this+coverage); iter.more (); iter.next ()) + for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { if (unlikely (iter.get_coverage () >= count)) break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 10f4ca24a..d24ea59af 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -48,7 +48,7 @@ struct SingleSubstFormat1 inline void closure (hb_closure_context_t *c) const { TRACE_CLOSURE (this); - for (hb_auto_t iter (this+coverage); iter.more (); iter.next ()) + for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { /* TODO Switch to range-based API to work around malicious fonts. * https://github.com/harfbuzz/harfbuzz/issues/363 */ @@ -62,7 +62,7 @@ struct SingleSubstFormat1 { TRACE_COLLECT_GLYPHS (this); if (unlikely (!(this+coverage).add_coverage (c->input))) return; - for (hb_auto_t iter (this+coverage); iter.more (); iter.next ()) + for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { /* TODO Switch to range-based API to work around malicious fonts. * https://github.com/harfbuzz/harfbuzz/issues/363 */ @@ -113,7 +113,7 @@ struct SingleSubstFormat1 hb_vector_t from; hb_vector_t to; hb_codepoint_t delta = deltaGlyphID; - for (hb_auto_t iter (this+coverage); iter.more (); iter.next ()) + for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { if (!c->plan->glyphset->has (iter.get_glyph ())) continue; @@ -157,7 +157,7 @@ struct SingleSubstFormat2 { TRACE_CLOSURE (this); unsigned int count = substitute.len; - for (hb_auto_t iter (this+coverage); iter.more (); iter.next ()) + for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { if (unlikely (iter.get_coverage () >= count)) break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ @@ -171,7 +171,7 @@ struct SingleSubstFormat2 TRACE_COLLECT_GLYPHS (this); if (unlikely (!(this+coverage).add_coverage (c->input))) return; unsigned int count = substitute.len; - for (hb_auto_t iter (this+coverage); iter.more (); iter.next ()) + for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { if (unlikely (iter.get_coverage () >= count)) break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ @@ -218,7 +218,7 @@ struct SingleSubstFormat2 TRACE_SUBSET (this); hb_vector_t from; hb_vector_t to; - for (hb_auto_t iter (this+coverage); iter.more (); iter.next ()) + for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { if (!c->plan->glyphset->has (iter.get_glyph ())) continue; @@ -395,7 +395,7 @@ struct MultipleSubstFormat1 { TRACE_CLOSURE (this); unsigned int count = sequence.len; - for (hb_auto_t iter (this+coverage); iter.more (); iter.next ()) + for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { if (unlikely (iter.get_coverage () >= count)) break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ @@ -585,7 +585,7 @@ struct AlternateSubstFormat1 { TRACE_CLOSURE (this); unsigned int count = alternateSet.len; - for (hb_auto_t iter (this+coverage); iter.more (); iter.next ()) + for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { if (unlikely (iter.get_coverage () >= count)) break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ @@ -599,7 +599,7 @@ struct AlternateSubstFormat1 TRACE_COLLECT_GLYPHS (this); if (unlikely (!(this+coverage).add_coverage (c->input))) return; unsigned int count = alternateSet.len; - for (hb_auto_t iter (this+coverage); iter.more (); iter.next ()) + for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { if (unlikely (iter.get_coverage () >= count)) break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ @@ -906,7 +906,7 @@ struct LigatureSubstFormat1 inline bool intersects (const hb_set_t *glyphs) const { unsigned int count = ligatureSet.len; - for (hb_auto_t iter (this+coverage); iter.more (); iter.next ()) + for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { if (unlikely (iter.get_coverage () >= count)) break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ @@ -921,7 +921,7 @@ struct LigatureSubstFormat1 { TRACE_CLOSURE (this); unsigned int count = ligatureSet.len; - for (hb_auto_t iter (this+coverage); iter.more (); iter.next ()) + for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { if (unlikely (iter.get_coverage () >= count)) break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ @@ -935,7 +935,7 @@ struct LigatureSubstFormat1 TRACE_COLLECT_GLYPHS (this); if (unlikely (!(this+coverage).add_coverage (c->input))) return; unsigned int count = ligatureSet.len; - for (hb_auto_t iter (this+coverage); iter.more (); iter.next ()) + for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { if (unlikely (iter.get_coverage () >= count)) break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ @@ -1114,7 +1114,7 @@ struct ReverseChainSingleSubstFormat1 const ArrayOf &substitute = StructAfter > (lookahead); count = substitute.len; - for (hb_auto_t iter (this+coverage); iter.more (); iter.next ()) + for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { if (unlikely (iter.get_coverage () >= count)) break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 09f642589..03fdac2a9 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -1441,7 +1441,7 @@ struct ContextFormat1 }; unsigned int count = ruleSet.len; - for (hb_auto_t iter (this+coverage); iter.more (); iter.next ()) + for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { if (unlikely (iter.get_coverage () >= count)) break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ @@ -1462,7 +1462,7 @@ struct ContextFormat1 }; unsigned int count = ruleSet.len; - for (hb_auto_t iter (this+coverage); iter.more (); iter.next ()) + for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { if (unlikely (iter.get_coverage () >= count)) break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ @@ -2105,7 +2105,7 @@ struct ChainContextFormat1 }; unsigned int count = ruleSet.len; - for (hb_auto_t iter (this+coverage); iter.more (); iter.next ()) + for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { if (unlikely (iter.get_coverage () >= count)) break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ @@ -2126,7 +2126,7 @@ struct ChainContextFormat1 }; unsigned int count = ruleSet.len; - for (hb_auto_t iter (this+coverage); iter.more (); iter.next ()) + for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { if (unlikely (iter.get_coverage () >= count)) break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ From 56e0fd345c4e68753123a05cd80291e933d71061 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Oct 2018 22:35:44 -0700 Subject: [PATCH 170/255] Remove last use of hb_auto_t<> --- src/hb-ot-cmap-table.hh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 86f9d2ca5..a1c5a9747 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -228,6 +228,10 @@ struct CmapSubtableFormat4 struct accelerator_t { + inline accelerator_t (void) {} + inline accelerator_t (const CmapSubtableFormat4 *subtable) { init (subtable); } + inline ~accelerator_t (void) { fini (); } + inline void init (const CmapSubtableFormat4 *subtable) { segCount = subtable->segCountX2 / 2; @@ -327,12 +331,12 @@ struct CmapSubtableFormat4 inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const { - hb_auto_t accel (this); + accelerator_t accel (this); return accel.get_glyph_func (&accel, codepoint, glyph); } inline void collect_unicodes (hb_set_t *out) const { - hb_auto_t accel (this); + accelerator_t accel (this); accel.collect_unicodes (out); } From 166ae8b0aa3b1e7298a1bbb872647cb352a0f924 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Oct 2018 22:40:37 -0700 Subject: [PATCH 171/255] Remove now unused hb_auto_t<> --- src/hb-dsalgs.hh | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index 837bb86bf..e8bd95c27 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -511,26 +511,6 @@ hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *o } -template -struct hb_auto_t : Type -{ - hb_auto_t (void) { Type::init (); } - /* Explicitly allow the following only for pointer and references, - * to avoid any accidental copies. - * - * Apparently if we template for all types, then gcc seems to - * capture a reference argument in the type, but clang doesn't, - * causing unwanted copies and bugs that come with it. Ideally - * we should use C++11-style rvalue reference &&t1. */ - template explicit hb_auto_t (T1 *t1) { Type::init (t1); } - template explicit hb_auto_t (T1 &t1) { Type::init (t1); } - ~hb_auto_t (void) { Type::fini (); } - private: /* Hide */ - void init (void) {} - void fini (void) {} -}; - - struct hb_bytes_t { inline hb_bytes_t (void) : arrayZ (nullptr), len (0) {} From 4ef671f25f38895e3f87cd69687670c3d8ea4600 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Oct 2018 22:46:19 -0700 Subject: [PATCH 172/255] [unicode] Fix a long-standing double-declaration warning --- src/hb-unicode.cc | 31 +++++++------------------------ 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc index cba18ab6a..8cf7898a1 100644 --- a/src/hb-unicode.cc +++ b/src/hb-unicode.cc @@ -123,40 +123,23 @@ hb_unicode_decompose_compatibility_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED } -#define HB_UNICODE_FUNCS_IMPLEMENT_SET \ - HB_UNICODE_FUNCS_IMPLEMENT (glib) \ - HB_UNICODE_FUNCS_IMPLEMENT (icu) \ - HB_UNICODE_FUNCS_IMPLEMENT (ucdn) \ - HB_UNICODE_FUNCS_IMPLEMENT (nil) \ - /* ^--- Add new callbacks before nil */ - -#define hb_nil_get_unicode_funcs hb_unicode_funcs_get_empty - -/* Prototype them all */ -#define HB_UNICODE_FUNCS_IMPLEMENT(set) \ -extern "C" hb_unicode_funcs_t *hb_##set##_get_unicode_funcs (void); -HB_UNICODE_FUNCS_IMPLEMENT_SET -#undef HB_UNICODE_FUNCS_IMPLEMENT - +extern "C" hb_unicode_funcs_t *hb_glib_get_unicode_funcs (void); +extern "C" hb_unicode_funcs_t *hb_icu_get_unicode_funcs (void); +extern "C" hb_unicode_funcs_t *hb_ucdn_get_unicode_funcs (void); hb_unicode_funcs_t * hb_unicode_funcs_get_default (void) { -#define HB_UNICODE_FUNCS_IMPLEMENT(set) \ - return hb_##set##_get_unicode_funcs (); - #if defined(HAVE_UCDN) - HB_UNICODE_FUNCS_IMPLEMENT(ucdn) + return hb_ucdn_get_unicode_funcs (); #elif defined(HAVE_GLIB) - HB_UNICODE_FUNCS_IMPLEMENT(glib) + return hb_glib_get_unicode_funcs (); #elif defined(HAVE_ICU) && defined(HAVE_ICU_BUILTIN) - HB_UNICODE_FUNCS_IMPLEMENT(icu) + return hb_icu_get_unicode_funcs (); #else #define HB_UNICODE_FUNCS_NIL 1 - HB_UNICODE_FUNCS_IMPLEMENT(nil) + return hb_unicode_funcs_get_empty (); #endif - -#undef HB_UNICODE_FUNCS_IMPLEMENT } #if !defined(HB_NO_UNICODE_FUNCS) && defined(HB_UNICODE_FUNCS_NIL) From ad3cededdd5ee6a364161e9d27e4cf4d95a80177 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Oct 2018 22:53:16 -0700 Subject: [PATCH 173/255] [fuzzing] Make test runners less verbose --- test/fuzzing/run-shape-fuzzer-tests.py | 3 ++- test/fuzzing/run-subset-fuzzer-tests.py | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/fuzzing/run-shape-fuzzer-tests.py b/test/fuzzing/run-shape-fuzzer-tests.py index 53c4f501a..e3d180f2b 100755 --- a/test/fuzzing/run-shape-fuzzer-tests.py +++ b/test/fuzzing/run-shape-fuzzer-tests.py @@ -76,7 +76,8 @@ for file in os.listdir (parent_path): path = os.path.join(parent_path, file) text, returncode = cmd ([hb_shape_fuzzer, path]) - print (text) + if text.strip (): + print (text) failed = False if returncode != 0 or 'error' in text: diff --git a/test/fuzzing/run-subset-fuzzer-tests.py b/test/fuzzing/run-subset-fuzzer-tests.py index d4e3487f0..7392a92ec 100755 --- a/test/fuzzing/run-subset-fuzzer-tests.py +++ b/test/fuzzing/run-subset-fuzzer-tests.py @@ -22,7 +22,6 @@ fails = 0 def run_dir (parent_path): global fails - print ("running subset fuzzer against fonts in %s" % parent_path) for file in os.listdir (parent_path): path = os.path.join(parent_path, file) From b186274362725b7501211c2a782c1a0badd57107 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Oct 2018 23:21:14 -0700 Subject: [PATCH 174/255] [set/map] Fix uninitialized memory I keep forgetting that primitive types are NOT initialized during construction. :| --- src/hb-map.hh | 4 ++-- src/hb-object.hh | 1 + src/hb-set.hh | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/hb-map.hh b/src/hb-map.hh index e5ca3f515..c54c9d7b6 100644 --- a/src/hb-map.hh +++ b/src/hb-map.hh @@ -45,8 +45,8 @@ inline uint32_t Hash (const T &v) struct hb_map_t { HB_NO_COPY_ASSIGN (hb_map_t); - inline hb_map_t (void) { init_shallow (); } - inline ~hb_map_t (void) { fini_shallow (); } + inline hb_map_t (void) { init (); } + inline ~hb_map_t (void) { fini (); } struct item_t { diff --git a/src/hb-object.hh b/src/hb-object.hh index d347b5ffa..106f59206 100644 --- a/src/hb-object.hh +++ b/src/hb-object.hh @@ -272,6 +272,7 @@ static inline void hb_object_fini (Type *obj) { user_data->fini (); free (user_data); + user_data = nullptr; } } template diff --git a/src/hb-set.hh b/src/hb-set.hh index 97ff291eb..0755498ba 100644 --- a/src/hb-set.hh +++ b/src/hb-set.hh @@ -40,8 +40,8 @@ struct hb_set_t { HB_NO_COPY_ASSIGN (hb_set_t); - inline hb_set_t (void) { init_shallow (); } - inline ~hb_set_t (void) { fini_shallow (); } + inline hb_set_t (void) { init (); } + inline ~hb_set_t (void) { fini (); } struct page_map_t { From 1b7bfb5e1864fc355715b536faac6693b5ce0218 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Tue, 30 Oct 2018 10:19:40 +0330 Subject: [PATCH 175/255] [cmake] Make build of tests and subset optional (#1329) --- .circleci/config.yml | 2 +- CMakeLists.txt | 19 ++++++------------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 46fb65b2e..8ed1c3940 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -37,7 +37,7 @@ jobs: # not needed to be a framework but we like to test that also # TODO: wrong way of targeting iOS as it doesn't point to iOS headers thus building # CoreText support is not possible, after the fix feel free HB_IOS from CMake altogether - - run: cmake -DBUILD_FRAMEWORK=ON -H. -Bbuild -GXcode -DHB_IOS=ON + - run: cmake -DBUILD_FRAMEWORK=ON -H. -Bbuild -GXcode -DHB_HAVE_CORETEXT=OFF -DHB_BUILD_SUBSET=OFF -DHB_BUILD_TESTS=OFF - run: cd build && xcodebuild -sdk iphoneos12.0 -configuration Release build -arch arm64 distcheck: diff --git a/CMakeLists.txt b/CMakeLists.txt index 4eb23af4d..019e205bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,6 +52,9 @@ if (HB_BUILD_UTILS) set (HB_HAVE_FREETYPE ON) endif () +option(HB_BUILD_SUBSET "Build harfbuzz-subset" ON) +option(HB_BUILD_TESTS "Build harfbuzz tests" ON) + option(HB_HAVE_GOBJECT "Enable GObject Bindings" OFF) if (HB_HAVE_GOBJECT) set (HB_HAVE_GLIB ON) @@ -82,16 +85,6 @@ if (HB_CHECK) endif () endif () -set (HB_DISABLE_SUBSET OFF) -set (HB_DISABLE_TESTS OFF) -option(HB_IOS "Apply iOS specific build flags" OFF) -if (HB_IOS) - # We should fix their issue and enable them - set (HB_DISABLE_SUBSET ON) - set (HB_DISABLE_TESTS ON) - set (HB_HAVE_CORETEXT OFF) -endif () - include_directories(AFTER ${PROJECT_SOURCE_DIR}/src ${PROJECT_BINARY_DIR}/src @@ -556,7 +549,7 @@ add_library(harfbuzz ${project_sources} ${project_extra_sources} ${project_heade target_link_libraries(harfbuzz ${THIRD_PARTY_LIBS}) ## Define harfbuzz-subset library -if (NOT HB_DISABLE_SUBSET) +if (HB_BUILD_SUBSET) add_library(harfbuzz-subset ${subset_project_sources} ${subset_project_headers}) add_dependencies(harfbuzz-subset harfbuzz) target_link_libraries(harfbuzz-subset harfbuzz ${THIRD_PARTY_LIBS}) @@ -580,7 +573,7 @@ if (UNIX OR MINGW) set (CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "m") # libm set (CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "") set_target_properties(harfbuzz PROPERTIES LINKER_LANGUAGE C) - if (NOT HB_DISABLE_SUBSET) + if (HB_BUILD_SUBSET) set_target_properties(harfbuzz-subset PROPERTIES LINKER_LANGUAGE C) endif () @@ -861,7 +854,7 @@ if (UNIX AND CMAKE_GENERATOR STREQUAL "Ninja") endif () -if (NOT HB_DISABLE_TESTS) +if (HB_BUILD_TESTS) ## src/ executables foreach (prog main test test-would-substitute test-size-params test-buffer-serialize hb-ot-tag test-unicode-ranges) set (prog_name ${prog}) From 7e998d193a1429b42bb69582f9e5738aa6fd1a72 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 29 Oct 2018 23:31:42 -0700 Subject: [PATCH 176/255] Fix spurious warning re uninitialized use --- src/hb-ot-layout-common.hh | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 47731053d..3505b9cdf 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -1110,6 +1110,7 @@ struct Coverage { inline Iter (const Coverage &c_) { + memset (this, 0, sizeof (*this)); format = c_.u.format; switch (format) { From 6131fb6283cff87333db14b9b32e92be6139c3d6 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 30 Oct 2018 00:38:01 -0700 Subject: [PATCH 177/255] [util] Don't close stdin/stdout --- util/options.cc | 6 ++++++ util/options.hh | 8 ++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/util/options.cc b/util/options.cc index 5661cd059..4815770f5 100644 --- a/util/options.cc +++ b/util/options.cc @@ -758,7 +758,10 @@ text_options_t::get_line (unsigned int *len) fail (true, "At least one of text or text-file must be set"); if (0 != strcmp (text_file, "-")) + { fp = fopen (text_file, "r"); + close_fp = true; + } else fp = stdin; @@ -795,7 +798,10 @@ output_options_t::get_file_handle (void) return fp; if (output_file) + { fp = fopen (output_file, "wb"); + close_fp = true; + } else { #if defined(_WIN32) || defined(__CYGWIN__) setmode (fileno (stdout), O_BINARY); diff --git a/util/options.hh b/util/options.hh index dd628590e..6f35ea3f4 100644 --- a/util/options.hh +++ b/util/options.hh @@ -510,6 +510,7 @@ struct text_options_t : option_group_t text_file = nullptr; fp = nullptr; + close_fp = false; gs = nullptr; line = nullptr; line_len = (unsigned int) -1; @@ -524,7 +525,7 @@ struct text_options_t : option_group_t g_free (text_file); if (gs) g_string_free (gs, true); - if (fp) + if (close_fp) fclose (fp); } @@ -547,6 +548,7 @@ struct text_options_t : option_group_t private: FILE *fp; + bool close_fp; GString *gs; char *line; unsigned int line_len; @@ -563,6 +565,7 @@ struct output_options_t : option_group_t explicit_output_format = false; fp = nullptr; + close_fp = false; add_options (parser); } @@ -570,7 +573,7 @@ struct output_options_t : option_group_t { g_free (output_file); g_free (output_format); - if (fp) + if (close_fp) fclose (fp); } @@ -602,6 +605,7 @@ struct output_options_t : option_group_t bool explicit_output_format; mutable FILE *fp; + bool close_fp; }; struct format_options_t : option_group_t From 58e20f53bf61244e3eef09be8ebed60aaf52fb11 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 30 Oct 2018 00:50:18 -0700 Subject: [PATCH 178/255] [util] Add hb-shape --batch --- util/hb-shape.cc | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/util/hb-shape.cc b/util/hb-shape.cc index 337cd4319..6c727d019 100644 --- a/util/hb-shape.cc +++ b/util/hb-shape.cc @@ -160,6 +160,36 @@ struct output_buffer_t int main (int argc, char **argv) { + if (argc == 2 && !strcmp (argv[1], "--batch")) + { + unsigned int ret = 0; + char *buf = nullptr; + size_t len; + while (getline (&buf, &len, stdin) > 0) + { + size_t l = strlen (buf); + if (l && buf[l - 1] == '\n') buf[l - 1] = '\0'; + main_font_text_t, FONT_SIZE_UPEM, 0> driver; + char *args[32]; + argc = 0; + char *p = buf, *e; + args[argc++] = p; + while ((e = strchr (p, ' ')) && argc < (int) (int) ARRAY_LENGTH (args)) + { + *e++ = '\0'; + while (*e == ' ') + e++; + args[argc++] = p = e; + } + ret |= driver.main (argc, args); + fflush (stdout); + + if (ret) + break; + } + free (buf); + return ret; + } main_font_text_t, FONT_SIZE_UPEM, 0> driver; return driver.main (argc, argv); } From 422debb830fe150c26e1628f77531f41f0871325 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 30 Oct 2018 00:51:43 -0700 Subject: [PATCH 179/255] [test/shaping] Spawn one hb-shape per test file Speeds up runnings in-house tests from over 20s to 2s. --- test/shaping/run-tests.py | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/test/shaping/run-tests.py b/test/shaping/run-tests.py index f77a17c3d..99c0a59f0 100755 --- a/test/shaping/run-tests.py +++ b/test/shaping/run-tests.py @@ -2,16 +2,13 @@ from __future__ import print_function, division, absolute_import -import sys, os, subprocess, tempfile - +import sys, os, subprocess def cmd(command): - # https://stackoverflow.com/a/4408409 - with tempfile.TemporaryFile() as tempf: - p = subprocess.Popen (command, stdout=tempf, stderr=sys.stdout) - p.wait () - tempf.seek(0) - return tempf.read().decode ("utf-8").strip (), p.returncode + global process + process.stdin.write (' '.join (command) + '\n') + process.stdin.flush () + return process.stdout.readline().decode ("utf-8").strip () args = sys.argv[1:] if not args or sys.argv[1].find('hb-shape') == -1 or not os.path.exists (sys.argv[1]): @@ -19,6 +16,11 @@ if not args or sys.argv[1].find('hb-shape') == -1 or not os.path.exists (sys.arg sys.exit (1) hb_shape, args = args[0], args[1:] +process = subprocess.Popen ([hb_shape, '--batch'], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=sys.stdout) + fails = 0 reference = False @@ -60,24 +62,14 @@ for filename in args: print ("%s %s %s %s --unicodes %s" % (hb_shape, fontfile, ' '.join(extra_options), options, unicodes)) - glyphs1, returncode = cmd ([hb_shape, "--font-funcs=ft", + glyphs1 = cmd ([hb_shape, "--font-funcs=ft", fontfile] + extra_options + ["--unicodes", unicodes] + (options.split (' ') if options else [])) - if returncode: - print ("ERROR: hb-shape --font-funcs=ft failed.") # file=sys.stderr - fails = fails + 1 - #continue - - glyphs2, returncode = cmd ([hb_shape, "--font-funcs=ot", + glyphs2 = cmd ([hb_shape, "--font-funcs=ot", fontfile] + extra_options + ["--unicodes", unicodes] + (options.split (' ') if options else [])) - if returncode: - print ("ERROR: hb-shape --font-funcs=ot failed.") # file=sys.stderr - fails = fails + 1 - #continue - if glyphs1 != glyphs2 and glyphs_expected != '*': print ("FT funcs: " + glyphs1) # file=sys.stderr print ("OT funcs: " + glyphs2) # file=sys.stderr From f7a08cd41df1ff3e44aa838306218ae0565b7273 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Tue, 30 Oct 2018 11:29:09 +0330 Subject: [PATCH 180/255] Fix extra semicolon issues and test that on CI (#1330) --- .circleci/config.yml | 2 +- src/hb-machinery.hh | 16 ++++++++-------- src/hb-ot-layout-common.hh | 6 +++--- src/hb-ot-layout-gsubgpos.hh | 2 +- src/hb.hh | 2 +- util/options.hh | 2 +- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8ed1c3940..90c094059 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -120,7 +120,7 @@ jobs: - run: apt update || true - run: apt install -y clang lld binutils libtool autoconf automake make pkg-config gtk-doc-tools ragel libfreetype6-dev libfontconfig1-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python python-pip - run: pip install fonttools - - run: CFLAGS="-Weverything -Wno-reserved-id-macro -Wno-conversion -Wno-padded -Wno-sign-conversion -Wno-cast-qual -Wno-documentation -Wno-documentation-unknown-command" CXXFLAGS="-Weverything -Wno-old-style-cast -Wno-documentation -Wno-documentation-unknown-command -Wno-c++98-compat -Wno-cast-qual -Wno-c++98-compat-pedantic -Wno-sign-conversion -Wno-padded -Wno-shorten-64-to-32 -Wno-extra-semi -Wno-reserved-id-macro -Wno-float-conversion -Wno-format-pedantic -Wno-shadow -Wno-conversion -Wno-zero-as-null-pointer-constant -Wno-missing-field-initializers -Wno-used-but-marked-unused -Wno-unused-macros -Wno-comma -Wno-float-equal -Wno-disabled-macro-expansion -Wno-weak-vtables -Wno-unused-parameter -Wno-covered-switch-default -Wno-unreachable-code" CC=clang CXX=clang++ ./autogen.sh --with-freetype --with-glib --with-cairo --with-icu --with-graphite2 --with-fontconfig + - run: CFLAGS="-Weverything -Wno-reserved-id-macro -Wno-conversion -Wno-padded -Wno-sign-conversion -Wno-cast-qual -Wno-documentation -Wno-documentation-unknown-command" CXXFLAGS="-Weverything -Wno-old-style-cast -Wno-documentation -Wno-documentation-unknown-command -Wno-c++98-compat -Wno-cast-qual -Wno-c++98-compat-pedantic -Wno-sign-conversion -Wno-padded -Wno-shorten-64-to-32 -Wno-reserved-id-macro -Wno-float-conversion -Wno-format-pedantic -Wno-shadow -Wno-conversion -Wno-zero-as-null-pointer-constant -Wno-missing-field-initializers -Wno-used-but-marked-unused -Wno-unused-macros -Wno-comma -Wno-float-equal -Wno-disabled-macro-expansion -Wno-weak-vtables -Wno-unused-parameter -Wno-covered-switch-default -Wno-unreachable-code" CC=clang CXX=clang++ ./autogen.sh --with-freetype --with-glib --with-cairo --with-icu --with-graphite2 --with-fontconfig - run: make -j32 CPPFLAGS="-Werror" - run: make check CPPFLAGS="-Werror" || .ci/fail.sh diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index 0ff3a7681..9e50bc028 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -95,30 +95,30 @@ static inline Type& StructAfter(TObject &X) #define DEFINE_SIZE_STATIC(size) \ - DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size)); \ + DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size)) \ + inline unsigned int get_size (void) const { return (size); } \ enum { static_size = (size) }; \ - enum { min_size = (size) }; \ - inline unsigned int get_size (void) const { return (size); } + enum { min_size = (size) } #define DEFINE_SIZE_UNION(size, _member) \ - DEFINE_INSTANCE_ASSERTION (0*sizeof(this->u._member.static_size) + sizeof(this->u._member) == (size)); \ + DEFINE_INSTANCE_ASSERTION (0*sizeof(this->u._member.static_size) + sizeof(this->u._member) == (size)) \ static const unsigned int min_size = (size) #define DEFINE_SIZE_MIN(size) \ - DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)); \ + DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)) \ static const unsigned int min_size = (size) #define DEFINE_SIZE_ARRAY(size, array) \ - DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + VAR * sizeof (array[0])); \ + DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + VAR * sizeof (array[0])) \ DEFINE_COMPILES_ASSERTION ((void) array[0].static_size) \ - enum { min_size = (size) } \ + enum { min_size = (size) } #define DEFINE_SIZE_ARRAY_SIZED(size, array) \ inline unsigned int get_size (void) const { return (size - array.min_size + array.get_size ()); } \ DEFINE_SIZE_ARRAY(size, array) #define DEFINE_SIZE_ARRAY2(size, array1, array2) \ - DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (this->array1[0]) + sizeof (this->array2[0])); \ + DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (this->array1[0]) + sizeof (this->array2[0])) \ DEFINE_COMPILES_ASSERTION ((void) array1[0].static_size; (void) array2[0].static_size) \ static const unsigned int min_size = (size) diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 3505b9cdf..7663bd3d7 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -860,8 +860,8 @@ struct CoverageFormat1 public: /* Older compilers need this to be public. */ struct Iter { - inline void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; }; - inline void fini (void) {}; + inline void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; } + inline void fini (void) {} inline bool more (void) { return i < c->glyphArray.len; } inline void next (void) { i++; } inline hb_codepoint_t get_glyph (void) { return c->glyphArray[i]; } @@ -988,7 +988,7 @@ struct CoverageFormat2 i = c->rangeRecord.len; } } - inline void fini (void) {}; + inline void fini (void) {} inline bool more (void) { return i < c->rangeRecord.len; } inline void next (void) { diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 03fdac2a9..c4af42048 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -271,7 +271,7 @@ struct hb_ot_apply_context_t : syllable arg1(0), #undef arg1 match_func (nullptr), - match_data (nullptr) {}; + match_data (nullptr) {} typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data); diff --git a/src/hb.hh b/src/hb.hh index 6f5d6aab2..fa6a7404d 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -360,7 +360,7 @@ static_assert ((sizeof (hb_var_int_t) == 4), ""); #define HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2(TypeName, T1, T2) \ TypeName(void); \ TypeName(const TypeName&); \ - void operator=(const TypeName&); + void operator=(const TypeName&) #else /* __cpluspplus >= 201103L */ diff --git a/util/options.hh b/util/options.hh index 6f35ea3f4..36f680f0a 100644 --- a/util/options.hh +++ b/util/options.hh @@ -536,7 +536,7 @@ struct text_options_t : option_group_t g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Only one of text and text-file can be set"); - }; + } const char *get_line (unsigned int *len); From 64e41d2c89c533f554e49ffbd18e6653a70ab999 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 30 Oct 2018 01:08:34 -0700 Subject: [PATCH 181/255] [test] Fix Python3 --- test/shaping/run-tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/shaping/run-tests.py b/test/shaping/run-tests.py index 99c0a59f0..65e0e1490 100755 --- a/test/shaping/run-tests.py +++ b/test/shaping/run-tests.py @@ -6,7 +6,7 @@ import sys, os, subprocess def cmd(command): global process - process.stdin.write (' '.join (command) + '\n') + process.stdin.write ((' '.join (command) + '\n').encode ("utf-8")) process.stdin.flush () return process.stdout.readline().decode ("utf-8").strip () From 83a612739accf6b0f2e1cb1be15097402f7ecf33 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 30 Oct 2018 01:24:23 -0700 Subject: [PATCH 182/255] [util] Minor --- util/options.cc | 6 ------ util/options.hh | 8 ++------ 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/util/options.cc b/util/options.cc index 4815770f5..5661cd059 100644 --- a/util/options.cc +++ b/util/options.cc @@ -758,10 +758,7 @@ text_options_t::get_line (unsigned int *len) fail (true, "At least one of text or text-file must be set"); if (0 != strcmp (text_file, "-")) - { fp = fopen (text_file, "r"); - close_fp = true; - } else fp = stdin; @@ -798,10 +795,7 @@ output_options_t::get_file_handle (void) return fp; if (output_file) - { fp = fopen (output_file, "wb"); - close_fp = true; - } else { #if defined(_WIN32) || defined(__CYGWIN__) setmode (fileno (stdout), O_BINARY); diff --git a/util/options.hh b/util/options.hh index 36f680f0a..6d57d7d61 100644 --- a/util/options.hh +++ b/util/options.hh @@ -510,7 +510,6 @@ struct text_options_t : option_group_t text_file = nullptr; fp = nullptr; - close_fp = false; gs = nullptr; line = nullptr; line_len = (unsigned int) -1; @@ -525,7 +524,7 @@ struct text_options_t : option_group_t g_free (text_file); if (gs) g_string_free (gs, true); - if (close_fp) + if (fp && fp != stdin) fclose (fp); } @@ -548,7 +547,6 @@ struct text_options_t : option_group_t private: FILE *fp; - bool close_fp; GString *gs; char *line; unsigned int line_len; @@ -565,7 +563,6 @@ struct output_options_t : option_group_t explicit_output_format = false; fp = nullptr; - close_fp = false; add_options (parser); } @@ -573,7 +570,7 @@ struct output_options_t : option_group_t { g_free (output_file); g_free (output_format); - if (close_fp) + if (fp && fp != stdout) fclose (fp); } @@ -605,7 +602,6 @@ struct output_options_t : option_group_t bool explicit_output_format; mutable FILE *fp; - bool close_fp; }; struct format_options_t : option_group_t From 138f9e0f25752bbf7f8e867f230ca91442f40028 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 30 Oct 2018 01:31:13 -0700 Subject: [PATCH 183/255] Minor --- src/hb-machinery.hh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index 9e50bc028..465bbb14f 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -82,7 +82,8 @@ static inline Type& StructAfter(TObject &X) /* Check _assertion in a method environment */ #define _DEFINE_INSTANCE_ASSERTION1(_line, _assertion) \ inline void _instance_assertion_on_line_##_line (void) const \ - { static_assert ((_assertion), ""); } + { static_assert ((_assertion), ""); } \ + static_assert (true, "") /* So we require semicolon here. */ # define _DEFINE_INSTANCE_ASSERTION0(_line, _assertion) _DEFINE_INSTANCE_ASSERTION1 (_line, _assertion) # define DEFINE_INSTANCE_ASSERTION(_assertion) _DEFINE_INSTANCE_ASSERTION0 (__LINE__, _assertion) @@ -95,21 +96,21 @@ static inline Type& StructAfter(TObject &X) #define DEFINE_SIZE_STATIC(size) \ - DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size)) \ + DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size)); \ inline unsigned int get_size (void) const { return (size); } \ enum { static_size = (size) }; \ enum { min_size = (size) } #define DEFINE_SIZE_UNION(size, _member) \ - DEFINE_INSTANCE_ASSERTION (0*sizeof(this->u._member.static_size) + sizeof(this->u._member) == (size)) \ + DEFINE_INSTANCE_ASSERTION (0*sizeof(this->u._member.static_size) + sizeof(this->u._member) == (size)); \ static const unsigned int min_size = (size) #define DEFINE_SIZE_MIN(size) \ - DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)) \ + DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)); \ static const unsigned int min_size = (size) #define DEFINE_SIZE_ARRAY(size, array) \ - DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + VAR * sizeof (array[0])) \ + DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + VAR * sizeof (array[0])); \ DEFINE_COMPILES_ASSERTION ((void) array[0].static_size) \ enum { min_size = (size) } @@ -118,7 +119,7 @@ static inline Type& StructAfter(TObject &X) DEFINE_SIZE_ARRAY(size, array) #define DEFINE_SIZE_ARRAY2(size, array1, array2) \ - DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (this->array1[0]) + sizeof (this->array2[0])) \ + DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (this->array1[0]) + sizeof (this->array2[0])); \ DEFINE_COMPILES_ASSERTION ((void) array1[0].static_size; (void) array2[0].static_size) \ static const unsigned int min_size = (size) From 56738429d667f6c35e5c7af30b51604fc133c23c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 30 Oct 2018 01:33:22 -0700 Subject: [PATCH 184/255] [test] Fix warnings --- test/api/test-ot-tag.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/api/test-ot-tag.c b/test/api/test-ot-tag.c index f89c25deb..c0329bffc 100644 --- a/test/api/test-ot-tag.c +++ b/test/api/test-ot-tag.c @@ -60,7 +60,7 @@ test_script_tags_from_language (const char *s, const char *lang_s, hb_script_t s { hb_script_t tag; unsigned int count = 1; - hb_script_t t; + hb_tag_t t; g_test_message ("Testing script %c%c%c%c: script tag %s, language tag %s", HB_UNTAG (hb_script_to_iso15924_tag (script)), s, lang_s); tag = hb_tag_from_string (s, -1); @@ -78,7 +78,7 @@ static void test_indic_tags (const char *s1, const char *s2, const char *s3, hb_script_t script) { hb_script_t tag1, tag2, tag3; - hb_script_t t[3]; + hb_tag_t t[3]; unsigned int count = 3; g_test_message ("Testing script %c%c%c%c: USE tag %s, new tag %s, old tag %s", HB_UNTAG (hb_script_to_iso15924_tag (script)), s1, s2, s3); @@ -103,7 +103,7 @@ test_indic_tags (const char *s1, const char *s2, const char *s3, hb_script_t scr static void test_ot_tag_script_degenerate (void) { - hb_script_t t[2]; + hb_tag_t t[2]; unsigned int count = 2; g_assert_cmphex (HB_TAG_CHAR4 ("DFLT"), ==, HB_OT_TAG_DEFAULT_SCRIPT); From edaa768253cfeb97d614537253f90d47aa93ff6f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 30 Oct 2018 01:35:58 -0700 Subject: [PATCH 185/255] [util] Use fgets instead of getline such that windows passes --- util/hb-shape.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/util/hb-shape.cc b/util/hb-shape.cc index 6c727d019..1a671230d 100644 --- a/util/hb-shape.cc +++ b/util/hb-shape.cc @@ -163,9 +163,8 @@ main (int argc, char **argv) if (argc == 2 && !strcmp (argv[1], "--batch")) { unsigned int ret = 0; - char *buf = nullptr; - size_t len; - while (getline (&buf, &len, stdin) > 0) + char buf[4092]; + while (fgets (buf, sizeof (buf), stdin)) { size_t l = strlen (buf); if (l && buf[l - 1] == '\n') buf[l - 1] = '\0'; @@ -187,7 +186,6 @@ main (int argc, char **argv) if (ret) break; } - free (buf); return ret; } main_font_text_t, FONT_SIZE_UPEM, 0> driver; From 0af3d176a64c0a57c7acb2a64ce8b9d08f449241 Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Tue, 30 Oct 2018 17:05:28 +0200 Subject: [PATCH 186/255] [sbix] Fix memory leak in early return Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11210 --- src/hb-ot-color-sbix-table.hh | 3 +++ ...ase-minimized-hb-shape-fuzzer-5768601332613120 | Bin 0 -> 108 bytes 2 files changed, 3 insertions(+) create mode 100644 test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5768601332613120 diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 39f85129a..4feb4e193 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -244,7 +244,10 @@ struct sbix hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset, &strike_ppem); if (unlikely (blob->length < sizeof (PNGHeader))) + { + hb_blob_destroy (blob); return false; + } const PNGHeader &png = *blob->as(); diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5768601332613120 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5768601332613120 new file mode 100644 index 0000000000000000000000000000000000000000..385e67079dd04d4dd898f761061449d9a53a5a48 GIT binary patch literal 108 zcmZQzWME)mQvieFq|6E+4 Date: Fri, 28 Sep 2018 16:07:37 -0500 Subject: [PATCH 187/255] Docs: update Usermanual-What Is HarfBuzz. --- docs/usermanual-what-is-harfbuzz.xml | 199 +++++++++++++++++---------- 1 file changed, 130 insertions(+), 69 deletions(-) diff --git a/docs/usermanual-what-is-harfbuzz.xml b/docs/usermanual-what-is-harfbuzz.xml index 38f40cf11..8ec7b4030 100644 --- a/docs/usermanual-what-is-harfbuzz.xml +++ b/docs/usermanual-what-is-harfbuzz.xml @@ -1,115 +1,176 @@ What is HarfBuzz? - HarfBuzz is a text shaping engine. It solves - the problem of selecting and positioning glyphs from a font given a - Unicode string. + HarfBuzz is a text shaping engine. If you + give HarfBuzz a font and a string containing a sequence of Unicode + codepoints, HarfBuzz selects and positions the corresponding + glyphs from the font, applying all of the necessary layout rules + and font features. HarfBuzz then returns the string to you in the + form that is correctly arranged for the language and writing + system. -
- Why do I need it? + + HarfBuzz can properly shape all of the world's major writing + systems. It runs on virtually all operating systems and software + platforms, and it supports all of the standard font formats in use + today. + +
+ Why do I need a shaping engine? - Text shaping is an integral part of preparing text for display. It - is a fairly low level operation; HarfBuzz is used directly by - graphic rendering libraries such as Pango, and the layout engines - in Firefox, LibreOffice and Chromium. Unless you are - writing one of these layout engines yourself, - you will probably not need to use HarfBuzz - normally higher level - libraries will turn text into glyphs for you. + Text shaping is an integral part of preparing text for + display. Before a Unicode sequence can be rendered, the + codepoints in the sequence must be mapped to the glyphs + provided in the font, and the glyphs must be positioned + correctly relative to each other. For many of the scripts + supported in Unicode, these steps involve script-specific layout + rules. + + + Text shaping is a fairly low-level operation. HarfBuzz is + used directly by graphic rendering libraries such as Pango, as + well as by the layout engines in Firefox, LibreOffice, and + Chromium. Unless you are writing one of + these layout engines yourself, you will probably not need to use + HarfBuzz: normally, lower-level libraries will turn text into + glyphs for you. However, if you are writing a layout engine or graphics library yourself, you will need to perform text - shaping, and this is where HarfBuzz can help you. Here are some - reasons why you need it: + shaping, and this is where HarfBuzz can help you. + + + Here are some specific scenarios where a text-shaping engine + like HarfBuzz helps you: - OpenType fonts contain a set of glyphs, indexed by glyph ID. - The glyph ID within the font does not necessarily relate to a - Unicode codepoint. For instance, some fonts have the letter - "a" as glyph ID 1. To pull the right glyph out of - the font in order to display it, you need to consult a table - within the font (the "cmap" table) which maps - Unicode codepoints to glyph IDs. Text shaping turns codepoints - into glyph IDs. + OpenType fonts contain a set of glyphs (that is, shapes + to represent the letters, numbers, punctuation marks, and + all other symbols), which are indexed by a glyph ID. + + + The glyph ID within the font does not necessarily correlate + to a predictable Unicode codepoint. For instance, some fonts + have the letter "a" as glyph ID 1, but many others do + not. To pull the right glyph out of the font in order to + display "a", you need to consult the table inside + the font (the cmap table) that maps Unicode + codepoints to glyph IDs. In other words, text shaping turns + codepoints into glyph IDs. Many OpenType fonts contain ligatures: combinations of - characters which are rendered together. For instance, it's - common for the fi combination to appear in - print as the single ligature "fi". Whether you should - render text as fi or "fi" does not - depend on the input text, but on the capabilities of the font - and the level of ligature application you wish to perform. - Text shaping involves querying the font's ligature tables and - determining what substitutions should be made. + characters that are rendered as a single unit. For instance, + it is common for the fi letter + combination to appear in print as the single ligature glyph + "fi". + + + Whether you should render an "f, i" sequence + as fi or as "fi" does not + depend on the input text. Rather, it depends on the whether + or not the font includes an "fi" glyph and on the + level of ligature application you wish to perform. The font + and the amount of ligature application used are under your + control. In other words, text shaping involves + querying the font's ligature tables and determining what + substitutions should be made. - While ligatures like "fi" are typographic - refinements, some languages require such + While ligatures like "fi" are optional typographic + refinements, some languages require certain substitutions to be made in order to display text correctly. - In Tamil, when the letter "TTA" (ட) letter is - followed by "U" (உ), the combination should appear - as the single glyph "டு". The sequence of Unicode - characters "டஉ" needs to be rendered as a single - glyph from the font - text shaping chooses the correct glyph - from the sequence of characters provided. + + + For example, in Tamil, when the letter "TTA" (ட) + letter is followed by "U" (உ), the pair + must be replaced by the single glyph "டு". The + sequence of Unicode characters "டஉ" needs to be + substituted with a single "டு" glyph from the + font. + + + But "டு" does not have a Unicode codepoint. To + find this glyph, you need to consult the table inside + the font (the GSUB table) that contains + substitution information. In other words, text shaping + chooses the correct glyph for a sequence of characters + provided. - Similarly, each Arabic character has four different variants: - within a font, there will be glyphs for the initial, medial, - final, and isolated forms of each letter. Unicode only encodes - one codepoint per character, and so a Unicode string will not - tell you which glyph to use. Text shaping chooses the correct - form of the letter and returns the correct glyph from the font - that you need to render. + Similarly, each Arabic character has four different variants + corresponding to the different positions in might appear in + within a sequence. Inside a font, there will be separate + glyphs for the initial, medial, final, and isolated forms of + each letter, each at a different glyph ID. + + + Unicode only assigns one codepoint per character, so a + Unicode string will not tell you which glyph variant to use + for each character. To decide, you need to analyze the whole + string and determine the appropriate glyph for each character + based on its position. In other words, text + shaping chooses the correct form of the letter by its + position and returns the correct glyph from the font. - Other languages have marks and accents which need to be - rendered in certain positions around a base character. For - instance, the Moldovan language has the Cyrillic letter - "zhe" (ж) with a breve accent, like so: ӂ. Some - fonts will contain this character as an individual glyph, - whereas other fonts will not contain a zhe-with-breve glyph - but expect the rendering engine to form the character by - overlaying the two glyphs ж and ˘. Where you should draw the - combining breve depends on the height of the preceding glyph. - Again, for Arabic, the correct positioning of vowel marks - depends on the height of the character on which you are - placing the mark. Text shaping tells you whether you have a + Other languages involve marks and accents that need to be + rendered in specific positions relative a base character. For + instance, the Moldovan language includes the Cyrillic letter + "zhe" (ж) with a breve accent, like so: "ӂ". + + + Some fonts will provide this character as a single + zhe-with-breve glyph, but other fonts will not and, instead, + will expect the rendering engine to form the character by + superimposing the separate "ж" and "˘" + glyphs. + + + But exactly where you should draw the breve depends on the + height and width of the preceding zhe glyph. To find the + right position, you need to consult the table inside + the font (the GPOS table) that contains + positioning information. + In other words, text shaping tells you whether you have a precomposed glyph within your font or if you need to compose a - glyph yourself out of combining marks, and if so, where to - position those marks. + glyph yourself out of combining marks—and, if so, where to + position those marks. - If this is something that you need to do, then you need a text - shaping engine: you could use Uniscribe if you are using Windows; - you could use CoreText on OS X; or you could use HarfBuzz. In the - rest of this manual, we are going to assume that you are the - implementor of a text layout engine. + If tasks like these are something that you need to do, then you need a text + shaping engine. You could use Uniscribe if you are writing + Windows software; you could use CoreText on macOS; or you could + use HarfBuzz. + + + In the rest of this manual, we are going to assume that you are the + implementor of a text-layout engine.
Why is it called HarfBuzz? - HarfBuzz began its life as text shaping code within the FreeType - project, (and you will see references to the FreeType authors - within the source code copyright declarations) but was then - abstracted out to its own project. This project is maintained by + HarfBuzz began its life as text-shaping code within the FreeType + project (and you will see references to the FreeType authors + within the source code copyright declarations), but was then + extracted out to its own project. This project is maintained by Behdad Esfahbod, and named HarfBuzz. Originally, it was a shaping engine for OpenType fonts - "HarfBuzz" is the Persian for "open type".
-
\ No newline at end of file +
From fd270beedb331c4685e918f5a3ef5789a23ffaeb Mon Sep 17 00:00:00 2001 From: Nathan Willis Date: Fri, 28 Sep 2018 16:36:38 -0500 Subject: [PATCH 188/255] Docs: Usermanual- What is HarfBuzz; add intro to shaping concepts. --- docs/usermanual-what-is-harfbuzz.xml | 51 ++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/docs/usermanual-what-is-harfbuzz.xml b/docs/usermanual-what-is-harfbuzz.xml index 8ec7b4030..59df9e3f7 100644 --- a/docs/usermanual-what-is-harfbuzz.xml +++ b/docs/usermanual-what-is-harfbuzz.xml @@ -15,6 +15,57 @@ platforms, and it supports all of the standard font formats in use today. +
+ What is text shaping? + + Text shaping is the process of translating a string of character + codes (such as Unicode codepoints) into a properly arranged + sequence of glyphs that can be rendered onto a screen or into + final output form for a document. + + + The shaping process is dependent on the input string, the active + font, the script (or writing system) that the string is in, and + the language that the string is in. + + + Modern software systems generally only deal with strings in the + Unicode encoding scheme (although legacy systems and documents may + involve other encodings). + + + There are several font formats that a program might + encounter, each of which has a set of standard text-shaping + rules. + + The dominant format is OpenType. The + OpenType specification defines a series of shaping models for + various scripts (including Indic, Arabic, Hangul, Hebrew, Khmer, + Myanmar, Thai and Lao, Tibetan, and a Universal Shaping Engine + designed to cover other scripts). These shaping models depend on + the font including certain features in its GSUB + and GPOS tables. + + + Alternatively, OpenType fonts can include shaping features for + the Graphite shaping model. + + + TrueType fonts can also include OpenType shaping + features. Alternatively, TrueType fonts can also include Apple + Advanced Typography (AAT) tables to implement shaping + support. AAT fonts are generally only found on macOS systems. + + + Text strings will usually be tagged with a script and language + tag that provide the context for text shaping. Script + and language + tags are defined by OpenType. + +
Why do I need a shaping engine? From 0956ab41851d30f50c39c28730cf30ea0bbc5466 Mon Sep 17 00:00:00 2001 From: Nathan Willis Date: Fri, 28 Sep 2018 17:15:59 -0500 Subject: [PATCH 189/255] Docs: Move What-HarfBuzz-doesnt-do to Usermanual-what-is-HarfBuzz. --- docs/usermanual-hello-harfbuzz.xml | 98 ++------------------------ docs/usermanual-what-is-harfbuzz.xml | 101 +++++++++++++++++++++++++-- 2 files changed, 104 insertions(+), 95 deletions(-) diff --git a/docs/usermanual-hello-harfbuzz.xml b/docs/usermanual-hello-harfbuzz.xml index 716b2f2dd..221692c60 100644 --- a/docs/usermanual-hello-harfbuzz.xml +++ b/docs/usermanual-hello-harfbuzz.xml @@ -90,94 +90,10 @@ hb_buffer_destroy(buf); hb_font_destroy(hb_ft_font); -
- What HarfBuzz doesn't do - - The code above will take a UTF8 string, shape it, and give you the - information required to lay it out correctly on a single - horizontal (or vertical) line using the font provided. That is the - extent of HarfBuzz's responsibility. - - - If you are implementing a text layout engine you may have other - responsibilities, that HarfBuzz will not help you with: - - - - - HarfBuzz won't help you with bidirectionality. If you want to - lay out text with mixed Hebrew and English, you will need to - ensure that the buffer provided to HarfBuzz has those - characters in the correct layout order. This will be different - from the logical order in which the Unicode text is stored. In - other words, the user will hit the keys in the following - sequence: - - -A B C [space] ג ב א [space] D E F - - - but will expect to see in the output: - - -ABC אבג DEF - - - This reordering is called bidi processing - ("bidi" is short for bidirectional), and there's an - algorithm as an annex to the Unicode Standard which tells you how - to reorder a string from logical order into presentation order. - Before sending your string to HarfBuzz, you may need to apply the - bidi algorithm to it. Libraries such as ICU and fribidi can do - this for you. - - - - - HarfBuzz won't help you with text that contains different font - properties. For instance, if you have the string "a - huge breakfast", and you expect - "huge" to be italic, you will need to send three - strings to HarfBuzz: a, in your Roman font; - huge using your italic font; and - breakfast using your Roman font again. - Similarly if you change font, font size, script, language or - direction within your string, you will need to shape each run - independently and then output them independently. HarfBuzz - expects to shape a run of characters sharing the same - properties. - - - - - HarfBuzz won't help you with line breaking, hyphenation or - justification. As mentioned above, it lays out the string - along a single line of, notionally, - infinite length. If you want to find out where the potential - word, sentence and line break points are in your text, you - could use the ICU library's break iterator functions. - - - HarfBuzz can tell you how wide a shaped piece of text is, which is - useful input to a justification algorithm, but it knows nothing - about paragraphs, lines or line lengths. Nor will it adjust the - space between words to fit them proportionally into a line. If you - want to layout text in paragraphs, you will probably want to send - each word of your text to HarfBuzz to determine its shaped width - after glyph substitutions, then work out how many words will fit - on a line, and then finally output each word of the line separated - by a space of the correct size to fully justify the paragraph. - - - - - As a layout engine implementor, HarfBuzz will help you with the - interface between your text and your font, and that's something - that you'll need - what you then do with the glyphs that your font - returns is up to you. The example we saw above enough to get us - started using HarfBuzz. Now we are going to use the remainder of - HarfBuzz's API to refine that example and improve our text shaping - capabilities. - -
- \ No newline at end of file + + + This example shows enough to get us started using HarfBuzz. Now we + are going to use the remainder of HarfBuzz's API to refine that + example and improve our text shaping capabilities. + + diff --git a/docs/usermanual-what-is-harfbuzz.xml b/docs/usermanual-what-is-harfbuzz.xml index 59df9e3f7..3a98b53f2 100644 --- a/docs/usermanual-what-is-harfbuzz.xml +++ b/docs/usermanual-what-is-harfbuzz.xml @@ -1,13 +1,13 @@ What is HarfBuzz? - HarfBuzz is a text shaping engine. If you + HarfBuzz is a text-shaping engine. If you give HarfBuzz a font and a string containing a sequence of Unicode codepoints, HarfBuzz selects and positions the corresponding glyphs from the font, applying all of the necessary layout rules and font features. HarfBuzz then returns the string to you in the form that is correctly arranged for the language and writing - system. + system. HarfBuzz can properly shape all of the world's major writing @@ -21,7 +21,7 @@ Text shaping is the process of translating a string of character codes (such as Unicode codepoints) into a properly arranged sequence of glyphs that can be rendered onto a screen or into - final output form for a document. + final output form for inclusion in a document. The shaping process is dependent on the input string, the active @@ -66,6 +66,7 @@ tags are defined by OpenType.
+
Why do I need a shaping engine? @@ -212,6 +213,98 @@ implementor of a text-layout engine.
+ +
+ What HarfBuzz doesn't do + + HarfBuzz will take a Unicode string, shape it, and give you the + information required to lay it out correctly on a single + horizontal (or vertical) line using the font provided. That is the + extent of HarfBuzz's responsibility. + + + It is important to note that if you are implementing a + text-layout engine you may have other responsibilities that + HarfBuzz will not help you with. For example: + + + + + HarfBuzz won't help you with bidirectionality. If you want to + lay out text that includes a mix of Hebrew and English, you + will need to ensure that each buffer provided to HarfBuzz has its + characters in the correct layout order. This will be different + from the logical order in which the Unicode text is stored. In + other words, the user will hit the keys in the following + sequence: + + +A B C [space] ג ב א [space] D E F + + + but will expect to see in the output: + + +ABC אבג DEF + + + This reordering is called bidi processing + ("bidi" is short for bidirectional), and there's an + algorithm as an annex to the Unicode Standard which tells you how + to reorder a string from logical order into presentation order. + Before sending your string to HarfBuzz, you may need to apply the + bidi algorithm to it. Libraries such as ICU and fribidi can do + this for you. + + + + + HarfBuzz won't help you with text that contains different font + properties. For instance, if you have the string "a + huge breakfast", and you expect + "huge" to be italic, then you will need to send three + strings to HarfBuzz: a, in your Roman font; + huge using your italic font; and + breakfast using your Roman font again. + + + Similarly, if you change the font, font size, script, + language, or direction within your string, then you will + need to shape each run independently and output them + independently. HarfBuzz expects to shape a run of characters + that all share the same properties. + + + + + HarfBuzz won't help you with line breaking, hyphenation, or + justification. As mentioned above, HarfBuzz lays out the string + along a single line of, notionally, + infinite length. If you want to find out where the potential + word, sentence and line break points are in your text, you + could use the ICU library's break iterator functions. + + + HarfBuzz can tell you how wide a shaped piece of text is, which is + useful input to a justification algorithm, but it knows nothing + about paragraphs, lines or line lengths. Nor will it adjust the + space between words to fit them proportionally into a line. If you + want to layout text in paragraphs, you will probably want to send + each word of your text to HarfBuzz to determine its shaped width + after glyph substitutions, then work out how many words will fit + on a line, and then finally output each word of the line separated + by a space of the correct size to fully justify the paragraph. + + + + + As a layout-engine implementor, HarfBuzz will help you with the + interface between your text and your font, and that's something + that you'll need—what you then do with the glyphs that your font + returns is up to you. + +
+
Why is it called HarfBuzz? @@ -220,7 +313,7 @@ within the source code copyright declarations), but was then extracted out to its own project. This project is maintained by Behdad Esfahbod, and named HarfBuzz. Originally, it was a shaping - engine for OpenType fonts - "HarfBuzz" is the Persian + engine for OpenType fonts—"HarfBuzz" is the Persian for "open type".
From 088755f9e654d2ec638dce0c68d523084b9eaf5a Mon Sep 17 00:00:00 2001 From: Nathan Willis Date: Wed, 10 Oct 2018 16:37:29 -0500 Subject: [PATCH 190/255] Docs: update usermanual What Is HarfBuzz material. --- docs/usermanual-what-is-harfbuzz.xml | 222 +++++++++++++++++++++------ 1 file changed, 173 insertions(+), 49 deletions(-) diff --git a/docs/usermanual-what-is-harfbuzz.xml b/docs/usermanual-what-is-harfbuzz.xml index 3a98b53f2..6a3ac1029 100644 --- a/docs/usermanual-what-is-harfbuzz.xml +++ b/docs/usermanual-what-is-harfbuzz.xml @@ -11,8 +11,8 @@ HarfBuzz can properly shape all of the world's major writing - systems. It runs on virtually all operating systems and software - platforms, and it supports all of the standard font formats in use + systems. It runs on all major operating systems and software + platforms, and it supports all of the modern font formats in use today.
@@ -41,9 +41,7 @@ The dominant format is OpenType. The OpenType specification defines a series of shaping models for - various scripts (including Indic, Arabic, Hangul, Hebrew, Khmer, - Myanmar, Thai and Lao, Tibetan, and a Universal Shaping Engine - designed to cover other scripts). These shaping models depend on + various scripts from around the world. These shaping models depend on the font including certain features in its GSUB and GPOS tables. @@ -55,12 +53,13 @@ TrueType fonts can also include OpenType shaping features. Alternatively, TrueType fonts can also include Apple Advanced Typography (AAT) tables to implement shaping - support. AAT fonts are generally only found on macOS systems. + support. AAT fonts are generally only found on macOS and iOS systems. Text strings will usually be tagged with a script and language - tag that provide the context for text shaping. Script + tag that provide the context needed to perform text shaping + correctly. The necessary Script and language tags are defined by OpenType. @@ -72,24 +71,25 @@ Text shaping is an integral part of preparing text for display. Before a Unicode sequence can be rendered, the - codepoints in the sequence must be mapped to the glyphs - provided in the font, and the glyphs must be positioned + codepoints in the sequence must be mapped to the corresponding + glyphs provided in the font, and those glyphs must be positioned correctly relative to each other. For many of the scripts supported in Unicode, these steps involve script-specific layout - rules. + rules, including complex joining, reordering, and positioning + behavior. Implementing these rules is the job of the shaping engine. Text shaping is a fairly low-level operation. HarfBuzz is - used directly by graphic rendering libraries such as Pango, as - well as by the layout engines in Firefox, LibreOffice, and - Chromium. Unless you are writing one of - these layout engines yourself, you will probably not need to use - HarfBuzz: normally, lower-level libraries will turn text into - glyphs for you. + used directly by graphical rendering libraries like Pango, as well as by the layout + engines in Firefox, LibreOffice, and Chromium. Unless you are + writing one of these layout engines + yourself, you will probably not need to use HarfBuzz: normally, + lower-level libraries will turn text into glyphs for you. However, if you are writing a layout engine - or graphics library yourself, you will need to perform text + or graphics library yourself, then you will need to perform text shaping, and this is where HarfBuzz can help you. @@ -104,14 +104,15 @@ all other symbols), which are indexed by a glyph ID. - The glyph ID within the font does not necessarily correlate - to a predictable Unicode codepoint. For instance, some fonts - have the letter "a" as glyph ID 1, but many others do - not. To pull the right glyph out of the font in order to - display "a", you need to consult the table inside - the font (the cmap table) that maps Unicode - codepoints to glyph IDs. In other words, text shaping turns - codepoints into glyph IDs. + A particular glyph ID within the font does not necessarily + correlate to a predictable Unicode codepoint. For instance, + some fonts have the letter "a" as glyph ID 1, but + many others do not. In order to retrieve the right glyph + from the font to display "a", you need to consult + the table inside the font (the cmap + table) that maps Unicode codepoints to glyph IDs. In other + words, text shaping turns codepoints into glyph + IDs. @@ -125,7 +126,7 @@ Whether you should render an "f, i" sequence as fi or as "fi" does not - depend on the input text. Rather, it depends on the whether + depend on the input text. Instead, it depends on the whether or not the font includes an "fi" glyph and on the level of ligature application you wish to perform. The font and the amount of ligature application used are under your @@ -195,26 +196,148 @@ right position, you need to consult the table inside the font (the GPOS table) that contains positioning information. - In other words, text shaping tells you whether you have a - precomposed glyph within your font or if you need to compose a - glyph yourself out of combining marks—and, if so, where to - position those marks. + In other words, text shaping tells you whether you + have a precomposed glyph within your font or if you need to + compose a glyph yourself out of combining marks—and, + if so, where to position those marks. - If tasks like these are something that you need to do, then you need a text - shaping engine. You could use Uniscribe if you are writing - Windows software; you could use CoreText on macOS; or you could - use HarfBuzz. - - - In the rest of this manual, we are going to assume that you are the - implementor of a text-layout engine. + If tasks like these are something that you need to do, then you + need a text shaping engine. You could use Uniscribe if you are + writing Windows software; you could use CoreText on macOS; or + you could use HarfBuzz. + + + In the rest of this manual, the text will assume that the reader + is that implementor of a text-layout engine. + +
-
+ +
+ What does HarfBuzz do? + + HarfBuzz provides OpenType text shaping through a cross-platform + C API that accepts sequences of Unicode input text. Currently, + the following OpenType shaping models are supported: + + + + + Indic (covering Devanagari, Bengali, Gujarati, + Gurmukhi, Kannada, Malayalam, Oriya, Tamil, Telugu, and + Sinhala) + + + + + Arabic (covering Arabic, N'Ko, Syriac, and Mongolian) + + + + + Thai and Lao + + + + + Khmer + + + + + Myanmar + + + + + + Tibetan + + + + + + Hangul + + + + + + Hebrew + + + + + The Universal Shaping Engine or USE + (covering complex scripts not covered by the above shaping + models) + + + + + A default shaping model for non-complex scripts + (covering Latin, Cyrillic, Greek, Armenian, Georgian, Tifinagh, + and many others) + + + + + Emoji (including emoji modifier sequences, flag sequences, + and ZWJ sequences) + + + + + + In addition to OpenType shaping, HarfBuzz supports the latest + version of Graphite shaping. HarfBuzz currently supports AAT + shaping only on macOS and iOS systems, and in a pass-through + fashion: HarfBuzz hands off AAT support to the system CoreText + library. However, full, built-in AAT support within HarfBuzz is + under development. + + + + HarfBuzz can read and understand TrueType fonts (.ttf), TrueType + collections (.ttc), and OpenType fonts (.otf, including those + fonts that contain TrueType-style outlines and those that + contain PostScript CFF or CFF2 outlines). + + + + HarfBuzz can run on top of the FreeType, CoreText, DirectWrite, + or Uniscribe font renderers. + + + + In addition to its core shaping functionality, HarfBuzz provides + functions for accessing other font features, including optional + GSUB and GPOS OpenType features, as well as + all color-font formats (CBDT, + sbix, COLR/CPAL, and + SVG-OT) and OpenType variable fonts. HarfBuzz + also includes a font-subsetting feature. + + + + HarfBuzz can perform some low-level math-shaping operations, + although it does not currently perform full shaping for + mathematical typesetting. + + + + A suite of command-line utilities is also provided in the + source-code tree, designed to help users test and debug + HarfBuzz's features on real-world fonts and input. + +
+ +
What HarfBuzz doesn't do HarfBuzz will take a Unicode string, shape it, and give you the @@ -223,7 +346,7 @@ extent of HarfBuzz's responsibility. - It is important to note that if you are implementing a + It is important to note that if you are implementing a complete text-layout engine you may have other responsibilities that HarfBuzz will not help you with. For example: @@ -239,13 +362,13 @@ sequence: -A B C [space] ג ב א [space] D E F + A B C [space] ג ב א [space] D E F but will expect to see in the output: -ABC אבג DEF + ABC אבג DEF This reordering is called bidi processing @@ -253,8 +376,9 @@ ABC אבג DEF algorithm as an annex to the Unicode Standard which tells you how to reorder a string from logical order into presentation order. Before sending your string to HarfBuzz, you may need to apply the - bidi algorithm to it. Libraries such as ICU and fribidi can do - this for you. + bidi algorithm to it. Libraries such as ICU and fribidi can do this for you. @@ -304,7 +428,7 @@ ABC אבג DEF returns is up to you.
- +
Why is it called HarfBuzz? @@ -312,9 +436,9 @@ ABC אבג DEF project (and you will see references to the FreeType authors within the source code copyright declarations), but was then extracted out to its own project. This project is maintained by - Behdad Esfahbod, and named HarfBuzz. Originally, it was a shaping - engine for OpenType fonts—"HarfBuzz" is the Persian - for "open type". + Behdad Esfahbod, who named it HarfBuzz. Originally, it was a + shaping engine for OpenType fonts—"HarfBuzz" is + the Persian for "open type".
From 97c1c46cd2241d77b531a582dd1a2432af976357 Mon Sep 17 00:00:00 2001 From: Nathan Willis Date: Wed, 10 Oct 2018 16:38:22 -0500 Subject: [PATCH 191/255] Docs: update and linearize build instructions; add installation overview material. --- docs/usermanual-install-harfbuzz.xml | 247 +++++++++++++++++++++------ 1 file changed, 197 insertions(+), 50 deletions(-) diff --git a/docs/usermanual-install-harfbuzz.xml b/docs/usermanual-install-harfbuzz.xml index 899cc5bd6..9d10e2da0 100644 --- a/docs/usermanual-install-harfbuzz.xml +++ b/docs/usermanual-install-harfbuzz.xml @@ -1,70 +1,217 @@ - Install HarfBuzz + Installing HarfBuzz +
- Download + Downloading HarfBuzz - For tarball releases of HarfBuzz, look - here. - At the same place you will - also find Win32 binary bundles that include libharfbuzz DLL, hb-view.exe, - hb-shape.exe, and all dependencies. + The HarfBuzz source code is hosted at github.com/harfbuzz/harfbuzz. The + same source tree is also available at the + Freedesktop.org + site. - The canonical source tree is available - here. - Also available on github. + Tarball releases and Win32 binary bundles (which include the + libharfbuzz DLL, hb-view.exe, hb-shape.exe, and all + dependencies) of HarfBuzz can be downloaded from github.com/harfbuzz/harfbuzz/releases + or from + Freedesktop.org. - The API that comes with hb.h will - not change incompatibly. Other, peripheral, headers are more likely to go - through minor modifications, but again, will do our best to never change - API in an incompatible way. We will never break the ABI. + Release notes are posted with each new release to provide an + overview of the changes. The project tracks bug + reports and other issues on GitHub. Discussion and + questions are welcome on the HarfBuzz + mailing list. - If you are not sure whether Pango or HarfBuzz is right for you, read - this. + The API included in the hb.h file will not change in a + compatibility-breaking way in any release. However, other, + peripheral headers are more likely to go through minor + modifications. We will do our best to never change APIs in an + incompatible way. We will never break the ABI.
+
- Building + Building HarfBuzz + +
+ Building on Linux - On Linux, install the development packages for FreeType, Cairo, and GLib. - For example, on Ubuntu / Debian, you would do: - -sudo apt-get install gcc g++ libfreetype6-dev libglib2.0-dev libcairo2-dev - - whereas on Fedora, RHEL, CentOS, and other Red Hat based systems you would do: - -sudo yum install gcc gcc-c++ freetype-devel glib2-devel cairo-devel - - or using MacPorts: - -sudo port install freetype glib2 cairo - + (1) To build HarfBuzz on Linux, you must first install the + development packages for FreeType, Cairo, and GLib. The exact + commands required for this step will vary depending on + the Linux distribution you use. - If you are using a tarball, you can now proceed to running - configure and make as with any - other standard package. That should leave you with a shared library in - src/, and a few utility programs including hb-view - and hb-shape under util/. + For example, on an Ubuntu or Debian system, you would run: + + sudo apt install gcc g++ libfreetype6-dev libglib2.0-dev libcairo2-dev + + On Fedora, RHEL, CentOS, or other Red-Hat–based systems, you would run: + + sudo yum install gcc gcc-c++ freetype-devel glib2-devel cairo-devel + + + + + + (2) The next step depends on whether you + are building from the source in a downloaded release tarball or + from the source directly from the git repository. - If you are bootstrapping from git, you need a few more tools before you - can run autogen.sh for the first time. Namely, - pkg-config and ragel. - Again, on Ubuntu / Debian: - -sudo apt-get install autoconf automake libtool pkg-config ragel gtk-doc-tools - - and on Fedora, RHEL, CentOS: - -sudo yum install autoconf automake libtool pkgconfig ragel gtk-doc - - or using MacPorts: - -sudo port install autoconf automake libtool pkgconfig ragel gtk-doc - + (2)(a) If you downloaded the HarfBuzz + source code in a tarball, you can now extract the source. + + From a shell in the top-level directory of the extracted source + code, you can run ./configure followed by + make as with any other standard package. + + + This should leave you with a shared + library in the src/ directory, and a few + utility programs including hb-view and + hb-shape under the util/ + directory. + + + (2)(b) If you are building from the source in the HarfBuzz git + repository, rather than installing from a downloaded tarball + release, then you must install two more auxiliary tools before you + can build for the first time: pkg-config and + ragel. + + + On Ubuntu or Debian, run: + + sudo apt-get install autoconf automake libtool pkg-config ragel gtk-doc-tools + + On Fedora, RHEL, CentOS, run: + + sudo yum install autoconf automake libtool pkgconfig ragel gtk-doc + + + + + With pkg-config and ragel + installed, you can now run ./autogen.sh, + followed by ./configure and + make to build HarfBuzz. + +
+ + +
+ Building on Windows + + + On Windows, consider using Microsoft's free vcpkg utility + to build HarfBuzz, its dependencies, and other open-source + libraries. + + + If you need to build HarfBuzz from source, first put the + ragel binary on your + PATH, then follow the appveyor CI cmake + build + instructions. + +
+ + +
+ Building on macOS + + + There are two ways to build HarfBuzz on Mac systems: MacPorts + and Homebrew. The process is similar to the process used on a + Linux system. + + + (1) You must first install the + development packages for FreeType, Cairo, and GLib. If you are + using MacPorts, you should run: + + sudo port install freetype glib2 cairo + + + + If you are using Homebrew, you should run: + + brew install freetype glib cairo + + + + (2) The next step depends on whether you are building from the + source in a downloaded release tarball or from the source directly + from the git repository. + + + (2)(a) If you are installing HarfBuzz + from a downloaded tarball release, extract the tarball and + open a Terminal in the extracted source-code directory. Run: + + ./configure + + followed by: + + make + + to build HarfBuzz. + + + (2)(b) Alternatively, if you are building + HarfBuzz from the source in the HarfBuzz git repository, then + you must install several built-time dependencies before + proceeding. + + If you are + using MacPorts, you should run: + + sudo port install autoconf + automake libtool pkgconfig ragel gtk-doc + + to install the build dependencies. + + If you are using Homebrew, you should run: + + brew install autoconf automake libtool pkgconfig ragel gtk-doc + + Finally, you can run: + + ./autogen.sh + + + + (3) You can now build HarfBuzz (on either + a MacPorts or a Homebrew system) by running: + + ./configure + + followed by: + + make + + + + This should leave you with a shared + library in the src/ directory, and a few + utility programs including hb-view and + hb-shape under the util/ + directory. + + +
+ +
From 325e2745cfa55f9ef114ee8eeaf7bd8176743822 Mon Sep 17 00:00:00 2001 From: Nathan Willis Date: Wed, 10 Oct 2018 17:01:21 -0500 Subject: [PATCH 192/255] Docs: add basic config-options section to Usermanual Installation chapter. --- docs/usermanual-install-harfbuzz.xml | 132 ++++++++++++++++++++++++++- 1 file changed, 131 insertions(+), 1 deletion(-) diff --git a/docs/usermanual-install-harfbuzz.xml b/docs/usermanual-install-harfbuzz.xml index 9d10e2da0..f032b888d 100644 --- a/docs/usermanual-install-harfbuzz.xml +++ b/docs/usermanual-install-harfbuzz.xml @@ -51,7 +51,8 @@ For example, on an Ubuntu or Debian system, you would run: - sudo apt install gcc g++ libfreetype6-dev libglib2.0-dev libcairo2-dev + sudo apt install gcc g++ + libfreetype6-dev libglib2.0-dev libcairo2-dev On Fedora, RHEL, CentOS, or other Red-Hat–based systems, you would run: @@ -212,6 +213,135 @@
+
+ Configuration options + + + The instructions in the "Building HarfBuzz" section will build + the source code under its default configuration. If needed, + the following additional configuration options are available. + + + + + --with-libstdc++ + + + Allow linking with libstdc++. (Default = no) + + + + + + --with-glib + + + Use GLib. (Default = auto) + + + + + + --with-gobject + + + Use GObject. (Default = no) + + + + + + --with-cairo + + + Use Cairo. (Default = auto) + + + + + + --with-fontconfig + + + Use Fontconfig. (Default = auto) + + + + + + --with-icu + + + Use the ICU library. (Default = auto) + + + + + + --with-ucdn + + + Use the built-in UCDN library. (Default = auto) + + + + + + --with-graphite2 + + + Use the graphite2 library. (Default = no) + + + + + + --with-freetype + + + Use the FreeType library. (Default = auto) + + + + + + --with-uniscribe + + + Use the Uniscribe library. (Default = no) + + + + + + --with-directwrite + + + se the DirectWrite library (experimental). (Default = no) + + + + + + --with-coretext + + + Use the CoreText library. (Default = no) + + + + + + + + + (Default = no) + + + + + +
From 792af5d254fddcdc4292dffb76b81d65754e65a9 Mon Sep 17 00:00:00 2001 From: Nathan Willis Date: Thu, 11 Oct 2018 14:05:59 -0500 Subject: [PATCH 193/255] Docs: flesh out config options in Usermanual:Install chapter. --- docs/usermanual-install-harfbuzz.xml | 108 +++++++++++++++++++++------ 1 file changed, 85 insertions(+), 23 deletions(-) diff --git a/docs/usermanual-install-harfbuzz.xml b/docs/usermanual-install-harfbuzz.xml index f032b888d..cd1e2e134 100644 --- a/docs/usermanual-install-harfbuzz.xml +++ b/docs/usermanual-install-harfbuzz.xml @@ -229,6 +229,10 @@ Allow linking with libstdc++. (Default = no) + + This option enables or disables linking HarfBuzz to the + system's libstdc++ library. + @@ -236,8 +240,15 @@ --with-glib - Use GLib. (Default = auto) + Use GLib. (Default = auto) + + This option enables or disables usage of the GLib + library. The default setting is to check for the + presence of GLib and, if it is found, build with + GLib support. GLib is native to GNU/Linux systems but is + available on other operating system as well. + @@ -245,8 +256,15 @@ --with-gobject - Use GObject. (Default = no) - + Use GObject. (Default = no) + + + This option enables or disables usage of the GObject + library. The default setting is to check for the + presence of GObject and, if it is found, build with + GObject support. GObject is native to GNU/Linux systems but is + available on other operating system as well. + @@ -254,8 +272,14 @@ --with-cairo - Use Cairo. (Default = auto) - + Use Cairo. (Default = auto) + + + This option enables or disables usage of the Cairo + graphics-rendering library. The default setting is to + check for the presence of Cairo and, if it is found, + build with Cairo support. + @@ -263,8 +287,15 @@ --with-fontconfig - Use Fontconfig. (Default = auto) + Use Fontconfig. (Default = auto) + + This option enables or disables usage of the Fontconfig + library, which provides font-matching functions and + provides access to font properties. The default setting + is to check for the presence of Fontconfig and, if it is + found, build with Fontconfig support. + @@ -272,8 +303,17 @@ --with-icu - Use the ICU library. (Default = auto) + Use the ICU library. (Default = auto) + + This option enables or disables usage of the + International Components for + Unicode (ICU) library, which provides access + to Unicode Character Database (UCD) properties as well + as normalization and conversion functions. The default + setting is to check for the presence of ICU and, if it + is found, build with ICU support. + @@ -281,8 +321,17 @@ --with-ucdn - Use the built-in UCDN library. (Default = auto) + Use HarfBuzz's built-in UCDN library. (Default = auto) + + The HarfBuzz source tree includes a Unicode + Database and Normalization (UCDN) library + that provides access to basic character properties in + the Unicode Character Database (UCD) as well as low-level + normalization functions. HarfBuzz can be built without + this UCDN support if the usage of a different UCDN + library is desired. + @@ -290,8 +339,13 @@ --with-graphite2 - Use the graphite2 library. (Default = no) + Use the Graphite2 library. (Default = no) + + This option enables or disables usage of the Graphite2 + library, which provides support for the Graphite shaping + model. + @@ -299,8 +353,14 @@ --with-freetype - Use the FreeType library. (Default = auto) + Use the FreeType library. (Default = auto) + + This option enables or disables usage of the FreeType + font-rendering library. The default setting is to check for the + presence of FreeType and, if it is found, build with + FreeType support. + @@ -308,8 +368,12 @@ --with-uniscribe - Use the Uniscribe library. (Default = no) + Use the Uniscribe library. (Default = no) + + This option enables or disables usage of the Uniscribe + font-rendering library. Uniscribe is available on Windows systems. + @@ -317,8 +381,12 @@ --with-directwrite - se the DirectWrite library (experimental). (Default = no) + Use the DirectWrite library (experimental). (Default = no) + + This option enables or disables usage of the DirectWrite + font-rendering library. DirectWrite is available on Windows systems. + @@ -326,20 +394,14 @@ --with-coretext - Use the CoreText library. (Default = no) + Use the CoreText library. (Default = no) - - - - - - - (Default = no) - + This option enables or disables usage of the CoreText + library. CoreText is available on macOS and iOS systems. + - - +
From 443f87213272be5ae0579dce4749b2036dfe3815 Mon Sep 17 00:00:00 2001 From: Nathan Willis Date: Thu, 11 Oct 2018 15:40:08 -0500 Subject: [PATCH 194/255] Docs: move harfbuzz-ng-vs-old discussion down below the TOC; put in note. --- docs/harfbuzz-docs.xml | 63 ++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/docs/harfbuzz-docs.xml b/docs/harfbuzz-docs.xml index 21c251d0d..48ea67e60 100644 --- a/docs/harfbuzz-docs.xml +++ b/docs/harfbuzz-docs.xml @@ -12,29 +12,20 @@ HarfBuzz is an OpenType - text shaping engine. + text shaping engine. Using the HarfBuzz library allows + programs to convert a sequence of Unicode input text into + properly formatted and positioned output—for any writing + system and language. + - The current HarfBuzz codebase, formerly known as harfbuzz-ng, is - versioned 1.x.x and is stable and under active maintenance. This is - what is used in latest versions of Firefox, GNOME, ChromeOS, Chrome, - LibreOffice, XeTeX, Android, and KDE, among other places. The canonical - source tree is available - here. - Also available on - github. + The canonical source-code tree is available at + cgit.freedesktop.org/harfbuzz + and at + github.com/harfbuzz/harfbuzz. See for release tarballs. - - - The old HarfBuzz codebase, these days known as harfbuzz-old, was - derived from FreeType, - Pango, and - Qt and is available - here. - It is not actively developed or maintained, and is extremely buggy. All - users are encouraged to switch over to the new HarfBuzz as soon as - possible. There are no release tarballs of old HarfBuzz whatsoever. - @@ -58,6 +49,38 @@ http://[SERVER]/libharfbuzz/.--> + + + + The current HarfBuzz codebase is versioned 1.x.x and is stable + and under active maintenance. This is what is used in latest + versions of Firefox, GNOME, ChromeOS, Chrome, LibreOffice, + XeTeX, Android, and KDE, among other places. + + + Prior to 2012, the original HarfBuzz codebase (which, these + days, is referred to as harfbuzz-old) was + derived from code in FreeType, Pango, and + Qt. + It is not actively developed or + maintained, and is extremely buggy. All users of harfbuzz-old + are encouraged to switch over to the new HarfBuzz as soon as possible. + + + To make this distinction clearer in discussions, the current + HarfBuzz codebase is sometimes referred to as + harfbuzz-ng. + + + For reference purposes, the harfbuzz-old source tree is archived + here. There + are no release tarballs of harfbuzz-old whatsoever. + + + Reference manual Core API From 9aa865dcc68ec207741e07ba3f7aacf4ac750c1c Mon Sep 17 00:00:00 2001 From: Nathan Willis Date: Fri, 12 Oct 2018 18:22:41 -0500 Subject: [PATCH 195/255] Docs: usermanual, minor cleanup to What Is HarfBuzz chapter. --- docs/usermanual-what-is-harfbuzz.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/usermanual-what-is-harfbuzz.xml b/docs/usermanual-what-is-harfbuzz.xml index 6a3ac1029..0c961e2f7 100644 --- a/docs/usermanual-what-is-harfbuzz.xml +++ b/docs/usermanual-what-is-harfbuzz.xml @@ -80,8 +80,8 @@ Text shaping is a fairly low-level operation. HarfBuzz is - used directly by graphical rendering libraries like Pango, as well as by the layout + used directly by text-handling libraries like Pango, as well as by the layout engines in Firefox, LibreOffice, and Chromium. Unless you are writing one of these layout engines yourself, you will probably not need to use HarfBuzz: normally, @@ -222,7 +222,7 @@ What does HarfBuzz do? HarfBuzz provides OpenType text shaping through a cross-platform - C API that accepts sequences of Unicode input text. Currently, + C API that accepts sequences of Unicode codepoints as input. Currently, the following OpenType shaping models are supported: From 3a27e8fb97f716c17b03e3a4a634a4900bcb6045 Mon Sep 17 00:00:00 2001 From: Nathan Willis Date: Fri, 12 Oct 2018 18:23:26 -0500 Subject: [PATCH 196/255] Docs: usermanual, add Shaping Concepts chapter. --- docs/harfbuzz-docs.xml | 5 +- docs/usermanual-shaping-concepts.xml | 368 +++++++++++++++++++++++++++ 2 files changed, 371 insertions(+), 2 deletions(-) create mode 100644 docs/usermanual-shaping-concepts.xml diff --git a/docs/harfbuzz-docs.xml b/docs/harfbuzz-docs.xml index 48ea67e60..b7d5cec72 100644 --- a/docs/harfbuzz-docs.xml +++ b/docs/harfbuzz-docs.xml @@ -13,8 +13,8 @@ HarfBuzz is an OpenType text shaping engine. Using the HarfBuzz library allows - programs to convert a sequence of Unicode input text into - properly formatted and positioned output—for any writing + programs to convert a sequence of Unicode input into + properly formatted and positioned text output—for any writing system and language. @@ -34,6 +34,7 @@ + diff --git a/docs/usermanual-shaping-concepts.xml b/docs/usermanual-shaping-concepts.xml new file mode 100644 index 000000000..8c49ab136 --- /dev/null +++ b/docs/usermanual-shaping-concepts.xml @@ -0,0 +1,368 @@ + + Shaping concepts +
+ Text shaping + + Text shaping is the process of transforming a sequence of Unicode + codepoints that represent individual characters (letters, + diacritics, tone marks, numbers, symbols, etc.) into the + orthographically and linguistically correct two-dimensional layout + of glyph shapes taken from a specified font. + + + For some writing systems (or scripts) and + languages, the process is simple, requiring the shaper to do + little more than advance the horizontal position forward by the + correct amount for each successive glyph. + + + But, for complex scripts, any combination of + several shaping operations may be required, and the rules for how + and when they are applied vary from script to script. HarfBuzz and + other shaping engines implement these rules. + + + The exact rules and necessary operations for a particular script + constitute a shaping model. OpenType + specifies a set of shaping models that covers all of + Unicode. Other shaping models are available, however, including + Graphite and Apple Advanced Typography (AAT). + +
+ +
+ Complex scripts + + In text-shaping terminology, scripts are generally classified as + either complex or non-complex. + + + Complex scripts are those for which transforming the input + sequence into the final layout requires some combination of + operations—such as context-dependent substitutions, + context-dependent mark positioning, glyph-to-glyph joining, + glyph reordering, or glyph stacking. + + + In some complex scripts, the shaping rules require that a text + run be divided into syllables before the operations can be + applied. Other complex scripts may apply shaping operations over + entire words or over the entire text run, with no subdivision + required. + + + Non-complex scripts, by definition, do not require these + operations. However, correctly shaping a text run in a + non-complex script may still involve Unicode normalization, + ligature substitutions, mark positioning, kerning, and applying + other font features. The key difference is that a text run in a + non-complex script can be processed sequentially and in the same + order as the input sequence of Unicode codepoints, without + requiring an analysis stage. + +
+ +
+ Shaping operations + + Shaping a complex-script text run involves transforming the + input sequence of Unicode codepoints with some combination of + operations that is specified in the shaping model for the + script. + + + The specific conditions that trigger a given operation for a + text run varies from script to script, as do the order that the + operations are performed in and which codepoints are + affected. However, the same general set of shaping operations is + common to all of the complex-script shaping models. + + + + + + A reordering operation moves a glyph + from its original ("logical") position in the sequence to + some other ("visual") position. + + + The shaping model for a given complex script might involve + more than one reordering step. + + + + + + A joining operation replaces a glyph + with an alternate form that is designed to connect with one + or more of the adjacent glyphs in the sequence. + + + + + + A contextual substitution operation + replaces either a single glyph or a subsequence of several + glyphs with an alternate glyph. This substitution is + performed when the original glyph or subsequence of glyphs + occurs in a specified position with respect to the + surrounding sequence. For example, one substitution might be + performed only when the target glyph is the first glyph in + the sequence, while another substitution is performed only + when a different target glyph occurs immediately after a + particular string pattern. + + + The shaping model for a given complex script might involve + multiple contextual-substitution operations, each applying + to different target glyphs and patterns, and which are + performed in separate steps. + + + + + + A contextual positioning operation + moves the horizontal and/or vertical position of a + glyph. This positioning move is performed when the glyph + occurs in a specified position with respect to the + surrounding sequence. + + + Many contextual positioning operations are used to place + mark glyphs (such as diacritics, vowel + signs, and tone markers) with respect to + base glyphs. However, some complex + scripts may use contextual positioning operations to + correctly place base glyphs as well, such as + when the script uses stacking characters. + + + + +
+ +
+ Unicode character categories + + Shaping models are typically specified with respect to how + scripts are defined in the Unicode standard. + + + Every codepoint in the Unicode Character Database (UCD) is + assigned a Unicode General Category (UGC), + which provides the most fundamental information about the + codepoint: whether the codepoint represents a + Letter, a Mark, a + Number, Punctuation, a + Symbol, a Separator, + or something else (Other). + + + These UGC properties are "Major" categories. Each codepoint is + further assigned to a "minor" category within its Major + category, such as "Letter, uppercase" (Lu) or + "Letter, modifier" (Lm). + + + Shaping models are concerned primarily with Letter and Mark + codepoints. The minor categories of Mark codepoints are + particularly important for shaping. Marks can be nonspacing + (Mn), spacing combining + (Mc), or enclosing (Me). + + + In addition to the UGC property, codepoints in the Indic and + Southeast Asian scripts are also assigned + Unicode Indic Syllabic Category (UISC) and + Unicode Indic Positional Category (UIPC) + property that provides more detailed information needed for + shaping. + + + The UISC property sub-categorizes Letters and Marks according to + common script-shaping behaviors. For example, UISC distinguishes + between consonant letters, vowel letters, and vowel marks. The + UIPC property sub-categorizes Mark codepoints by the visual + position that they occupy (above, below, right, left, or in + multiple positions). + + + Some complex scripts require that the text run be split into + syllables, and what constitutes a valid syllable in these + scripts is specified in regular expressions of the Letter and + Mark codepoints that take the UISC and UIPC properties into account. + + +
+ +
+ Text runs + + Real-world text usually contains codepoints from a mixture of + different Unicode scripts (including punctuation, numbers, symbols, + white-space characters, and other codepoints that do not belong + to any script). Real-world text may also be marked up with + formatting that changes font properties (including the font, + font style, and font size). + + + For shaping purposes, all real-world text streams must be first + segmented into runs that have a uniform set of properties. + + + In particular, shaping models always assume that every codepoint + in a text run has the same direction, + script tag, and + language tag. + +
+ +
+ OpenType shaping models + + OpenType provides shaping models for the following scripts: + + + + + + The default shaping model handles all + non-complex scripts, and may also be used as a fallback for + handling unrecognized scripts. + + + + + + The Indic shaping model handles the Indic + scripts Bengali, Devanagari, Gujarati, Gurmukhi, Kannada, + Malayalam, Oriya, Tamil, Telugu, and Sinhala. + + + The Indic shaping model was revised significantly in + 2005. To denote the change, a new set of script + tags was assigned for Bengali, Devanagari, + Gujarati, Gurmukhi, Kannada, Malayalam, Oriya, Tamil, and + Telugu. For the sake of clarity, the term "Indic2" is + sometimes used to refer to the current, revised shaping + model. + + + + + + The Arabic shaping model supports + Arabic, Mongolian, N'Ko, Syriac, and several other connected + or cursive scripts. + + + + + + The Thai/Lao shaping model supports + the Thai and Lao scripts. + + + + + + The Khmer shaping model supports the + Khmer script. + + + + + + The Myanmar shaping model supports the + Myanmar (or Burmese) script. + + + + + + The Tibetan shaping model supports the + Tibetan script. + + + + + + The Hangul shaping model supports the + Hangul script. + + + + + + The Hebrew shaping model supports the + Hebrew script. + + + + + + The Universal Shaping Engine (USE) + shaping model supports complex scripts not covered by one of + the above, script-specific shaping models, including + Javanese, Balinese, Buginese, Batak, Chakma, Lepcha, Modi, + Phags-pa, Tagalog, Siddham, Sundanese, Tai Le, Tai Tham, Tai + Viet, and many others. + + + + + + Text runs that do not fall under one of the above shaping + models may still require processing by a shaping engine. Of + particular note is Emoji shaping, which + may involve variation-selector sequences and glyph + substitution. Emoji shaping is handled by the default + shaping model. + + + + + +
+ +
+ Graphite shaping + + In contrast to OpenType shaping, Graphite shaping does not + specify a predefined set of shaping models or a set of supported + scripts. + + + Instead, each Graphite font contains a complete set of rules that + implement the required shaping model for the intended + script. These rules include finite-state machines to match + sequences of codepoints to the shaping operations to perform. + + + Graphite shaping can perform the same shaping operations used in + OpenType shaping, as well as other functions that have not been + defined for OpenType shaping. + +
+ +
+ AAT shaping + + In contrast to OpenType shaping, AAT shaping does not specify a + predefined set of shaping models or a set of supported scripts. + + + Instead, each AAT font includes a complete set of rules that + implement the desired shaping model for the intended + script. These rules include finite-state machines to match glyph + sequences and the shaping operations to perform. + + + Notably, AAT shaping rules are expressed for glyphs in the font, + not for Unicode codepoints. AAT shaping can perform the same + shaping operations used in OpenType shaping, as well as other + functions that have not been defined for OpenType shaping. + +
+
From 9e7efa3f47557a77852a15d89619787fd9933ed1 Mon Sep 17 00:00:00 2001 From: Nathan Willis Date: Tue, 16 Oct 2018 17:46:03 -0500 Subject: [PATCH 197/255] Docs: usermanual, add API Overview to Hello HarfBuzz chapter. Start Terminology section. --- docs/usermanual-hello-harfbuzz.xml | 309 ++++++++++++++++++++--------- 1 file changed, 212 insertions(+), 97 deletions(-) diff --git a/docs/usermanual-hello-harfbuzz.xml b/docs/usermanual-hello-harfbuzz.xml index 221692c60..188d449de 100644 --- a/docs/usermanual-hello-harfbuzz.xml +++ b/docs/usermanual-hello-harfbuzz.xml @@ -1,99 +1,214 @@ - - Hello, HarfBuzz - - Here's the simplest HarfBuzz that can possibly work. We will improve - it later. - - - - - Create a buffer and put your text in it. - - - - - #include <hb.h> - hb_buffer_t *buf; - buf = hb_buffer_create(); - hb_buffer_add_utf8(buf, text, strlen(text), 0, strlen(text)); - - - - - Guess the script, language and direction of the buffer. - - - - - hb_buffer_guess_segment_properties(buf); - - - - - Create a face and a font, using FreeType for now. - - - - - #include <hb-ft.h> - FT_New_Face(ft_library, font_path, index, &face) - hb_font_t *font = hb_ft_font_create(face); - - - - - Shape! - - - - - hb_shape(font, buf, NULL, 0); - - - - - Get the glyph and position information. - - - - - hb_glyph_info_t *glyph_info = hb_buffer_get_glyph_infos(buf, &glyph_count); - hb_glyph_position_t *glyph_pos = hb_buffer_get_glyph_positions(buf, &glyph_count); - - - - - Iterate over each glyph. - - - - - for (i = 0; i < glyph_count; ++i) { - glyphid = glyph_info[i].codepoint; - x_offset = glyph_pos[i].x_offset / 64.0; - y_offset = glyph_pos[i].y_offset / 64.0; - x_advance = glyph_pos[i].x_advance / 64.0; - y_advance = glyph_pos[i].y_advance / 64.0; - draw_glyph(glyphid, cursor_x + x_offset, cursor_y + y_offset); - cursor_x += x_advance; - cursor_y += y_advance; - } - - - - - Tidy up. - - - - - hb_buffer_destroy(buf); - hb_font_destroy(hb_ft_font); - + + Getting started with HarfBuzz +
+ An overview of the HarfBuzz shaping API + + The core of the HarfBuzz shaping API is the function + hb_shape(). This function takes a font, a + buffer containing a string of Unicode codepoints and + (optionally) a list of font features as its input. It replaces + the codepoints in the buffer with the corresponding glyphs from + the font, correctly ordered and positioned, and with any of the + optional font features applied. + + + In addition to holding the pre-shaping input (the Unicode + codepoints that comprise the input string) and the post-shaping + output (the glyphs and positions), a HarfBuzz buffer has several + properties that affect shaping. The most important are the + text-flow direction (e.g., left-to-right, right-to-left, + top-to-bottom, or bottom-to-top), the script tag, and the + language tag. HarfBuzz can attempt to guess the correct values + for the buffer based on its contents if you do not set them + explicitly. + - - This example shows enough to get us started using HarfBuzz. Now we - are going to use the remainder of HarfBuzz's API to refine that - example and improve our text shaping capabilities. - + + For input string buffers, flags are available to denote when the + buffer represents the beginning or end of a paragraph, to + indicate whether or not to visibly render Unicode Default + Ignorable codepoints, and to modify the cluster-merging + behavior for the buffer. For shaped output buffers, the + individual X and Y offsets and widths of each glyph are + accessible. HarfBuzz also flags glyphs as + UNSAFE_TO_BREAK if breaking the string at + that glyph (e.g., in a line-breaking or hyphenation process) + would alter the shaping output for the buffer. + + + + HarfBuzz also provides methods to compare the contents of + buffers, join buffers, normalize buffer contents, and handle + invalid codepoints, as well as to determine the state of a + buffer (e.g., input codepoints or output glyphs). Buffer + lifecycles are managed and all buffers are reference-counted. + + + + Although the default hb_shape() function is + sufficient for most use cases, a variant is also provide that + lets you specify which of HarfBuzz's shapers to use on a buffer. + + + + HarfBuzz can read TrueType fonts, TrueType collections, OpenType + fonts, and OpenType collections. Functions are provided to query + font objects about metrics, Unicode coverage, available tables and + features, and variation selectors. Individual glyphs can also be + queried for metrics, variations, and glyph names. OpenType + variable fonts are supported, and HarfBuzz allows you to set + variation-axis coordinates on font objects. + + + + HarfBuzz provides glue code to integrate with FreeType, GObject, + Uniscribe, and CoreText. Support for integrating with + DirectWrite is experimental at present. + +
+ +
+ Terminology + + + shaper + + + In HarfBuzz, a shaper is a + handler for a specific script shaping model. HarfBuzz + implements separate shapers for Indic, Arabic, Thai and + Lao, Khmer, Myanmar, Tibetan, Hangul, Hebrew, the + Universal Shaping Engine (USE), and a default shaper for + non-complex scripts. + + + + + + cluster + + + In text shaping, a cluster is a + sequence of codepoints that must be handled as an + indivisible unit. Clusters can include codepoint + sequences that form a ligature or base-and-mark + sequences. Tracking and preserving clusters is important + when shaping operations might separate or reorder + codepoints. + + + HarfBuzz provides three cluster + levels that implement different + approaches to the problem of preserving clusters during + shaping operations. + + + + + + + +
+ + +
+ A simple shaping example + + + Below is the simplest HarfBuzz shaping example possible. + + + + + Create a buffer and put your text in it. + + + + + #include <hb.h> + hb_buffer_t *buf; + buf = hb_buffer_create(); + hb_buffer_add_utf8(buf, text, strlen(text), 0, strlen(text)); + + + + + Guess the script, language and direction of the buffer. + + + + + hb_buffer_guess_segment_properties(buf); + + + + + Create a face and a font, using FreeType for now. + + + + + #include <hb-ft.h> + FT_New_Face(ft_library, font_path, index, &face) + hb_font_t *font = hb_ft_font_create(face); + + + + + Shape! + + + + + hb_shape(font, buf, NULL, 0); + + + + + Get the glyph and position information. + + + + + hb_glyph_info_t *glyph_info = hb_buffer_get_glyph_infos(buf, &glyph_count); + hb_glyph_position_t *glyph_pos = hb_buffer_get_glyph_positions(buf, &glyph_count); + + + + + Iterate over each glyph. + + + + + for (i = 0; i < glyph_count; ++i) { + glyphid = glyph_info[i].codepoint; + x_offset = glyph_pos[i].x_offset / 64.0; + y_offset = glyph_pos[i].y_offset / 64.0; + x_advance = glyph_pos[i].x_advance / 64.0; + y_advance = glyph_pos[i].y_advance / 64.0; + draw_glyph(glyphid, cursor_x + x_offset, cursor_y + y_offset); + cursor_x += x_advance; + cursor_y += y_advance; + } + + + + + Tidy up. + + + + + hb_buffer_destroy(buf); + hb_font_destroy(hb_ft_font); + + + + This example shows enough to get us started using HarfBuzz. In + the sections that follow, we will use the remainder of + HarfBuzz's API to refine and extend the example and improve its + text-shaping capabilities. + +
From 163ab81ab0f4000d968cc55b418402497e605e6c Mon Sep 17 00:00:00 2001 From: Nathan Willis Date: Tue, 16 Oct 2018 17:48:15 -0500 Subject: [PATCH 198/255] Docs: rename Hello HarfBuzz to Getting Started. --- docs/harfbuzz-docs.xml | 2 +- ...manual-hello-harfbuzz.xml => usermanual-getting-started.xml} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename docs/{usermanual-hello-harfbuzz.xml => usermanual-getting-started.xml} (100%) diff --git a/docs/harfbuzz-docs.xml b/docs/harfbuzz-docs.xml index b7d5cec72..15d194cf1 100644 --- a/docs/harfbuzz-docs.xml +++ b/docs/harfbuzz-docs.xml @@ -33,7 +33,7 @@ User's manual - + diff --git a/docs/usermanual-hello-harfbuzz.xml b/docs/usermanual-getting-started.xml similarity index 100% rename from docs/usermanual-hello-harfbuzz.xml rename to docs/usermanual-getting-started.xml From 236285545b5da8513f2b61fc8066ba78308a555a Mon Sep 17 00:00:00 2001 From: Nathan Willis Date: Wed, 17 Oct 2018 10:10:48 -0500 Subject: [PATCH 199/255] Docs: minor, update Makefile w new file name. --- docs/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Makefile.am b/docs/Makefile.am index e48b9ccd8..595dd83e5 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -76,7 +76,7 @@ content_files= \ usermanual-clusters.xml \ usermanual-fonts-and-faces.xml \ usermanual-glyph-information.xml \ - usermanual-hello-harfbuzz.xml \ + usermanual-getting-started.xml \ usermanual-install-harfbuzz.xml \ usermanual-opentype-features.xml \ usermanual-what-is-harfbuzz.xml \ From ed5547f828fe7559cc3331f05780ae9f041b1e0f Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Sat, 20 Oct 2018 15:00:52 +0100 Subject: [PATCH 200/255] Use 'glyphs' instead of 'text' Co-Authored-By: n8willis --- docs/harfbuzz-docs.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/harfbuzz-docs.xml b/docs/harfbuzz-docs.xml index 15d194cf1..ee04bae2f 100644 --- a/docs/harfbuzz-docs.xml +++ b/docs/harfbuzz-docs.xml @@ -14,7 +14,7 @@ HarfBuzz is an OpenType text shaping engine. Using the HarfBuzz library allows programs to convert a sequence of Unicode input into - properly formatted and positioned text output—for any writing + properly formatted and positioned glyph output—for any writing system and language.
From f028da59d902c39e61021b48fc73f2821a9f3be2 Mon Sep 17 00:00:00 2001 From: Nathan Willis Date: Sat, 20 Oct 2018 15:18:29 +0100 Subject: [PATCH 201/255] Minor. --- docs/harfbuzz-docs.xml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/harfbuzz-docs.xml b/docs/harfbuzz-docs.xml index ee04bae2f..6d2411900 100644 --- a/docs/harfbuzz-docs.xml +++ b/docs/harfbuzz-docs.xml @@ -21,11 +21,13 @@ The canonical source-code tree is available at cgit.freedesktop.org/harfbuzz - and at + url="https://github.com/harfbuzz/harfbuzz">github.com/harfbuzz/harfbuzz + and is also available at github.com/harfbuzz/harfbuzz. - See for release tarballs. + url="http://cgit.freedesktop.org/harfbuzz/">cgit.freedesktop.org/harfbuzz. + See for + release tarballs. + @@ -53,7 +55,7 @@ - The current HarfBuzz codebase is versioned 1.x.x and is stable + The current HarfBuzz codebase is versioned 2.x.x and is stable and under active maintenance. This is what is used in latest versions of Firefox, GNOME, ChromeOS, Chrome, LibreOffice, XeTeX, Android, and KDE, among other places. From f9ee0deceebd8952a8d80f3fd7b264b33e70f703 Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Sat, 20 Oct 2018 15:41:00 +0100 Subject: [PATCH 202/255] Minor; drop 'OpenType' from sentence Co-Authored-By: n8willis --- docs/usermanual-what-is-harfbuzz.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/usermanual-what-is-harfbuzz.xml b/docs/usermanual-what-is-harfbuzz.xml index 0c961e2f7..e6fa25290 100644 --- a/docs/usermanual-what-is-harfbuzz.xml +++ b/docs/usermanual-what-is-harfbuzz.xml @@ -221,7 +221,7 @@
What does HarfBuzz do? - HarfBuzz provides OpenType text shaping through a cross-platform + HarfBuzz provides text shaping through a cross-platform C API that accepts sequences of Unicode codepoints as input. Currently, the following OpenType shaping models are supported: From 6e4dd58a4af003eeec93cbe90d1258d91a38b53c Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Sat, 20 Oct 2018 15:44:51 +0100 Subject: [PATCH 203/255] Minor: simplify example code Co-Authored-By: n8willis --- docs/usermanual-getting-started.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/usermanual-getting-started.xml b/docs/usermanual-getting-started.xml index 188d449de..72a374624 100644 --- a/docs/usermanual-getting-started.xml +++ b/docs/usermanual-getting-started.xml @@ -128,7 +128,7 @@ #include <hb.h> hb_buffer_t *buf; buf = hb_buffer_create(); - hb_buffer_add_utf8(buf, text, strlen(text), 0, strlen(text)); + hb_buffer_add_utf8(buf, text, -1, 0, -1); From 722099487be72346e7109872b6abf30696f3b7c3 Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Sat, 20 Oct 2018 15:45:24 +0100 Subject: [PATCH 204/255] Minor; simplify example code Co-Authored-By: n8willis --- docs/usermanual-getting-started.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/usermanual-getting-started.xml b/docs/usermanual-getting-started.xml index 72a374624..69f92dbb0 100644 --- a/docs/usermanual-getting-started.xml +++ b/docs/usermanual-getting-started.xml @@ -138,7 +138,9 @@ - hb_buffer_guess_segment_properties(buf); + hb_buffer_set_direction(buf, HB_DIRECTION_LTR); + hb_buffer_set_script(buf, HB_SCRIPT_LATIN); + hb_buffer_set_language(buf, hb_language_from_string("en", -1)); From ccdfb634382596a6114380c72f2f344b1af23f94 Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Sat, 20 Oct 2018 15:46:04 +0100 Subject: [PATCH 205/255] Trivial; typo. Co-Authored-By: n8willis --- docs/usermanual-what-is-harfbuzz.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/usermanual-what-is-harfbuzz.xml b/docs/usermanual-what-is-harfbuzz.xml index e6fa25290..0c01adae2 100644 --- a/docs/usermanual-what-is-harfbuzz.xml +++ b/docs/usermanual-what-is-harfbuzz.xml @@ -161,7 +161,7 @@ Similarly, each Arabic character has four different variants - corresponding to the different positions in might appear in + corresponding to the different positions it might appear in within a sequence. Inside a font, there will be separate glyphs for the initial, medial, final, and isolated forms of each letter, each at a different glyph ID. From e89f43dc0884cb4a73beff86e49b7bd8565a01f1 Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Sat, 20 Oct 2018 16:12:45 +0100 Subject: [PATCH 206/255] Minor; rewording unsafe-to-break note. Co-Authored-By: n8willis --- docs/usermanual-getting-started.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/usermanual-getting-started.xml b/docs/usermanual-getting-started.xml index 69f92dbb0..07593f56e 100644 --- a/docs/usermanual-getting-started.xml +++ b/docs/usermanual-getting-started.xml @@ -33,7 +33,7 @@ accessible. HarfBuzz also flags glyphs as UNSAFE_TO_BREAK if breaking the string at that glyph (e.g., in a line-breaking or hyphenation process) - would alter the shaping output for the buffer. + would require re-shaping the text. From 01400f7425f7aec852f39ebee17aa502a74025fb Mon Sep 17 00:00:00 2001 From: Nathan Willis Date: Sat, 20 Oct 2018 17:21:49 +0100 Subject: [PATCH 207/255] Usermanual; minor wording changes. --- docs/usermanual-getting-started.xml | 14 ++++++------- docs/usermanual-install-harfbuzz.xml | 10 ++++++++- docs/usermanual-what-is-harfbuzz.xml | 31 +++++++++------------------- 3 files changed, 26 insertions(+), 29 deletions(-) diff --git a/docs/usermanual-getting-started.xml b/docs/usermanual-getting-started.xml index 07593f56e..f8f525c65 100644 --- a/docs/usermanual-getting-started.xml +++ b/docs/usermanual-getting-started.xml @@ -18,9 +18,7 @@ properties that affect shaping. The most important are the text-flow direction (e.g., left-to-right, right-to-left, top-to-bottom, or bottom-to-top), the script tag, and the - language tag. HarfBuzz can attempt to guess the correct values - for the buffer based on its contents if you do not set them - explicitly. + language tag. @@ -29,7 +27,8 @@ indicate whether or not to visibly render Unicode Default Ignorable codepoints, and to modify the cluster-merging behavior for the buffer. For shaped output buffers, the - individual X and Y offsets and widths of each glyph are + individual X and Y offsets and advances + (the logical dimensions) of each glyph are accessible. HarfBuzz also flags glyphs as UNSAFE_TO_BREAK if breaking the string at that glyph (e.g., in a line-breaking or hyphenation process) @@ -61,9 +60,10 @@ - HarfBuzz provides glue code to integrate with FreeType, GObject, - Uniscribe, and CoreText. Support for integrating with - DirectWrite is experimental at present. + HarfBuzz provides glue code to integrate with various other + libraries, including FreeType, GObject, and CoreText. Support + for integrating with Uniscribe and DirectWrite is experimental + at present.
diff --git a/docs/usermanual-install-harfbuzz.xml b/docs/usermanual-install-harfbuzz.xml index cd1e2e134..54b5fc954 100644 --- a/docs/usermanual-install-harfbuzz.xml +++ b/docs/usermanual-install-harfbuzz.xml @@ -279,7 +279,11 @@ graphics-rendering library. The default setting is to check for the presence of Cairo and, if it is found, build with Cairo support. -
+ + + Note: Cairo is used only by the HarfBuzz + command-line utilities, and not by the HarfBuzz library. + @@ -296,6 +300,10 @@ is to check for the presence of Fontconfig and, if it is found, build with Fontconfig support. + + Note: Fontconfig is used only by the HarfBuzz + command-line utilities, and not by the HarfBuzz library. + diff --git a/docs/usermanual-what-is-harfbuzz.xml b/docs/usermanual-what-is-harfbuzz.xml index 0c01adae2..4719dd4ff 100644 --- a/docs/usermanual-what-is-harfbuzz.xml +++ b/docs/usermanual-what-is-harfbuzz.xml @@ -296,10 +296,7 @@ In addition to OpenType shaping, HarfBuzz supports the latest version of Graphite shaping. HarfBuzz currently supports AAT - shaping only on macOS and iOS systems, and in a pass-through - fashion: HarfBuzz hands off AAT support to the system CoreText - library. However, full, built-in AAT support within HarfBuzz is - under development. + shaping only on macOS and iOS systems. @@ -321,13 +318,9 @@ all color-font formats (CBDT, sbix, COLR/CPAL, and SVG-OT) and OpenType variable fonts. HarfBuzz - also includes a font-subsetting feature. - - - - HarfBuzz can perform some low-level math-shaping operations, - although it does not currently perform full shaping for - mathematical typesetting. + also includes a font-subsetting feature. HarfBuzz can perform + some low-level math-shaping operations, although it does not + currently perform full shaping for mathematical typesetting. @@ -355,9 +348,10 @@ HarfBuzz won't help you with bidirectionality. If you want to lay out text that includes a mix of Hebrew and English, you - will need to ensure that each buffer provided to HarfBuzz has its - characters in the correct layout order. This will be different - from the logical order in which the Unicode text is stored. In + will need to ensure that each buffer provided to HarfBuzz + has all of its characters in the same order and that the + directionality of the buffer is set correctly. This may mean + segmenting the text before it is placed into HarfBuzz buffers. In other words, the user will hit the keys in the following sequence: @@ -374,7 +368,7 @@ This reordering is called bidi processing ("bidi" is short for bidirectional), and there's an algorithm as an annex to the Unicode Standard which tells you how - to reorder a string from logical order into presentation order. + to process a string of mixed directionality. Before sending your string to HarfBuzz, you may need to apply the bidi algorithm to it. Libraries such as ICU and From e110032b914db9f417cc152b2beb51cda0a91dd7 Mon Sep 17 00:00:00 2001 From: Nathan Willis Date: Mon, 29 Oct 2018 16:42:59 -0500 Subject: [PATCH 208/255] Usermanual: update DTD in chapter XML to avoid HTML entity parsing errors. --- docs/usermanual-what-is-harfbuzz.xml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/usermanual-what-is-harfbuzz.xml b/docs/usermanual-what-is-harfbuzz.xml index 4719dd4ff..4d9acc99f 100644 --- a/docs/usermanual-what-is-harfbuzz.xml +++ b/docs/usermanual-what-is-harfbuzz.xml @@ -1,3 +1,9 @@ + + + +]> What is HarfBuzz? @@ -12,7 +18,7 @@ HarfBuzz can properly shape all of the world's major writing systems. It runs on all major operating systems and software - platforms, and it supports all of the modern font formats in use + platforms and it supports the modern font formats in use today.
@@ -372,7 +378,7 @@ Before sending your string to HarfBuzz, you may need to apply the bidi algorithm to it. Libraries such as ICU and fribidi can do this for you. + url="http://fribidi.org/">fribidi can do this for you. From 9f4b375e396fe65b30c792b9524a732da0b477d1 Mon Sep 17 00:00:00 2001 From: Nathan Willis Date: Mon, 29 Oct 2018 17:10:53 -0500 Subject: [PATCH 209/255] Usermanual: minor wording updates, build fixes. --- ...-buffers-language-script-and-direction.xml | 8 +++++++- docs/usermanual-clusters.xml | 6 ++++++ docs/usermanual-fonts-and-faces.xml | 8 +++++++- docs/usermanual-getting-started.xml | 6 ++++++ docs/usermanual-glyph-information.xml | 8 +++++++- docs/usermanual-install-harfbuzz.xml | 20 ++++++++++++++++--- docs/usermanual-opentype-features.xml | 8 +++++++- docs/usermanual-shaping-concepts.xml | 6 ++++++ docs/usermanual-what-is-harfbuzz.xml | 12 ++++++----- 9 files changed, 70 insertions(+), 12 deletions(-) diff --git a/docs/usermanual-buffers-language-script-and-direction.xml b/docs/usermanual-buffers-language-script-and-direction.xml index 9eddb71a9..68ce9bd0b 100644 --- a/docs/usermanual-buffers-language-script-and-direction.xml +++ b/docs/usermanual-buffers-language-script-and-direction.xml @@ -1,3 +1,9 @@ + + + +]> Buffers, language, script and direction @@ -74,4 +80,4 @@ void somefunc(hb_buffer_t *buffer) {
-
\ No newline at end of file +
diff --git a/docs/usermanual-clusters.xml b/docs/usermanual-clusters.xml index 608371b00..7b2c7adc7 100644 --- a/docs/usermanual-clusters.xml +++ b/docs/usermanual-clusters.xml @@ -1,3 +1,9 @@ + + + +]> Clusters diff --git a/docs/usermanual-fonts-and-faces.xml b/docs/usermanual-fonts-and-faces.xml index 7de0f051a..553600439 100644 --- a/docs/usermanual-fonts-and-faces.xml +++ b/docs/usermanual-fonts-and-faces.xml @@ -1,3 +1,9 @@ + + + +]> Fonts and faces
@@ -15,4 +21,4 @@
-
\ No newline at end of file +
diff --git a/docs/usermanual-getting-started.xml b/docs/usermanual-getting-started.xml index f8f525c65..9e16ecbf2 100644 --- a/docs/usermanual-getting-started.xml +++ b/docs/usermanual-getting-started.xml @@ -1,3 +1,9 @@ + + + +]> Getting started with HarfBuzz
diff --git a/docs/usermanual-glyph-information.xml b/docs/usermanual-glyph-information.xml index ca674c0c5..78f06c739 100644 --- a/docs/usermanual-glyph-information.xml +++ b/docs/usermanual-glyph-information.xml @@ -1,3 +1,9 @@ + + + +]> Glyph information @@ -5,4 +11,4 @@ - \ No newline at end of file + diff --git a/docs/usermanual-install-harfbuzz.xml b/docs/usermanual-install-harfbuzz.xml index 54b5fc954..a6484fc5a 100644 --- a/docs/usermanual-install-harfbuzz.xml +++ b/docs/usermanual-install-harfbuzz.xml @@ -1,3 +1,9 @@ + + + +]> Installing HarfBuzz @@ -376,11 +382,16 @@ --with-uniscribe - Use the Uniscribe library. (Default = no) + Use the Uniscribe + library (experimental). (Default = no) This option enables or disables usage of the Uniscribe - font-rendering library. Uniscribe is available on Windows systems. + font-rendering library. Uniscribe is available on + Windows systems. Uniscribe support is used only for + testing purposes and does not need to be enabled for + HarfBuzz to run on Windows systems. @@ -393,7 +404,10 @@ This option enables or disables usage of the DirectWrite - font-rendering library. DirectWrite is available on Windows systems. + font-rendering library. DirectWrite is available on + Windows systems. DirectWrite support is used only for + testing purposes and does not need to be enabled for + HarfBuzz to run on Windows systems. diff --git a/docs/usermanual-opentype-features.xml b/docs/usermanual-opentype-features.xml index 470bab8d1..51ff55a77 100644 --- a/docs/usermanual-opentype-features.xml +++ b/docs/usermanual-opentype-features.xml @@ -1,3 +1,9 @@ + + + +]> Shaping and shape plans
@@ -10,4 +16,4 @@
-
\ No newline at end of file +
diff --git a/docs/usermanual-shaping-concepts.xml b/docs/usermanual-shaping-concepts.xml index 8c49ab136..bc9f1b830 100644 --- a/docs/usermanual-shaping-concepts.xml +++ b/docs/usermanual-shaping-concepts.xml @@ -1,3 +1,9 @@ + + + +]> Shaping concepts
diff --git a/docs/usermanual-what-is-harfbuzz.xml b/docs/usermanual-what-is-harfbuzz.xml index 4d9acc99f..8532d7cc2 100644 --- a/docs/usermanual-what-is-harfbuzz.xml +++ b/docs/usermanual-what-is-harfbuzz.xml @@ -91,7 +91,8 @@ engines in Firefox, LibreOffice, and Chromium. Unless you are writing one of these layout engines yourself, you will probably not need to use HarfBuzz: normally, - lower-level libraries will turn text into glyphs for you. + a layout engine, toolkit, or other library will turn text into + glyphs for you. However, if you are writing a layout engine @@ -301,8 +302,8 @@ In addition to OpenType shaping, HarfBuzz supports the latest - version of Graphite shaping. HarfBuzz currently supports AAT - shaping only on macOS and iOS systems. + version of Graphite shaping (the "Graphite 2" model) and AAT + shaping. @@ -313,8 +314,9 @@ - HarfBuzz can run on top of the FreeType, CoreText, DirectWrite, - or Uniscribe font renderers. + HarfBuzz is designed and tested to run on top of the FreeType + font renderer. It can run on Linux, Android, Windows, macOS, and + iOS systems. From f236f790884d7b5c7afb73768724c360d4ea5212 Mon Sep 17 00:00:00 2001 From: Nathan Willis Date: Tue, 30 Oct 2018 11:24:56 -0500 Subject: [PATCH 210/255] Docs Makefile: sync SGML list to harfbuzz-docs.xml include list. Hopefully fixes distcheck failure. --- docs/Makefile.am | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/Makefile.am b/docs/Makefile.am index 595dd83e5..9b54b40e1 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -72,14 +72,15 @@ HTML_IMAGES= \ # Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). # e.g. content_files=running.sgml building.sgml changes-2.0.sgml content_files= \ - usermanual-buffers-language-script-and-direction.xml \ - usermanual-clusters.xml \ - usermanual-fonts-and-faces.xml \ - usermanual-glyph-information.xml \ - usermanual-getting-started.xml \ - usermanual-install-harfbuzz.xml \ - usermanual-opentype-features.xml \ usermanual-what-is-harfbuzz.xml \ + usermanual-install-harfbuzz.xml \ + usermanual-getting-started.xml \ + usermanual-shaping-concepts.xml \ + usermanual-buffers-language-script-and-direction.xml \ + usermanual-fonts-and-faces.xml \ + usermanual-clusters.xml \ + usermanual-opentype-features.xml \ + usermanual-glyph-information.xml \ version.xml # SGML files where gtk-doc abbrevations (#GtkWidget) are expanded From a2a7422aaf47dd43c2c55ad48dd15513f9d5b081 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 30 Oct 2018 13:14:56 -0700 Subject: [PATCH 211/255] [CBDT] Bound checks in reference_png --- src/hb-ot-color-cbdt-table.hh | 57 +++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index ae6d3b5e6..f1b1196bf 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -434,7 +434,6 @@ struct CBDT case 17: { if (unlikely (image_length < GlyphBitmapDataFormat17::min_size)) return false; - const GlyphBitmapDataFormat17& glyphFormat17 = StructAtOffset (this->cbdt, image_offset); glyphFormat17.glyphMetrics.get_extents (extents); @@ -473,30 +472,42 @@ struct CBDT if (!subtable_record->get_image_data (glyph, base, &image_offset, &image_length, &image_format)) return hb_blob_get_empty (); - switch (image_format) { - case 17: { - const GlyphBitmapDataFormat17& glyphFormat17 = - StructAtOffset (this->cbdt, image_offset); - return hb_blob_create_sub_blob (cbdt_blob, - image_offset + GlyphBitmapDataFormat17::min_size, - glyphFormat17.data.len); - } - case 18: { - const GlyphBitmapDataFormat18& glyphFormat18 = - StructAtOffset (this->cbdt, image_offset); - return hb_blob_create_sub_blob (cbdt_blob, - image_offset + GlyphBitmapDataFormat18::min_size, - glyphFormat18.data.len); - } - case 19: { - const GlyphBitmapDataFormat19& glyphFormat19 = - StructAtOffset (this->cbdt, image_offset); - return hb_blob_create_sub_blob (cbdt_blob, - image_offset + GlyphBitmapDataFormat19::min_size, - glyphFormat19.data.len); - } + if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length)) + return hb_blob_get_empty (); + + switch (image_format) + { + case 17: { + if (unlikely (image_length < GlyphBitmapDataFormat17::min_size)) + return hb_blob_get_empty (); + const GlyphBitmapDataFormat17& glyphFormat17 = + StructAtOffset (this->cbdt, image_offset); + return hb_blob_create_sub_blob (cbdt_blob, + image_offset + GlyphBitmapDataFormat17::min_size, + glyphFormat17.data.len); + } + case 18: { + if (unlikely (image_length < GlyphBitmapDataFormat18::min_size)) + return hb_blob_get_empty (); + const GlyphBitmapDataFormat18& glyphFormat18 = + StructAtOffset (this->cbdt, image_offset); + return hb_blob_create_sub_blob (cbdt_blob, + image_offset + GlyphBitmapDataFormat18::min_size, + glyphFormat18.data.len); + } + case 19: { + if (unlikely (image_length < GlyphBitmapDataFormat19::min_size)) + return hb_blob_get_empty (); + const GlyphBitmapDataFormat19& glyphFormat19 = + StructAtOffset (this->cbdt, image_offset); + return hb_blob_create_sub_blob (cbdt_blob, + image_offset + GlyphBitmapDataFormat19::min_size, + glyphFormat19.data.len); + } + } } + return hb_blob_get_empty (); } From dc9bd29feac6675c79343b88a06f03f356f9175b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 30 Oct 2018 13:16:07 -0700 Subject: [PATCH 212/255] [CBDT] Implement Format18 get_extens Part of https://github.com/harfbuzz/harfbuzz/issues/1327 --- src/hb-ot-color-cbdt-table.hh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index f1b1196bf..614cc80ce 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -437,8 +437,16 @@ struct CBDT const GlyphBitmapDataFormat17& glyphFormat17 = StructAtOffset (this->cbdt, image_offset); glyphFormat17.glyphMetrics.get_extents (extents); + break; + } + case 18: { + if (unlikely (image_length < GlyphBitmapDataFormat18::min_size)) + return false; + const GlyphBitmapDataFormat18& glyphFormat18 = + StructAtOffset (this->cbdt, image_offset); + glyphFormat18.glyphMetrics.get_extents (extents); + break; } - break; default: // TODO: Support other image formats. return false; From 881e1054bc66fd07489d661dd5c3f84a5d077edc Mon Sep 17 00:00:00 2001 From: Simon Tooke Date: Tue, 30 Oct 2018 14:16:23 -0400 Subject: [PATCH 213/255] fix various GCC function pointer warnings --- src/hb-debug.hh | 6 +++--- src/hb-set.hh | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hb-debug.hh b/src/hb-debug.hh index 58c190d27..d218e4328 100644 --- a/src/hb-debug.hh +++ b/src/hb-debug.hh @@ -173,7 +173,7 @@ _hb_debug_msg_va (const char *what, fprintf (stderr, "\n"); } -template <> inline void +template <> inline void HB_PRINTF_FUNC(7, 0) _hb_debug_msg_va<0> (const char *what HB_UNUSED, const void *obj HB_UNUSED, const char *func HB_UNUSED, @@ -192,7 +192,7 @@ _hb_debug_msg (const char *what, int level_dir, const char *message, ...) HB_PRINTF_FUNC(7, 8); -template static inline void +template static inline void HB_PRINTF_FUNC(7, 8) _hb_debug_msg (const char *what, const void *obj, const char *func, @@ -216,7 +216,7 @@ _hb_debug_msg<0> (const char *what HB_UNUSED, int level_dir HB_UNUSED, const char *message HB_UNUSED, ...) HB_PRINTF_FUNC(7, 8); -template <> inline void +template <> inline void HB_PRINTF_FUNC(7, 8) _hb_debug_msg<0> (const char *what HB_UNUSED, const void *obj HB_UNUSED, const char *func HB_UNUSED, diff --git a/src/hb-set.hh b/src/hb-set.hh index 0755498ba..2dfcc242a 100644 --- a/src/hb-set.hh +++ b/src/hb-set.hh @@ -53,8 +53,8 @@ struct hb_set_t struct page_t { - inline void init0 (void) { memset (&v, 0, sizeof (v)); } - inline void init1 (void) { memset (&v, 0xff, sizeof (v)); } + inline void init0 (void) { memset (reinterpret_cast(&v), 0, sizeof (v)); } + inline void init1 (void) { memset (reinterpret_cast(&v), 0xff, sizeof (v)); } inline unsigned int len (void) const { return ARRAY_LENGTH_CONST (v); } From a7aba99baab2d6e6105675ceedbe22222fa0f166 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 30 Oct 2018 14:04:09 -0700 Subject: [PATCH 214/255] [name] Rename hb_name_id_t to hb_ot_name_id_t https://github.com/harfbuzz/harfbuzz/pull/1254 --- docs/harfbuzz-sections.txt | 3 +- src/hb-ot-color-cpal-table.hh | 12 ++--- src/hb-ot-color.cc | 6 +-- src/hb-ot-color.h | 4 +- src/hb-ot-layout.cc | 44 ++++++++-------- src/hb-ot-layout.h | 28 +++++----- src/hb-ot-name-table.hh | 6 +-- src/hb-ot-name.cc | 38 +++++++------- src/hb-ot-name.h | 96 +++++++++++++++++------------------ test/api/test-ot-color.c | 30 +++++------ test/api/test-ot-name.c | 8 +-- 11 files changed, 138 insertions(+), 137 deletions(-) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index c33a1c125..6a498e940 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -481,7 +481,8 @@ hb_ot_font_set_funcs
hb-ot-name -hb_name_id_t +hb_ot_name_id_t +HB_OT_NAME_ID_INVALID hb_ot_name_entry_t hb_ot_name_list_names hb_ot_name_get_utf16 diff --git a/src/hb-ot-color-cpal-table.hh b/src/hb-ot-color-cpal-table.hh index 0b4bf377e..df4d9b4e7 100644 --- a/src/hb-ot-color-cpal-table.hh +++ b/src/hb-ot-color-cpal-table.hh @@ -58,21 +58,21 @@ struct CPALV1Tail hb_array (base+paletteFlagsZ, palette_count)[palette_index]; } - inline hb_name_id_t + inline hb_ot_name_id_t get_palette_name_id (const void *base, unsigned int palette_index, unsigned int palette_count) const { - if (!paletteLabelsZ) return HB_NAME_ID_INVALID; + if (!paletteLabelsZ) return HB_OT_NAME_ID_INVALID; return hb_array (base+paletteLabelsZ, palette_count)[palette_index]; } - inline hb_name_id_t + inline hb_ot_name_id_t get_color_name_id (const void *base, unsigned int color_index, unsigned int color_count) const { - if (!colorLabelsZ) return HB_NAME_ID_INVALID; + if (!colorLabelsZ) return HB_OT_NAME_ID_INVALID; return hb_array (base+colorLabelsZ, color_count)[color_index]; } @@ -123,10 +123,10 @@ struct CPAL inline hb_ot_color_palette_flags_t get_palette_flags (unsigned int palette_index) const { return v1 ().get_palette_flags (this, palette_index, numPalettes); } - inline hb_name_id_t get_palette_name_id (unsigned int palette_index) const + inline hb_ot_name_id_t get_palette_name_id (unsigned int palette_index) const { return v1 ().get_palette_name_id (this, palette_index, numPalettes); } - inline hb_name_id_t get_color_name_id (unsigned int color_index) const + inline hb_ot_name_id_t get_color_name_id (unsigned int color_index) const { return v1 ().get_color_name_id (this, color_index, numColors); } inline unsigned int get_palette_colors (unsigned int palette_index, diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index a3cd61905..11fc12afb 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -129,11 +129,11 @@ hb_ot_color_palette_get_count (hb_face_t *face) * have themed palettes like "Spring", "Summer", "Fall", and "Winter". * * Returns: an identifier within @face's `name` table. - * If the requested palette has no name the result is #HB_NAME_ID_INVALID. + * If the requested palette has no name the result is #HB_OT_NAME_ID_INVALID. * * Since: 2.1.0 */ -hb_name_id_t +hb_ot_name_id_t hb_ot_color_palette_get_name_id (hb_face_t *face, unsigned int palette_index) { @@ -149,7 +149,7 @@ hb_ot_color_palette_get_name_id (hb_face_t *face, * * Since: 2.1.0 */ -hb_name_id_t +hb_ot_name_id_t hb_ot_color_palette_color_get_name_id (hb_face_t *face, unsigned int color_index) { diff --git a/src/hb-ot-color.h b/src/hb-ot-color.h index 1cc04d4f3..e2d9a9620 100644 --- a/src/hb-ot-color.h +++ b/src/hb-ot-color.h @@ -49,11 +49,11 @@ hb_ot_color_has_palettes (hb_face_t *face); HB_EXTERN unsigned int hb_ot_color_palette_get_count (hb_face_t *face); -HB_EXTERN hb_name_id_t +HB_EXTERN hb_ot_name_id_t hb_ot_color_palette_get_name_id (hb_face_t *face, unsigned int palette_index); -HB_EXTERN hb_name_id_t +HB_EXTERN hb_ot_name_id_t hb_ot_color_palette_color_get_name_id (hb_face_t *face, unsigned int color_index); diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index ea59b8354..a8cfcf556 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -1053,12 +1053,12 @@ hb_ot_layout_position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer) * Since: 0.9.10 **/ hb_bool_t -hb_ot_layout_get_size_params (hb_face_t *face, - unsigned int *design_size, /* OUT. May be NULL */ - unsigned int *subfamily_id, /* OUT. May be NULL */ - hb_name_id_t *subfamily_name_id, /* OUT. May be NULL */ - unsigned int *range_start, /* OUT. May be NULL */ - unsigned int *range_end /* OUT. May be NULL */) +hb_ot_layout_get_size_params (hb_face_t *face, + unsigned int *design_size, /* OUT. May be NULL */ + unsigned int *subfamily_id, /* OUT. May be NULL */ + hb_ot_name_id_t *subfamily_name_id, /* OUT. May be NULL */ + unsigned int *range_start, /* OUT. May be NULL */ + unsigned int *range_end /* OUT. May be NULL */) { const OT::GPOS &gpos = _get_gpos (face); const hb_tag_t tag = HB_TAG ('s','i','z','e'); @@ -1086,7 +1086,7 @@ hb_ot_layout_get_size_params (hb_face_t *face, if (design_size) *design_size = 0; if (subfamily_id) *subfamily_id = 0; - if (subfamily_name_id) *subfamily_name_id = HB_NAME_ID_INVALID; + if (subfamily_name_id) *subfamily_name_id = HB_OT_NAME_ID_INVALID; if (range_start) *range_start = 0; if (range_end) *range_end = 0; @@ -1118,14 +1118,14 @@ hb_ot_layout_get_size_params (hb_face_t *face, * Since: 2.0.0 **/ hb_bool_t -hb_ot_layout_feature_get_name_ids (hb_face_t *face, - hb_tag_t table_tag, - unsigned int feature_index, - hb_name_id_t *label_id, /* OUT. May be NULL */ - hb_name_id_t *tooltip_id, /* OUT. May be NULL */ - hb_name_id_t *sample_id, /* OUT. May be NULL */ - unsigned int *num_named_parameters, /* OUT. May be NULL */ - hb_name_id_t *first_param_id /* OUT. May be NULL */) +hb_ot_layout_feature_get_name_ids (hb_face_t *face, + hb_tag_t table_tag, + unsigned int feature_index, + hb_ot_name_id_t *label_id, /* OUT. May be NULL */ + hb_ot_name_id_t *tooltip_id, /* OUT. May be NULL */ + hb_ot_name_id_t *sample_id, /* OUT. May be NULL */ + unsigned int *num_named_parameters, /* OUT. May be NULL */ + hb_ot_name_id_t *first_param_id /* OUT. May be NULL */) { const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); @@ -1141,10 +1141,10 @@ hb_ot_layout_feature_get_name_ids (hb_face_t *face, { if (label_id) *label_id = ss_params.uiNameID; // ssXX features don't have the rest - if (tooltip_id) *tooltip_id = HB_NAME_ID_INVALID; - if (sample_id) *sample_id = HB_NAME_ID_INVALID; + if (tooltip_id) *tooltip_id = HB_OT_NAME_ID_INVALID; + if (sample_id) *sample_id = HB_OT_NAME_ID_INVALID; if (num_named_parameters) *num_named_parameters = 0; - if (first_param_id) *first_param_id = HB_NAME_ID_INVALID; + if (first_param_id) *first_param_id = HB_OT_NAME_ID_INVALID; return true; } const OT::FeatureParamsCharacterVariants& cv_params = @@ -1160,11 +1160,11 @@ hb_ot_layout_feature_get_name_ids (hb_face_t *face, } } - if (label_id) *label_id = HB_NAME_ID_INVALID; - if (tooltip_id) *tooltip_id = HB_NAME_ID_INVALID; - if (sample_id) *sample_id = HB_NAME_ID_INVALID; + if (label_id) *label_id = HB_OT_NAME_ID_INVALID; + if (tooltip_id) *tooltip_id = HB_OT_NAME_ID_INVALID; + if (sample_id) *sample_id = HB_OT_NAME_ID_INVALID; if (num_named_parameters) *num_named_parameters = 0; - if (first_param_id) *first_param_id = HB_NAME_ID_INVALID; + if (first_param_id) *first_param_id = HB_OT_NAME_ID_INVALID; return false; } diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index 287d02217..7a016c390 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -364,23 +364,23 @@ Xhb_ot_layout_lookup_position (hb_font_t *font, /* Optical 'size' feature info. Returns true if found. * https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#size */ HB_EXTERN hb_bool_t -hb_ot_layout_get_size_params (hb_face_t *face, - unsigned int *design_size, /* OUT. May be NULL */ - unsigned int *subfamily_id, /* OUT. May be NULL */ - hb_name_id_t *subfamily_name_id, /* OUT. May be NULL */ - unsigned int *range_start, /* OUT. May be NULL */ - unsigned int *range_end /* OUT. May be NULL */); +hb_ot_layout_get_size_params (hb_face_t *face, + unsigned int *design_size, /* OUT. May be NULL */ + unsigned int *subfamily_id, /* OUT. May be NULL */ + hb_ot_name_id_t *subfamily_name_id, /* OUT. May be NULL */ + unsigned int *range_start, /* OUT. May be NULL */ + unsigned int *range_end /* OUT. May be NULL */); HB_EXTERN hb_bool_t -hb_ot_layout_feature_get_name_ids (hb_face_t *face, - hb_tag_t table_tag, - unsigned int feature_index, - hb_name_id_t *label_id /* OUT. May be NULL */, - hb_name_id_t *tooltip_id /* OUT. May be NULL */, - hb_name_id_t *sample_id /* OUT. May be NULL */, - unsigned int *num_named_parameters /* OUT. May be NULL */, - hb_name_id_t *first_param_id /* OUT. May be NULL */); +hb_ot_layout_feature_get_name_ids (hb_face_t *face, + hb_tag_t table_tag, + unsigned int feature_index, + hb_ot_name_id_t *label_id /* OUT. May be NULL */, + hb_ot_name_id_t *tooltip_id /* OUT. May be NULL */, + hb_ot_name_id_t *sample_id /* OUT. May be NULL */, + unsigned int *num_named_parameters /* OUT. May be NULL */, + hb_ot_name_id_t *first_param_id /* OUT. May be NULL */); HB_EXTERN unsigned int diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index b84edd185..9f67b5745 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -224,9 +224,9 @@ struct name hb_blob_destroy (this->blob); } - inline int get_index (hb_name_id_t name_id, - hb_language_t language, - unsigned int *width=nullptr) const + inline int get_index (hb_ot_name_id_t name_id, + hb_language_t language, + unsigned int *width=nullptr) const { const hb_ot_name_entry_t key = {name_id, {0}, language}; const hb_ot_name_entry_t *entry = (const hb_ot_name_entry_t *) diff --git a/src/hb-ot-name.cc b/src/hb-ot-name.cc index e8aa3d8e7..e0c971087 100644 --- a/src/hb-ot-name.cc +++ b/src/hb-ot-name.cc @@ -118,10 +118,10 @@ hb_ot_name_convert_utf (const hb_bytes_t *bytes, template static inline unsigned int -hb_ot_name_get_utf (hb_face_t *face, - hb_name_id_t name_id, - hb_language_t language, - unsigned int *text_size /* IN/OUT */, +hb_ot_name_get_utf (hb_face_t *face, + hb_ot_name_id_t name_id, + hb_language_t language, + unsigned int *text_size /* IN/OUT */, typename utf_t::codepoint_t *text /* OUT */) { const OT::name_accelerator_t &name = _get_name (face); @@ -168,11 +168,11 @@ hb_ot_name_get_utf (hb_face_t *face, * Since: 2.1.0 **/ unsigned int -hb_ot_name_get_utf8 (hb_face_t *face, - hb_name_id_t name_id, - hb_language_t language, - unsigned int *text_size /* IN/OUT */, - char *text /* OUT */) +hb_ot_name_get_utf8 (hb_face_t *face, + hb_ot_name_id_t name_id, + hb_language_t language, + unsigned int *text_size /* IN/OUT */, + char *text /* OUT */) { return hb_ot_name_get_utf (face, name_id, language, text_size, (hb_utf8_t::codepoint_t *) text); @@ -195,11 +195,11 @@ hb_ot_name_get_utf8 (hb_face_t *face, * Since: 2.1.0 **/ unsigned int -hb_ot_name_get_utf16 (hb_face_t *face, - hb_name_id_t name_id, - hb_language_t language, - unsigned int *text_size /* IN/OUT */, - uint16_t *text /* OUT */) +hb_ot_name_get_utf16 (hb_face_t *face, + hb_ot_name_id_t name_id, + hb_language_t language, + unsigned int *text_size /* IN/OUT */, + uint16_t *text /* OUT */) { return hb_ot_name_get_utf (face, name_id, language, text_size, text); } @@ -221,11 +221,11 @@ hb_ot_name_get_utf16 (hb_face_t *face, * Since: 2.1.0 **/ unsigned int -hb_ot_name_get_utf32 (hb_face_t *face, - hb_name_id_t name_id, - hb_language_t language, - unsigned int *text_size /* IN/OUT */, - uint32_t *text /* OUT */) +hb_ot_name_get_utf32 (hb_face_t *face, + hb_ot_name_id_t name_id, + hb_language_t language, + unsigned int *text_size /* IN/OUT */, + uint32_t *text /* OUT */) { return hb_ot_name_get_utf (face, name_id, language, text_size, text); } diff --git a/src/hb-ot-name.h b/src/hb-ot-name.h index e4ef5f07a..8b8316884 100644 --- a/src/hb-ot-name.h +++ b/src/hb-ot-name.h @@ -35,8 +35,8 @@ HB_BEGIN_DECLS /** - * hb_name_id_t: - * @HB_NAME_ID_INVALID: Value to represent a nonexistent name ID. + * hb_ot_name_id_t: + * @HB_OT_NAME_ID_INVALID: Value to represent a nonexistent name ID. * * An integral type representing an OpenType 'name' table name identifier. * There are predefined name IDs, as well as name IDs return from other @@ -46,37 +46,37 @@ HB_BEGIN_DECLS **/ enum { - HB_NAME_ID_COPYRIGHT = 0, - HB_NAME_ID_FONT_FAMILY = 1, - HB_NAME_ID_FONT_SUBFAMILY = 2, - HB_NAME_ID_UNIQUE_ID = 3, - HB_NAME_ID_FULL_NAME = 4, - HB_NAME_ID_VERSION_STRING = 5, - HB_NAME_ID_POSTSCRIPT_NAME = 6, - HB_NAME_ID_TRADEMARK = 7, - HB_NAME_ID_MANUFACTURER = 8, - HB_NAME_ID_DESIGNER = 9, - HB_NAME_ID_DESCRIPTION = 10, - HB_NAME_ID_VENDOR_URL = 11, - HB_NAME_ID_DESIGNER_URL = 12, - HB_NAME_ID_LICENSE = 13, - HB_NAME_ID_LICENSE_URL = 14, -/*HB_NAME_ID_RESERVED = 15,*/ - HB_NAME_ID_TYPOGRAPHIC_FAMILY = 16, - HB_NAME_ID_TYPOGRAPHIC_SUBFAMILY = 17, - HB_NAME_ID_MAC_FULL_NAME = 18, - HB_NAME_ID_SAMPLE_TEXT = 19, - HB_NAME_ID_CID_FINDFONT_NAME = 20, - HB_NAME_ID_WWS_FAMILY = 21, - HB_NAME_ID_WWS_SUBFAMILY = 22, - HB_NAME_ID_LIGHT_BACKGROUND = 23, - HB_NAME_ID_DARK_BACKGROUND = 24, - HB_NAME_ID_VARIATIONS_PS_PREFIX = 25, + HB_OT_NAME_ID_COPYRIGHT = 0, + HB_OT_NAME_ID_FONT_FAMILY = 1, + HB_OT_NAME_ID_FONT_SUBFAMILY = 2, + HB_OT_NAME_ID_UNIQUE_ID = 3, + HB_OT_NAME_ID_FULL_NAME = 4, + HB_OT_NAME_ID_VERSION_STRING = 5, + HB_OT_NAME_ID_POSTSCRIPT_NAME = 6, + HB_OT_NAME_ID_TRADEMARK = 7, + HB_OT_NAME_ID_MANUFACTURER = 8, + HB_OT_NAME_ID_DESIGNER = 9, + HB_OT_NAME_ID_DESCRIPTION = 10, + HB_OT_NAME_ID_VENDOR_URL = 11, + HB_OT_NAME_ID_DESIGNER_URL = 12, + HB_OT_NAME_ID_LICENSE = 13, + HB_OT_NAME_ID_LICENSE_URL = 14, +/*HB_OT_NAME_ID_RESERVED = 15,*/ + HB_OT_NAME_ID_TYPOGRAPHIC_FAMILY = 16, + HB_OT_NAME_ID_TYPOGRAPHIC_SUBFAMILY = 17, + HB_OT_NAME_ID_MAC_FULL_NAME = 18, + HB_OT_NAME_ID_SAMPLE_TEXT = 19, + HB_OT_NAME_ID_CID_FINDFONT_NAME = 20, + HB_OT_NAME_ID_WWS_FAMILY = 21, + HB_OT_NAME_ID_WWS_SUBFAMILY = 22, + HB_OT_NAME_ID_LIGHT_BACKGROUND = 23, + HB_OT_NAME_ID_DARK_BACKGROUND = 24, + HB_OT_NAME_ID_VARIATIONS_PS_PREFIX = 25, - HB_NAME_ID_INVALID = 0xFFFF, + HB_OT_NAME_ID_INVALID = 0xFFFF, }; -typedef unsigned int hb_name_id_t; +typedef unsigned int hb_ot_name_id_t; /** @@ -90,11 +90,11 @@ typedef unsigned int hb_name_id_t; **/ typedef struct hb_ot_name_entry_t { - hb_name_id_t name_id; + hb_ot_name_id_t name_id; /*< private >*/ - hb_var_int_t var; + hb_var_int_t var; /*< public >*/ - hb_language_t language; + hb_language_t language; } hb_ot_name_entry_t; HB_EXTERN const hb_ot_name_entry_t * @@ -103,25 +103,25 @@ hb_ot_name_list_names (hb_face_t *face, HB_EXTERN unsigned int -hb_ot_name_get_utf8 (hb_face_t *face, - hb_name_id_t name_id, - hb_language_t language, - unsigned int *text_size /* IN/OUT */, - char *text /* OUT */); +hb_ot_name_get_utf8 (hb_face_t *face, + hb_ot_name_id_t name_id, + hb_language_t language, + unsigned int *text_size /* IN/OUT */, + char *text /* OUT */); HB_EXTERN unsigned int -hb_ot_name_get_utf16 (hb_face_t *face, - hb_name_id_t name_id, - hb_language_t language, - unsigned int *text_size /* IN/OUT */, - uint16_t *text /* OUT */); +hb_ot_name_get_utf16 (hb_face_t *face, + hb_ot_name_id_t name_id, + hb_language_t language, + unsigned int *text_size /* IN/OUT */, + uint16_t *text /* OUT */); HB_EXTERN unsigned int -hb_ot_name_get_utf32 (hb_face_t *face, - hb_name_id_t name_id, - hb_language_t language, - unsigned int *text_size /* IN/OUT */, - uint32_t *text /* OUT */); +hb_ot_name_get_utf32 (hb_face_t *face, + hb_ot_name_id_t name_id, + hb_language_t language, + unsigned int *text_size /* IN/OUT */, + uint32_t *text /* OUT */); HB_END_DECLS diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index ba3a0abcd..e93f5d7b1 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -141,19 +141,19 @@ static void test_hb_ot_color_palette_get_name_id_empty (void) { /* numPalettes=0, so all calls are for out-of-bounds palette indices */ - g_assert_cmpint (hb_ot_color_palette_get_name_id (hb_face_get_empty(), 0), ==, HB_NAME_ID_INVALID); - g_assert_cmpint (hb_ot_color_palette_get_name_id (hb_face_get_empty(), 1), ==, HB_NAME_ID_INVALID); + g_assert_cmpint (hb_ot_color_palette_get_name_id (hb_face_get_empty(), 0), ==, HB_OT_NAME_ID_INVALID); + g_assert_cmpint (hb_ot_color_palette_get_name_id (hb_face_get_empty(), 1), ==, HB_OT_NAME_ID_INVALID); } static void test_hb_ot_color_palette_get_name_id_v0 (void) { - g_assert_cmpint (hb_ot_color_palette_get_name_id (cpal_v0, 0), ==, HB_NAME_ID_INVALID); - g_assert_cmpint (hb_ot_color_palette_get_name_id (cpal_v0, 1), ==, HB_NAME_ID_INVALID); + g_assert_cmpint (hb_ot_color_palette_get_name_id (cpal_v0, 0), ==, HB_OT_NAME_ID_INVALID); + g_assert_cmpint (hb_ot_color_palette_get_name_id (cpal_v0, 1), ==, HB_OT_NAME_ID_INVALID); /* numPalettes=2, so palette #2 is out of bounds */ - g_assert_cmpint (hb_ot_color_palette_get_name_id (cpal_v0, 2), ==, HB_NAME_ID_INVALID); + g_assert_cmpint (hb_ot_color_palette_get_name_id (cpal_v0, 2), ==, HB_OT_NAME_ID_INVALID); } @@ -161,11 +161,11 @@ static void test_hb_ot_color_palette_get_name_id_v1 (void) { g_assert_cmpint (hb_ot_color_palette_get_name_id (cpal_v1, 0), ==, 257); - g_assert_cmpint (hb_ot_color_palette_get_name_id (cpal_v1, 1), ==, HB_NAME_ID_INVALID); + g_assert_cmpint (hb_ot_color_palette_get_name_id (cpal_v1, 1), ==, HB_OT_NAME_ID_INVALID); g_assert_cmpint (hb_ot_color_palette_get_name_id (cpal_v1, 2), ==, 258); /* numPalettes=3, so palette #3 is out of bounds */ - g_assert_cmpint (hb_ot_color_palette_get_name_id (cpal_v1, 3), ==, HB_NAME_ID_INVALID); + g_assert_cmpint (hb_ot_color_palette_get_name_id (cpal_v1, 3), ==, HB_OT_NAME_ID_INVALID); } @@ -302,15 +302,15 @@ test_hb_ot_color_palette_get_colors_v1 (void) static void test_hb_ot_color_palette_color_get_name_id (void) { - g_assert_cmpuint (hb_ot_color_palette_color_get_name_id (empty, 0), ==, HB_NAME_ID_INVALID); - g_assert_cmpuint (hb_ot_color_palette_color_get_name_id (empty, 1), ==, HB_NAME_ID_INVALID); - g_assert_cmpuint (hb_ot_color_palette_color_get_name_id (empty, 2), ==, HB_NAME_ID_INVALID); - g_assert_cmpuint (hb_ot_color_palette_color_get_name_id (cpal_v0, 0), ==, HB_NAME_ID_INVALID); - g_assert_cmpuint (hb_ot_color_palette_color_get_name_id (cpal_v0, 1), ==, HB_NAME_ID_INVALID); - g_assert_cmpuint (hb_ot_color_palette_color_get_name_id (cpal_v0, 2), ==, HB_NAME_ID_INVALID); - g_assert_cmpuint (hb_ot_color_palette_color_get_name_id (cpal_v1, 0), ==, HB_NAME_ID_INVALID); + g_assert_cmpuint (hb_ot_color_palette_color_get_name_id (empty, 0), ==, HB_OT_NAME_ID_INVALID); + g_assert_cmpuint (hb_ot_color_palette_color_get_name_id (empty, 1), ==, HB_OT_NAME_ID_INVALID); + g_assert_cmpuint (hb_ot_color_palette_color_get_name_id (empty, 2), ==, HB_OT_NAME_ID_INVALID); + g_assert_cmpuint (hb_ot_color_palette_color_get_name_id (cpal_v0, 0), ==, HB_OT_NAME_ID_INVALID); + g_assert_cmpuint (hb_ot_color_palette_color_get_name_id (cpal_v0, 1), ==, HB_OT_NAME_ID_INVALID); + g_assert_cmpuint (hb_ot_color_palette_color_get_name_id (cpal_v0, 2), ==, HB_OT_NAME_ID_INVALID); + g_assert_cmpuint (hb_ot_color_palette_color_get_name_id (cpal_v1, 0), ==, HB_OT_NAME_ID_INVALID); g_assert_cmpuint (hb_ot_color_palette_color_get_name_id (cpal_v1, 1), ==, 256); - g_assert_cmpuint (hb_ot_color_palette_color_get_name_id (cpal_v1, 2), ==, HB_NAME_ID_INVALID); + g_assert_cmpuint (hb_ot_color_palette_color_get_name_id (cpal_v1, 2), ==, HB_OT_NAME_ID_INVALID); } diff --git a/test/api/test-ot-name.c b/test/api/test-ot-name.c index d73339785..431ee3a20 100644 --- a/test/api/test-ot-name.c +++ b/test/api/test-ot-name.c @@ -41,11 +41,11 @@ test_ot_layout_feature_get_name_ids_and_characters (void) &feature_index)) g_error ("Failed to find feature index"); - hb_name_id_t label_id; - hb_name_id_t tooltip_id; - hb_name_id_t sample_id; + hb_ot_name_id_t label_id; + hb_ot_name_id_t tooltip_id; + hb_ot_name_id_t sample_id; unsigned int num_named_parameters; - hb_name_id_t first_param_id; + hb_ot_name_id_t first_param_id; if (!hb_ot_layout_feature_get_name_ids (face, HB_OT_TAG_GSUB, feature_index, &label_id, &tooltip_id, &sample_id, &num_named_parameters, &first_param_id)) From 0e1ad5a075c6858ca60bad0e2da58b5256e15815 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Tue, 30 Oct 2018 11:29:58 -0700 Subject: [PATCH 215/255] [subset] Limit the number of scripts and langsys' that should be checked when collecting features. --- src/hb-ot-layout-common.hh | 8 ++++++++ src/hb-ot-layout.cc | 11 ++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 7663bd3d7..7b1d39aa0 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -51,6 +51,14 @@ #define HB_CLOSURE_MAX_STAGES 32 #endif +#ifndef HB_MAX_SCRIPTS +#define HB_MAX_SCRIPTS 500 +#endif + +#ifndef HB_MAX_LANGSYS +#define HB_MAX_LANGSYS 2000 +#endif + namespace OT { diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index a8cfcf556..18c810736 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -668,7 +668,8 @@ struct hb_collect_features_context_t hb_tag_t table_tag, hb_set_t *feature_indexes_) : g (get_gsubgpos_table (face, table_tag)), - feature_indexes (feature_indexes_) {} + feature_indexes (feature_indexes_), + langsys_count(0), script_count(0) {} bool inline visited (const OT::Script &s) { @@ -678,6 +679,9 @@ struct hb_collect_features_context_t !s.get_lang_sys_count ())) return true; + if (script_count++ > HB_MAX_SCRIPTS) + return true; + return visited (s, visited_script); } bool inline visited (const OT::LangSys &l) @@ -688,6 +692,9 @@ struct hb_collect_features_context_t !l.get_feature_count ())) return true; + if (langsys_count++ > HB_MAX_LANGSYS) + return true; + return visited (l, visited_langsys); } @@ -710,6 +717,8 @@ struct hb_collect_features_context_t private: hb_set_t visited_script; hb_set_t visited_langsys; + unsigned int script_count; + unsigned int langsys_count; }; static void From bfd549daaa078e7edba5a65971b1d3e872664f2d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 30 Oct 2018 14:47:27 -0700 Subject: [PATCH 216/255] Fix everything-bot --- src/hb-ot-layout.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 18c810736..e135e4a9e 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -669,7 +669,7 @@ struct hb_collect_features_context_t hb_set_t *feature_indexes_) : g (get_gsubgpos_table (face, table_tag)), feature_indexes (feature_indexes_), - langsys_count(0), script_count(0) {} + script_count(0),langsys_count(0) {} bool inline visited (const OT::Script &s) { From 1019391046cf01524c4ef20c9256a47b7411610b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 30 Oct 2018 15:52:26 -0700 Subject: [PATCH 217/255] 2.1.0 --- NEWS | 81 ++++++++++++++++++++++++++++++++++++++++++ RELEASING.md | 3 +- configure.ac | 2 +- docs/harfbuzz-docs.xml | 1 + src/hb-ot-color.cc | 22 ++++++++---- src/hb-ot-color.h | 4 +-- src/hb-version.h | 6 ++-- 7 files changed, 105 insertions(+), 14 deletions(-) diff --git a/NEWS b/NEWS index b8d364081..cb8a28ff0 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,84 @@ +Overview of changes leading to 2.1.0 +Tuesday, October 30, 2018 +==================================== +- AAT shaping improvements: + o Allow user controlling AAT features, for whole buffer only currently. + o Several 'morx' fixes. + o Implement tuple-kerns in 'kerx'; Fixes kerning with Apple default + San Francisco fonts. +- Support for color fonts: + o COLR/CPAL API to fetch color layers. + o SVG table to fetch SVG documents. + o CBDT/sbix API to fetch PNG images. +- New 'name' table API. +- hb-ot-font now uses 'VORG' table to correctly position CFF glyphs + in vertical layout. +- Various fuzzer-found bug fixes. + +Changed API: + +A type and a macro added in 2.0.0 were renamed: + +hb_name_id_t -> hb_ot_name_id_t +HB_NAME_ID_INVALID -> HB_OT_NAME_ID_INVALID + +New API: + ++hb_color_t ++HB_COLOR ++hb_color_get_alpha() ++hb_color_get_red() ++hb_color_get_green() ++hb_color_get_blue() ++hb_ot_color_has_palettes() ++hb_ot_color_palette_get_count() ++hb_ot_color_palette_get_name_id() ++hb_ot_color_palette_color_get_name_id() ++hb_ot_color_palette_flags_t ++hb_ot_color_palette_get_flags() ++hb_ot_color_palette_get_colors() ++hb_ot_color_has_layers() ++hb_ot_color_layer_t ++hb_ot_color_glyph_get_layers() ++hb_ot_color_has_svg() ++hb_ot_color_glyph_reference_svg() ++hb_ot_color_has_png() ++hb_ot_color_glyph_reference_png() + ++hb_ot_name_id_t ++HB_OT_NAME_ID_INVALID ++HB_OT_NAME_ID_COPYRIGHT ++HB_OT_NAME_ID_FONT_FAMILY ++HB_OT_NAME_ID_FONT_SUBFAMILY ++HB_OT_NAME_ID_UNIQUE_ID ++HB_OT_NAME_ID_FULL_NAME ++HB_OT_NAME_ID_VERSION_STRING ++HB_OT_NAME_ID_POSTSCRIPT_NAME ++HB_OT_NAME_ID_TRADEMARK ++HB_OT_NAME_ID_MANUFACTURER ++HB_OT_NAME_ID_DESIGNER ++HB_OT_NAME_ID_DESCRIPTION ++HB_OT_NAME_ID_VENDOR_URL ++HB_OT_NAME_ID_DESIGNER_URL ++HB_OT_NAME_ID_LICENSE ++HB_OT_NAME_ID_LICENSE_URL ++HB_OT_NAME_ID_TYPOGRAPHIC_FAMILY ++HB_OT_NAME_ID_TYPOGRAPHIC_SUBFAMILY ++HB_OT_NAME_ID_MAC_FULL_NAME ++HB_OT_NAME_ID_SAMPLE_TEXT ++HB_OT_NAME_ID_CID_FINDFONT_NAME ++HB_OT_NAME_ID_WWS_FAMILY ++HB_OT_NAME_ID_WWS_SUBFAMILY ++HB_OT_NAME_ID_LIGHT_BACKGROUND ++HB_OT_NAME_ID_DARK_BACKGROUND ++HB_OT_NAME_ID_VARIATIONS_PS_PREFIX ++hb_ot_name_entry_t ++hb_ot_name_list_names() ++hb_ot_name_get_utf8() ++hb_ot_name_get_utf16() ++hb_ot_name_get_utf32() + + Overview of changes leading to 2.0.2 Saturday, October 20, 2018 ==================================== diff --git a/RELEASING.md b/RELEASING.md index 4f5705e53..1fd836545 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -8,7 +8,8 @@ HarfBuzz release walk-through checklist: Document them in NEWS. All API and API semantic changes should be clearly marked as API additions, API changes, or API deletions. Document deprecations. Ensure all new API / deprecations are in listed correctly in - docs/harfbuzz-sections.txt + docs/harfbuzz-sections.txt. If release added new API, add entry for new + API index at the end of docs/harfbuzz-docs.xml. If there's a backward-incompatible API change (including deletions for API used anywhere), that's a release blocker. Do NOT release. diff --git a/configure.ac b/configure.ac index a2d0992a7..21d48f39a 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ([2.64]) AC_INIT([HarfBuzz], - [2.0.2], + [2.1.0], [https://github.com/harfbuzz/harfbuzz/issues/new], [harfbuzz], [http://harfbuzz.org/]) diff --git a/docs/harfbuzz-docs.xml b/docs/harfbuzz-docs.xml index 6d2411900..66a64d8f9 100644 --- a/docs/harfbuzz-docs.xml +++ b/docs/harfbuzz-docs.xml @@ -131,6 +131,7 @@ API Index Index of deprecated API + Index of new symbols in 2.1.0 Index of new symbols in 2.0.0 Index of new symbols in 1.9.0 Index of new symbols in 1.8.6 diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index 11fc12afb..b87ed56fa 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -257,9 +257,11 @@ hb_ot_color_glyph_get_layers (hb_face_t *face, * hb_ot_color_has_svg: * @face: a font face. * - * Returns: whether SVG table is available. + * Check whether @face has SVG glyph images. * - * Since: REPLACEME + * Returns true if available, false otherwise. + * + * Since: 2.1.0 */ hb_bool_t hb_ot_color_has_svg (hb_face_t *face) @@ -272,9 +274,11 @@ hb_ot_color_has_svg (hb_face_t *face) * @face: a font face. * @glyph: a svg glyph index. * + * Get SVG document for a glyph. + * * Returns: (transfer full): respective svg blob of the glyph, if available. * - * Since: REPLACEME + * Since: 2.1.0 */ hb_blob_t * hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph) @@ -291,9 +295,11 @@ hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph) * hb_ot_color_has_png: * @face: a font face. * - * Returns: whether either of CBDT or sbix tables is available. + * Check whether @face has PNG glyph images (either CBDT or sbix tables). * - * Since: REPLACEME + * Returns true if available, false otherwise. + * + * Since: 2.1.0 */ hb_bool_t hb_ot_color_has_png (hb_face_t *face) @@ -308,9 +314,11 @@ hb_ot_color_has_png (hb_face_t *face) * return the biggest one * @glyph: a glyph index. * - * Returns: (transfer full): respective png blob of the glyph, if available. + * Get PNG image for a glyph. * - * Since: REPLACEME + * Returns: (transfer full): respective PNG blob of the glyph, if available. + * + * Since: 2.1.0 */ hb_blob_t * hb_ot_color_glyph_reference_png (hb_font_t *font, hb_codepoint_t glyph) diff --git a/src/hb-ot-color.h b/src/hb-ot-color.h index e2d9a9620..a4f205329 100644 --- a/src/hb-ot-color.h +++ b/src/hb-ot-color.h @@ -66,7 +66,7 @@ hb_ot_color_palette_color_get_name_id (hb_face_t *face, * @HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_DARK_BACKGROUND: flag indicating that the color * palette is appropriate to use when displaying the font on a dark background such as black. * - * Since: REPLACEME + * Since: 2.1.0 */ typedef enum { /*< flags >*/ HB_OT_COLOR_PALETTE_FLAG_DEFAULT = 0x00000000u, @@ -98,7 +98,7 @@ hb_ot_color_has_layers (hb_face_t *face); * * Pairs of glyph and color index. * - * Since: REPLACEME + * Since: 2.1.0 **/ typedef struct hb_ot_color_layer_t { diff --git a/src/hb-version.h b/src/hb-version.h index a8db51606..68af8f864 100644 --- a/src/hb-version.h +++ b/src/hb-version.h @@ -37,10 +37,10 @@ HB_BEGIN_DECLS #define HB_VERSION_MAJOR 2 -#define HB_VERSION_MINOR 0 -#define HB_VERSION_MICRO 2 +#define HB_VERSION_MINOR 1 +#define HB_VERSION_MICRO 0 -#define HB_VERSION_STRING "2.0.2" +#define HB_VERSION_STRING "2.1.0" #define HB_VERSION_ATLEAST(major,minor,micro) \ ((major)*10000+(minor)*100+(micro) <= \ From 69297bb21640677532b7030332f803c0768c6579 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 30 Oct 2018 19:06:21 -0700 Subject: [PATCH 218/255] [fuzzing] Call hb-ot-color API --- test/fuzzing/hb-shape-fuzzer.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/fuzzing/hb-shape-fuzzer.cc b/test/fuzzing/hb-shape-fuzzer.cc index b5a6c12e0..e8bc186b1 100644 --- a/test/fuzzing/hb-shape-fuzzer.cc +++ b/test/fuzzing/hb-shape-fuzzer.cc @@ -39,6 +39,10 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) hb_glyph_extents_t extents; hb_font_get_glyph_extents (font, info.codepoint, &extents); + + hb_ot_color_glyph_get_layers (face, info.codepoint, 0, nullptr, nullptr); + hb_blob_destroy (hb_ot_color_glyph_reference_svg (face, info.codepoint)); + hb_blob_destroy (hb_ot_color_glyph_reference_png (font, info.codepoint)); } hb_buffer_destroy (buffer); From 5cd544a621f10b307bb97aea27ea54e55aacb2e9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 30 Oct 2018 19:16:00 -0700 Subject: [PATCH 219/255] Fix build Fixes https://github.com/harfbuzz/harfbuzz/issues/1338 --- src/test-ot-color.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test-ot-color.cc b/src/test-ot-color.cc index 2cb9b03b2..cb369c0f3 100644 --- a/src/test-ot-color.cc +++ b/src/test-ot-color.cc @@ -23,7 +23,7 @@ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ -#include "hb.h" +#include "hb.hh" #include "hb-ot.h" #include "hb-ft.h" From b053cabacd99ff69144a1459fe02ffd574c2416c Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Tue, 30 Oct 2018 18:41:34 +0330 Subject: [PATCH 220/255] [mort] Bring back mort generalizations Started by reverting https://github.com/harfbuzz/harfbuzz/commit/1f1c85a5 Just a starting point, if we agree even mort can come back. --- src/hb-aat-layout-common.hh | 76 +++++++++++++++--- src/hb-aat-layout-kerx-table.hh | 17 ++-- src/hb-aat-layout-morx-table.hh | 133 +++++++++++++++++++------------- src/hb-aat-layout.cc | 16 +++- src/hb-ot-face.hh | 1 + 5 files changed, 171 insertions(+), 72 deletions(-) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index ce40abd55..7327cc5b2 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -410,9 +410,13 @@ struct Entry DEFINE_SIZE_STATIC (4); }; -template +template struct StateTable { + typedef typename Types::HBUINT HBUINT; + typedef typename Types::HBUSHORT HBUSHORT; + typedef typename Types::ClassType ClassType; + enum State { STATE_START_OF_TEXT = 0, @@ -504,23 +508,73 @@ struct StateTable } protected: - HBUINT32 nClasses; /* Number of classes, which is the number of indices + HBUINT nClasses; /* Number of classes, which is the number of indices * in a single line in the state array. */ - LOffsetTo, false> + OffsetTo classTable; /* Offset to the class table. */ - LOffsetTo, false> + OffsetTo, HBUINT, false> stateArrayTable;/* Offset to the state array. */ - LOffsetTo >, false> + OffsetTo >, HBUINT, false> entryTable; /* Offset to the entry array. */ public: DEFINE_SIZE_STATIC (16); }; -template +struct ClassTable +{ + inline unsigned int get_class (hb_codepoint_t glyph_id) const + { + return firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount ? classArrayZ[glyph_id - firstGlyph] : 1; + } + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && classArrayZ.sanitize (c, glyphCount)); + } + protected: + GlyphID firstGlyph; /* First glyph index included in the trimmed array. */ + HBUINT16 glyphCount; /* Total number of glyphs (equivalent to the last + * glyph minus the value of firstGlyph plus 1). */ + UnsizedArrayOf + classArrayZ; /* The class codes (indexed by glyph index minus + * firstGlyph). */ + public: + DEFINE_SIZE_ARRAY (4, classArrayZ); +}; + +struct MortTypes +{ + static const bool extended = false; + typedef HBUINT16 HBUINT; + typedef HBUINT8 HBUSHORT; + struct ClassType : ClassTable + { + inline unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs HB_UNUSED) const + { + return ClassTable::get_class (glyph_id); + } + }; +}; +struct MorxTypes +{ + static const bool extended = true; + typedef HBUINT32 HBUINT; + typedef HBUINT16 HBUSHORT; + struct ClassType : Lookup + { + inline unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs) const + { + const HBUINT16 *v = get_value (glyph_id, num_glyphs); + return v ? *v : 1; + } + }; +}; + +template struct StateTableDriver { - inline StateTableDriver (const StateTable &machine_, + inline StateTableDriver (const StateTable &machine_, hb_buffer_t *buffer_, hb_face_t *face_) : machine (machine_), @@ -533,13 +587,13 @@ struct StateTableDriver if (!c->in_place) buffer->clear_output (); - unsigned int state = StateTable::STATE_START_OF_TEXT; + unsigned int state = StateTable::STATE_START_OF_TEXT; bool last_was_dont_advance = false; for (buffer->idx = 0; buffer->successful;) { unsigned int klass = buffer->idx < buffer->len ? machine.get_class (buffer->info[buffer->idx].codepoint, num_glyphs) : - (unsigned) StateTable::CLASS_END_OF_TEXT; + (unsigned) StateTable::CLASS_END_OF_TEXT; const Entry *entry = machine.get_entryZ (state, klass); if (unlikely (!entry)) break; @@ -553,7 +607,7 @@ struct StateTableDriver /* If there's no action and we're just epsilon-transitioning to state 0, * safe to break. */ if (c->is_actionable (this, entry) || - !(entry->newState == StateTable::STATE_START_OF_TEXT && + !(entry->newState == StateTable::STATE_START_OF_TEXT && entry->flags == context_t::DontAdvance)) buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1); } @@ -590,7 +644,7 @@ struct StateTableDriver } public: - const StateTable &machine; + const StateTable &machine; hb_buffer_t *buffer; unsigned int num_glyphs; }; diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index a88312501..94e0a9b62 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -163,12 +163,12 @@ struct KerxSubTableFormat1 kernAction (&table->machine + table->kernAction), depth (0) {} - inline bool is_actionable (StateTableDriver *driver HB_UNUSED, + inline bool is_actionable (StateTableDriver *driver HB_UNUSED, const Entry *entry) { return entry->data.kernActionIndex != 0xFFFF; } - inline bool transition (StateTableDriver *driver, + inline bool transition (StateTableDriver *driver, const Entry *entry) { hb_buffer_t *buffer = driver->buffer; @@ -239,7 +239,7 @@ struct KerxSubTableFormat1 driver_context_t dc (this, c); - StateTableDriver driver (machine, c->buffer, c->font->face); + StateTableDriver driver (machine, c->buffer, c->font->face); driver.drive (&dc); return_trace (true); @@ -255,7 +255,7 @@ struct KerxSubTableFormat1 protected: KerxSubTableHeader header; - StateTable machine; + StateTable machine; LOffsetTo, false> kernAction; public: DEFINE_SIZE_STATIC (32); @@ -365,12 +365,12 @@ struct KerxSubTableFormat4 mark_set (false), mark (0) {} - inline bool is_actionable (StateTableDriver *driver HB_UNUSED, + inline bool is_actionable (StateTableDriver *driver HB_UNUSED, const Entry *entry) { return entry->data.ankrActionIndex != 0xFFFF; } - inline bool transition (StateTableDriver *driver, + inline bool transition (StateTableDriver *driver, const Entry *entry) { hb_buffer_t *buffer = driver->buffer; @@ -473,7 +473,7 @@ struct KerxSubTableFormat4 driver_context_t dc (this, c); - StateTableDriver driver (machine, c->buffer, c->font->face); + StateTableDriver driver (machine, c->buffer, c->font->face); driver.drive (&dc); return_trace (true); @@ -489,7 +489,8 @@ struct KerxSubTableFormat4 protected: KerxSubTableHeader header; - StateTable machine; + StateTable + machine; HBUINT32 flags; public: DEFINE_SIZE_STATIC (32); diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index a56209104..336d0e35f 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -35,17 +35,21 @@ /* * morx -- Extended Glyph Metamorphosis * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6morx.html + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6mort.html */ #define HB_AAT_TAG_morx HB_TAG('m','o','r','x') +#define HB_AAT_TAG_mort HB_TAG('m','o','r','t') namespace AAT { using namespace OT; - +template struct RearrangementSubtable { + typedef typename Types::HBUINT HBUINT; + typedef void EntryData; struct driver_context_t @@ -69,12 +73,12 @@ struct RearrangementSubtable ret (false), start (0), end (0) {} - inline bool is_actionable (StateTableDriver *driver HB_UNUSED, + inline bool is_actionable (StateTableDriver *driver HB_UNUSED, const Entry *entry) { return (entry->flags & Verb) && start < end; } - inline bool transition (StateTableDriver *driver, + inline bool transition (StateTableDriver *driver, const Entry *entry) { hb_buffer_t *buffer = driver->buffer; @@ -165,7 +169,7 @@ struct RearrangementSubtable driver_context_t dc (this); - StateTableDriver driver (machine, c->buffer, c->face); + StateTableDriver driver (machine, c->buffer, c->face); driver.drive (&dc); return_trace (dc.ret); @@ -178,13 +182,16 @@ struct RearrangementSubtable } protected: - StateTable machine; + StateTable machine; public: DEFINE_SIZE_STATIC (16); }; +template struct ContextualSubtable { + typedef typename Types::HBUINT HBUINT; + struct EntryData { HBUINT16 markIndex; /* Index of the substitution table for the @@ -212,7 +219,7 @@ struct ContextualSubtable mark (0), subs (table+table->substitutionTables) {} - inline bool is_actionable (StateTableDriver *driver, + inline bool is_actionable (StateTableDriver *driver, const Entry *entry) { hb_buffer_t *buffer = driver->buffer; @@ -222,7 +229,7 @@ struct ContextualSubtable return entry->data.markIndex != 0xFFFF || entry->data.currentIndex != 0xFFFF; } - inline bool transition (StateTableDriver *driver, + inline bool transition (StateTableDriver *driver, const Entry *entry) { hb_buffer_t *buffer = driver->buffer; @@ -280,7 +287,7 @@ struct ContextualSubtable driver_context_t dc (this); - StateTableDriver driver (machine, c->buffer, c->face); + StateTableDriver driver (machine, c->buffer, c->face); driver.drive (&dc); return_trace (dc.ret); @@ -310,16 +317,19 @@ struct ContextualSubtable } protected: - StateTable + StateTable machine; - LOffsetTo, HBUINT32, false>, false> + OffsetTo, HBUINT, false>, HBUINT, false> substitutionTables; public: DEFINE_SIZE_STATIC (20); }; +template struct LigatureSubtable { + typedef typename Types::HBUINT HBUINT; + struct EntryData { HBUINT16 ligActionIndex; /* Index to the first ligActionTable entry @@ -363,12 +373,12 @@ struct LigatureSubtable ligature (table+table->ligature), match_length (0) {} - inline bool is_actionable (StateTableDriver *driver HB_UNUSED, + inline bool is_actionable (StateTableDriver *driver HB_UNUSED, const Entry *entry) { return entry->flags & PerformAction; } - inline bool transition (StateTableDriver *driver, + inline bool transition (StateTableDriver *driver, const Entry *entry) { hb_buffer_t *buffer = driver->buffer; @@ -482,7 +492,7 @@ struct LigatureSubtable driver_context_t dc (this, c); - StateTableDriver driver (machine, c->buffer, c->face); + StateTableDriver driver (machine, c->buffer, c->face); driver.drive (&dc); return_trace (dc.ret); @@ -497,18 +507,19 @@ struct LigatureSubtable } protected: - StateTable + StateTable machine; - LOffsetTo, false> + OffsetTo, HBUINT, false> ligAction; /* Offset to the ligature action table. */ - LOffsetTo, false> + OffsetTo, HBUINT, false> component; /* Offset to the component table. */ - LOffsetTo, false> + OffsetTo, HBUINT, false> ligature; /* Offset to the actual ligature lists. */ public: DEFINE_SIZE_STATIC (28); }; +template struct NoncontextualSubtable { inline bool apply (hb_aat_apply_context_t *c) const @@ -545,8 +556,11 @@ struct NoncontextualSubtable DEFINE_SIZE_MIN (2); }; +template struct InsertionSubtable { + typedef typename Types::HBUINT HBUINT; + struct EntryData { HBUINT16 currentInsertIndex; /* Zero-based index into the insertion glyph table. @@ -622,13 +636,13 @@ struct InsertionSubtable mark (0), insertionAction (table+table->insertionAction) {} - inline bool is_actionable (StateTableDriver *driver HB_UNUSED, + inline bool is_actionable (StateTableDriver *driver HB_UNUSED, const Entry *entry) { return (entry->flags & (CurrentInsertCount | MarkedInsertCount)) && (entry->data.currentInsertIndex != 0xFFFF ||entry->data.markedInsertIndex != 0xFFFF); } - inline bool transition (StateTableDriver *driver, + inline bool transition (StateTableDriver *driver, const Entry *entry) { hb_buffer_t *buffer = driver->buffer; @@ -720,7 +734,7 @@ struct InsertionSubtable driver_context_t dc (this, c); - StateTableDriver driver (machine, c->buffer, c->face); + StateTableDriver driver (machine, c->buffer, c->face); driver.drive (&dc); return_trace (dc.ret); @@ -735,9 +749,9 @@ struct InsertionSubtable } protected: - StateTable + StateTable machine; - LOffsetTo, false> + OffsetTo, HBUINT, false> insertionAction; /* Byte offset from stateHeader to the start of * the insertion glyph table. */ public: @@ -765,9 +779,10 @@ struct Feature DEFINE_SIZE_STATIC (12); }; - +template struct ChainSubtable { + template friend struct Chain; inline unsigned int get_size (void) const { return length; } @@ -830,18 +845,21 @@ struct ChainSubtable HBUINT32 coverage; /* Coverage flags and subtable type. */ HBUINT32 subFeatureFlags;/* The 32-bit mask identifying which subtable this is. */ union { - RearrangementSubtable rearrangement; - ContextualSubtable contextual; - LigatureSubtable ligature; - NoncontextualSubtable noncontextual; - InsertionSubtable insertion; + RearrangementSubtable rearrangement; + ContextualSubtable contextual; + LigatureSubtable ligature; + NoncontextualSubtable noncontextual; + InsertionSubtable insertion; } u; public: - DEFINE_SIZE_MIN (12); + DEFINE_SIZE_MIN (2 * sizeof (HBUINT32) + 4); }; +template struct Chain { + typedef typename Types::HBUINT HBUINT; + inline hb_mask_t compile_flags (const hb_aat_map_builder_t *map) const { hb_mask_t flags = defaultFlags; @@ -868,7 +886,7 @@ struct Chain inline void apply (hb_aat_apply_context_t *c, hb_mask_t flags) const { - const ChainSubtable *subtable = &StructAtOffset (&featureZ, featureZ[0].static_size * featureCount); + const ChainSubtable *subtable = &StructAtOffset > (&featureZ, featureZ[0].static_size * featureCount); unsigned int count = subtableCount; for (unsigned int i = 0; i < count; i++) { @@ -877,9 +895,9 @@ struct Chain if (!(subtable->subFeatureFlags & flags)) goto skip; - if (!(subtable->coverage & ChainSubtable::AllDirections) && + if (!(subtable->coverage & ChainSubtable::AllDirections) && HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) != - bool (subtable->coverage & ChainSubtable::Vertical)) + bool (subtable->coverage & ChainSubtable::Vertical)) goto skip; /* Buffer contents is always in logical direction. Determine if @@ -909,9 +927,9 @@ struct Chain (the order opposite that of the characters, which may be right-to-left or left-to-right). */ - reverse = subtable->coverage & ChainSubtable::Logical ? - bool (subtable->coverage & ChainSubtable::Backwards) : - bool (subtable->coverage & ChainSubtable::Backwards) != + reverse = subtable->coverage & ChainSubtable::Logical ? + bool (subtable->coverage & ChainSubtable::Backwards) : + bool (subtable->coverage & ChainSubtable::Backwards) != HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction); if (!c->buffer->message (c->font, "start chain subtable %d", c->lookup_index)) @@ -932,7 +950,7 @@ struct Chain if (unlikely (!c->buffer->successful)) return; skip: - subtable = &StructAfter (*subtable); + subtable = &StructAfter > (*subtable); c->set_lookup_index (c->lookup_index + 1); } } @@ -950,38 +968,39 @@ struct Chain if (!c->check_array (featureZ.arrayZ, featureCount)) return_trace (false); - const ChainSubtable *subtable = &StructAtOffset (&featureZ, featureZ[0].static_size * featureCount); + const ChainSubtable *subtable = &StructAtOffset > (&featureZ, featureZ[0].static_size * featureCount); unsigned int count = subtableCount; for (unsigned int i = 0; i < count; i++) { if (!subtable->sanitize (c)) return_trace (false); - subtable = &StructAfter (*subtable); + subtable = &StructAfter > (*subtable); } return_trace (true); } protected: - HBUINT32 defaultFlags; /* The default specification for subtables. */ - HBUINT32 length; /* Total byte count, including this header. */ - HBUINT32 featureCount; /* Number of feature subtable entries. */ - HBUINT32 subtableCount; /* The number of subtables in the chain. */ + HBUINT defaultFlags; /* The default specification for subtables. */ + HBUINT length; /* Total byte count, including this header. */ + HBUINT featureCount; /* Number of feature subtable entries. */ + HBUINT subtableCount; /* The number of subtables in the chain. */ UnsizedArrayOf featureZ; /* Features. */ /*ChainSubtable firstSubtable;*//* Subtables. */ /*subtableGlyphCoverageArray*/ /* Only if version >= 3. We don't use. */ public: - DEFINE_SIZE_MIN (16); + DEFINE_SIZE_MIN (2 * sizeof (HBUINT) + 4); }; /* - * The 'morx' Table + * The 'mort'/'morx' Table */ -struct morx +template +struct mortmorx { static const hb_tag_t tableTag = HB_AAT_TAG_morx; @@ -990,12 +1009,12 @@ struct morx inline void compile_flags (const hb_aat_map_builder_t *mapper, hb_aat_map_t *map) const { - const Chain *chain = &firstChain; + const Chain *chain = &firstChain; unsigned int count = chainCount; for (unsigned int i = 0; i < count; i++) { map->chain_flags.push (chain->compile_flags (mapper)); - chain = &StructAfter (*chain); + chain = &StructAfter > (*chain); } } @@ -1019,13 +1038,13 @@ struct morx { if (unlikely (!c->buffer->successful)) return; c->set_lookup_index (0); - const Chain *chain = &firstChain; + const Chain *chain = &firstChain; unsigned int count = chainCount; for (unsigned int i = 0; i < count; i++) { chain->apply (c, c->plan->aat_map.chain_flags[i]); if (unlikely (!c->buffer->successful)) return; - chain = &StructAfter (*chain); + chain = &StructAfter > (*chain); } remove_deleted_glyphs (c->buffer); } @@ -1037,13 +1056,13 @@ struct morx !chainCount.sanitize (c)) return_trace (false); - const Chain *chain = &firstChain; + const Chain *chain = &firstChain; unsigned int count = chainCount; for (unsigned int i = 0; i < count; i++) { if (!chain->sanitize (c, version)) return_trace (false); - chain = &StructAfter (*chain); + chain = &StructAfter > (*chain); } return_trace (true); @@ -1055,12 +1074,22 @@ struct morx HBUINT16 unused; /* Set to 0. */ HBUINT32 chainCount; /* Number of metamorphosis chains contained in this * table. */ - Chain firstChain; /* Chains. */ + Chain firstChain; /* Chains. */ public: DEFINE_SIZE_MIN (8); }; +struct morx : mortmorx +{ + static const hb_tag_t tableTag = HB_AAT_TAG_morx; +}; +struct mort : mortmorx +{ + static const hb_tag_t tableTag = HB_AAT_TAG_mort; +}; + + } /* namespace AAT */ diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index ec053938f..59157c216 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -130,9 +130,23 @@ hb_aat_layout_find_feature_mapping (hb_tag_t tag) /* - * morx/kerx/trak + * mort/morx/kerx/trak */ +// static inline const AAT::mort& +// _get_mort (hb_face_t *face, hb_blob_t **blob = nullptr) +// { +// if (unlikely (!hb_ot_shaper_face_data_ensure (face))) +// { +// if (blob) +// *blob = hb_blob_get_empty (); +// return Null(AAT::mort); +// } +// const AAT::morx& mort = *(hb_ot_face_data (face)->mort.get ()); +// if (blob) +// *blob = hb_ot_face_data (face)->mort.get_blob (); +// return mort; +// } static inline const AAT::morx& _get_morx (hb_face_t *face, hb_blob_t **blob = nullptr) { diff --git a/src/hb-ot-face.hh b/src/hb-ot-face.hh index f3b7945bb..6e629eb41 100644 --- a/src/hb-ot-face.hh +++ b/src/hb-ot-face.hh @@ -52,6 +52,7 @@ HB_OT_TABLE(OT, BASE) \ /* AAT shaping. */ \ HB_OT_TABLE(AAT, morx) \ + HB_OT_TABLE(AAT, mort) \ HB_OT_TABLE(AAT, kerx) \ HB_OT_TABLE(AAT, ankr) \ HB_OT_TABLE(AAT, trak) \ From 933babdc075c27fbcc1b726c3c9b2aa67338c6ad Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 30 Oct 2018 19:22:43 -0700 Subject: [PATCH 221/255] [mort] Fixup on previous commit --- src/hb-aat-layout-morx-table.hh | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 336d0e35f..99627d3a1 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -73,12 +73,12 @@ struct RearrangementSubtable ret (false), start (0), end (0) {} - inline bool is_actionable (StateTableDriver *driver HB_UNUSED, + inline bool is_actionable (StateTableDriver *driver HB_UNUSED, const Entry *entry) { return (entry->flags & Verb) && start < end; } - inline bool transition (StateTableDriver *driver, + inline bool transition (StateTableDriver *driver, const Entry *entry) { hb_buffer_t *buffer = driver->buffer; @@ -169,7 +169,7 @@ struct RearrangementSubtable driver_context_t dc (this); - StateTableDriver driver (machine, c->buffer, c->face); + StateTableDriver driver (machine, c->buffer, c->face); driver.drive (&dc); return_trace (dc.ret); @@ -219,7 +219,7 @@ struct ContextualSubtable mark (0), subs (table+table->substitutionTables) {} - inline bool is_actionable (StateTableDriver *driver, + inline bool is_actionable (StateTableDriver *driver, const Entry *entry) { hb_buffer_t *buffer = driver->buffer; @@ -229,7 +229,7 @@ struct ContextualSubtable return entry->data.markIndex != 0xFFFF || entry->data.currentIndex != 0xFFFF; } - inline bool transition (StateTableDriver *driver, + inline bool transition (StateTableDriver *driver, const Entry *entry) { hb_buffer_t *buffer = driver->buffer; @@ -287,7 +287,7 @@ struct ContextualSubtable driver_context_t dc (this); - StateTableDriver driver (machine, c->buffer, c->face); + StateTableDriver driver (machine, c->buffer, c->face); driver.drive (&dc); return_trace (dc.ret); @@ -373,12 +373,12 @@ struct LigatureSubtable ligature (table+table->ligature), match_length (0) {} - inline bool is_actionable (StateTableDriver *driver HB_UNUSED, + inline bool is_actionable (StateTableDriver *driver HB_UNUSED, const Entry *entry) { return entry->flags & PerformAction; } - inline bool transition (StateTableDriver *driver, + inline bool transition (StateTableDriver *driver, const Entry *entry) { hb_buffer_t *buffer = driver->buffer; @@ -492,7 +492,7 @@ struct LigatureSubtable driver_context_t dc (this, c); - StateTableDriver driver (machine, c->buffer, c->face); + StateTableDriver driver (machine, c->buffer, c->face); driver.drive (&dc); return_trace (dc.ret); @@ -636,13 +636,13 @@ struct InsertionSubtable mark (0), insertionAction (table+table->insertionAction) {} - inline bool is_actionable (StateTableDriver *driver HB_UNUSED, + inline bool is_actionable (StateTableDriver *driver HB_UNUSED, const Entry *entry) { return (entry->flags & (CurrentInsertCount | MarkedInsertCount)) && (entry->data.currentInsertIndex != 0xFFFF ||entry->data.markedInsertIndex != 0xFFFF); } - inline bool transition (StateTableDriver *driver, + inline bool transition (StateTableDriver *driver, const Entry *entry) { hb_buffer_t *buffer = driver->buffer; @@ -734,7 +734,7 @@ struct InsertionSubtable driver_context_t dc (this, c); - StateTableDriver driver (machine, c->buffer, c->face); + StateTableDriver driver (machine, c->buffer, c->face); driver.drive (&dc); return_trace (dc.ret); From c2527a1bc2b493473f06ea6ae79f0a87b722c4d3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 30 Oct 2018 19:26:16 -0700 Subject: [PATCH 222/255] [mort] Make it compile / hook it up Untested. --- src/hb-aat-layout-common.hh | 11 ++++---- src/hb-aat-layout-morx-table.hh | 2 +- src/hb-aat-layout.cc | 49 +++++++++++++++++++++------------ 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 7327cc5b2..c9d5cfe95 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -433,8 +433,7 @@ struct StateTable inline unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs) const { if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH; - const HBUINT16 *v = (this+classTable).get_value (glyph_id, num_glyphs); - return v ? (unsigned) *v : (unsigned) CLASS_OUT_OF_BOUNDS; + return (this+classTable).get_class (glyph_id, num_glyphs); } inline const Entry *get_entries () const @@ -446,7 +445,7 @@ struct StateTable { if (unlikely (klass >= nClasses)) return nullptr; - const HBUINT16 *states = (this+stateArrayTable).arrayZ; + const HBUSHORT *states = (this+stateArrayTable).arrayZ; const Entry *entries = (this+entryTable).arrayZ; unsigned int entry = states[state * nClasses + klass]; @@ -461,7 +460,7 @@ struct StateTable if (unlikely (!(c->check_struct (this) && classTable.sanitize (c, this)))) return_trace (false); - const HBUINT16 *states = (this+stateArrayTable).arrayZ; + const HBUSHORT *states = (this+stateArrayTable).arrayZ; const Entry *entries = (this+entryTable).arrayZ; unsigned int num_classes = nClasses; @@ -483,8 +482,8 @@ struct StateTable if ((c->max_ops -= num_states - state) < 0) return_trace (false); { /* Sweep new states. */ - const HBUINT16 *stop = &states[num_states * num_classes]; - for (const HBUINT16 *p = &states[state * num_classes]; p < stop; p++) + const HBUSHORT *stop = &states[num_states * num_classes]; + for (const HBUSHORT *p = &states[state * num_classes]; p < stop; p++) num_entries = MAX (num_entries, *p + 1); state = num_states; } diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 99627d3a1..e619d9e92 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -278,7 +278,7 @@ struct ContextualSubtable private: bool mark_set; unsigned int mark; - const UnsizedOffsetListOf, HBUINT32, false> &subs; + const UnsizedOffsetListOf, HBUINT, false> &subs; }; inline bool apply (hb_aat_apply_context_t *c) const diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index 59157c216..2b4f57837 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -133,20 +133,20 @@ hb_aat_layout_find_feature_mapping (hb_tag_t tag) * mort/morx/kerx/trak */ -// static inline const AAT::mort& -// _get_mort (hb_face_t *face, hb_blob_t **blob = nullptr) -// { -// if (unlikely (!hb_ot_shaper_face_data_ensure (face))) -// { -// if (blob) -// *blob = hb_blob_get_empty (); -// return Null(AAT::mort); -// } -// const AAT::morx& mort = *(hb_ot_face_data (face)->mort.get ()); -// if (blob) -// *blob = hb_ot_face_data (face)->mort.get_blob (); -// return mort; -// } +static inline const AAT::mort& +_get_mort (hb_face_t *face, hb_blob_t **blob = nullptr) +{ + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) + { + if (blob) + *blob = hb_blob_get_empty (); + return Null(AAT::mort); + } + const AAT::mort& mort = *(hb_ot_face_data (face)->mort.get ()); + if (blob) + *blob = hb_ot_face_data (face)->mort.get_blob (); + return mort; +} static inline const AAT::morx& _get_morx (hb_face_t *face, hb_blob_t **blob = nullptr) { @@ -214,7 +214,8 @@ hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper, hb_bool_t hb_aat_layout_has_substitution (hb_face_t *face) { - return _get_morx (face).has_data (); + return _get_morx (face).has_data () || + _get_mort (face).has_data (); } void @@ -223,10 +224,22 @@ hb_aat_layout_substitute (hb_ot_shape_plan_t *plan, hb_buffer_t *buffer) { hb_blob_t *blob; - const AAT::morx& morx = _get_morx (font->face, &blob); - AAT::hb_aat_apply_context_t c (plan, font, buffer, blob); - morx.apply (&c); + const AAT::morx& morx = _get_morx (font->face, &blob); + if (morx.has_data ()) + { + AAT::hb_aat_apply_context_t c (plan, font, buffer, blob); + morx.apply (&c); + return; + } + + const AAT::mort& mort = _get_mort (font->face, &blob); + if (mort.has_data ()) + { + AAT::hb_aat_apply_context_t c (plan, font, buffer, blob); + mort.apply (&c); + return; + } } From 2d9467340b1498ccc0cd47bf915b84ab12dfa025 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 30 Oct 2018 19:33:31 -0700 Subject: [PATCH 223/255] [mort] Fix version check in sanitize --- src/hb-aat-layout-morx-table.hh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index e619d9e92..a2dd45a03 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -1052,8 +1052,7 @@ struct mortmorx inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!version.sanitize (c) || version < 2 || - !chainCount.sanitize (c)) + if (!version.sanitize (c) || !version || !chainCount.sanitize (c)) return_trace (false); const Chain *chain = &firstChain; @@ -1070,7 +1069,7 @@ struct mortmorx protected: HBUINT16 version; /* Version number of the glyph metamorphosis table. - * 2 or 3. */ + * 1, 2, or 3. */ HBUINT16 unused; /* Set to 0. */ HBUINT32 chainCount; /* Number of metamorphosis chains contained in this * table. */ From f864ef215e1354a1e5a3c8796afafba761404e08 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 30 Oct 2018 19:42:21 -0700 Subject: [PATCH 224/255] [mort] More massaging towards mort --- src/hb-aat-layout-morx-table.hh | 53 +++++++++++++++++---------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index a2dd45a03..6d6ef708d 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -782,28 +782,29 @@ struct Feature template struct ChainSubtable { + typedef typename Types::HBUINT HBUINT; + template friend struct Chain; inline unsigned int get_size (void) const { return length; } - inline unsigned int get_type (void) const { return coverage & SubtableType; } + inline unsigned int get_type (void) const { return coverage & 0xFF; } + inline unsigned int get_coverage (void) const { return coverage >> (sizeof (HBUINT) * 8 - 8); } enum Coverage { - Vertical = 0x80000000, /* If set, this subtable will only be applied - * to vertical text. If clear, this subtable - * will only be applied to horizontal text. */ - Backwards = 0x40000000, /* If set, this subtable will process glyphs - * in descending order. If clear, it will - * process the glyphs in ascending order. */ - AllDirections = 0x20000000, /* If set, this subtable will be applied to - * both horizontal and vertical text (i.e. - * the state of bit 0x80000000 is ignored). */ - Logical = 0x10000000, /* If set, this subtable will process glyphs - * in logical order (or reverse logical order, - * depending on the value of bit 0x80000000). */ - Reserved = 0x0FFFFF00, /* Reserved, set to zero. */ - SubtableType = 0x000000FF, /* Subtable type; see following table. */ + Vertical = 0x80, /* If set, this subtable will only be applied + * to vertical text. If clear, this subtable + * will only be applied to horizontal text. */ + Backwards = 0x40, /* If set, this subtable will process glyphs + * in descending order. If clear, it will + * process the glyphs in ascending order. */ + AllDirections = 0x20, /* If set, this subtable will be applied to + * both horizontal and vertical text (i.e. + * the state of bit 0x80000000 is ignored). */ + Logical = 0x10, /* If set, this subtable will process glyphs + * in logical order (or reverse logical order, + * depending on the value of bit 0x80000000). */ }; enum Type { @@ -841,8 +842,8 @@ struct ChainSubtable } protected: - HBUINT32 length; /* Total subtable length, including this header. */ - HBUINT32 coverage; /* Coverage flags and subtable type. */ + HBUINT length; /* Total subtable length, including this header. */ + HBUINT coverage; /* Coverage flags and subtable type. */ HBUINT32 subFeatureFlags;/* The 32-bit mask identifying which subtable this is. */ union { RearrangementSubtable rearrangement; @@ -852,7 +853,7 @@ struct ChainSubtable InsertionSubtable insertion; } u; public: - DEFINE_SIZE_MIN (2 * sizeof (HBUINT32) + 4); + DEFINE_SIZE_MIN (2 * sizeof (HBUINT) + 4); }; template @@ -895,9 +896,9 @@ struct Chain if (!(subtable->subFeatureFlags & flags)) goto skip; - if (!(subtable->coverage & ChainSubtable::AllDirections) && + if (!(subtable->get_coverage() & ChainSubtable::AllDirections) && HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) != - bool (subtable->coverage & ChainSubtable::Vertical)) + bool (subtable->get_coverage() & ChainSubtable::Vertical)) goto skip; /* Buffer contents is always in logical direction. Determine if @@ -927,9 +928,9 @@ struct Chain (the order opposite that of the characters, which may be right-to-left or left-to-right). */ - reverse = subtable->coverage & ChainSubtable::Logical ? - bool (subtable->coverage & ChainSubtable::Backwards) : - bool (subtable->coverage & ChainSubtable::Backwards) != + reverse = subtable->get_coverage () & ChainSubtable::Logical ? + bool (subtable->get_coverage () & ChainSubtable::Backwards) : + bool (subtable->get_coverage () & ChainSubtable::Backwards) != HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction); if (!c->buffer->message (c->font, "start chain subtable %d", c->lookup_index)) @@ -981,8 +982,8 @@ struct Chain } protected: - HBUINT defaultFlags; /* The default specification for subtables. */ - HBUINT length; /* Total byte count, including this header. */ + HBUINT32 defaultFlags; /* The default specification for subtables. */ + HBUINT32 length; /* Total byte count, including this header. */ HBUINT featureCount; /* Number of feature subtable entries. */ HBUINT subtableCount; /* The number of subtables in the chain. */ @@ -991,7 +992,7 @@ struct Chain /*subtableGlyphCoverageArray*/ /* Only if version >= 3. We don't use. */ public: - DEFINE_SIZE_MIN (2 * sizeof (HBUINT) + 4); + DEFINE_SIZE_MIN (8 + 2 * sizeof (HBUINT)); }; From 9346b1f158dfd7d25ed0057b40aaa6980a85ea17 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 30 Oct 2018 20:04:13 -0700 Subject: [PATCH 225/255] [morx] Remove stale comment --- src/hb-aat-layout-morx-table.hh | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 6d6ef708d..dba352f9a 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -865,8 +865,6 @@ struct Chain { hb_mask_t flags = defaultFlags; { - /* Compute applicable flags. TODO Should move this to planning - * stage and take user-requested features into account. */ unsigned int count = featureCount; for (unsigned i = 0; i < count; i++) { From 90667b31bc3e61e68e27966e4781aba456c6b93b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 30 Oct 2018 20:15:28 -0700 Subject: [PATCH 226/255] [mort] Hook up more --- src/hb-aat-layout.cc | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index 2b4f57837..b6bdb0beb 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -207,7 +207,19 @@ void hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper, hb_aat_map_t *map) { - _get_morx (mapper->face).compile_flags (mapper, map); + const AAT::morx& morx = _get_morx (mapper->face, nullptr); + if (morx.has_data ()) + { + morx.compile_flags (mapper, map); + return; + } + + const AAT::mort& mort = _get_mort (mapper->face, nullptr); + if (mort.has_data ()) + { + mort.compile_flags (mapper, map); + return; + } } From 0cf282a32e5b0fe1fec454ff293ffe04b33f1112 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 30 Oct 2018 20:51:44 -0700 Subject: [PATCH 227/255] [mort] Grind some more --- src/hb-aat-layout-common.hh | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index c9d5cfe95..65e7fd93b 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -430,6 +430,10 @@ struct StateTable CLASS_END_OF_LINE = 3, }; + inline unsigned int row_stride (void) const { return nClasses * sizeof (HBUSHORT); } + inline unsigned int new_state (unsigned int newState) const + { return newState / (Types::extended ? 1 : row_stride ()); } + inline unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs) const { if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH; @@ -495,7 +499,10 @@ struct StateTable { /* Sweep new entries. */ const Entry *stop = &entries[num_entries]; for (const Entry *p = &entries[entry]; p < stop; p++) - num_states = MAX (num_states, p->newState + 1); + { + unsigned int newState = new_state (p->newState); + num_states = MAX (num_states, newState + 1); + } entry = num_entries; } } @@ -620,17 +627,17 @@ struct StateTableDriver } if (unlikely (!c->transition (this, entry))) - break; + break; last_was_dont_advance = (entry->flags & context_t::DontAdvance) && buffer->max_ops-- > 0; - state = entry->newState; + state = machine.new_state (entry->newState); if (buffer->idx == buffer->len) - break; + break; if (!last_was_dont_advance) - buffer->next_glyph (); + buffer->next_glyph (); } if (!c->in_place) From e1552af95b6c17571f7ee58ebac92f48d93c8f98 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 30 Oct 2018 21:09:05 -0700 Subject: [PATCH 228/255] [maxp] Minor --- src/hb-ot-maxp-table.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-maxp-table.hh b/src/hb-ot-maxp-table.hh index 648f232d9..198dd2518 100644 --- a/src/hb-ot-maxp-table.hh +++ b/src/hb-ot-maxp-table.hh @@ -92,7 +92,7 @@ struct maxp if (version.major == 1) { const maxpV1Tail &v1 = StructAfter (*this); - return v1.sanitize (c); + return_trace (v1.sanitize (c)); } return_trace (likely (version.major == 0 && version.minor == 0x5000u)); } From 11dbf0f12926b80d0c308c70a218342280045c23 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 30 Oct 2018 21:49:59 -0700 Subject: [PATCH 229/255] [mort] More fixes] --- src/hb-aat-layout-common.hh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 65e7fd93b..33d9e5564 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -430,9 +430,8 @@ struct StateTable CLASS_END_OF_LINE = 3, }; - inline unsigned int row_stride (void) const { return nClasses * sizeof (HBUSHORT); } inline unsigned int new_state (unsigned int newState) const - { return newState / (Types::extended ? 1 : row_stride ()); } + { return Types::extended ? newState : (newState - stateArrayTable) / nClasses; } inline unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs) const { @@ -524,7 +523,7 @@ struct StateTable entryTable; /* Offset to the entry array. */ public: - DEFINE_SIZE_STATIC (16); + DEFINE_SIZE_STATIC (4 * sizeof (HBUINT)); }; struct ClassTable From 28b68cffe4e5ebf82217ebf439f428431d672af3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 30 Oct 2018 23:33:30 -0700 Subject: [PATCH 230/255] [mort] Implement / adjust Contextual substitution --- src/hb-aat-layout-morx-table.hh | 70 ++++++++++++++++++++++++--------- src/hb-open-type.hh | 7 ++++ 2 files changed, 59 insertions(+), 18 deletions(-) diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index dba352f9a..c3a74835b 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -213,10 +213,13 @@ struct ContextualSubtable Reserved = 0x3FFF, /* These bits are reserved and should be set to 0. */ }; - inline driver_context_t (const ContextualSubtable *table) : + inline driver_context_t (const ContextualSubtable *table_, + hb_aat_apply_context_t *c_) : ret (false), + c (c_), mark_set (false), mark (0), + table (table_), subs (table+table->substitutionTables) {} inline bool is_actionable (StateTableDriver *driver, @@ -239,30 +242,57 @@ struct ContextualSubtable if (buffer->idx == buffer->len && !mark_set) return true; - if (entry->data.markIndex != 0xFFFF) + const GlyphID *replacement; + + replacement = nullptr; + if (Types::extended) { - const Lookup &lookup = subs[entry->data.markIndex]; - hb_glyph_info_t *info = buffer->info; - const GlyphID *replacement = lookup.get_value (info[mark].codepoint, driver->num_glyphs); - if (replacement) + if (entry->data.markIndex != 0xFFFF) { - buffer->unsafe_to_break (mark, MIN (buffer->idx + 1, buffer->len)); - info[mark].codepoint = *replacement; - ret = true; + const Lookup &lookup = subs[entry->data.markIndex]; + replacement = lookup.get_value (buffer->info[mark].codepoint, driver->num_glyphs); } } - if (entry->data.currentIndex != 0xFFFF) + else { - unsigned int idx = MIN (buffer->idx, buffer->len - 1); - const Lookup &lookup = subs[entry->data.currentIndex]; - hb_glyph_info_t *info = buffer->info; - const GlyphID *replacement = lookup.get_value (info[idx].codepoint, driver->num_glyphs); - if (replacement) + unsigned int offset = 2 * (entry->data.markIndex + buffer->info[mark].codepoint); + replacement = &StructAtOffset (table, offset); + if ((const void *) replacement < (const void *) subs || + !replacement->sanitize (&c->sanitizer) || + !*replacement) + replacement = nullptr; + } + if (replacement) + { + buffer->unsafe_to_break (mark, MIN (buffer->idx + 1, buffer->len)); + buffer->info[mark].codepoint = *replacement; + ret = true; + } + + replacement = nullptr; + unsigned int idx = MIN (buffer->idx, buffer->len - 1); + if (Types::extended) + { + if (entry->data.currentIndex != 0xFFFF) { - info[idx].codepoint = *replacement; - ret = true; + const Lookup &lookup = subs[entry->data.currentIndex]; + replacement = lookup.get_value (buffer->info[idx].codepoint, driver->num_glyphs); } } + else + { + unsigned int offset = 2 * (entry->data.currentIndex + buffer->info[idx].codepoint); + replacement = &StructAtOffset (table, offset); + if ((const void *) replacement < (const void *) subs || + !replacement->sanitize (&c->sanitizer) || + !*replacement) + replacement = nullptr; + } + if (replacement) + { + buffer->info[idx].codepoint = *replacement; + ret = true; + } if (entry->flags & SetMark) { @@ -276,8 +306,10 @@ struct ContextualSubtable public: bool ret; private: + hb_aat_apply_context_t *c; bool mark_set; unsigned int mark; + const ContextualSubtable *table; const UnsizedOffsetListOf, HBUINT, false> &subs; }; @@ -285,7 +317,7 @@ struct ContextualSubtable { TRACE_APPLY (this); - driver_context_t dc (this); + driver_context_t dc (this, c); StateTableDriver driver (machine, c->buffer, c->face); driver.drive (&dc); @@ -300,6 +332,8 @@ struct ContextualSubtable unsigned int num_entries = 0; if (unlikely (!machine.sanitize (c, &num_entries))) return_trace (false); + if (!Types::extended) return_trace (true); + unsigned int num_lookups = 0; const Entry *entries = machine.get_entries (); diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index e9f99b104..00bd134dd 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -340,6 +340,9 @@ struct UnsizedArrayOf inline const Type& operator [] (unsigned int i) const { return arrayZ[i]; } inline Type& operator [] (unsigned int i) { return arrayZ[i]; } + template inline operator T * (void) { return arrayZ; } + template inline operator const T * (void) const { return arrayZ; } + inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const { TRACE_SANITIZE (this); @@ -450,6 +453,10 @@ struct ArrayOf if (unlikely (i >= len)) return Crap(Type); return arrayZ[i]; } + + template inline operator T * (void) { return arrayZ; } + template inline operator const T * (void) const { return arrayZ; } + inline unsigned int get_size (void) const { return len.static_size + len * Type::static_size; } From 431c6e496be56e441ee4b9b705f40a1246bdd0d6 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 31 Oct 2018 00:15:00 -0700 Subject: [PATCH 231/255] [mort] Some Ligature work --- src/hb-aat-layout-morx-table.hh | 38 +++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index c3a74835b..cc83987d6 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -359,19 +359,43 @@ struct ContextualSubtable DEFINE_SIZE_STATIC (20); }; -template -struct LigatureSubtable -{ - typedef typename Types::HBUINT HBUINT; - struct EntryData +template +struct LigatureEntry; + +template <> +struct LigatureEntry +{ + typedef struct { HBUINT16 ligActionIndex; /* Index to the first ligActionTable entry * for processing this group, if indicated * by the flags. */ public: DEFINE_SIZE_STATIC (2); - }; + } EntryData; + + template + static inline unsigned int ligActionIndex (Entry &entry, Flags flags) + { return entry->data.ligActionIndex; }; +}; +template <> +struct LigatureEntry +{ + typedef void EntryData; + + template + static inline unsigned int ligActionIndex (Entry &entry, Flags flags) + { return flags & 0x3FFF; }; +}; + + +template +struct LigatureSubtable +{ + typedef typename Types::HBUINT HBUINT; + + typedef typename LigatureEntry::EntryData EntryData; struct driver_context_t { @@ -436,7 +460,7 @@ struct LigatureSubtable { DEBUG_MSG (APPLY, nullptr, "Perform action with %d", match_length); unsigned int end = buffer->out_len; - unsigned int action_idx = entry->data.ligActionIndex; + unsigned int action_idx = LigatureEntry::ligActionIndex (entry, flags); unsigned int action; unsigned int ligature_idx = 0; From c07798960004439fcd8fa0f4ae33e225428d1065 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 31 Oct 2018 00:36:03 -0700 Subject: [PATCH 232/255] [mort] More Ligature work --- src/hb-aat-layout-morx-table.hh | 54 ++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index cc83987d6..28cdc8dea 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -366,6 +366,17 @@ struct LigatureEntry; template <> struct LigatureEntry { + enum Flags + { + SetComponent = 0x8000, /* Push this glyph onto the component stack for + * eventual processing. */ + DontAdvance = 0x4000, /* Leave the glyph pointer at this glyph for the + next iteration. */ + PerformAction = 0x2000, /* Use the ligActionIndex to process a ligature + * group. */ + Reserved = 0x1FFF, /* These bits are reserved and should be set to 0. */ + }; + typedef struct { HBUINT16 ligActionIndex; /* Index to the first ligActionTable entry @@ -375,6 +386,10 @@ struct LigatureEntry DEFINE_SIZE_STATIC (2); } EntryData; + template + static inline bool performAction (Flags flags) + { return flags & PerformAction; }; + template static inline unsigned int ligActionIndex (Entry &entry, Flags flags) { return entry->data.ligActionIndex; }; @@ -382,8 +397,23 @@ struct LigatureEntry template <> struct LigatureEntry { + enum Flags + { + SetComponent = 0x8000, /* Push this glyph onto the component stack for + * eventual processing. */ + DontAdvance = 0x4000, /* Leave the glyph pointer at this glyph for the + next iteration. */ + Offset = 0x3FFF, /* Byte offset from beginning of subtable to the + * ligature action list. This value must be a + * multiple of 4. */ + }; + typedef void EntryData; + template + static inline bool performAction (Flags flags) + { return flags & Offset; }; + template static inline unsigned int ligActionIndex (Entry &entry, Flags flags) { return flags & 0x3FFF; }; @@ -395,21 +425,17 @@ struct LigatureSubtable { typedef typename Types::HBUINT HBUINT; - typedef typename LigatureEntry::EntryData EntryData; + typedef LigatureEntry LigatureEntryT; + typedef typename LigatureEntryT::EntryData EntryData; + typedef typename LigatureEntryT::Flags Flags; struct driver_context_t { - static const bool in_place = false; - enum Flags + enum { - SetComponent = 0x8000, /* Push this glyph onto the component stack for - * eventual processing. */ - DontAdvance = 0x4000, /* Leave the glyph pointer at this glyph for the - next iteration. */ - PerformAction = 0x2000, /* Use the ligActionIndex to process a ligature - * group. */ - Reserved = 0x1FFF, /* These bits are reserved and should be set to 0. */ + DontAdvance = LigatureEntry::DontAdvance, }; + static const bool in_place = false; enum LigActionFlags { LigActionLast = 0x80000000, /* This is the last action in the list. This also @@ -434,7 +460,7 @@ struct LigatureSubtable inline bool is_actionable (StateTableDriver *driver HB_UNUSED, const Entry *entry) { - return entry->flags & PerformAction; + return LigatureEntryT::performAction (entry->flags); } inline bool transition (StateTableDriver *driver, const Entry *entry) @@ -443,7 +469,7 @@ struct LigatureSubtable unsigned int flags = entry->flags; DEBUG_MSG (APPLY, nullptr, "Ligature transition at %d", buffer->idx); - if (flags & SetComponent) + if (flags & Flags::SetComponent) { if (unlikely (match_length >= ARRAY_LENGTH (match_positions))) return false; @@ -456,11 +482,11 @@ struct LigatureSubtable DEBUG_MSG (APPLY, nullptr, "Set component at %d", buffer->out_len); } - if (flags & PerformAction) + if (LigatureEntryT::performAction (flags)) { DEBUG_MSG (APPLY, nullptr, "Perform action with %d", match_length); unsigned int end = buffer->out_len; - unsigned int action_idx = LigatureEntry::ligActionIndex (entry, flags); + unsigned int action_idx = LigatureEntryT::ligActionIndex (entry, flags); unsigned int action; unsigned int ligature_idx = 0; From c962d5e714a6f88c4cb20bed219177b1bc4a2dfd Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 31 Oct 2018 01:16:33 -0700 Subject: [PATCH 233/255] [mort] Make ligatures work ./hb-shape Apple_Chancery_10_12.ttf "Th th ll te to tr fr fu fj" [T_h=0+2308|space=2+569|t_h=3+1687|space=5+569|l_l=6+1108|space=8+569|t_e=9+1408|space=11+569|t_o=12+1531|space=14+569|t_r=15+1385|space=17+569|f_r=18+1432|space=20+569|f_u=21+1733|space=23+569|f_j=24+1098] Part of https://github.com/harfbuzz/harfbuzz/issues/1331 --- src/hb-aat-layout-morx-table.hh | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 28cdc8dea..08a380a4a 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -448,10 +448,11 @@ struct LigatureSubtable * into the component table. */ }; - inline driver_context_t (const LigatureSubtable *table, + inline driver_context_t (const LigatureSubtable *table_, hb_aat_apply_context_t *c_) : ret (false), c (c_), + table (table_), ligAction (table+table->ligAction), component (table+table->component), ligature (table+table->ligature), @@ -497,6 +498,9 @@ struct LigatureSubtable return false; // TODO Work on previous instead? unsigned int cursor = match_length; + const HBUINT32 *actionData = Types::extended ? + &ligAction[action_idx] : + &StructAtOffset (table, action_idx); do { if (unlikely (!cursor)) @@ -510,17 +514,20 @@ struct LigatureSubtable DEBUG_MSG (APPLY, nullptr, "Moving to stack position %d", cursor - 1); buffer->move_to (match_positions[--cursor]); - const HBUINT32 &actionData = ligAction[action_idx]; - if (unlikely (!actionData.sanitize (&c->sanitizer))) return false; - action = actionData; + if (unlikely (!actionData->sanitize (&c->sanitizer))) return false; + action = *actionData; uint32_t uoffset = action & LigActionOffset; if (uoffset & 0x20000000) uoffset |= 0xC0000000; /* Sign-extend. */ int32_t offset = (int32_t) uoffset; unsigned int component_idx = buffer->cur().codepoint + offset; + if (!Types::extended) + component_idx *= 2; - const HBUINT16 &componentData = component[component_idx]; + const HBUINT16 &componentData = Types::extended ? + component[component_idx] : + StructAtOffset (table, component_idx); if (unlikely (!componentData.sanitize (&c->sanitizer))) return false; ligature_idx += componentData; @@ -529,8 +536,9 @@ struct LigatureSubtable bool (action & LigActionLast)); if (action & (LigActionStore | LigActionLast)) { - - const GlyphID &ligatureData = ligature[ligature_idx]; + const GlyphID &ligatureData = Types::extended ? + ligature[ligature_idx] : + StructAtOffset (table, ligature_idx); if (unlikely (!ligatureData.sanitize (&c->sanitizer))) return false; hb_codepoint_t lig = ligatureData; @@ -550,7 +558,7 @@ struct LigatureSubtable buffer->merge_out_clusters (match_positions[cursor], buffer->out_len); } - action_idx++; + actionData++; } while (!(action & LigActionLast)); buffer->move_to (end); @@ -563,6 +571,7 @@ struct LigatureSubtable bool ret; private: hb_aat_apply_context_t *c; + const LigatureSubtable *table; const UnsizedArrayOf &ligAction; const UnsizedArrayOf &component; const UnsizedArrayOf &ligature; From 642c9dcf1b34b51ffdbf88ccbef4762aa12a5cbe Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Wed, 31 Oct 2018 14:02:37 +0330 Subject: [PATCH 234/255] [aat] Minor, remove extra semicolons --- src/hb-aat-layout-morx-table.hh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 08a380a4a..51bb3b338 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -388,11 +388,11 @@ struct LigatureEntry template static inline bool performAction (Flags flags) - { return flags & PerformAction; }; + { return flags & PerformAction; } template static inline unsigned int ligActionIndex (Entry &entry, Flags flags) - { return entry->data.ligActionIndex; }; + { return entry->data.ligActionIndex; } }; template <> struct LigatureEntry @@ -412,11 +412,11 @@ struct LigatureEntry template static inline bool performAction (Flags flags) - { return flags & Offset; }; + { return flags & Offset; } template static inline unsigned int ligActionIndex (Entry &entry, Flags flags) - { return flags & 0x3FFF; }; + { return flags & 0x3FFF; } }; From 2e639c47c9d35ff7dc4dde21f744f9ee695a27f3 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Wed, 31 Oct 2018 14:20:14 +0330 Subject: [PATCH 235/255] [aat] Fix older compilers by not referencing enum directly (#1340) --- src/hb-aat-layout-morx-table.hh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 51bb3b338..45dbc28aa 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -427,13 +427,12 @@ struct LigatureSubtable typedef LigatureEntry LigatureEntryT; typedef typename LigatureEntryT::EntryData EntryData; - typedef typename LigatureEntryT::Flags Flags; struct driver_context_t { enum { - DontAdvance = LigatureEntry::DontAdvance, + DontAdvance = LigatureEntryT::DontAdvance, }; static const bool in_place = false; enum LigActionFlags @@ -470,7 +469,7 @@ struct LigatureSubtable unsigned int flags = entry->flags; DEBUG_MSG (APPLY, nullptr, "Ligature transition at %d", buffer->idx); - if (flags & Flags::SetComponent) + if (flags & LigatureEntryT::SetComponent) { if (unlikely (match_length >= ARRAY_LENGTH (match_positions))) return false; From 850a7af3a419c6c4ab92bff59991758a2951d41f Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Wed, 31 Oct 2018 14:20:23 +0330 Subject: [PATCH 236/255] [ot-color-test] Remove the non-working exact strike size storing (#1339) --- src/test-ot-color.cc | 135 ++++++++++++++++++++----------------------- 1 file changed, 62 insertions(+), 73 deletions(-) diff --git a/src/test-ot-color.cc b/src/test-ot-color.cc index cb369c0f3..1e492e663 100644 --- a/src/test-ot-color.cc +++ b/src/test-ot-color.cc @@ -23,7 +23,7 @@ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ -#include "hb.hh" +#include "hb.h" #include "hb-ot.h" #include "hb-ft.h" @@ -39,74 +39,6 @@ #include #include -static void -png_dump (hb_face_t *face, unsigned int face_index) -{ - unsigned glyph_count = hb_face_get_glyph_count (face); - hb_font_t *font = hb_font_create (face); - - /* ugly hack, scans the font for strikes, not needed for regular clients */ - #define STRIKES_MAX 20 - unsigned int strikes_count = 0; - unsigned int strikes[STRIKES_MAX] = {0}; - { - /* find a sample glyph */ - unsigned int sample_glyph_id; - /* we don't care much about different strikes for different glyphs */ - for (sample_glyph_id = 0; sample_glyph_id < glyph_count; sample_glyph_id++) - { - hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, sample_glyph_id); - unsigned int blob_length = hb_blob_get_length (blob); - hb_blob_destroy (blob); - if (blob_length != 0) - break; - } - /* find strikes it has */ - unsigned int upem = hb_face_get_upem (face); - unsigned int blob_length = 0; - for (unsigned int ppem = 1; ppem <= upem && strikes_count < STRIKES_MAX; ppem++) - { - hb_font_set_ppem (font, ppem, ppem); - hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, sample_glyph_id); - unsigned int new_blob_length = hb_blob_get_length (blob); - if (blob_length != new_blob_length) - { - strikes_count++; - blob_length = new_blob_length; - } - if (strikes_count != 0) - strikes[strikes_count - 1] = ppem; - hb_blob_destroy (blob); - } - /* can't report the biggest strike correctly, and, we can't do anything about it */ - } - #undef STRIKES_MAX - - for (unsigned int strike = 0; strike < strikes_count; strike++) - for (unsigned int glyph_id = 0; glyph_id < glyph_count; glyph_id++) - { - unsigned int ppem = strikes[strike]; - hb_font_set_ppem (font, ppem, ppem); - hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, glyph_id); - - if (hb_blob_get_length (blob) == 0) continue; - - unsigned int length; - const char *data = hb_blob_get_data (blob, &length); - - char output_path[255]; - sprintf (output_path, "out/png-%d-%d-%d.png", glyph_id, strike, face_index); - - FILE *f = fopen (output_path, "wb"); - fwrite (data, 1, length, f); - fclose (f); - - hb_blob_destroy (blob); - } - - hb_font_destroy (font); -} - static void svg_dump (hb_face_t *face, unsigned int face_index) { @@ -136,6 +68,63 @@ svg_dump (hb_face_t *face, unsigned int face_index) } } +/* _png API is so easy to use unlike the below code, don't get confused */ +static void +png_dump (hb_face_t *face, unsigned int face_index) +{ + unsigned glyph_count = hb_face_get_glyph_count (face); + hb_font_t *font = hb_font_create (face); + + /* scans the font for strikes */ + unsigned int sample_glyph_id; + /* we don't care about different strikes for different glyphs at this point */ + for (sample_glyph_id = 0; sample_glyph_id < glyph_count; sample_glyph_id++) + { + hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, sample_glyph_id); + unsigned int blob_length = hb_blob_get_length (blob); + hb_blob_destroy (blob); + if (blob_length != 0) + break; + } + + unsigned int upem = hb_face_get_upem (face); + unsigned int blob_length = 0; + unsigned int strike = 0; + for (unsigned int ppem = 1; ppem <= upem; ppem++) + { + hb_font_set_ppem (font, ppem, ppem); + hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, sample_glyph_id); + unsigned int new_blob_length = hb_blob_get_length (blob); + hb_blob_destroy (blob); + if (new_blob_length != blob_length) + { + for (unsigned int glyph_id = 0; glyph_id < glyph_count; glyph_id++) + { + hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, glyph_id); + + if (hb_blob_get_length (blob) == 0) continue; + + unsigned int length; + const char *data = hb_blob_get_data (blob, &length); + + char output_path[255]; + sprintf (output_path, "out/png-%d-%d-%d.png", glyph_id, strike, face_index); + + FILE *f = fopen (output_path, "wb"); + fwrite (data, 1, length, f); + fclose (f); + + hb_blob_destroy (blob); + } + + strike++; + blob_length = new_blob_length; + } + } + + hb_font_destroy (font); +} + static void layered_glyph_dump (hb_face_t *face, cairo_font_face_t *cairo_face, unsigned int face_index) { @@ -144,7 +133,7 @@ layered_glyph_dump (hb_face_t *face, cairo_font_face_t *cairo_face, unsigned int unsigned glyph_count = hb_face_get_glyph_count (face); for (hb_codepoint_t gid = 0; gid < glyph_count; ++gid) { - unsigned int num_layers = hb_ot_color_glyph_get_layers (face, gid, 0, nullptr, nullptr); + unsigned int num_layers = hb_ot_color_glyph_get_layers (face, gid, 0, NULL, NULL); if (!num_layers) continue; @@ -181,7 +170,7 @@ layered_glyph_dump (hb_face_t *face, cairo_font_face_t *cairo_face, unsigned int for (unsigned int palette = 0; palette < palette_count; palette++) { char output_path[255]; - unsigned int num_colors = hb_ot_color_palette_get_colors (face, palette, 0, nullptr, nullptr); + unsigned int num_colors = hb_ot_color_palette_get_colors (face, palette, 0, NULL, NULL); if (!num_colors) continue; @@ -282,14 +271,14 @@ main (int argc, char **argv) FILE *font_name_file = fopen ("out/.dumped_font_name", "r"); - if (font_name_file != nullptr) + if (font_name_file != NULL) { fprintf (stderr, "Purge or move ./out folder in order to run a new dump\n"); exit (1); } font_name_file = fopen ("out/.dumped_font_name", "w"); - if (font_name_file == nullptr) + if (font_name_file == NULL) { fprintf (stderr, "./out is not accessible as a folder, create it please\n"); exit (1); From 5854d3fa251069f8158b97a831d1439c2ff8b510 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 31 Oct 2018 10:42:49 -0700 Subject: [PATCH 237/255] [set] Warning fix with gcc 8.1 https://github.com/harfbuzz/harfbuzz/pull/1334 --- src/hb-dsalgs.hh | 6 ++++-- src/hb-set.hh | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index e8bd95c27..59df860df 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -610,8 +610,10 @@ struct HbOpXor template struct hb_vector_size_t { - elt_t& operator [] (unsigned int i) { return u.v[i]; } - const elt_t& operator [] (unsigned int i) const { return u.v[i]; } + inline elt_t& operator [] (unsigned int i) { return u.v[i]; } + inline const elt_t& operator [] (unsigned int i) const { return u.v[i]; } + + inline void clear (unsigned char v = 0) { memset (this, v, sizeof (*this)); } template inline hb_vector_size_t process (const hb_vector_size_t &o) const diff --git a/src/hb-set.hh b/src/hb-set.hh index 2dfcc242a..947e8d9d1 100644 --- a/src/hb-set.hh +++ b/src/hb-set.hh @@ -53,8 +53,8 @@ struct hb_set_t struct page_t { - inline void init0 (void) { memset (reinterpret_cast(&v), 0, sizeof (v)); } - inline void init1 (void) { memset (reinterpret_cast(&v), 0xff, sizeof (v)); } + inline void init0 (void) { v.clear (); } + inline void init1 (void) { v.clear (0xFF); } inline unsigned int len (void) const { return ARRAY_LENGTH_CONST (v); } From 4d4e526b5cc703111eb445b7e319a4cd1917489f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 31 Oct 2018 13:19:42 -0700 Subject: [PATCH 238/255] Improve blob->as<> It's true that blob->as<> should only be called on null or sanitized data. But this change is safe, so keep it. --- src/hb-blob.hh | 2 +- src/hb-ot-glyf-table.hh | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hb-blob.hh b/src/hb-blob.hh index 26e2dd70a..0181e94a4 100644 --- a/src/hb-blob.hh +++ b/src/hb-blob.hh @@ -60,7 +60,7 @@ struct hb_blob_t template inline const Type* as (void) const { - return unlikely (!data) ? &Null(Type) : reinterpret_cast (data); + return length < Type::min_size ? &Null(Type) : reinterpret_cast (data); } inline hb_bytes_t as_bytes (void) const { diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh index 9437a83d8..7bd175e39 100644 --- a/src/hb-ot-glyf-table.hh +++ b/src/hb-ot-glyf-table.hh @@ -55,6 +55,7 @@ struct loca protected: UnsizedArrayOf dataZ; /* Location data. */ + public: DEFINE_SIZE_ARRAY (0, dataZ); }; @@ -484,7 +485,7 @@ struct glyf protected: UnsizedArrayOf dataZ; /* Glyphs data. */ - + public: DEFINE_SIZE_ARRAY (0, dataZ); }; From 995bf6c6f82d6b2dabcb81e1426910ee82b91b44 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 31 Oct 2018 13:21:33 -0700 Subject: [PATCH 239/255] [sbix] Rely on blob->as<> checking size against Type::min_size --- src/hb-ot-color-sbix-table.hh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 4feb4e193..065c0dd18 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -243,12 +243,6 @@ struct sbix unsigned int strike_ppem = 0; hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset, &strike_ppem); - if (unlikely (blob->length < sizeof (PNGHeader))) - { - hb_blob_destroy (blob); - return false; - } - const PNGHeader &png = *blob->as(); extents->x_bearing = x_offset; From b9db610add702da0a257db2eb21f3a7fb56682f7 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 31 Oct 2018 14:22:31 -0700 Subject: [PATCH 240/255] Minor --- src/hb-font.cc | 28 ++++++++++++++-------------- src/hb-font.h | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/hb-font.cc b/src/hb-font.cc index 135d310ca..86b03f4b6 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -54,23 +54,23 @@ static hb_bool_t hb_font_get_font_h_extents_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, - hb_font_extents_t *metrics, + hb_font_extents_t *extents, void *user_data HB_UNUSED) { - memset (metrics, 0, sizeof (*metrics)); + memset (extents, 0, sizeof (*extents)); return false; } static hb_bool_t hb_font_get_font_h_extents_default (hb_font_t *font, void *font_data HB_UNUSED, - hb_font_extents_t *metrics, + hb_font_extents_t *extents, void *user_data HB_UNUSED) { - hb_bool_t ret = font->parent->get_font_h_extents (metrics); + hb_bool_t ret = font->parent->get_font_h_extents (extents); if (ret) { - metrics->ascender = font->parent_scale_y_distance (metrics->ascender); - metrics->descender = font->parent_scale_y_distance (metrics->descender); - metrics->line_gap = font->parent_scale_y_distance (metrics->line_gap); + extents->ascender = font->parent_scale_y_distance (extents->ascender); + extents->descender = font->parent_scale_y_distance (extents->descender); + extents->line_gap = font->parent_scale_y_distance (extents->line_gap); } return ret; } @@ -78,23 +78,23 @@ hb_font_get_font_h_extents_default (hb_font_t *font, static hb_bool_t hb_font_get_font_v_extents_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, - hb_font_extents_t *metrics, + hb_font_extents_t *extents, void *user_data HB_UNUSED) { - memset (metrics, 0, sizeof (*metrics)); + memset (extents, 0, sizeof (*extents)); return false; } static hb_bool_t hb_font_get_font_v_extents_default (hb_font_t *font, void *font_data HB_UNUSED, - hb_font_extents_t *metrics, + hb_font_extents_t *extents, void *user_data HB_UNUSED) { - hb_bool_t ret = font->parent->get_font_v_extents (metrics); + hb_bool_t ret = font->parent->get_font_v_extents (extents); if (ret) { - metrics->ascender = font->parent_scale_x_distance (metrics->ascender); - metrics->descender = font->parent_scale_x_distance (metrics->descender); - metrics->line_gap = font->parent_scale_x_distance (metrics->line_gap); + extents->ascender = font->parent_scale_x_distance (extents->ascender); + extents->descender = font->parent_scale_x_distance (extents->descender); + extents->line_gap = font->parent_scale_x_distance (extents->line_gap); } return ret; } diff --git a/src/hb-font.h b/src/hb-font.h index 74c61aba4..e2086d818 100644 --- a/src/hb-font.h +++ b/src/hb-font.h @@ -110,7 +110,7 @@ typedef struct hb_glyph_extents_t /* func types */ typedef hb_bool_t (*hb_font_get_font_extents_func_t) (hb_font_t *font, void *font_data, - hb_font_extents_t *metrics, + hb_font_extents_t *extents, void *user_data); typedef hb_font_get_font_extents_func_t hb_font_get_font_h_extents_func_t; typedef hb_font_get_font_extents_func_t hb_font_get_font_v_extents_func_t; From 3087046d3144afb50bcc13e4afa2d20d9f71f2c8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 31 Oct 2018 14:59:14 -0700 Subject: [PATCH 241/255] [mort] Refactor offset-to-index mapping --- src/hb-aat-layout-morx-table.hh | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 45dbc28aa..396457c1f 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -457,6 +457,14 @@ struct LigatureSubtable ligature (table+table->ligature), match_length (0) {} + template + static inline unsigned int offsetToIndex (unsigned int offset, + const void *base, + const T *array) + { + return (offset - ((const char *) array - (const char *) base)) / sizeof (T); + } + inline bool is_actionable (StateTableDriver *driver HB_UNUSED, const Entry *entry) { @@ -497,9 +505,9 @@ struct LigatureSubtable return false; // TODO Work on previous instead? unsigned int cursor = match_length; - const HBUINT32 *actionData = Types::extended ? - &ligAction[action_idx] : - &StructAtOffset (table, action_idx); + if (!Types::extended) + action_idx = offsetToIndex (action_idx, table, ligAction.arrayZ); + const HBUINT32 *actionData = &ligAction[action_idx]; do { if (unlikely (!cursor)) @@ -522,11 +530,8 @@ struct LigatureSubtable int32_t offset = (int32_t) uoffset; unsigned int component_idx = buffer->cur().codepoint + offset; if (!Types::extended) - component_idx *= 2; - - const HBUINT16 &componentData = Types::extended ? - component[component_idx] : - StructAtOffset (table, component_idx); + component_idx = offsetToIndex (component_idx * 2, table, component.arrayZ); + const HBUINT16 &componentData = component[component_idx]; if (unlikely (!componentData.sanitize (&c->sanitizer))) return false; ligature_idx += componentData; @@ -535,9 +540,9 @@ struct LigatureSubtable bool (action & LigActionLast)); if (action & (LigActionStore | LigActionLast)) { - const GlyphID &ligatureData = Types::extended ? - ligature[ligature_idx] : - StructAtOffset (table, ligature_idx); + if (!Types::extended) + ligature_idx = offsetToIndex (ligature_idx, table, ligature.arrayZ); + const GlyphID &ligatureData = ligature[ligature_idx]; if (unlikely (!ligatureData.sanitize (&c->sanitizer))) return false; hb_codepoint_t lig = ligatureData; From cbaff4ef1910e2872bfff61f3d5427c076b3673d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 31 Oct 2018 15:06:12 -0700 Subject: [PATCH 242/255] [mort] Some more --- src/hb-aat-layout-morx-table.hh | 34 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 396457c1f..5ac9d7814 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -45,6 +45,14 @@ namespace AAT { using namespace OT; +template +static inline unsigned int offsetToIndex (unsigned int offset, + const void *base, + const T *array) +{ + return (offset - ((const char *) array - (const char *) base)) / sizeof (T); +} + template struct RearrangementSubtable { @@ -255,11 +263,10 @@ struct ContextualSubtable } else { - unsigned int offset = 2 * (entry->data.markIndex + buffer->info[mark].codepoint); - replacement = &StructAtOffset (table, offset); - if ((const void *) replacement < (const void *) subs || - !replacement->sanitize (&c->sanitizer) || - !*replacement) + unsigned int offset = entry->data.markIndex + buffer->info[mark].codepoint; + const UnsizedArrayOf &subs_old = (const UnsizedArrayOf &) subs; + replacement = &subs_old[offsetToIndex (offset * 2, table, subs_old.arrayZ)]; + if (!replacement->sanitize (&c->sanitizer) || !*replacement) replacement = nullptr; } if (replacement) @@ -281,11 +288,10 @@ struct ContextualSubtable } else { - unsigned int offset = 2 * (entry->data.currentIndex + buffer->info[idx].codepoint); - replacement = &StructAtOffset (table, offset); - if ((const void *) replacement < (const void *) subs || - !replacement->sanitize (&c->sanitizer) || - !*replacement) + unsigned int offset = entry->data.currentIndex + buffer->info[idx].codepoint; + const UnsizedArrayOf &subs_old = (const UnsizedArrayOf &) subs; + replacement = &subs_old[offsetToIndex (offset * 2, table, subs_old.arrayZ)]; + if (!replacement->sanitize (&c->sanitizer) || !*replacement) replacement = nullptr; } if (replacement) @@ -457,14 +463,6 @@ struct LigatureSubtable ligature (table+table->ligature), match_length (0) {} - template - static inline unsigned int offsetToIndex (unsigned int offset, - const void *base, - const T *array) - { - return (offset - ((const char *) array - (const char *) base)) / sizeof (T); - } - inline bool is_actionable (StateTableDriver *driver HB_UNUSED, const Entry *entry) { From 36e90ef56e6c0643ef61e947d7361c6fa4eadf10 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 31 Oct 2018 15:09:09 -0700 Subject: [PATCH 243/255] [mort] Massage some more --- src/hb-aat-layout-common.hh | 28 ++++++++++++++++++++++++++++ src/hb-aat-layout-morx-table.hh | 21 +++++---------------- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 33d9e5564..51add2213 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -560,6 +560,20 @@ struct MortTypes return ClassTable::get_class (glyph_id); } }; + template + static inline unsigned int offsetToIndex (unsigned int offset, + const void *base, + const T *array) + { + return (offset - ((const char *) array - (const char *) base)) / sizeof (T); + } + template + static inline unsigned int wordOffsetToIndex (unsigned int offset, + const void *base, + const T *array) + { + return offsetToIndex (2 * offset, base, array); + } }; struct MorxTypes { @@ -574,6 +588,20 @@ struct MorxTypes return v ? *v : 1; } }; + template + static inline unsigned int offsetToIndex (unsigned int offset, + const void *base, + const T *array) + { + return offset; + } + template + static inline unsigned int wordOffsetToIndex (unsigned int offset, + const void *base, + const T *array) + { + return offset; + } }; template diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 5ac9d7814..ab867bba9 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -45,14 +45,6 @@ namespace AAT { using namespace OT; -template -static inline unsigned int offsetToIndex (unsigned int offset, - const void *base, - const T *array) -{ - return (offset - ((const char *) array - (const char *) base)) / sizeof (T); -} - template struct RearrangementSubtable { @@ -265,7 +257,7 @@ struct ContextualSubtable { unsigned int offset = entry->data.markIndex + buffer->info[mark].codepoint; const UnsizedArrayOf &subs_old = (const UnsizedArrayOf &) subs; - replacement = &subs_old[offsetToIndex (offset * 2, table, subs_old.arrayZ)]; + replacement = &subs_old[Types::wordOffsetToIndex (offset, table, subs_old.arrayZ)]; if (!replacement->sanitize (&c->sanitizer) || !*replacement) replacement = nullptr; } @@ -290,7 +282,7 @@ struct ContextualSubtable { unsigned int offset = entry->data.currentIndex + buffer->info[idx].codepoint; const UnsizedArrayOf &subs_old = (const UnsizedArrayOf &) subs; - replacement = &subs_old[offsetToIndex (offset * 2, table, subs_old.arrayZ)]; + replacement = &subs_old[Types::wordOffsetToIndex (offset, table, subs_old.arrayZ)]; if (!replacement->sanitize (&c->sanitizer) || !*replacement) replacement = nullptr; } @@ -503,8 +495,7 @@ struct LigatureSubtable return false; // TODO Work on previous instead? unsigned int cursor = match_length; - if (!Types::extended) - action_idx = offsetToIndex (action_idx, table, ligAction.arrayZ); + action_idx = Types::offsetToIndex (action_idx, table, ligAction.arrayZ); const HBUINT32 *actionData = &ligAction[action_idx]; do { @@ -527,8 +518,7 @@ struct LigatureSubtable uoffset |= 0xC0000000; /* Sign-extend. */ int32_t offset = (int32_t) uoffset; unsigned int component_idx = buffer->cur().codepoint + offset; - if (!Types::extended) - component_idx = offsetToIndex (component_idx * 2, table, component.arrayZ); + component_idx = Types::wordOffsetToIndex (component_idx, table, component.arrayZ); const HBUINT16 &componentData = component[component_idx]; if (unlikely (!componentData.sanitize (&c->sanitizer))) return false; ligature_idx += componentData; @@ -538,8 +528,7 @@ struct LigatureSubtable bool (action & LigActionLast)); if (action & (LigActionStore | LigActionLast)) { - if (!Types::extended) - ligature_idx = offsetToIndex (ligature_idx, table, ligature.arrayZ); + ligature_idx = Types::offsetToIndex (ligature_idx, table, ligature.arrayZ); const GlyphID &ligatureData = ligature[ligature_idx]; if (unlikely (!ligatureData.sanitize (&c->sanitizer))) return false; hb_codepoint_t lig = ligatureData; From e01250230b1ad85e49cc0021365d1ee43feb9855 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 31 Oct 2018 18:14:00 -0700 Subject: [PATCH 244/255] [hmtx/vmtx] Fix a crasher --- src/hb-ot-hmtx-table.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-hmtx-table.hh b/src/hb-ot-hmtx-table.hh index 607358584..1eb6cc68f 100644 --- a/src/hb-ot-hmtx-table.hh +++ b/src/hb-ot-hmtx-table.hh @@ -255,7 +255,7 @@ struct hmtxvmtx if (glyph < num_advances) return table->longMetricZ[glyph].sb; - if (unlikely (glyph > num_metrics)) + if (unlikely (glyph >= num_metrics)) return 0; const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_advances]; From cf203af8a33591c163b63dbdf0fd341bc4606190 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 31 Oct 2018 18:21:48 -0700 Subject: [PATCH 245/255] Implement space fallback in vertical direction Fixes https://github.com/harfbuzz/harfbuzz/issues/1343 --- src/hb-ot-shape-fallback.cc | 36 +++++++++++++------ test/shaping/data/in-house/tests/spaces.tests | 17 +++++++++ 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/src/hb-ot-shape-fallback.cc b/src/hb-ot-shape-fallback.cc index 94bc4afb1..766efe20d 100644 --- a/src/hb-ot-shape-fallback.cc +++ b/src/hb-ot-shape-fallback.cc @@ -476,11 +476,9 @@ _hb_ot_shape_fallback_spaces (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_font_t *font, hb_buffer_t *buffer) { - if (!HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) - return; - hb_glyph_info_t *info = buffer->info; hb_glyph_position_t *pos = buffer->pos; + bool horizontal = HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction); unsigned int count = buffer->len; for (unsigned int i = 0; i < count; i++) if (_hb_glyph_info_is_unicode_space (&info[i]) && !_hb_glyph_info_ligated (&info[i])) @@ -501,27 +499,40 @@ _hb_ot_shape_fallback_spaces (const hb_ot_shape_plan_t *plan HB_UNUSED, case t::SPACE_EM_5: case t::SPACE_EM_6: case t::SPACE_EM_16: - pos[i].x_advance = (font->x_scale + ((int) space_type)/2) / (int) space_type; + if (horizontal) + pos[i].x_advance = (font->x_scale + ((int) space_type)/2) / (int) space_type; + else + pos[i].y_advance = (font->y_scale + ((int) space_type)/2) / (int) space_type; break; case t::SPACE_4_EM_18: - pos[i].x_advance = (int64_t) font->x_scale * 4 / 18; + if (horizontal) + pos[i].x_advance = (int64_t) font->x_scale * 4 / 18; + else + pos[i].y_advance = (int64_t) font->y_scale * 4 / 18; break; case t::SPACE_FIGURE: for (char u = '0'; u <= '9'; u++) if (font->get_nominal_glyph (u, &glyph)) { - pos[i].x_advance = font->get_glyph_h_advance (glyph); + if (horizontal) + pos[i].x_advance = font->get_glyph_h_advance (glyph); + else + pos[i].y_advance = font->get_glyph_v_advance (glyph); break; } break; case t::SPACE_PUNCTUATION: - if (font->get_nominal_glyph ('.', &glyph)) - pos[i].x_advance = font->get_glyph_h_advance (glyph); - else if (font->get_nominal_glyph (',', &glyph)) - pos[i].x_advance = font->get_glyph_h_advance (glyph); + if (font->get_nominal_glyph ('.', &glyph) || + font->get_nominal_glyph (',', &glyph)) + { + if (horizontal) + pos[i].x_advance = font->get_glyph_h_advance (glyph); + else + pos[i].y_advance = font->get_glyph_v_advance (glyph); + } break; case t::SPACE_NARROW: @@ -530,7 +541,10 @@ _hb_ot_shape_fallback_spaces (const hb_ot_shape_plan_t *plan HB_UNUSED, * However, in my testing, many fonts have their regular space being about that * size. To me, a percentage of the space width makes more sense. Half is as * good as any. */ - pos[i].x_advance /= 2; + if (horizontal) + pos[i].x_advance /= 2; + else + pos[i].y_advance /= 2; break; } } diff --git a/test/shaping/data/in-house/tests/spaces.tests b/test/shaping/data/in-house/tests/spaces.tests index 3ebaac51c..526d158b1 100644 --- a/test/shaping/data/in-house/tests/spaces.tests +++ b/test/shaping/data/in-house/tests/spaces.tests @@ -15,3 +15,20 @@ ../fonts/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+202F:[gid1=0+280] ../fonts/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+205F:[gid1=0+455] ../fonts/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+3000:[gid1=0+2048] +../fonts/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot --direction=ttb:U+0020:[gid1=0@-280,0+0,-2048] +../fonts/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot --direction=ttb:U+00A0:[gid1=0@-280,0+0,-2048] +../fonts/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot --direction=ttb:U+1680:[gid0=0@-346,0+0,-2048] +../fonts/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot --direction=ttb:U+2000:[gid1=0@-280,0+0,1024] +../fonts/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot --direction=ttb:U+2001:[gid1=0@-280,0+0,2048] +../fonts/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot --direction=ttb:U+2002:[gid1=0@-280,0+0,1024] +../fonts/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot --direction=ttb:U+2003:[gid1=0@-280,0+0,2048] +../fonts/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot --direction=ttb:U+2004:[gid1=0@-280,0+0,683] +../fonts/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot --direction=ttb:U+2005:[gid1=0@-280,0+0,512] +../fonts/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot --direction=ttb:U+2006:[gid1=0@-280,0+0,341] +../fonts/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot --direction=ttb:U+2007:[gid1=0@-280,0+0,-2048] +../fonts/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot --direction=ttb:U+2008:[gid1=0@-280,0+0,-2048] +../fonts/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot --direction=ttb:U+2009:[gid1=0@-280,0+0,410] +../fonts/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot --direction=ttb:U+200A:[gid1=0@-280,0+0,128] +../fonts/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot --direction=ttb:U+202F:[gid1=0@-280,0+0,-1024] +../fonts/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot --direction=ttb:U+205F:[gid1=0@-280,0+0,455] +../fonts/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot --direction=ttb:U+3000:[gid1=0@-280,0+0,2048] From f9289319481a1e9762ad366b287e781c44ba9fc6 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 31 Oct 2018 18:25:05 -0700 Subject: [PATCH 246/255] [test] Minor --- test/shaping/run-tests.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/test/shaping/run-tests.py b/test/shaping/run-tests.py index 65e0e1490..abb25ab3e 100755 --- a/test/shaping/run-tests.py +++ b/test/shaping/run-tests.py @@ -11,7 +11,13 @@ def cmd(command): return process.stdout.readline().decode ("utf-8").strip () args = sys.argv[1:] -if not args or sys.argv[1].find('hb-shape') == -1 or not os.path.exists (sys.argv[1]): + +reference = False +if len (args) and args[0] == "--reference": + reference = True + args = args[1:] + +if not args or args[0].find('hb-shape') == -1 or not os.path.exists (args[0]): print ("""First argument does not seem to point to usable hb-shape.""") sys.exit (1) hb_shape, args = args[0], args[1:] @@ -23,11 +29,6 @@ process = subprocess.Popen ([hb_shape, '--batch'], fails = 0 -reference = False -if len (args) and args[0] == "--reference": - reference = True - args = args[1:] - if not len (args): args = ['-'] From 40b19fd46951e2f9b402e59e1fbbf06fde7ecd61 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 31 Oct 2018 18:51:45 -0700 Subject: [PATCH 247/255] [aat] Fallback to old style "Letter Case" small caps Fixes https://github.com/harfbuzz/harfbuzz/issues/1342 --- src/hb-aat-layout-morx-table.hh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index ab867bba9..d56af7bfe 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -955,12 +955,20 @@ struct Chain const Feature &feature = featureZ[i]; uint16_t type = feature.featureType; uint16_t setting = feature.featureSetting; + retry: const hb_aat_map_builder_t::feature_info_t *info = map->features.bsearch (type); if (info && info->setting == setting) { flags &= feature.disableFlags; flags |= feature.enableFlags; } + else if (type == 3/*kLetterCaseType*/ && setting == 3/*kSmallCapsSelector*/) + { + /* Deprecated. https://github.com/harfbuzz/harfbuzz/issues/1342 */ + type = 37/*kLowerCaseType*/; + setting = 1/*kLowerCaseSmallCapsSelector*/; + goto retry; + } } } return flags; From 6e3ea269fa1fe0a3de7a8a13c6e853c91231808e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 31 Oct 2018 19:00:11 -0700 Subject: [PATCH 248/255] [aat] Add 'afrc' feature mapping https://github.com/harfbuzz/harfbuzz/issues/1342#issuecomment-434829028 --- src/hb-aat-layout.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index b6bdb0beb..d917c29c6 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -41,6 +41,7 @@ * when moving to this file. */ static const hb_aat_feature_mapping_t feature_mappings[] = { + {HB_TAG ('a','f','r','c'), 11/*kFractionsType*/, 1/*kVerticalFractionsSelector*/, 0/*kNoFractionsSelector*/}, {HB_TAG ('c','2','p','c'), 38/*kUpperCaseType*/, 2/*kUpperCasePetiteCapsSelector*/, 0/*kDefaultUpperCaseSelector*/}, {HB_TAG ('c','2','s','c'), 38/*kUpperCaseType*/, 1/*kUpperCaseSmallCapsSelector*/, 0/*kDefaultUpperCaseSelector*/}, {HB_TAG ('c','a','l','t'), 36/*kContextualAlternatesType*/, 0/*kContextualAlternatesOnSelector*/, 1/*kContextualAlternatesOffSelector*/}, From 52a00cd87f63c8ab32413a1a9ce792a3e2ec84e2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 31 Oct 2018 19:05:53 -0700 Subject: [PATCH 249/255] [aat] Implement 'aalt' mapping Fixes https://github.com/harfbuzz/harfbuzz/issues/1160 --- src/hb-aat-map.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/hb-aat-map.cc b/src/hb-aat-map.cc index f2736bfd1..1ce1b12b0 100644 --- a/src/hb-aat-map.cc +++ b/src/hb-aat-map.cc @@ -34,6 +34,14 @@ void hb_aat_map_builder_t::add_feature (hb_tag_t tag, unsigned int value) { + if (tag == HB_TAG ('a','a','l','t')) + { + feature_info_t *info = features.push(); + info->type = 17/*kCharacterAlternativesType*/; + info->setting = value; + return; + } + const hb_aat_feature_mapping_t *mapping = hb_aat_layout_find_feature_mapping (tag); if (!mapping) return; From cad90be4ea56a85ddc084f86f36dd7129850f6d7 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Thu, 1 Nov 2018 13:39:06 +0330 Subject: [PATCH 250/255] [test] minor --- test/api/test-ot-color.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index e93f5d7b1..fdea16258 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -28,8 +28,6 @@ #include "hb-test.h" #include -#include -#include /* Unit tests for hb-ot-color.h */ From c32280b30fb3844addda31a0d97ae7cb55ef07d2 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Thu, 1 Nov 2018 15:31:14 +0330 Subject: [PATCH 251/255] [ot-layout] minor --- src/hb-ot-layout.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index e135e4a9e..e1b6b2e30 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -38,9 +38,9 @@ #include "hb-ot-layout-gsub-table.hh" #include "hb-ot-layout-gpos-table.hh" -// Just so we compile them; unused otherwise: -#include "hb-ot-layout-base-table.hh" -#include "hb-ot-layout-jstf-table.hh" +#include "hb-ot-layout-base-table.hh" // Just so we compile them; unused otherwise +#include "hb-ot-layout-jstf-table.hh" // Just so we compile them; unused otherwise + #include "hb-ot-kern-table.hh" #include "hb-ot-name-table.hh" From 07ec792212063851ee41eae33792d3d90d31e6a1 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 1 Nov 2018 10:31:12 -0400 Subject: [PATCH 252/255] Warning fix --- src/test-ot-color.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test-ot-color.cc b/src/test-ot-color.cc index 1e492e663..4b10e0177 100644 --- a/src/test-ot-color.cc +++ b/src/test-ot-color.cc @@ -90,7 +90,7 @@ png_dump (hb_face_t *face, unsigned int face_index) unsigned int upem = hb_face_get_upem (face); unsigned int blob_length = 0; unsigned int strike = 0; - for (unsigned int ppem = 1; ppem <= upem; ppem++) + for (unsigned int ppem = 1; ppem < upem; ppem++) { hb_font_set_ppem (font, ppem, ppem); hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, sample_glyph_id); From 5a18d97b35d05c826c242e6847764c2418831a55 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 1 Nov 2018 18:01:26 -0400 Subject: [PATCH 253/255] [aat] Remove unused forward declaration --- src/hb-aat-map.hh | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/hb-aat-map.hh b/src/hb-aat-map.hh index 846cdc1a9..d974bd3f0 100644 --- a/src/hb-aat-map.hh +++ b/src/hb-aat-map.hh @@ -30,8 +30,6 @@ #include "hb.hh" -struct hb_ot_shape_plan_t; - struct hb_aat_map_t { friend struct hb_aat_map_builder_t; From f9353bd68c112dea8962dd586bf5e664f75a2a07 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 1 Nov 2018 18:05:22 -0400 Subject: [PATCH 254/255] [aat] Rely on vector auto initialization --- src/hb-aat-map.hh | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/hb-aat-map.hh b/src/hb-aat-map.hh index d974bd3f0..6fd3fa1ea 100644 --- a/src/hb-aat-map.hh +++ b/src/hb-aat-map.hh @@ -56,15 +56,7 @@ struct hb_aat_map_builder_t HB_INTERNAL hb_aat_map_builder_t (hb_face_t *face_, const hb_segment_properties_t *props_ HB_UNUSED) : - face (face_) - { - features.init (); - } - - ~hb_aat_map_builder_t (void) - { - features.fini (); - } + face (face_) {} HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value=1); From de96e5c81c7f473520df93052ecea162baa5a350 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 1 Nov 2018 18:13:58 -0400 Subject: [PATCH 255/255] [Crap] Avoid operator= --- src/hb-null.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-null.hh b/src/hb-null.hh index 3d8a1ae6c..d5b74bf56 100644 --- a/src/hb-null.hh +++ b/src/hb-null.hh @@ -87,7 +87,7 @@ template static inline Type& Crap (void) { static_assert (sizeof (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); Type *obj = reinterpret_cast (_hb_CrapPool); - *obj = Null(Type); + memcpy (obj, &Null(Type), sizeof (*obj)); return *obj; } #define Crap(Type) Crap::value>::value>()