From 00cddd8f501726c55398988ec393b39824688bc9 Mon Sep 17 00:00:00 2001 From: Akira Kakuto Date: Thu, 2 Aug 2018 22:27:18 +0000 Subject: harfbuzz 1.8.5 git-svn-id: svn://tug.org/texlive/trunk@48337 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/libs/README | 2 +- Build/source/libs/harfbuzz/ChangeLog | 5 + Build/source/libs/harfbuzz/Makefile.am | 2 + Build/source/libs/harfbuzz/Makefile.in | 2 + Build/source/libs/harfbuzz/TLpatches/ChangeLog | 5 + Build/source/libs/harfbuzz/TLpatches/TL-Changes | 2 +- Build/source/libs/harfbuzz/configure | 24 +- Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog | 1250 ++++++++++++++++++++ Build/source/libs/harfbuzz/harfbuzz-src/NEWS | 8 + .../source/libs/harfbuzz/harfbuzz-src/configure.ac | 2 +- .../libs/harfbuzz/harfbuzz-src/src/Makefile.am | 4 - .../harfbuzz/harfbuzz-src/src/Makefile.sources | 4 +- .../libs/harfbuzz/harfbuzz-src/src/dump-emoji.cc | 6 +- .../libs/harfbuzz/harfbuzz-src/src/dump-fon.cc | 555 --------- .../harfbuzz/harfbuzz-src/src/gen-use-table.py | 10 + .../harfbuzz/harfbuzz-src/src/hb-aat-fmtx-table.hh | 67 -- .../harfbuzz/harfbuzz-src/src/hb-aat-gcid-table.hh | 73 -- .../src/hb-aat-layout-common-private.hh | 4 +- .../harfbuzz/harfbuzz-src/src/hb-aat-layout.cc | 64 +- .../harfbuzz/harfbuzz-src/src/hb-atomic-private.hh | 128 +- .../libs/harfbuzz/harfbuzz-src/src/hb-common.cc | 13 +- .../libs/harfbuzz/harfbuzz-src/src/hb-debug.hh | 42 + .../libs/harfbuzz/harfbuzz-src/src/hb-face.cc | 29 +- .../source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc | 3 + .../harfbuzz-src/src/hb-gobject-structs.cc | 1 + .../harfbuzz/harfbuzz-src/src/hb-gobject-structs.h | 4 + .../harfbuzz/harfbuzz-src/src/hb-iter-private.hh | 149 +++ .../harfbuzz-src/src/hb-machinery-private.hh | 696 +++++++++++ .../libs/harfbuzz/harfbuzz-src/src/hb-map.cc | 6 +- .../harfbuzz/harfbuzz-src/src/hb-object-private.hh | 12 +- .../harfbuzz-src/src/hb-open-file-private.hh | 2 - .../harfbuzz-src/src/hb-open-type-private.hh | 655 +--------- .../harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh | 77 +- .../harfbuzz-src/src/hb-ot-color-cbdt-table.hh | 4 +- .../harfbuzz-src/src/hb-ot-color-sbix-table.hh | 12 +- .../harfbuzz-src/src/hb-ot-color-svg-table.hh | 6 +- .../harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh | 10 +- .../harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh | 10 +- .../harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh | 2 +- .../src/hb-ot-layout-common-private.hh | 28 +- .../harfbuzz-src/src/hb-ot-layout-gsub-table.hh | 26 +- .../src/hb-ot-layout-gsubgpos-private.hh | 14 +- .../harfbuzz-src/src/hb-ot-layout-private.hh | 1 + .../libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc | 181 +-- .../libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h | 7 + .../harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh | 6 +- .../harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh | 4 +- .../harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh | 4 +- .../src/hb-ot-shape-complex-indic-private.hh | 4 +- .../harfbuzz-src/src/hb-ot-shape-complex-indic.cc | 40 +- .../harfbuzz-src/src/hb-ot-shape-complex-khmer.cc | 478 ++------ .../src/hb-ot-shape-complex-private.hh | 13 - .../src/hb-ot-shape-complex-use-table.cc | 4 +- .../harfbuzz-src/src/hb-ot-shape-complex-use.cc | 21 +- .../libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc | 9 +- .../libs/harfbuzz/harfbuzz-src/src/hb-private.hh | 54 +- .../harfbuzz/harfbuzz-src/src/hb-shaper-private.hh | 26 +- .../libs/harfbuzz/harfbuzz-src/src/hb-static.cc | 26 + .../harfbuzz/harfbuzz-src/src/hb-subset-glyf.cc | 2 +- .../harfbuzz/harfbuzz-src/src/hb-subset-plan.cc | 12 +- .../libs/harfbuzz/harfbuzz-src/src/hb-subset.cc | 4 +- .../libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc | 2 +- .../source/libs/harfbuzz/harfbuzz-src/src/main.cc | 3 +- Build/source/libs/harfbuzz/version.ac | 2 +- 64 files changed, 2713 insertions(+), 2208 deletions(-) delete mode 100644 Build/source/libs/harfbuzz/harfbuzz-src/src/dump-fon.cc delete mode 100644 Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-fmtx-table.hh delete mode 100644 Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-gcid-table.hh create mode 100644 Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter-private.hh create mode 100644 Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery-private.hh (limited to 'Build') diff --git a/Build/source/libs/README b/Build/source/libs/README index df0573ca65f..b9f29d74df7 100644 --- a/Build/source/libs/README +++ b/Build/source/libs/README @@ -24,7 +24,7 @@ gmp 6.1.2 - checked 16dec16 graphite2 1.3.11 - checked 05mar18 http://sourceforge.net/projects/silgraphite/files/graphite2/ -harfbuzz 1.8.4 - checked 18jul18 +harfbuzz 1.8.5 - checked 03aug18 http://www.freedesktop.org/software/harfbuzz/release/ icu 61.1 - checked 29mar18 diff --git a/Build/source/libs/harfbuzz/ChangeLog b/Build/source/libs/harfbuzz/ChangeLog index f1b35ac9381..3a1fa6076c8 100644 --- a/Build/source/libs/harfbuzz/ChangeLog +++ b/Build/source/libs/harfbuzz/ChangeLog @@ -1,3 +1,8 @@ +2018-08-03 Akira Kakuto + + Import harfbuzz-1.8.5. + * version.ac, Makefile.am: Adjusted. + 2018-07-18 Akira Kakuto Import harfbuzz-1.8.4. diff --git a/Build/source/libs/harfbuzz/Makefile.am b/Build/source/libs/harfbuzz/Makefile.am index 5d8ce9852a0..6358f660d6f 100644 --- a/Build/source/libs/harfbuzz/Makefile.am +++ b/Build/source/libs/harfbuzz/Makefile.am @@ -44,8 +44,10 @@ libharfbuzz_a_SOURCES = \ @HARFBUZZ_TREE@/src/hb-face.cc \ @HARFBUZZ_TREE@/src/hb-font-private.hh \ @HARFBUZZ_TREE@/src/hb-font.cc \ + @HARFBUZZ_TREE@/src/hb-iter-private.hh \ @HARFBUZZ_TREE@/src/hb-map-private.hh \ @HARFBUZZ_TREE@/src/hb-map.cc \ + @HARFBUZZ_TREE@/src/hb-machinery-private.hh \ @HARFBUZZ_TREE@/src/hb-mutex-private.hh \ @HARFBUZZ_TREE@/src/hb-object-private.hh \ @HARFBUZZ_TREE@/src/hb-open-file-private.hh \ diff --git a/Build/source/libs/harfbuzz/Makefile.in b/Build/source/libs/harfbuzz/Makefile.in index 8aa933b24f8..26adbb78e2e 100644 --- a/Build/source/libs/harfbuzz/Makefile.in +++ b/Build/source/libs/harfbuzz/Makefile.in @@ -707,8 +707,10 @@ libharfbuzz_a_SOURCES = @HARFBUZZ_TREE@/src/hb-atomic-private.hh \ @HARFBUZZ_TREE@/src/hb-face.cc \ @HARFBUZZ_TREE@/src/hb-font-private.hh \ @HARFBUZZ_TREE@/src/hb-font.cc \ + @HARFBUZZ_TREE@/src/hb-iter-private.hh \ @HARFBUZZ_TREE@/src/hb-map-private.hh \ @HARFBUZZ_TREE@/src/hb-map.cc \ + @HARFBUZZ_TREE@/src/hb-machinery-private.hh \ @HARFBUZZ_TREE@/src/hb-mutex-private.hh \ @HARFBUZZ_TREE@/src/hb-object-private.hh \ @HARFBUZZ_TREE@/src/hb-open-file-private.hh \ diff --git a/Build/source/libs/harfbuzz/TLpatches/ChangeLog b/Build/source/libs/harfbuzz/TLpatches/ChangeLog index 27b3c9eec01..10de7723d25 100644 --- a/Build/source/libs/harfbuzz/TLpatches/ChangeLog +++ b/Build/source/libs/harfbuzz/TLpatches/ChangeLog @@ -1,3 +1,8 @@ +2018-08-03 Akira Kakuto + + Imported harfbuzz-1.8.5 source tree from: + http://www.freedesktop.org/software/harfbuzz/release/ + 2018-07-18 Akira Kakuto Imported harfbuzz-1.8.4 source tree from: diff --git a/Build/source/libs/harfbuzz/TLpatches/TL-Changes b/Build/source/libs/harfbuzz/TLpatches/TL-Changes index 2f56c6d39d5..3a0b7c86b9a 100644 --- a/Build/source/libs/harfbuzz/TLpatches/TL-Changes +++ b/Build/source/libs/harfbuzz/TLpatches/TL-Changes @@ -1,4 +1,4 @@ -Changes applied to the harfbuzz-1.8.4/ tree as obtained from: +Changes applied to the harfbuzz-1.8.5/ tree as obtained from: http://www.freedesktop.org/software/harfbuzz/release/ Removed: diff --git a/Build/source/libs/harfbuzz/configure b/Build/source/libs/harfbuzz/configure index 6e3413d3495..4ad07773dd0 100755 --- a/Build/source/libs/harfbuzz/configure +++ b/Build/source/libs/harfbuzz/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for harfbuzz (TeX Live) 1.8.4. +# Generated by GNU Autoconf 2.69 for harfbuzz (TeX Live) 1.8.5. # # Report bugs to . # @@ -580,8 +580,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='harfbuzz (TeX Live)' PACKAGE_TARNAME='harfbuzz--tex-live-' -PACKAGE_VERSION='1.8.4' -PACKAGE_STRING='harfbuzz (TeX Live) 1.8.4' +PACKAGE_VERSION='1.8.5' +PACKAGE_STRING='harfbuzz (TeX Live) 1.8.5' PACKAGE_BUGREPORT='tex-k@tug.org' PACKAGE_URL='' @@ -1317,7 +1317,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures harfbuzz (TeX Live) 1.8.4 to adapt to many kinds of systems. +\`configure' configures harfbuzz (TeX Live) 1.8.5 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1388,7 +1388,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of harfbuzz (TeX Live) 1.8.4:";; + short | recursive ) echo "Configuration of harfbuzz (TeX Live) 1.8.5:";; esac cat <<\_ACEOF @@ -1495,7 +1495,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -harfbuzz (TeX Live) configure 1.8.4 +harfbuzz (TeX Live) configure 1.8.5 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2131,7 +2131,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by harfbuzz (TeX Live) $as_me 1.8.4, which was +It was created by harfbuzz (TeX Live) $as_me 1.8.5, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -4054,7 +4054,7 @@ fi # Define the identity of the package. PACKAGE='harfbuzz--tex-live-' - VERSION='1.8.4' + VERSION='1.8.5' # Some tools Automake needs. @@ -4248,8 +4248,8 @@ WARNING_CFLAGS=$kpse_cv_warning_cflags HB_VERSION_MAJOR=1 HB_VERSION_MINOR=8 -HB_VERSION_MICRO=4 -HB_VERSION=1.8.4 +HB_VERSION_MICRO=5 +HB_VERSION=1.8.5 ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -8140,7 +8140,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by harfbuzz (TeX Live) $as_me 1.8.4, which was +This file was extended by harfbuzz (TeX Live) $as_me 1.8.5, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -8206,7 +8206,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -harfbuzz (TeX Live) config.status 1.8.4 +harfbuzz (TeX Live) config.status 1.8.5 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog b/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog index ac451d81213..97ac4f04e14 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog +++ b/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog @@ -1,3 +1,1253 @@ +commit 13f4c137c686aed5c2888b5c47d9f16892be0d5e +Author: Behdad Esfahbod +Date: Wed Aug 1 14:13:59 2018 -0700 + + [atomic] Fix Solaris ones to add proper barriers + + src/hb-atomic-private.hh | 52 + +++++++++++++++++++++++++++++++++--------------- + 1 file changed, 36 insertions(+), 16 deletions(-) + +commit 19dfaa351568887a74cee2c46d6acfcc3fa718ff +Author: Behdad Esfahbod +Date: Wed Aug 1 14:02:39 2018 -0700 + + [atomic] Remove volatile from IBM impl signature + + src/hb-atomic-private.hh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 2093a3e0cbb98c2daa39f308d50a12f0a719bc81 +Author: Behdad Esfahbod +Date: Wed Aug 1 14:00:46 2018 -0700 + + [atomic] Oops + + src/hb-atomic-private.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 19b98348ffc660501e518bf48cd63d232f7585e7 +Author: Behdad Esfahbod +Date: Wed Aug 1 13:59:59 2018 -0700 + + [atomic] Use read-barrier for get() + + src/hb-atomic-private.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 006d4f031a30dd04f5bb9c3d1daca187ef6b7f1e +Author: Behdad Esfahbod +Date: Wed Aug 1 13:59:31 2018 -0700 + + [atomic] Some more minor tweaks + + src/hb-atomic-private.hh | 31 ++++++++++++++++++++----------- + 1 file changed, 20 insertions(+), 11 deletions(-) + +commit 28d03a8afcc1f0ba6d9d0d88f669cc53bb030dd8 +Author: Ebrahim Byagowi +Date: Thu Aug 2 00:11:43 2018 +0430 + + [ci] Fix Appveyor bot (#1123) + + appveyor.yml | 1 + + 1 file changed, 1 insertion(+) + +commit 1a7fed631880fff8a947ebec9c7427efff581916 +Author: Ebrahim Byagowi +Date: Wed Aug 1 12:15:44 2018 +0430 + + Revert "Add a new API, hb_ot_layout_get_feature_name_ids (#976)" + (#1121) + + This reverts commit 0c1b287b72e91e0898d75acb5d5acf1c6b9a7498. + + docs/harfbuzz-sections.txt | 1 - + src/hb-ot-layout-common-private.hh | 14 ------- + src/hb-ot-layout.cc | 86 + -------------------------------------- + src/hb-ot-layout.h | 8 ---- + 4 files changed, 109 deletions(-) + +commit dfc86e4b35ffdeb8f73e83511712e75413bbb7d9 +Author: Behdad Esfahbod +Date: Wed Aug 1 00:22:18 2018 -0700 + + [atomic] Fix cast to fallback ptr_get() + + src/hb-atomic-private.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 7a4d576e81c4de68ea66b2d5fe7712e29d715272 +Author: Behdad Esfahbod +Date: Wed Aug 1 00:19:25 2018 -0700 + + [gobject] Fix copy/paste error + + src/hb-gobject-structs.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit ad275627425c9b3c4fb1e69aa408067bd0bb77da +Author: Behdad Esfahbod +Date: Tue Jul 31 23:01:05 2018 -0700 + + [atomic] On IBM, use light-weight sync for everything + + lwsync() is a full read/write-barrier. That's all we need, never + need sync(). I'm not sure why an isync() was used in fetch_and_add, + but since that's a read-modify-write, I just changed it to have + lwsync() on both sides. + + src/hb-atomic-private.hh | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit fd638d215feb058c2294e447cc68f6f50e2b481d +Author: Behdad Esfahbod +Date: Tue Jul 31 23:00:15 2018 -0700 + + [atomic] Add XXX items around Solaris ops + + Since add_int and cas are both read-modify-write, I wonder if we + also need a barrier after them. + + src/hb-atomic-private.hh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 896ff15ae60a4a4b94c62946e69196b877839bb5 +Author: Behdad Esfahbod +Date: Tue Jul 31 22:51:38 2018 -0700 + + [atomic] Fix get() impl + + Originally, glib's atomic_get was implemented as "memory_barrier; + load". + I copied this into cairo, fontconfig, and harfbuzz. However, that's + wrong. Correct way is "load; memory_barrier". The details are long + and hard to fully grasp. Best to read: + + https://www.kernel.org/doc/Documentation/memory-barriers.txt + + Also see my report against GNOME: + + https://gitlab.gnome.org/GNOME/glib/issues/1449 + + Note that this is irrelevant if C++11-like atomic ops are available. + + src/hb-atomic-private.hh | 28 +++++++++++++++++----------- + 1 file changed, 17 insertions(+), 11 deletions(-) + +commit d7a15799d40dac1f9521674a82c3293a7cb42ee4 +Author: Behdad Esfahbod +Date: Tue Jul 31 22:28:28 2018 -0700 + + [gobject] Hook up hb_map_t + + docs/harfbuzz-sections.txt | 2 ++ + src/hb-gobject-structs.cc | 1 + + src/hb-gobject-structs.h | 4 ++++ + src/hb-map.cc | 6 ++---- + 4 files changed, 9 insertions(+), 4 deletions(-) + +commit 63c74e8d1d85067cbeffe635eb5ed4e8aa130776 +Author: Behdad Esfahbod +Date: Tue Jul 31 22:21:21 2018 -0700 + + [atomic] Fix fallback impl + + src/hb-atomic-private.hh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 4bc16aca4760ac9ffd8c63bbaea24fc7d234f715 +Author: Behdad Esfahbod +Date: Tue Jul 31 21:05:51 2018 -0700 + + [atomic] Add get_relaxed / set_relaxed + + To help TSan and be more "correct". + + src/hb-atomic-private.hh | 37 ++++++++++++++++++++++------------- + src/hb-common.cc | 4 ++-- + src/hb-debug.hh | 42 + ++++++++++++++++++++++++++++++++++++++++ + src/hb-object-private.hh | 12 ++++++------ + src/hb-ot-shape-complex-indic.cc | 22 +++++++++++---------- + src/hb-private.hh | 28 --------------------------- + 6 files changed, 86 insertions(+), 59 deletions(-) + +commit 3dd1b88765f6ce91bd0558a16cdd8cf0c1e15d1b +Author: Behdad Esfahbod +Date: Tue Jul 31 19:33:37 2018 -0700 + + [atomic] Use CONSUME, not ACQUIRE, memory-order for get() + + Although, all implementations just elevate that to ACQUIRE. + But requirement for us is just CONSUME. + + src/hb-atomic-private.hh | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 06b91d935da1a40ef9de6697717eb0af1015989e +Author: Behdad Esfahbod +Date: Tue Jul 31 19:29:49 2018 -0700 + + Revert "[atomic] Make pointer get op relaxed instead of acquire" + + This reverts commit b1e5650c67266dc158f22355fed206cd1c413f70. + + After lots of head-scratching and finally finding the only truly + readable source to be the good old: + + https://www.kernel.org/doc/Documentation/memory-barriers.txt + + I've convinced myself that we need consume memory-ordering on get(). + The location of memory-barrier in a load should be after, not before + the load. That needs fixing. I'll do that separately. + + src/hb-atomic-private.hh | 34 +++++++++++++++++++++++++--------- + 1 file changed, 25 insertions(+), 9 deletions(-) + +commit 2bdd903c69eb3a34f3d3bf5e4f4c94cd66337117 +Author: Garret Rieger +Date: Tue Jul 31 17:44:02 2018 -0700 + + [subset] limit the max codepoint value to the unicode limit. + When collecting all codepoints in the cmap avoid using large amount + of memory for fonts that declare coverage over all 32 bit integers. + + src/hb-ot-cmap-table.hh | 9 +++++++-- + ...mized-hb-subset-get-codepoints-fuzzer-5973295416475648 | Bin 0 -> + 109 bytes + 2 files changed, 7 insertions(+), 2 deletions(-) + +commit 7278d9df3093a87f99cec9b4cea38bd688c5d020 +Author: Garret Rieger +Date: Tue Jul 31 17:59:19 2018 -0700 + + [subset] Add hb_ot_layout_collect_features to harfbuzz-sections.txt. + Add the fuzzer test case for feature collection timeout. + + docs/harfbuzz-sections.txt | 1 + + ...estcase-minimized-hb-subset-fuzzer-5542653037903872 | Bin 0 -> + 160249 bytes + 2 files changed, 1 insertion(+) + +commit 89733755a48feef0a663e1ea7b8294949581ce7e +Author: Garret Rieger +Date: Mon Jul 30 18:10:43 2018 -0700 + + [subset] use add_array to populate feature_indexes. + This is much faster then calling a bunch of individual add()'s. + + src/hb-ot-layout-common-private.hh | 7 +++++++ + src/hb-ot-layout.cc | 40 + +++++++++++++++++++------------------- + 2 files changed, 27 insertions(+), 20 deletions(-) + +commit 7d92bef9c5afb319d125f60b0fce4763afeaa686 +Author: Garret Rieger +Date: Mon Jul 30 17:17:43 2018 -0700 + + [subset] collect features first, then use those to collect lookups. + + src/hb-ot-layout.cc | 148 + +++++++++++++++++++++++++--------------------------- + src/hb-ot-layout.h | 7 +++ + 2 files changed, 78 insertions(+), 77 deletions(-) + +commit af876cce3066833c7c34d213a578eec6b09dd5c9 +Author: Behdad Esfahbod +Date: Tue Jul 31 15:27:29 2018 -0700 + + [indic] Flip default logic for double-halants in old-school + + Oriya went down from 9 to 2. + + BENGALI: 353725 out of 354188 tests passed. 463 failed (0.130722%) + DEVANAGARI: 707311 out of 707394 tests passed. 83 failed (0.0117332%) + GUJARATI: 366355 out of 366457 tests passed. 102 failed (0.0278341%) + GURMUKHI: 60729 out of 60747 tests passed. 18 failed (0.0296311%) + KANNADA: 951300 out of 951913 tests passed. 613 failed (0.0643966%) + MALAYALAM: 1048136 out of 1048334 tests passed. 198 failed + (0.0188871%) + MYANMAR: 1115830 out of 1123883 tests passed. 8053 failed (0.716534%) + ORIYA: 42327 out of 42329 tests passed. 2 failed (0.00472489%) + SINHALA: 271596 out of 271847 tests passed. 251 failed (0.0923313%) + TAMIL: 1091754 out of 1091754 tests passed. 0 failed (0%) + TELUGU: 970555 out of 970573 tests passed. 18 failed (0.00185457%) + + src/hb-ot-shape-complex-indic.cc | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +commit 92ba9905caa060466230f63b428ccee767696464 +Author: Behdad Esfahbod +Date: Tue Jul 31 15:19:32 2018 -0700 + + [indic] Allow double-halant in old-spec Devanagari + + Fixes https://github.com/harfbuzz/harfbuzz/issues/1071 + + src/hb-ot-shape-complex-indic.cc | 18 + ++++++++++++------ + .../b722a7d09e60421f3efbc706ad348ab47b88567b.ttf | Bin 0 -> + 4672 bytes + test/shaping/data/in-house/tests/indic-old-spec.tests | 2 ++ + 3 files changed, 14 insertions(+), 6 deletions(-) + +commit fe099a844b9b8fe05dd4eb187b5ca3769441f012 +Author: Behdad Esfahbod +Date: Tue Jul 31 14:20:31 2018 -0700 + + [test] Add Khmer tests, with NotoSansKhmer-Regular.ttf + + Note that there's minor positioning differences, and ONE reordering + difference between what we get for these and what Uniscribe gets. + Probably same as what's described in commit message for + 1a96cc825dc9c8e3b6eef1403fe0864a1cfc0245 + + .../3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf | Bin 0 -> 24392 bytes + test/shaping/data/in-house/tests/khmer-misc.tests | 89 + +++++++++++++++++++++ + 2 files changed, 89 insertions(+) + +commit 5772edc0ea8f697c6123e439c5d0c3e813ebeb45 +Author: Behdad Esfahbod +Date: Tue Jul 31 14:10:31 2018 -0700 + + [khmer] Typo + + src/hb-ot-shape-complex-khmer.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 2d6edc9008182c1446951f2c5c04df20094597f8 +Author: Behdad Esfahbod +Date: Tue Jul 31 13:56:55 2018 -0700 + + [test] Add Khmer test texts from recent bugs + + test/shaping/texts/in-house/shaper-khmer/misc.txt | 66 + +++++++++++++++++++++++ + 1 file changed, 66 insertions(+) + +commit df26a32c8fd22cbd486e2a1014d30b9f38f51cd1 +Author: Behdad Esfahbod +Date: Tue Jul 31 13:55:53 2018 -0700 + + [test] Move things around for shaper updates + + .../texts/in-house/shaper-indic/{indic => }/script-assamese/utrrs/LICENSE + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-assamese/utrrs/README + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-assamese/utrrs/SOURCES + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-AdditionalVowels.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-Consonants.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-DependentVowels.txt + | 0 + .../script-assamese/utrrs/codepoint/IndicFontFeatureCodepoint-Digits.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-IndependentVowels.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-Reserved.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-VariousSigns.txt + | 0 + .../script-assamese/utrrs/gpos/IndicFontFeatureGPOS-AboveBase.txt + | 0 + .../script-assamese/utrrs/gpos/IndicFontFeatureGPOS-BelowBase.txt + | 0 + .../{indic => }/script-assamese/utrrs/gsub/IndicFontFeatureGSUB.txt + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-bengali/misc/misc.txt + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-bengali/misc/reph.txt + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-bengali/utrrs/LICENSE + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-bengali/utrrs/README + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-bengali/utrrs/SOURCES + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-AdditionalVowels.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-Consonants.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-DependentVowels.txt + | 0 + .../script-bengali/utrrs/codepoint/IndicFontFeatureCodepoint-Digits.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-IndependentVowels.txt + | 0 + .../script-bengali/utrrs/codepoint/IndicFontFeatureCodepoint-Reserved.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-VariousSigns.txt + | 0 + .../script-bengali/utrrs/gpos/IndicFontFeatureGPOS-AboveBase.txt + | 0 + .../script-bengali/utrrs/gpos/IndicFontFeatureGPOS-BelowBase.txt + | 0 + .../{indic => }/script-bengali/utrrs/gsub/IndicFontFeatureGSUB.txt + | 0 + .../shaper-indic/{indic => }/script-devanagari/misc/dottedcircle.txt + | 0 + .../in-house/shaper-indic/{indic => }/script-devanagari/misc/eyelash.txt + | 0 + .../in-house/shaper-indic/{indic => }/script-devanagari/misc/joiners.txt + | 0 + .../in-house/shaper-indic/{indic => }/script-devanagari/misc/misc.txt + | 0 + .../shaper-indic/{indic => }/script-devanagari/misc/spec-deviations.txt + | 0 + .../shaper-indic/{indic => }/script-devanagari/misc/tricky-reordering.txt + | 0 + .../in-house/shaper-indic/{indic => }/script-devanagari/utrrs/LICENSE + | 0 + .../in-house/shaper-indic/{indic => }/script-devanagari/utrrs/README + | 0 + .../in-house/shaper-indic/{indic => }/script-devanagari/utrrs/SOURCES + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-AdditionalConsonants.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-AdditionalVowels.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-Consonants.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-DependentVowels.txt + | 0 + .../codepoint/IndicFontFeatureCodepoint-DevnagariSpecificAddition.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-Digits.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-GenericPunctuation.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-IndependentVowels.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-VariousSigns.txt + | 0 + .../script-devanagari/utrrs/gpos/IndicFontFeatureGPOS-AboveBase.txt + | 0 + .../script-devanagari/utrrs/gpos/IndicFontFeatureGPOS-BelowBase.txt + | 0 + .../{indic => }/script-devanagari/utrrs/gsub/IndicFontFeatureGSUB.txt + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-gujarati/utrrs/LICENSE + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-gujarati/utrrs/README + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-gujarati/utrrs/SOURCES + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-AdditionalVowels.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-Consonants.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-DependentVowels.txt + | 0 + .../script-gujarati/utrrs/codepoint/IndicFontFeatureCodepoint-Digits.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-IndependentVowels.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-Reserved.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-VariousSigns.txt + | 0 + .../script-gujarati/utrrs/gpos/IndicFontFeatureGPOS-AboveBase.txt + | 0 + .../script-gujarati/utrrs/gpos/IndicFontFeatureGPOS-BelowBase.txt + | 0 + .../{indic => }/script-gujarati/utrrs/gsub/IndicFontFeatureGSUB.txt + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-gurmukhi/misc/misc.txt + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-gurmukhi/utrrs/LICENSE + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-gurmukhi/utrrs/README + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-gurmukhi/utrrs/SOURCES + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-Consonants.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-DependentVowels.txt + | 0 + .../script-gurmukhi/utrrs/codepoint/IndicFontFeatureCodepoint-Digits.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-GurmukhiSpecific.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-IndependentVowels.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-Reserved.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-VariousSigns.txt + | 0 + .../script-gurmukhi/utrrs/gpos/IndicFontFeatureGPOS-AboveBase.txt + | 0 + .../script-gurmukhi/utrrs/gpos/IndicFontFeatureGPOS-BelowBase.txt + | 0 + .../{indic => }/script-gurmukhi/utrrs/gsub/IndicFontFeatureGSUB.txt + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-kannada/misc/misc.txt + | 0 + .../shaper-indic/{indic => }/script-kannada/misc/right-matras.txt + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-kannada/utrrs/LICENSE + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-kannada/utrrs/README + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-kannada/utrrs/SOURCES + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-AdditionalConsonants.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-AdditionalVowels.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-Consonants.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-DependentVowels.txt + | 0 + .../script-kannada/utrrs/codepoint/IndicFontFeatureCodepoint-Digits.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-IndependentVowels.txt + | 0 + .../script-kannada/utrrs/codepoint/IndicFontFeatureCodepoint-Reserved.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-VariousSigns.txt + | 0 + .../script-kannada/utrrs/gpos/IndicFontFeatureGPOS-AboveBase.txt + | 0 + .../{indic => }/script-kannada/utrrs/gsub/IndicFontFeatureGSUB.txt + | 0 + .../in-house/shaper-indic/{indic => }/script-malayalam/misc/cibu.txt + | 0 + .../in-house/shaper-indic/{indic => }/script-malayalam/misc/dot-reph.txt + | 0 + .../in-house/shaper-indic/{indic => }/script-malayalam/misc/misc.txt + | 0 + .../in-house/shaper-indic/{indic => }/script-malayalam/utrrs/LICENSE + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-malayalam/utrrs/README + | 0 + .../in-house/shaper-indic/{indic => }/script-malayalam/utrrs/SOURCES + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-AdditionalVowels.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-Consonants.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-DependentVowels.txt + | 0 + .../script-malayalam/utrrs/codepoint/IndicFontFeatureCodepoint-Digits.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-IndependentVowels.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-Reserved.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-VariousSigns.txt + | 0 + .../{indic => }/script-malayalam/utrrs/gsub/IndicFontFeatureGSUB.txt + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-oriya/misc/bindu.txt + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-oriya/misc/misc.txt + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-oriya/utrrs/LICENSE + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-oriya/utrrs/README + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-oriya/utrrs/SOURCES + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-AdditionalConsonants.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-AdditionalVowels.txt + | 0 + .../script-oriya/utrrs/codepoint/IndicFontFeatureCodepoint-Consonants.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-DependentVowels.txt + | 0 + .../script-oriya/utrrs/codepoint/IndicFontFeatureCodepoint-Digits.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-IndependentVowels.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-OriyaSpecific.txt + | 0 + .../script-oriya/utrrs/codepoint/IndicFontFeatureCodepoint-Reserved.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-VariousSigns.txt + | 0 + .../{indic => }/script-oriya/utrrs/gsub/IndicFontFeatureGSUB.txt + | 0 + .../in-house/shaper-indic/{indic => }/script-sinhala/misc/extensive.txt + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-sinhala/misc/misc.txt + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-sinhala/misc/reph.txt + | 0 + .../shaper-indic/{indic => }/script-sinhala/misc/split-matras.txt + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-sinhala/utrrs/LICENSE + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-sinhala/utrrs/README + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-sinhala/utrrs/SOURCES + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-Consonants.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-DependentVowels.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-IndependentVowels.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-Punctuation.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-VariousSigns.txt + | 0 + .../{indic => }/script-sinhala/utrrs/gpos/IndicFontFeatureGPOS.txt + | 0 + .../script-sinhala/utrrs/gsub/IndicFontFeatureGSUB-Conjunct.txt + | 0 + .../script-sinhala/utrrs/gsub/IndicFontFeatureGSUB-Rakaaraansaya.txt + | 0 + .../{indic => }/script-sinhala/utrrs/gsub/IndicFontFeatureGSUB-Repaya.txt + | 0 + .../script-sinhala/utrrs/gsub/IndicFontFeatureGSUB-Special-Cases.txt + | 0 + .../script-sinhala/utrrs/gsub/IndicFontFeatureGSUB-TouchingLetters.txt + | 0 + .../script-sinhala/utrrs/gsub/IndicFontFeatureGSUB-Yansaya.txt + | 0 + .../{indic => }/script-sinhala/utrrs/gsub/IndicFontFeatureGSUB.txt + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-tamil/misc/misc.txt + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-tamil/utrrs/LICENSE + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-tamil/utrrs/README + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-tamil/utrrs/SOURCES + | 0 + .../script-tamil/utrrs/codepoint/IndicFontFeatureCodepoint-Consonants.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-CurrencySymbols.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-DependentVowels.txt + | 0 + .../script-tamil/utrrs/codepoint/IndicFontFeatureCodepoint-Digits.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-IndependentVowels.txt + | 0 + .../script-tamil/utrrs/codepoint/IndicFontFeatureCodepoint-Numerics.txt + | 0 + .../script-tamil/utrrs/codepoint/IndicFontFeatureCodepoint-Reserved.txt + | 0 + .../script-tamil/utrrs/codepoint/IndicFontFeatureCodepoint-Symbols.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-TamilSymbol.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-VariousSigns.txt + | 0 + .../script-tamil/utrrs/gpos/IndicFontFeatureGPOS-AboveBase.txt + | 0 + .../script-tamil/utrrs/gpos/IndicFontFeatureGPOS-BelowBase.txt + | 0 + .../{indic => }/script-tamil/utrrs/gsub/IndicFontFeatureGSUB.txt + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-telugu/misc/misc.txt + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-telugu/utrrs/LICENSE + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-telugu/utrrs/README + | 0 + .../texts/in-house/shaper-indic/{indic => }/script-telugu/utrrs/SOURCES + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-AdditionalVowels.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-Consonants.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-DependentVowels.txt + | 0 + .../script-telugu/utrrs/codepoint/IndicFontFeatureCodepoint-Digits.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-IndependentVowels.txt + | 0 + .../script-telugu/utrrs/codepoint/IndicFontFeatureCodepoint-Reserved.txt + | 0 + .../utrrs/codepoint/IndicFontFeatureCodepoint-VariousSigns.txt + | 0 + .../script-telugu/utrrs/gpos/IndicFontFeatureGPOS-AboveBase.txt + | 0 + .../{indic => }/script-telugu/utrrs/gsub/IndicFontFeatureGSUB.txt + | 0 + .../south-east-asian/script-khmer/misc => shaper-khmer}/misc.txt + | 0 + .../script-khmer/misc => shaper-khmer}/other-marks-invalid.txt + | 0 + .../south-east-asian/script-khmer/misc => shaper-khmer}/other-marks.txt + | 0 + .../south-east-asian => shaper-use}/script-javanese/misc.txt + | 0 + 174 files changed, 0 insertions(+), 0 deletions(-) + +commit 6ddd669e205cf2c1c3b0a362330b686386f68519 +Author: Behdad Esfahbod +Date: Tue Jul 31 13:38:07 2018 -0700 + + [khmer] Clear syllables before presentation features + + Probably not what Uniscribe does, but good idea? + + src/hb-ot-shape-complex-khmer.cc | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +commit 8eef1964a708c3db52e5e7312689c4664afa9839 +Author: Behdad Esfahbod +Date: Tue Jul 31 13:35:10 2018 -0700 + + [khmer] Revert previous change, and remove pauses + + This makes test suite happy again (at 44) while fixing the sequences + we were fixing, which were the following with KhmerUI.ttf: + + U+1789,U+17BC + U+1789,U+17D2,U+1789 + U+1789,U+17D2,U+1789,U+17BC + + Fixes rest of https://github.com/harfbuzz/harfbuzz/issues/974 + + src/hb-ot-shape-complex-khmer.cc | 23 ++++++++++------------- + 1 file changed, 10 insertions(+), 13 deletions(-) + +commit 7c658ea2f20a77cac35e8988e54316425396198a +Author: Behdad Esfahbod +Date: Tue Jul 31 12:49:02 2018 -0700 + + [khmer] Apply ccmp after basic features + + Part of https://github.com/harfbuzz/harfbuzz/issues/974 + + src/hb-ot-shape-complex-khmer.cc | 22 +++++++++++++++++----- + 1 file changed, 17 insertions(+), 5 deletions(-) + +commit 1a96cc825dc9c8e3b6eef1403fe0864a1cfc0245 +Author: Behdad Esfahbod +Date: Tue Jul 31 11:45:32 2018 -0700 + + [khmer] Rewrite most of shaper to better follow spec + + Khmer spec has only one reordering phase, and only simple prebase + matra and Coeng-Ro reordering. Implement that. Specifically, + this was done to address recognizing different orders of the matra + and Coeng-Ro sequence. That said, some combinations are now + reordered differently from Uniscribe. Not clear if that's intended + or a bug in Uniscribe. The following two sequences render the same + in Uniscribe whereas we reorder them differently: + + U+17A0,U+17D2,U+179A,U+17C2 + U+17A0,U+17C2,U+17D2,U+179A + + For that reason, our test suite numbers regressed slightly. Used + to be at 34 for fails, now at: + + KHMER: 299080 out of 299124 tests passed. 44 failed (0.0147096%) + + But generally a good change, and removed lots of code. + + Fixes https://github.com/harfbuzz/harfbuzz/issues/1026 + + src/hb-ot-shape-complex-indic-private.hh | 4 +- + src/hb-ot-shape-complex-khmer.cc | 460 + ++++--------------------------- + src/hb-ot-shape-complex-private.hh | 13 - + 3 files changed, 64 insertions(+), 413 deletions(-) + +commit f5152cea423947cd8a85332566443b4e2e091672 +Author: Behdad Esfahbod +Date: Tue Jul 31 01:27:04 2018 -0700 + + [shaper] Move code around + + src/hb-shaper-private.hh | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +commit 36d0fbbc52bdf2c71da022fb1fdc31eca17078ce +Author: Behdad Esfahbod +Date: Tue Jul 31 01:15:04 2018 -0700 + + [shaper] Remove a macro + + src/hb-shaper-private.hh | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +commit b1e5650c67266dc158f22355fed206cd1c413f70 +Author: Behdad Esfahbod +Date: Tue Jul 31 01:02:31 2018 -0700 + + [atomic] Make pointer get op relaxed instead of acquire + + We only use it before cmpexch, so relaxed is fine and faster for + common case. + + src/hb-atomic-private.hh | 34 +++++++++------------------------- + 1 file changed, 9 insertions(+), 25 deletions(-) + +commit 66ccd8ac405c9c25b37de9eb467a7382880dda35 +Author: Behdad Esfahbod +Date: Mon Jul 30 17:03:06 2018 -0700 + + [serialize] Increase stage count from 8 to 32 + + Indic shaper uses many stages. Now we are provably not limiting + functionality whereas the previous limit of 8 was assuming real-world + practices. + + src/hb-ot-layout-common-private.hh | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +commit ee8cf919654cb191e955fe1f89b1ebfb2b8b32ee +Author: Behdad Esfahbod +Date: Mon Jul 30 16:59:41 2018 -0700 + + [serialize] Remove unused truncate() method + + src/hb-machinery-private.hh | 6 ------ + 1 file changed, 6 deletions(-) + +commit 5edf454aa64aad461c90bd991e7eaf27668b7e6b +Author: Garret Rieger +Date: Thu Jul 26 17:42:02 2018 -0700 + + [subset] During lookup collection remember the features we've + already processed. + + src/hb-ot-layout.cc | 26 + +++++++++++++++++---- + ...ase-minimized-hb-subset-fuzzer-5670861909524480 | Bin 0 -> 1298 bytes + ...b-subset-get-codepoints-fuzzer-6136125075750912 | Bin 0 -> 65816 bytes + 3 files changed, 21 insertions(+), 5 deletions(-) + +commit 42c183f80355fe7cadac2931a23d389285c8b98c +Author: Behdad Esfahbod +Date: Fri Jul 27 14:55:29 2018 -0700 + + Minor + + src/hb-ft.cc | 5 +++-- + src/hb-ot-shape.cc | 5 +++-- + 2 files changed, 6 insertions(+), 4 deletions(-) + +commit ecab6604e57ea2bb4e78250a7a400e15b3e86f7a +Author: Behdad Esfahbod +Date: Wed Jul 25 17:37:38 2018 -0700 + + [serialize] Allocate for markFilteringSet + + src/hb-ot-layout-common-private.hh | 9 +++++++++ + 1 file changed, 9 insertions(+) + +commit 7f08818c441517f73c5bea0a2a88f494dfc8fa58 +Author: Behdad Esfahbod +Date: Wed Jul 25 17:22:05 2018 -0700 + + Minor + + src/hb-iter-private.hh | 8 +++++--- + src/hb-machinery-private.hh | 1 - + 2 files changed, 5 insertions(+), 4 deletions(-) + +commit 2e25d8f49181ab1d7fda520ae6587d293a982acf +Author: prrace +Date: Fri Jul 27 13:58:27 2018 -0700 + + Fix unlikely leaks + + src/hb-ft.cc | 4 +++- + src/hb-ot-shape.cc | 4 +++- + 2 files changed, 6 insertions(+), 2 deletions(-) + +commit 3c2842cbcf8cded73d1e310379e1a4ca124a6fc2 +Author: Behdad Esfahbod +Date: Wed Jul 25 17:07:17 2018 -0700 + + Add hb-iter-private.hh + + Unused so far. + + src/Makefile.sources | 1 + + src/hb-iter-private.hh | 147 + ++++++++++++++++++++++++++++++++++++++++++++ + src/hb-machinery-private.hh | 1 + + 3 files changed, 149 insertions(+) + +commit 92b1e025c639d006f55400bf68fc23bdeaa1c716 +Author: Behdad Esfahbod +Date: Wed Jul 25 16:58:47 2018 -0700 + + Move some code from hb-open-type-private.hh to hb-machinery-private.hh + + src/Makefile.sources | 1 + + src/hb-machinery-private.hh | 702 + ++++++++++++++++++++++++++++++++++++++++++++ + src/hb-open-type-private.hh | 669 + +---------------------------------------- + 3 files changed, 706 insertions(+), 666 deletions(-) + +commit 6b11fea99716e22522b563d919ef7c72fe9a3c45 +Author: Behdad Esfahbod +Date: Wed Jul 25 16:01:37 2018 -0700 + + [closure] Allocate out set on the stack + + src/hb-ot-layout-gsubgpos-private.hh | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +commit 74467b790154838e86c3ca8df0eaafe82e87f976 +Author: Behdad Esfahbod +Date: Wed Jul 25 14:30:07 2018 -0700 + + Fix compile + + src/hb-shaper-private.hh | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit bf90f35302c319ec4699ccbcd1e28b15ef2ec423 +Author: Behdad Esfahbod +Date: Tue Jul 24 18:00:14 2018 -0700 + + [coretext] Add note + + src/hb-shaper-private.hh | 4 ++++ + 1 file changed, 4 insertions(+) + +commit fb58cb4b5ca7043fa746b1a01790abf53bedfa86 +Author: Garret Rieger +Date: Wed Jul 25 13:39:17 2018 -0700 + + [subset] Only used reachable lookups for gsub closure. + + src/hb-subset-plan.cc | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +commit c38bd4025f3f6ff4c1a39cc106b8618361a0c62b +Author: Behdad Esfahbod +Date: Tue Jul 24 09:43:27 2018 -0700 + + [closure] Separate in and out glyphs + + Fixes https://github.com/harfbuzz/harfbuzz/issues/1107 + + src/hb-ot-layout-gsub-table.hh | 26 ++++++++++++++++++-------- + src/hb-ot-layout-gsubgpos-private.hh | 16 +++++++++++++++- + 2 files changed, 33 insertions(+), 9 deletions(-) + +commit 85646fdadb2f102333485e07425361795b4e0412 +Author: Garret Rieger +Date: Mon Jul 23 15:37:18 2018 -0700 + + [subset] Limit the iterations of the closure algorithm. + Prevents O(n^2) run times. + + src/hb-ot-layout-common-private.hh | 7 +++++++ + src/hb-ot-layout.cc | 5 ++++- + 2 files changed, 11 insertions(+), 1 deletion(-) + +commit 94759d4cf8986388399026ef5204ac55ee187180 +Author: Behdad Esfahbod +Date: Mon Jul 23 15:01:39 2018 -0700 + + Fix visibility on mingw32 + + Should fix bots again. + + src/hb-private.hh | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +commit 61eddbd8ef64dc66e3c42723533d53967e61c9af +Author: Behdad Esfahbod +Date: Mon Jul 23 14:44:10 2018 -0700 + + Fix infinite loop in loading num_glyphs within sanitizer + + src/hb-open-type-private.hh | 13 ++++++++++--- + src/hb-static.cc | 4 +++- + 2 files changed, 13 insertions(+), 4 deletions(-) + +commit e22a48ac95a60fac5e1bca26eed7f5623d73a7be +Author: Behdad Esfahbod +Date: Mon Jul 23 13:24:26 2018 -0700 + + One more visibility trick + + Should fix Windows build again. + + src/hb-common.cc | 9 +++++++++ + src/hb-private.hh | 20 ++------------------ + src/hb-static.cc | 4 +++- + 3 files changed, 14 insertions(+), 19 deletions(-) + +commit e57a638bdec378eed8e83513818c8add3ffae896 +Author: Behdad Esfahbod +Date: Mon Jul 23 12:00:02 2018 -0700 + + One more + + src/hb-ot-cmap-table.hh | 40 ++++++++++++++++++++-------------------- + 1 file changed, 20 insertions(+), 20 deletions(-) + +commit 36ed163fdd50419e4619c665a4a9dbf97f66c349 +Author: Behdad Esfahbod +Date: Mon Jul 23 11:57:45 2018 -0700 + + Remove unnecessary OT:: namespace specifiers + + src/hb-ot-cmap-table.hh | 30 +++++++++++++++--------------- + src/hb-ot-color-sbix-table.hh | 4 ++-- + src/hb-ot-color-svg-table.hh | 4 ++-- + src/hb-ot-glyf-table.hh | 4 ++-- + src/hb-ot-hmtx-table.hh | 2 +- + src/hb-ot-maxp-table.hh | 6 +++--- + src/hb-ot-os2-table.hh | 4 ++-- + src/hb-ot-post-table.hh | 2 +- + 8 files changed, 28 insertions(+), 28 deletions(-) + +commit c6bc7c38314ea831418fdd1434bbe5afc0875f33 +Author: Behdad Esfahbod +Date: Mon Jul 23 11:46:46 2018 -0700 + + Set num glyphs on sanitizer reference_table() + + Move out-of-class definitions of two methods to hb-static so they + are accessible in libharfbuzz-subset. + + src/hb-face.cc | 20 -------------------- + src/hb-open-type-private.hh | 1 + + src/hb-static.cc | 22 ++++++++++++++++++++++ + 3 files changed, 23 insertions(+), 20 deletions(-) + +commit 9401829d4e93f6f433957fa2d053f3b9d42da557 +Author: Behdad Esfahbod +Date: Sun Jul 22 22:50:58 2018 -0700 + + Remove Sanitizer<> + + src/hb-open-type-private.hh | 16 +--------------- + 1 file changed, 1 insertion(+), 15 deletions(-) + +commit 8e3e41272b3896274459c5961aac813ef2666321 +Author: Behdad Esfahbod +Date: Sun Jul 22 22:49:26 2018 -0700 + + Port rest of code away from Sanitizer<> + + src/hb-face.cc | 4 ++-- + src/main.cc | 3 +-- + 2 files changed, 3 insertions(+), 4 deletions(-) + +commit d6a8f64045ca3bf4c7d01520909fa0c7dfca4d64 +Author: Behdad Esfahbod +Date: Sun Jul 22 22:47:19 2018 -0700 + + Port dump-emoji away from Sanitizer<> + + src/dump-emoji.cc | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +commit 14f78d2b3bb1e1292efbd6a3e3f0d618179c171a +Author: Behdad Esfahbod +Date: Sun Jul 22 22:45:26 2018 -0700 + + . + + src/hb-aat-layout.cc | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +commit 4547051f48ca6aa53309b81a768b5b44c4ab6e3b +Author: Behdad Esfahbod +Date: Sun Jul 22 22:44:22 2018 -0700 + + Minor + + src/hb-open-file-private.hh | 2 -- + 1 file changed, 2 deletions(-) + +commit 740ae27d5c0f5ff87e2ff489fb49d5db1a0c95be +Author: Behdad Esfahbod +Date: Sun Jul 22 22:40:56 2018 -0700 + + Port sbix off of Sanitizer<> + + src/hb-ot-color-sbix-table.hh | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +commit 9583e0077d0a3a043f8b5bd23925014e04da8d32 +Author: Behdad Esfahbod +Date: Sun Jul 22 22:40:32 2018 -0700 + + Port more off of Sanitizer<> + + src/hb-face.cc | 4 ++-- + src/hb-open-type-private.hh | 2 +- + src/hb-ot-cmap-table.hh | 2 +- + src/hb-ot-color-cbdt-table.hh | 4 ++-- + src/hb-ot-color-svg-table.hh | 4 +--- + src/hb-ot-glyf-table.hh | 8 ++++---- + src/hb-ot-hmtx-table.hh | 10 +++++----- + src/hb-ot-kern-table.hh | 2 +- + src/hb-ot-layout.cc | 6 +++--- + src/hb-ot-maxp-table.hh | 2 +- + src/hb-ot-os2-table.hh | 2 +- + src/hb-ot-post-table.hh | 2 +- + src/hb-subset.cc | 4 +--- + 13 files changed, 24 insertions(+), 28 deletions(-) + +commit e7737b41d793bfce9455d1797eb5e0af60794f23 +Author: Behdad Esfahbod +Date: Sun Jul 22 22:24:31 2018 -0700 + + Add sanitizer reference_table, also fix clang build + + Clang is being really peculiar. Fix with: + + - inline hb_blob_t *sanitize (hb_blob_t *blob) { return + c->sanitize (blob); } + + inline hb_blob_t *sanitize (hb_blob_t *blob) { return + c[0].template/*clang idiosyncrasy*/sanitize_blob (blob); } + + src/hb-open-type-private.hh | 10 ++++++++-- + src/hb-ot-post-table.hh | 2 +- + src/hb-subset-glyf.cc | 2 +- + src/hb-uniscribe.cc | 2 +- + 4 files changed, 11 insertions(+), 5 deletions(-) + +commit 62fa7cd1ccff4d4448ef84f9cc146464672636aa +Author: David Corbett +Date: Fri Apr 13 18:45:37 2018 -0400 + + Order Chakma split vowels in accordance with NFC + + Fixes #1105. + + src/gen-use-table.py | 10 ++++++++++ + src/hb-ot-shape-complex-use-table.cc | 4 ++-- + src/hb-ot-shape-complex-use.cc | 21 + +-------------------- + .../2a670df15b73a5dc75a5cc491bde5ac93c5077dc.ttf | Bin 0 -> 1344 bytes + test/shaping/data/in-house/tests/use.tests | 5 +++++ + 5 files changed, 18 insertions(+), 22 deletions(-) + +commit 0c1b287b72e91e0898d75acb5d5acf1c6b9a7498 +Author: Ebrahim Byagowi +Date: Sat Jul 21 21:14:48 2018 +0430 + + Add a new API, hb_ot_layout_get_feature_name_ids (#976) + + This new API returns cvXX and ssXX related NameId, things like + featUiLabelNameId, featUiTooltipTextNameId, sampleTextNameId, + ... of cvXX + and UINameId of ssXX, in a unified way. + + However HarfBuzz currently doesn't expose an API for retrieving + the actual + information associated with NameId from the `name` table and that + should be + done separately. + + docs/harfbuzz-sections.txt | 1 + + src/hb-ot-layout-common-private.hh | 14 +++++++ + src/hb-ot-layout.cc | 86 + ++++++++++++++++++++++++++++++++++++++ + src/hb-ot-layout.h | 8 ++++ + 4 files changed, 109 insertions(+) + +commit 93b65d9fe331a217640069fad4159cb7c3ec35e6 +Author: Ebrahim Byagowi +Date: Tue Jul 17 23:29:16 2018 +0430 + + Remove dump-fon (#1100) + + It had interesting stuffs like EXE parsing and + big-endian parsers but added in an attempt to find + a solution for #681 which later found not related. + + src/Makefile.am | 4 - + src/dump-fon.cc | 555 + -------------------------------------------------------- + 2 files changed, 559 deletions(-) + +commit d5cd47a69c40966b4d5b5aed87dd7ac6f070c37a +Author: Ebrahim Byagowi +Date: Tue Jul 17 22:32:37 2018 +0430 + + Remove AAT's gcid/fmtx (#1099) + + We are not going to use them, at least in the foreseeable future + + src/Makefile.sources | 2 -- + src/hb-aat-fmtx-table.hh | 67 + -------------------------------------------- + src/hb-aat-gcid-table.hh | 73 + ------------------------------------------------ + src/hb-aat-layout.cc | 2 -- + 4 files changed, 144 deletions(-) + +commit 1e9e344b2ba076a5fd6d57d1705e17a59c3875ce +Author: Behdad Esfahbod +Date: Tue Jul 17 19:17:59 2018 +0200 + + Fix hb_face_count() sanitize referencing + + src/hb-face.cc | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +commit a8cc0b5907e61199334a3a886fe22efe9cc17149 +Author: Behdad Esfahbod +Date: Tue Jul 17 19:09:03 2018 +0200 + + Remove TODO that is not gonna be done + + Previously the idea was to cache sanitize results externally (think, + in Fontconfig) and avoid resanitizing every time. That's, not a good + idea. + + src/hb-open-type-private.hh | 2 -- + 1 file changed, 2 deletions(-) + +commit be7073840097c873ce4954c6cffadab175a007d3 +Author: Behdad Esfahbod +Date: Tue Jul 17 18:45:25 2018 +0200 + + Move sanitizer code around a bit + + src/hb-aat-layout-common-private.hh | 4 +- + src/hb-open-type-private.hh | 95 + ++++++++++++++++++++----------------- + src/hb-ot-color-sbix-table.hh | 12 ++--- + src/hb-ot-layout-common-private.hh | 3 -- + 4 files changed, 58 insertions(+), 56 deletions(-) + +commit db5d430effce67db57ddea2545694b7275ee8b35 +Author: Behdad Esfahbod +Date: Tue Jul 17 18:14:45 2018 +0200 + + [aat] Update for blob changes + + Also, uncomment code again, just "if (0)" it out, so it doesn't get + stale again. + + src/hb-aat-layout.cc | 58 + ++------------------------------------------- + src/hb-open-type-private.hh | 27 +++++++++++++-------- + src/hb-ot-layout-private.hh | 1 + + src/hb-ot-layout.cc | 2 ++ + src/hb-ot-shape.cc | 6 ++--- + 5 files changed, 25 insertions(+), 69 deletions(-) + +commit 68310a65cba7eed20f8696f4c670bb195677f467 +Author: Behdad Esfahbod +Date: Tue Jul 17 13:20:40 2018 +0200 + + 1.8.4 + + NEWS | 7 +++++++ + configure.ac | 2 +- + src/hb-version.h | 4 ++-- + 3 files changed, 10 insertions(+), 3 deletions(-) + commit 04b7b81bcbf19cb85d06d930192d6591ba45ef72 Author: Behdad Esfahbod Date: Tue Jul 17 10:57:01 2018 +0200 diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/NEWS b/Build/source/libs/harfbuzz/harfbuzz-src/NEWS index fce43a3648e..13aa66295b8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/NEWS +++ b/Build/source/libs/harfbuzz/harfbuzz-src/NEWS @@ -1,3 +1,11 @@ +Overview of changes leading to 1.8.5 +Wednesday, August 1, 2018 +==================================== +- Major Khmer shaper improvements to better match Microsoft. +- Indic bug fixes. +- Internal improvements to atomic operations. + + Overview of changes leading to 1.8.4 Tuesday, July 17, 2018 ==================================== diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac b/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac index 0dd70e68f8d..c439f54d034 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac +++ b/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ([2.64]) AC_INIT([HarfBuzz], - [1.8.4], + [1.8.5], [https://github.com/harfbuzz/harfbuzz/issues/new], [harfbuzz], [http://harfbuzz.org/]) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am index 66594bbcd19..9e7fd2995c3 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am @@ -374,15 +374,11 @@ dist_check_SCRIPTS += \ endif check_PROGRAMS += \ - dump-fon \ dump-indic-data \ dump-khmer-data \ dump-myanmar-data \ dump-use-data \ $(NULL) -dump_fon_SOURCES = dump-fon.cc -dump_fon_CPPFLAGS = $(HBCFLAGS) -dump_fon_LDADD = libharfbuzz.la $(HBLIBS) dump_indic_data_SOURCES = dump-indic-data.cc hb-ot-shape-complex-indic-table.cc dump_indic_data_CPPFLAGS = $(HBCFLAGS) dump_indic_data_LDADD = libharfbuzz.la $(HBLIBS) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources index 0bc9e589eef..80b8e261c41 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources @@ -14,8 +14,10 @@ HB_BASE_sources = \ hb-face.cc \ hb-font-private.hh \ hb-font.cc \ + hb-iter-private.hh \ hb-map-private.hh \ hb-map.cc \ + hb-machinery-private.hh \ hb-mutex-private.hh \ hb-object-private.hh \ hb-open-file-private.hh \ @@ -93,8 +95,6 @@ HB_OT_sources = \ hb-aat-layout-morx-table.hh \ hb-aat-layout-trak-table.hh \ hb-aat-layout-private.hh \ - hb-aat-fmtx-table.hh \ - hb-aat-gcid-table.hh \ hb-aat-ltag-table.hh \ hb-ot-font.cc \ hb-ot-layout.cc \ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-emoji.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-emoji.cc index 99e8ef9f393..400b890ad33 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-emoji.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-emoji.cc @@ -233,12 +233,10 @@ int main (int argc, char **argv) svg.dump (svg_callback); svg.fini (); - OT::Sanitizer sanitizerCOLR; - hb_blob_t* colr_blob = sanitizerCOLR.sanitize (face->reference_table (HB_OT_TAG_COLR)); + hb_blob_t* colr_blob = OT::hb_sanitize_context_t().reference_table (face); const OT::COLR *colr = colr_blob->as (); - OT::Sanitizer sanitizerCPAL; - hb_blob_t* cpal_blob = sanitizerCPAL.sanitize (face->reference_table (HB_OT_TAG_CPAL)); + hb_blob_t* cpal_blob = OT::hb_sanitize_context_t().reference_table (face); const OT::CPAL *cpal = cpal_blob->as (); cairo_font_face_t *cairo_face; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-fon.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-fon.cc deleted file mode 100644 index 401540940ac..00000000000 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-fon.cc +++ /dev/null @@ -1,555 +0,0 @@ -/* - * Copyright © 2018 Ebrahim Byagowi - * - * 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 -#include -#include "hb-open-type-private.hh" - -template struct LEInt; - -template -struct LEInt -{ - public: - inline void set (Type V) - { - v = V; - } - inline operator Type (void) const - { - return v; - } - private: uint8_t v; -}; -template -struct LEInt -{ - public: - inline void set (Type V) - { - v[1] = (V >> 8) & 0xFF; - v[0] = (V ) & 0xFF; - } - inline operator Type (void) const - { - return (v[1] << 8) - + (v[0] ); - } - private: uint8_t v[2]; -}; -template -struct LEInt -{ - public: - inline void set (Type V) - { - v[2] = (V >> 16) & 0xFF; - v[1] = (V >> 8) & 0xFF; - v[0] = (V ) & 0xFF; - } - inline operator Type (void) const - { - return (v[2] << 16) - + (v[1] << 8) - + (v[0] ); - } - private: uint8_t v[3]; -}; -template -struct LEInt -{ - public: - inline void set (Type V) - { - v[3] = (V >> 24) & 0xFF; - v[2] = (V >> 16) & 0xFF; - v[1] = (V >> 8) & 0xFF; - v[0] = (V ) & 0xFF; - } - inline operator Type (void) const - { - return (v[3] << 24) - + (v[2] << 16) - + (v[1] << 8) - + (v[0] ); - } - private: uint8_t v[4]; -}; - -template -struct LEIntType -{ - inline void set (Type i) { v.set (i); } - inline operator Type(void) const { return v; } - inline bool sanitize (OT::hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); - } - protected: - LEInt v; - public: - DEFINE_SIZE_STATIC (Size); -}; - -typedef LEIntType LEUINT8; /* 8-bit unsigned integer. */ -typedef LEIntType LEINT8; /* 8-bit signed integer. */ -typedef LEIntType LEUINT16; /* 16-bit unsigned integer. */ -typedef LEIntType LEINT16; /* 16-bit signed integer. */ -typedef LEIntType LEUINT32; /* 32-bit unsigned integer. */ -typedef LEIntType LEINT32; /* 32-bit signed integer. */ -typedef LEIntType LEUINT24; /* 24-bit unsigned integer. */ - - -struct LE_FONTINFO16 -{ - inline bool sanitize (OT::hb_sanitize_context_t *c, unsigned int length) const - { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && c->check_range (this, length))); - } - - // https://msdn.microsoft.com/en-us/library/cc194829.aspx - enum charset_t - { - // dfCharSet possible values and the codepage they are indicating to - ANSI = 0x00, // 1252 - DEFAULT = 0x01, // - SYMBOL = 0x02, // - SHIFTJIS = 0x80, // 932 - HANGUL = 0x81, // 949 - GB2312 = 0x86, // 936 - CHINESEBIG5 = 0x88, // 950 - GREEK = 0xA1, // 1253 - TURKISH = 0xA2, // 1254 - HEBREW = 0xB1, // 1255 - ARABIC = 0xB2, // 1256 - BALTIC = 0xBA, // 1257 - RUSSIAN = 0xCC, // 1251 - THAI = 0xDE, // 874 - EE = 0xEE, // 1250 - OEM = 0xFF // - }; - - inline const char* get_charset() const - { - switch (dfCharSet) { - case ANSI: return "ISO8859"; - case DEFAULT: return "WinDefault"; - case SYMBOL: return "Symbol"; - case SHIFTJIS: return "JISX0208.1983"; - case HANGUL: return "MSHangul"; - case GB2312: return "GB2312.1980"; - case CHINESEBIG5: return "Big5"; - case GREEK: return "CP1253"; - case TURKISH: return "CP1254"; - case HEBREW: return "CP1255"; - case ARABIC: return "CP1256"; - case BALTIC: return "CP1257"; - case RUSSIAN: return "CP1251"; - case THAI: return "CP874"; - case EE: return "CP1250"; - case OEM: return "OEM"; - default: return "Unknown"; - } - } - - inline unsigned int get_version () const - { - return dfVersion; - } - - inline unsigned int get_weight () const - { - return dfWeight; - } - - enum weight_t { - DONTCARE = 0, - THIN = 100, - EXTRALIGHT = 200, - ULTRALIGHT = 200, - LIGHT = 300, - NORMAL = 400, - REGULAR = 400, - MEDIUM = 500, - SEMIBOLD = 600, - DEMIBOLD = 600, - BOLD = 700, - EXTRABOLD = 800, - ULTRABOLD = 800, - HEAVY = 900, - BLACK = 900 - }; - - inline void dump () const - { - // With https://github.com/juanitogan/mkwinfont/blob/master/python/dewinfont.py help - // Should be implemented differently eventually, but for now - unsigned int ctstart; - unsigned int ctsize; - if (dfVersion == 0x200) - { - ctstart = 0x76; - ctsize = 4; - } - else - { - return; // must of ".fon"s are version 2 and even dewinfont V1 implmentation doesn't seem correct - ctstart = 0x94; - ctsize = 6; - } - // unsigned int maxwidth = 0; - for (unsigned int i = dfFirstChar; i < dfLastChar; ++i) - { - unsigned int entry = ctstart + ctsize * (i-dfFirstChar); - unsigned int w = (uint16_t) OT::StructAtOffset (this, entry); - - unsigned int off; - if (ctsize == 4) - off = (uint16_t) OT::StructAtOffset (this, entry+2); - else - off = (uint32_t) OT::StructAtOffset (this, entry+2); - - unsigned int widthbytes = (w + 7) / 8; - for (unsigned int j = 0; j < dfPixHeight; ++j) - { - for (unsigned int k = 0; k < widthbytes; ++k) - { - unsigned int bytepos = off + k * dfPixHeight + j; - const uint8_t b = (uint8_t) OT::StructAtOffset (this, bytepos); - for (unsigned int a = 128; a > 0; a >>= 1) - printf (b & a ? "x" : "."); - } - printf ("\n"); - } - printf ("\n\n"); - } - } - - protected: - LEUINT16 dfVersion; - LEUINT32 dfSize; - LEUINT8 dfCopyright[60]; - LEUINT16 dfType; - LEUINT16 dfPoints; - LEUINT16 dfVertRes; - LEUINT16 dfHorizRes; - LEUINT16 dfAscent; - LEUINT16 dfInternalLeading; - LEUINT16 dfExternalLeading; - LEUINT8 dfItalic; - LEUINT8 dfUnderline; - LEUINT8 dfStrikeOut; - LEUINT16 dfWeight; // see weight_t - LEUINT8 dfCharSet; // see charset_t - LEUINT16 dfPixWidth; - LEUINT16 dfPixHeight; - LEUINT8 dfPitchAndFamily; - LEUINT16 dfAvgWidth; - LEUINT16 dfMaxWidth; - LEUINT8 dfFirstChar; - LEUINT8 dfLastChar; - LEUINT8 dfDefaultChar; - LEUINT8 dfBreakChar; - LEUINT16 dfWidthBytes; - LEUINT32 dfDevice; - LEUINT32 dfFace; - LEUINT32 dfBitsPointer; - LEUINT32 dfBitsOffset; - LEUINT8 dfReserved; -// LEUINT32 dfFlags; -// LEUINT16 dfAspace; -// LEUINT16 dfBspace; -// LEUINT16 dfCspace; -// LEUINT32 dfColorPointer; -// LEUINT32 dfReserved1[4]; - OT::UnsizedArrayOf - dataZ; - public: - DEFINE_SIZE_ARRAY (118, dataZ); -}; - -struct NE_NAMEINFO -{ - friend struct NE_TYPEINFO; - - inline bool sanitize (OT::hb_sanitize_context_t *c, const void *base, unsigned int shift) const - { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && - get_font (base, shift).sanitize (c, length << shift))); - } - - inline const LE_FONTINFO16& get_font (const void *base, int shift) const - { - return OT::StructAtOffset (base, offset << shift); - } - - enum resource_type_flag_t { - NONE = 0x0000, - MOVEABLE = 0x0010, - PURE = 0x0020, - PRELOAD = 0x0040 - }; - - protected: - LEUINT16 offset; // Should be shifted with alignmentShiftCount before use - LEUINT16 length; // Should be shifted with alignmentShiftCount before use - LEUINT16 flags; // resource_type_flag_t - LEUINT16 id; - LEUINT16 handle; - LEUINT16 usage; - public: - DEFINE_SIZE_STATIC (12); -}; - -struct NE_TYPEINFO -{ - inline bool sanitize (OT::hb_sanitize_context_t *c, const void *base, unsigned int shift) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && resources.sanitize (c, count, base, shift)); - } - - inline unsigned int get_size (void) const - { return 8 + count * NE_NAMEINFO::static_size; } - - inline const NE_TYPEINFO& next () const - { - const NE_TYPEINFO& next = OT::StructAfter (*this); - if (type_id == 0) - return Null(NE_TYPEINFO); - return next; - } - - inline const LE_FONTINFO16& get_font (unsigned int idx, const void *base, int shift) const - { - if (idx < count) - return resources[idx].get_font (base, shift); - return Null(LE_FONTINFO16); - } - - inline unsigned int get_count () const - { - return count; - } - - inline unsigned int get_type_id () const - { - return type_id; - } - - enum type_id_t { - CURSOR = 0x8001, - BITMAP = 0x8002, - ICON = 0x8003, - MENU = 0x8004, - DIALOG = 0x8005, - STRING = 0x8006, - FONT_DIRECTORY = 0x8007, - FONT = 0x8008, - ACCELERATOR_TABLE = 0x8009, - RESOURCE_DATA = 0x800a, - GROUP_CURSOR = 0x800c, - GROUP_ICON = 0x800e, - VERSION = 0x8010 - }; - - protected: - LEUINT16 type_id; // see type_id_t - LEUINT16 count; - LEUINT32 resloader; - OT::UnsizedArrayOf - resources; - public: - DEFINE_SIZE_ARRAY (8, resources); -}; - -struct NE_RESOURCE_TABLE -{ - inline bool sanitize (OT::hb_sanitize_context_t *c, const void *base) const - { - TRACE_SANITIZE (this); - - if (!c->check_struct (this)) - return_trace (false); - - const NE_TYPEINFO* n = &chain; - while (n != &Null(NE_TYPEINFO) && c->check_struct (n) && n->get_type_id () != 0) - { - if (n->get_type_id () == NE_TYPEINFO::FONT) - return_trace (n->sanitize (c, base, alignmentShiftCount)); - n = &n->next(); - } - return_trace (false); - } - - inline unsigned int get_shift_value () const - { - return alignmentShiftCount; - } - - inline const NE_TYPEINFO& get_fonts_entry () const - { - const NE_TYPEINFO* n = &chain; - while (n != &Null(NE_TYPEINFO) && n->get_type_id () != 0) - { - if (n->get_type_id () == NE_TYPEINFO::FONT) - return *n; - n = &n->next(); - } - return Null(NE_TYPEINFO); - } - - protected: - LEUINT16 alignmentShiftCount; - NE_TYPEINFO chain; - // It is followed by an array of OT::ArrayOf chars; - public: - DEFINE_SIZE_MIN (2); -}; - -// https://github.com/wine-mirror/wine/blob/master/include/winnt.h#L2467 -struct LE_IMAGE_OS2_HEADER -{ - inline bool sanitize (OT::hb_sanitize_context_t *c, const void *base) const - { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && (this+rsrctab).sanitize (c, base))); - } - - inline const NE_RESOURCE_TABLE& get_resource_table () const - { - if (magic != 0x454E) // Only NE containers are support for now, NE == 0x454E - return Null(NE_RESOURCE_TABLE); - return this+rsrctab; - } - - protected: - LEUINT16 magic; /* 00 NE signature 'NE' */ - LEUINT8 ver; /* 02 Linker version number */ - LEUINT8 rev; /* 03 Linker revision number */ - LEUINT16 enttab; /* 04 Offset to entry table relative to NE */ - LEUINT16 cbenttab; /* 06 Length of entry table in bytes */ - LEUINT32 crc; /* 08 Checksum */ - LEUINT16 flags; /* 0c Flags about segments in this file */ - LEUINT16 autodata; /* 0e Automatic data segment number */ - LEUINT16 heap; /* 10 Initial size of local heap */ - LEUINT16 stack; /* 12 Initial size of stack */ - LEUINT32 csip; /* 14 Initial CS:IP */ - LEUINT32 sssp; /* 18 Initial SS:SP */ - LEUINT16 cseg; /* 1c # of entries in segment table */ - LEUINT16 cmod; /* 1e # of entries in module reference tab. */ - LEUINT16 cbnrestab; /* 20 Length of nonresident-name table */ - LEUINT16 segtab; /* 22 Offset to segment table */ - OT::OffsetTo - rsrctab; /* 24 Offset to resource table */ - LEUINT16 restab; /* 26 Offset to resident-name table */ - LEUINT16 modtab; /* 28 Offset to module reference table */ - LEUINT16 imptab; /* 2a Offset to imported name table */ - LEUINT32 nrestab; /* 2c Offset to nonresident-name table */ - LEUINT16 cmovent; /* 30 # of movable entry points */ - LEUINT16 align; /* 32 Logical sector alignment shift count */ - LEUINT16 cres; /* 34 # of resource segments */ - LEUINT8 exetyp; /* 36 Flags indicating target OS */ - LEUINT8 flagsothers; /* 37 Additional information flags */ - LEUINT16 pretthunks; /* 38 Offset to return thunks */ - LEUINT16 psegrefbytes; /* 3a Offset to segment ref. bytes */ - LEUINT16 swaparea; /* 3c Reserved by Microsoft */ - LEUINT16 expver; /* 3e Expected Windows version number */ - public: - DEFINE_SIZE_STATIC (64); -}; - -struct LE_IMAGE_DOS_HEADER { - inline bool sanitize (OT::hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && - get_os2_header ().sanitize (c, this))); - } - - inline const LE_IMAGE_OS2_HEADER& get_os2_header () const - { - return this+e_lfanew; - } - - protected: - LEUINT16 e_magic; // Magic number - LEUINT16 e_cblp; // Bytes on last page of file - LEUINT16 e_cp; // Pages in file - LEUINT16 e_crlc; // Relocations - LEUINT16 e_cparhdr; // Size of header in paragraphs - LEUINT16 e_minalloc; // Minimum extra paragraphs needed - LEUINT16 e_maxalloc; // Maximum extra paragraphs needed - LEUINT16 e_ss; // Initial (relative) SS value - LEUINT16 e_sp; // Initial SP value - LEUINT16 e_csum; // Checksum - LEUINT16 e_ip; // Initial IP value - LEUINT16 e_cs; // Initial (relative) CS value - LEUINT16 e_lfarlc; // File address of relocation table - LEUINT16 e_ovno; // Overlay number - LEUINT16 e_res_0; // Reserved words - LEUINT16 e_res_1; // Reserved words - LEUINT16 e_res_2; // Reserved words - LEUINT16 e_res_3; // Reserved words - LEUINT16 e_oemid; // OEM identifier (for e_oeminfo) - LEUINT16 e_oeminfo; // OEM information; e_oemid specific - LEUINT16 e_res2_0; // Reserved words - LEUINT16 e_res2_1; // Reserved words - LEUINT16 e_res2_2; // Reserved words - LEUINT16 e_res2_3; // Reserved words - LEUINT16 e_res2_4; // Reserved words - LEUINT16 e_res2_5; // Reserved words - LEUINT16 e_res2_6; // Reserved words - LEUINT16 e_res2_7; // Reserved words - LEUINT16 e_res2_8; // Reserved words - LEUINT16 e_res2_9; // Reserved words - OT::OffsetTo - e_lfanew; // File address of new exe header - public: - DEFINE_SIZE_STATIC (64); -}; - -int main (int argc, char** argv) { - hb_blob_t *blob = hb_blob_create_from_file (argv[1]); - - OT::Sanitizer sanitizer; - hb_blob_t *font_blob = sanitizer.sanitize (blob); - const LE_IMAGE_DOS_HEADER* dos_header = font_blob->as (); - - const NE_RESOURCE_TABLE &rtable = dos_header->get_os2_header ().get_resource_table (); - int shift = rtable.get_shift_value (); - const NE_TYPEINFO& entry = rtable.get_fonts_entry (); - for (unsigned int i = 0; i < entry.get_count (); ++i) - { - const LE_FONTINFO16& font = entry.get_font (i, dos_header, shift); - printf ("version: %x, weight: %d, charset: %s\n", font.get_version (), - font.get_weight (), font.get_charset ()); - // font.dump (); - } - return 0; -} diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py index e7c621cac49..c742ebacae4 100755 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py @@ -328,6 +328,9 @@ def map_to_use(data): # TODO: https://github.com/harfbuzz/harfbuzz/pull/626 if U == 0xA8B4: UISC = Consonant_Medial + # TODO: https://github.com/harfbuzz/harfbuzz/issues/1105 + if U == 0x11134: UISC = Gemination_Mark + values = [k for k,v in items if v(U,UISC,UGC)] assert len(values) == 1, "%s %s %s %s" % (hex(U), UISC, UGC, values) USE = values[0] @@ -356,6 +359,13 @@ def map_to_use(data): # https://github.com/roozbehp/unicode-data/issues/8 if U == 0x0A51: UIPC = Bottom + # TODO: https://github.com/harfbuzz/harfbuzz/pull/982 + if UBlock == 'Chakma' and is_VOWEL (U, UISC, UGC): + if UIPC == Top: + UIPC = Bottom + elif UIPC == Bottom: + UIPC = Top + assert (UIPC in [Not_Applicable, Visual_Order_Left] or USE in use_positions), "%s %s %s %s %s" % (hex(U), UIPC, USE, UISC, UGC) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-fmtx-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-fmtx-table.hh deleted file mode 100644 index aa82c88cf95..00000000000 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-fmtx-table.hh +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright © 2018 Ebrahim Byagowi - * - * 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. - */ - -#ifndef HB_AAT_FMTX_TABLE_HH -#define HB_AAT_FMTX_TABLE_HH - -#include "hb-aat-layout-common-private.hh" - -/* - * fmtx -- Font Metrics - * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6fmtx.html - */ -#define HB_AAT_TAG_fmtx HB_TAG('f','m','t','x') - - -namespace AAT { - - -struct fmtx -{ - static const hb_tag_t tableTag = HB_AAT_TAG_fmtx; - - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); - } - - FixedVersion<>version; /* Version (set to 0x00020000). */ - HBUINT32 glyphIndex; /* The glyph whose points represent the metrics. */ - HBUINT8 horizontalBefore; /* Point number for the horizontal ascent. */ - HBUINT8 horizontalAfter; /* Point number for the horizontal descent. */ - HBUINT8 horizontalCaretHead; /* Point number for the horizontal caret head. */ - HBUINT8 horizontalCaretBase; /* Point number for the horizontal caret base. */ - HBUINT8 verticalBefore; /* Point number for the vertical ascent. */ - HBUINT8 verticalAfter; /* Point number for the vertical descent. */ - HBUINT8 verticalCaretHead; /* Point number for the vertical caret head. */ - HBUINT8 verticalCaretBase; /* Point number for the vertical caret base. */ - public: - DEFINE_SIZE_STATIC (16); -}; - -} /* namespace AAT */ - - -#endif /* HB_AAT_FMTX_TABLE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-gcid-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-gcid-table.hh deleted file mode 100644 index b48a27984bc..00000000000 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-gcid-table.hh +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright © 2018 Ebrahim Byagowi - * - * 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. - */ - -#ifndef HB_AAT_GCID_TABLE_HH -#define HB_AAT_GCID_TABLE_HH - -#include "hb-aat-layout-common-private.hh" - -/* - * gcid -- Glyphs CIDs - * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6gcid.html - */ -#define HB_AAT_TAG_gcid HB_TAG('g','c','i','d') - - -namespace AAT { - - -struct gcid -{ - static const hb_tag_t tableTag = HB_AAT_TAG_gcid; - - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && CIDs.sanitize (c))); - } - - protected: - HBUINT16 version; /* Version number (set to 0) */ - HBUINT16 format; /* Data format (set to 0) */ - HBUINT32 size; /* Size of the table, including header */ - HBUINT16 registry; /* The registry ID */ - HBUINT8 registryName[64]; - /* The registry name in ASCII */ - HBUINT16 order; /* The order ID */ - HBUINT8 orderName[64]; /* The order name in ASCII */ - HBUINT16 supplementVersion; - /* The supplement version */ - ArrayOf - CIDs; /* The CIDs for the glyphs in the font, - * starting with glyph 0. If a glyph does not correspond - * to a CID in the identified collection, 0xFFFF is used. - * This should not exceed the number of glyphs in the font. */ - public: - DEFINE_SIZE_ARRAY (144, CIDs); -}; - -} /* namespace AAT */ - - -#endif /* HB_AAT_GCID_TABLE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common-private.hh index 2825b181325..d7f35052d77 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common-private.hh @@ -161,7 +161,7 @@ struct LookupFormat0 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (arrayZ.sanitize (c, c->num_glyphs)); + return_trace (arrayZ.sanitize (c, c->get_num_glyphs ())); } protected: @@ -625,7 +625,7 @@ struct hb_aat_apply_context_t : sanitizer (), lookup_index (0), debug_depth (0) { sanitizer.init (table); - sanitizer.num_glyphs = face->get_num_glyphs (); + sanitizer.set_num_glyphs (face->get_num_glyphs ()); sanitizer.start_processing (); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc index 7784fae3331..405aafccb81 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc @@ -36,48 +36,12 @@ #include "hb-aat-layout-kerx-table.hh" #include "hb-aat-layout-morx-table.hh" #include "hb-aat-layout-trak-table.hh" -#include "hb-aat-fmtx-table.hh" // Just so we compile it; unused otherwise. -#include "hb-aat-gcid-table.hh" // Just so we compile it; unused otherwise. #include "hb-aat-ltag-table.hh" // Just so we compile it; unused otherwise. /* - * morx/kerx/trak + * morx/kerx/trak/ankr */ -#if 0 -static inline const AAT::ankr& -_get_ankr (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::ankr); - } - hb_ot_layout_t * layout = hb_ot_layout_from_face (face); - const AAT::ankr& ankr = *(layout->ankr.get ()); - if (blob) - *blob = layout->ankr.blob; - return ankr; -} - -static inline const AAT::kerx& -_get_kerx (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::kerx); - } - hb_ot_layout_t * layout = hb_ot_layout_from_face (face); - /* XXX this doesn't call set_num_glyphs on sanitizer. */ - const AAT::kerx& kerx = *(layout->kerx.get ()); - if (blob) - *blob = layout->kerx.blob; - return kerx; -} - static inline const AAT::morx& _get_morx (hb_face_t *face, hb_blob_t **blob = nullptr) { @@ -88,36 +52,16 @@ _get_morx (hb_face_t *face, hb_blob_t **blob = nullptr) return Null(AAT::morx); } hb_ot_layout_t * layout = hb_ot_layout_from_face (face); - /* XXX this doesn't call set_num_glyphs on sanitizer. */ const AAT::morx& morx = *(layout->morx.get ()); if (blob) - *blob = layout->morx.blob; + *blob = layout->morx.get_blob (); return morx; } -static inline const AAT::trak& -_get_trak (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::trak); - } - hb_ot_layout_t * layout = hb_ot_layout_from_face (face); - const AAT::trak& trak = *(layout->trak.get ()); - if (blob) - *blob = layout->trak.blob; - return trak; -} -#endif - // static inline void // _hb_aat_layout_create (hb_face_t *face) // { -// OT::Sanitizer sanitizer; -// sanitizer.set_num_glyphs (face->get_num_glyphs ()); -// hb_blob_t *morx_blob = sanitizer.sanitize (face->reference_table (HB_AAT_TAG_morx)); +// hb_blob_t *morx_blob = OT::hb_sanitize_context_t().reference_table (face); // morx_blob->as (); // if (0) @@ -129,13 +73,11 @@ _get_trak (hb_face_t *face, hb_blob_t **blob = nullptr) void hb_aat_layout_substitute (hb_font_t *font, hb_buffer_t *buffer) { -#if 0 hb_blob_t *blob; const AAT::morx& morx = _get_morx (font->face, &blob); AAT::hb_aat_apply_context_t c (font, buffer, blob); morx.apply (&c); -#endif } void diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic-private.hh index 02cf6f38811..0b043e69864 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic-private.hh @@ -46,21 +46,23 @@ /* Defined externally, i.e. in config.h; must have typedef'ed hb_atomic_int_impl_t as well. */ -#elif !defined(HB_NO_MT) && defined(__ATOMIC_ACQUIRE) +#elif !defined(HB_NO_MT) && defined(__ATOMIC_CONSUME) /* C++11-style GCC primitives. */ typedef int hb_atomic_int_impl_t; -#define hb_atomic_int_impl_add(AI, V) __atomic_fetch_add (&(AI), (V), __ATOMIC_ACQ_REL) +#define hb_atomic_int_impl_add(AI, V) __atomic_fetch_add ((AI), (V), __ATOMIC_ACQ_REL) +#define hb_atomic_int_impl_set_relaxed(AI, V) __atomic_store_n ((AI), (V), __ATOMIC_RELAXED) +#define hb_atomic_int_impl_get_relaxed(AI) __atomic_load_n ((AI), __ATOMIC_RELAXED) -#define hb_atomic_ptr_impl_get(P) __atomic_load_n ((P), __ATOMIC_ACQUIRE) +#define hb_atomic_ptr_impl_get(P) __atomic_load_n ((P), __ATOMIC_CONSUME) static inline bool _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) { const void *O = O_; // Need lvalue return __atomic_compare_exchange_n ((void **) P, (void **) &O, (void *) N, true, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED); } -#define hb_atomic_ptr_impl_cmpexch(P,O,N) (_hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N))) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N)) #elif !defined(HB_NO_MT) && __cplusplus >= 201103L @@ -69,47 +71,49 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) #include typedef int hb_atomic_int_impl_t; -#define hb_atomic_int_impl_add(AI, V) (reinterpret_cast *> (&AI)->fetch_add ((V), std::memory_order_acq_rel)) +#define hb_atomic_int_impl_add(AI, V) (reinterpret_cast *> (AI)->fetch_add ((V), std::memory_order_acq_rel)) +#define hb_atomic_int_impl_set_relaxed(AI, V) (reinterpret_cast *> (AI)->store ((V), std::memory_order_relaxed)) +#define hb_atomic_int_impl_get_relaxed(AI) (reinterpret_cast *> (AI)->load (std::memory_order_relaxed)) -#define hb_atomic_ptr_impl_get(P) (reinterpret_cast *> (P)->load (std::memory_order_acquire)) +#define hb_atomic_ptr_impl_get(P) (reinterpret_cast *> (P)->load (std::memory_order_consume)) static inline bool _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) { const void *O = O_; // Need lvalue return reinterpret_cast *> (P)->compare_exchange_weak (O, N, std::memory_order_acq_rel, std::memory_order_relaxed); } -#define hb_atomic_ptr_impl_cmpexch(P,O,N) (_hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N))) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N)) #elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__)) #include -/* MinGW has a convoluted history of supporting MemoryBarrier - * properly. As such, define a function to wrap the whole - * thing. */ -static inline void _HBMemoryBarrier (void) { +static inline void _hb_memory_barrier (void) +{ #if !defined(MemoryBarrier) + /* MinGW has a convoluted history of supporting MemoryBarrier. */ long dummy = 0; InterlockedExchange (&dummy, 1); #else MemoryBarrier (); #endif } +#define _hb_memory_barrier() _hb_memory_barrier () typedef LONG hb_atomic_int_impl_t; -#define hb_atomic_int_impl_add(AI, V) InterlockedExchangeAdd (&(AI), (V)) +#define hb_atomic_int_impl_add(AI, V) InterlockedExchangeAdd ((AI), (V)) -#define hb_atomic_ptr_impl_get(P) (_HBMemoryBarrier (), (void *) *(P)) #define hb_atomic_ptr_impl_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O)) #elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES) +#define _hb_memory_barrier() __sync_synchronize () + typedef int hb_atomic_int_impl_t; -#define hb_atomic_int_impl_add(AI, V) __sync_fetch_and_add (&(AI), (V)) +#define hb_atomic_int_impl_add(AI, V) __sync_fetch_and_add ((AI), (V)) -#define hb_atomic_ptr_impl_get(P) (void *) (__sync_synchronize (), *(P)) #define hb_atomic_ptr_impl_cmpexch(P,O,N) __sync_bool_compare_and_swap ((P), (O), (N)) @@ -118,11 +122,30 @@ typedef int hb_atomic_int_impl_t; #include #include +#define _hb_memory_r_barrier() __machine_r_barrier () +#define _hb_memory_w_barrier() __machine_w_barrier () +#define _hb_memory_barrier() __machine_rw_barrier () + typedef unsigned int hb_atomic_int_impl_t; -#define hb_atomic_int_impl_add(AI, V) ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V)) -#define hb_atomic_ptr_impl_get(P) ( ({__machine_rw_barrier ();}), (void *) *(P)) -#define hb_atomic_ptr_impl_cmpexch(P,O,N) ( ({__machine_rw_barrier ();}), atomic_cas_ptr ((void **) (P), (void *) (O), (void *) (N)) == (void *) (O) ? true : false) +static inline int _hb_fetch_and_add (hb_atomic_int_impl_t *AI, int V) +{ + _hb_memory_w_barrier (); + int result = atomic_add_int_nv (AI, V); + _hb_memory_r_barrier (); + return result; +} +static inline bool _hb_compare_and_swap_ptr (const void **P, const void *O, const void *N) +{ + _hb_memory_w_barrier (); + int result = atomic_cas_ptr ((void **) P, (void *) O, (void *) N) == (void *) O; + _hb_memory_r_barrier (); + return result; +} + +#define hb_atomic_int_impl_add(AI, V) _hb_fetch_and_add ((AI), (V)) + +#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_compare_and_swap_ptr ((const void **) (P), (O), (N)) #elif !defined(HB_NO_MT) && defined(__APPLE__) @@ -134,11 +157,11 @@ typedef unsigned int hb_atomic_int_impl_t; #include #endif +#define _hb_memory_barrier() OSMemoryBarrier () typedef int32_t hb_atomic_int_impl_t; -#define hb_atomic_int_impl_add(AI, V) (OSAtomicAdd32Barrier ((V), &(AI)) - (V)) +#define hb_atomic_int_impl_add(AI, V) (OSAtomicAdd32Barrier ((V), (AI)) - (V)) -#define hb_atomic_ptr_impl_get(P) (OSMemoryBarrier (), (void *) *(P)) #if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100) #define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P)) #else @@ -154,65 +177,88 @@ typedef int32_t hb_atomic_int_impl_t; #include +#define _hb_memory_barrier() __lwsync () + +typedef int hb_atomic_int_impl_t; -static inline int _hb_fetch_and_add(volatile int* AI, unsigned int V) { - __lwsync(); - int result = __fetch_and_add(AI, V); - __isync(); +static inline int _hb_fetch_and_add (hb_atomic_int_impl_t *AI, int V) +{ + _hb_memory_barrier (); + int result = __fetch_and_add (AI, V); + _hb_memory_barrier (); return result; } -static inline int _hb_compare_and_swaplp(volatile long* P, long O, long N) { - __sync(); - int result = __compare_and_swaplp (P, &O, N); - __sync(); +static inline bool _hb_compare_and_swaplp (long *P, long O, long N) +{ + _hb_memory_barrier (); + bool result = __compare_and_swaplp (P, &O, N); + _hb_memory_barrier (); return result; } -typedef int hb_atomic_int_impl_t; -#define hb_atomic_int_impl_add(AI, V) _hb_fetch_and_add (&(AI), (V)) +#define hb_atomic_int_impl_add(AI, V) _hb_fetch_and_add ((AI), (V)) + +#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_compare_and_swaplp ((long *) (P), (long) (O), (long) (N)) +static_assert ((sizeof (long) == sizeof (void *)), ""); -#define hb_atomic_ptr_impl_get(P) (__sync(), (void *) *(P)) -#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_compare_and_swaplp ((long*)(P), (long)(O), (long)(N)) #elif !defined(HB_NO_MT) #define HB_ATOMIC_INT_NIL 1 /* Warn that fallback implementation is in use. */ +#define _hb_memory_barrier() + typedef volatile int hb_atomic_int_impl_t; -#define hb_atomic_int_impl_add(AI, V) (((AI) += (V)) - (V)) +#define hb_atomic_int_impl_add(AI, V) ((*(AI) += (V)) - (V)) -#define hb_atomic_ptr_impl_get(P) ((void *) *(P)) #define hb_atomic_ptr_impl_cmpexch(P,O,N) (* (void * volatile *) (P) == (void *) (O) ? (* (void * volatile *) (P) = (void *) (N), true) : false) #else /* HB_NO_MT */ typedef int hb_atomic_int_impl_t; -#define hb_atomic_int_impl_add(AI, V) (((AI) += (V)) - (V)) +#define hb_atomic_int_impl_add(AI, V) ((*(AI) += (V)) - (V)) + +#define _hb_memory_barrier() -#define hb_atomic_ptr_impl_get(P) ((void *) *(P)) #define hb_atomic_ptr_impl_cmpexch(P,O,N) (* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false) #endif +#ifndef _hb_memory_r_barrier +#define _hb_memory_r_barrier() _hb_memory_barrier () +#endif +#ifndef _hb_memory_w_barrier +#define _hb_memory_w_barrier() _hb_memory_barrier () +#endif #ifndef HB_ATOMIC_INT_INIT #define HB_ATOMIC_INT_INIT(V) {V} #endif +#ifndef hb_atomic_int_impl_set_relaxed +#define hb_atomic_int_impl_set_relaxed(AI, V) (*(AI) = (V)) +#endif +#ifndef hb_atomic_int_impl_get_relaxed +#define hb_atomic_int_impl_get_relaxed(AI) (*(AI)) +#endif +#ifndef hb_atomic_ptr_impl_get +inline void *hb_atomic_ptr_impl_get (void **P) { void *v = *P; _hb_memory_r_barrier (); return v; } +#endif + struct hb_atomic_int_t { mutable hb_atomic_int_impl_t v; - inline void set_unsafe (int v_) { v = v_; } - inline int get_unsafe (void) const { return v; } - inline int inc (void) { return hb_atomic_int_impl_add (v, 1); } - inline int dec (void) { return hb_atomic_int_impl_add (v, -1); } + inline void set_relaxed (int v_) { hb_atomic_int_impl_set_relaxed (&v, v_); } + inline int get_relaxed (void) const { return hb_atomic_int_impl_get_relaxed (&v); } + inline int inc (void) { return hb_atomic_int_impl_add (&v, 1); } + inline int dec (void) { return hb_atomic_int_impl_add (&v, -1); } }; -#define hb_atomic_ptr_get(P) hb_atomic_ptr_impl_get(P) +#define hb_atomic_ptr_get(P) hb_atomic_ptr_impl_get((void **) P) #define hb_atomic_ptr_cmpexch(P,O,N) hb_atomic_ptr_impl_cmpexch((P),(O),(N)) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc index 243c2163ef1..bab1a66344e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc @@ -37,7 +37,7 @@ /* hb_options_t */ -hb_options_union_t _hb_options; +hb_atomic_int_t _hb_options; void _hb_options_init (void) @@ -50,7 +50,7 @@ _hb_options_init (void) u.opts.uniscribe_bug_compatible = c && strstr (c, "uniscribe-bug-compatible"); /* This is idempotent and threadsafe. */ - _hb_options = u; + _hb_options.set_relaxed (u.i); } @@ -1069,3 +1069,12 @@ hb_variation_to_string (hb_variation_t *variation, memcpy (buf, s, len); buf[len] = '\0'; } + +/* If there is no visibility control, then hb-static.cc will NOT + * define anything. Instead, we get it to define one set in here + * only, so only libharfbuzz.so defines them, not other libs. */ +#ifdef HB_NO_VISIBILITY +#undef HB_NO_VISIBILITY +#include "hb-static.cc" +#define HB_NO_VISIBILITY 1 +#endif diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh index ae0b6774d80..9056ffca2b1 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh @@ -28,6 +28,7 @@ #define HB_DEBUG_HH #include "hb-private.hh" +#include "hb-atomic-private.hh" #include "hb-dsalgs.hh" @@ -35,6 +36,47 @@ #define HB_DEBUG 0 #endif + +/* + * Global runtime options. + */ + +struct hb_options_t +{ + unsigned int unused : 1; /* In-case sign bit is here. */ + unsigned int initialized : 1; + unsigned int uniscribe_bug_compatible : 1; +}; + +union hb_options_union_t { + int i; + hb_options_t opts; +}; +static_assert ((sizeof (hb_atomic_int_t) >= sizeof (hb_options_union_t)), ""); + +HB_INTERNAL void +_hb_options_init (void); + +extern HB_INTERNAL hb_atomic_int_t _hb_options; + +static inline hb_options_t +hb_options (void) +{ + /* Make a local copy, so we can access bitfield threadsafely. */ + hb_options_union_t u; + u.i = _hb_options.get_relaxed (); + + if (unlikely (!u.i)) + _hb_options_init (); + + return u.opts; +} + + +/* + * Debug output (needs enabling at compile time.) + */ + static inline bool _hb_debug (unsigned int level, unsigned int max_level) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc index 2fef09d03d3..fab2aa3a9f8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc @@ -31,8 +31,6 @@ #include "hb-face-private.hh" #include "hb-blob-private.hh" #include "hb-open-file-private.hh" -#include "hb-ot-head-table.hh" -#include "hb-ot-maxp-table.hh" @@ -52,10 +50,13 @@ hb_face_count (hb_blob_t *blob) if (unlikely (!blob)) return 0; - hb_blob_t *sanitized = OT::Sanitizer ().sanitize (blob); + /* TODO We shouldn't be sanitizing blob. Port to run sanitizer and return if not sane. */ + hb_blob_t *sanitized = OT::hb_sanitize_context_t().sanitize_blob (hb_blob_reference (blob)); const OT::OpenTypeFontFile& ot = *sanitized->as (); + unsigned int ret = ot.get_face_count (); + hb_blob_destroy (sanitized); - return ot.get_face_count (); + return ret; } /* @@ -188,7 +189,7 @@ hb_face_create (hb_blob_t *blob, if (unlikely (!blob)) blob = hb_blob_get_empty (); - hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::Sanitizer().sanitize (hb_blob_reference (blob)), index); + hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::hb_sanitize_context_t().sanitize_blob (hb_blob_reference (blob)), index); if (unlikely (!closure)) return hb_face_get_empty (); @@ -445,15 +446,6 @@ hb_face_get_upem (hb_face_t *face) return face->get_upem (); } -void -hb_face_t::load_upem (void) const -{ - hb_blob_t *head_blob = OT::Sanitizer().sanitize (reference_table (HB_OT_TAG_head)); - const OT::head *head_table = head_blob->as (); - upem = head_table->get_upem (); - hb_blob_destroy (head_blob); -} - /** * hb_face_set_glyph_count: * @face: a face. @@ -489,15 +481,6 @@ hb_face_get_glyph_count (hb_face_t *face) return face->get_num_glyphs (); } -void -hb_face_t::load_num_glyphs (void) const -{ - hb_blob_t *maxp_blob = OT::Sanitizer().sanitize (reference_table (HB_OT_TAG_maxp)); - const OT::maxp *maxp_table = maxp_blob->as (); - num_glyphs = maxp_table->get_num_glyphs (); - hb_blob_destroy (maxp_blob); -} - /** * hb_face_get_table_tags: * @face: a face. diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc index 6670d9a60de..f8a6b0c4681 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc @@ -497,7 +497,10 @@ reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) error = FT_Load_Sfnt_Table (ft_face, tag, 0, buffer, &length); if (error) + { + free (buffer); return nullptr; + } return hb_blob_create ((const char *) buffer, length, HB_MEMORY_MODE_WRITABLE, diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.cc index a96c35804d5..0c8e55733eb 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.cc @@ -71,6 +71,7 @@ HB_DEFINE_OBJECT_TYPE (face) HB_DEFINE_OBJECT_TYPE (font) HB_DEFINE_OBJECT_TYPE (font_funcs) HB_DEFINE_OBJECT_TYPE (set) +HB_DEFINE_OBJECT_TYPE (map) HB_DEFINE_OBJECT_TYPE (shape_plan) HB_DEFINE_OBJECT_TYPE (unicode_funcs) HB_DEFINE_VALUE_TYPE (feature) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.h index 302dc9584e9..800beede0f1 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.h @@ -89,6 +89,10 @@ HB_EXTERN GType hb_gobject_set_get_type (void); #define HB_GOBJECT_TYPE_SET (hb_gobject_set_get_type ()) +HB_EXTERN GType +hb_gobject_map_get_type (void); +#define HB_GOBJECT_TYPE_MAP (hb_gobject_map_get_type ()) + HB_EXTERN GType hb_gobject_shape_plan_get_type (void); #define HB_GOBJECT_TYPE_SHAPE_PLAN (hb_gobject_shape_plan_get_type ()) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter-private.hh new file mode 100644 index 00000000000..410a50f94dc --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter-private.hh @@ -0,0 +1,149 @@ +/* + * 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_ITER_PRIVATE_HH +#define HB_ITER_PRIVATE_HH + +#include "hb-private.hh" + + +/* Unified iterator object. + * + * The goal of this template is to make the same iterator interface + * available to all types, and make it very easy and compact to use. + * Iterator objects are small, light-weight, objects that can be + * copied by value. If the collection / object being iterated on + * is writable, then the iterator points to lvalues, otherwise it + * returns rvalues. + * + * The way to declare, initialize, and use iterators, eg.: + * + * Iter s (src); + * Iter t (dst); + * for (; s && t; s++, t++) + * *s = *t; + */ + +template +struct Iter; + +#if 0 +template +struct Iter +{ + explicit inline Iter (const T &c); +}; +#endif + +template +struct Iter +{ + /* Type of items. */ + typedef T Value; + + /* Constructors. */ + inline Iter (T *array_, int length_) : + array (array_), length (MAX (length_, 0)) {} + template + explicit inline Iter (T (&array_)[length_]) : + array (array_), length (length_) {} + + /* Emptiness. */ + inline operator bool (void) const { return bool (length); } + + /* Current item. */ + inline T &operator * (void) + { + if (unlikely (!length)) return CrapOrNull(T); + return *array; + } + inline T &operator -> (void) + { + return (operator *); + } + + /* Next. */ + inline Iter & operator ++ (void) + { + if (unlikely (!length)) return *this; + array++; + length--; + return *this; + } + /* Might return void, or a copy of pre-increment iterator. */ + inline void operator ++ (int) + { + if (unlikely (!length)) return; + array++; + length--; + } + + /* Some iterators might implement len(). */ + inline unsigned int len (void) const { return length; } + + /* Some iterators might implement fast-forward. + * Only implement it if it's constant-time. */ + inline void operator += (unsigned int n) + { + n = MIN (n, length); + array += n; + length -= n; + } + + /* Some iterators might implement random-access. + * Only implement it if it's constant-time. */ + inline Iter & operator [] (unsigned int i) + { + if (unlikely (i >= length)) return CrapOrNull(T); + return array[i]; + } + + private: + T *array; + unsigned int length; +}; + +/* XXX Remove + * Just to test these compile. */ +static inline void +m (void) +{ + const int src[10] = {}; + int dst[20]; + + Iter s (src); + Iter s2 (src, 5); + Iter t (dst); + + s2 = s; + + for (; s && t; ++s, ++t) + { + *t = *s; + } +} + +#endif /* HB_ITER_PRIVATE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery-private.hh new file mode 100644 index 00000000000..ff56b1dc9bb --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery-private.hh @@ -0,0 +1,696 @@ +/* + * Copyright © 2007,2008,2009,2010 Red Hat, Inc. + * Copyright © 2012,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. + * + * Red Hat Author(s): Behdad Esfahbod + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_MACHINERY_PRIVATE_HH +#define HB_MACHINERY_PRIVATE_HH + +#include "hb-private.hh" +#include "hb-iter-private.hh" + + +namespace OT { + + +/* + * Casts + */ + +/* Cast to struct T, reference to reference */ +template +static inline const Type& CastR(const TObject &X) +{ return reinterpret_cast (X); } +template +static inline Type& CastR(TObject &X) +{ return reinterpret_cast (X); } + +/* Cast to struct T, pointer to pointer */ +template +static inline const Type* CastP(const TObject *X) +{ return reinterpret_cast (X); } +template +static inline Type* CastP(TObject *X) +{ return reinterpret_cast (X); } + +/* StructAtOffset(P,Ofs) returns the struct T& that is placed at memory + * location pointed to by P plus Ofs bytes. */ +template +static inline const Type& StructAtOffset(const void *P, unsigned int offset) +{ return * reinterpret_cast ((const char *) P + offset); } +template +static inline Type& StructAtOffset(void *P, unsigned int offset) +{ return * reinterpret_cast ((char *) P + offset); } + +/* StructAfter(X) returns the struct T& that is placed after X. + * Works with X of variable size also. X must implement get_size() */ +template +static inline const Type& StructAfter(const TObject &X) +{ return StructAtOffset(&X, X.get_size()); } +template +static inline Type& StructAfter(TObject &X) +{ return StructAtOffset(&X, X.get_size()); } + + +/* + * Size checking + */ + +/* 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. */ \ + } +# define _DEFINE_INSTANCE_ASSERTION0(_line, _assertion) _DEFINE_INSTANCE_ASSERTION1 (_line, _assertion) +# define DEFINE_INSTANCE_ASSERTION(_assertion) _DEFINE_INSTANCE_ASSERTION0 (__LINE__, _assertion) + +/* Check that _code compiles in a method environment */ +#define _DEFINE_COMPILES_ASSERTION1(_line, _code) \ + inline void _compiles_assertion_on_line_##_line (void) const \ + { _code; } +# define _DEFINE_COMPILES_ASSERTION0(_line, _code) _DEFINE_COMPILES_ASSERTION1 (_line, _code) +# define DEFINE_COMPILES_ASSERTION(_code) _DEFINE_COMPILES_ASSERTION0 (__LINE__, _code) + + +#define DEFINE_SIZE_STATIC(size) \ + DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size)); \ + static const unsigned int static_size = (size); \ + static const unsigned int min_size = (size); \ + inline unsigned int get_size (void) const { return (size); } + +#define DEFINE_SIZE_UNION(size, _member) \ + 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)); \ + static const unsigned int min_size = (size) + +#define DEFINE_SIZE_ARRAY(size, array) \ + DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (array[0])); \ + DEFINE_COMPILES_ASSERTION ((void) array[0].static_size) \ + static const unsigned int min_size = (size) + +#define DEFINE_SIZE_ARRAY2(size, array1, array2) \ + 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) + + +/* + * Dispatch + */ + +template +struct hb_dispatch_context_t +{ + static const unsigned int max_debug_depth = MaxDebugDepth; + typedef Return return_t; + template + inline bool may_dispatch (const T *obj, const F *format) { return true; } + static return_t no_dispatch_return_value (void) { return Context::default_return_value (); } +}; + + +/* + * Sanitize + */ + +/* This limits sanitizing time on really broken fonts. */ +#ifndef HB_SANITIZE_MAX_EDITS +#define HB_SANITIZE_MAX_EDITS 32 +#endif +#ifndef HB_SANITIZE_MAX_OPS_FACTOR +#define HB_SANITIZE_MAX_OPS_FACTOR 8 +#endif +#ifndef HB_SANITIZE_MAX_OPS_MIN +#define HB_SANITIZE_MAX_OPS_MIN 16384 +#endif + +struct hb_sanitize_context_t : + hb_dispatch_context_t +{ + inline hb_sanitize_context_t (void) : + debug_depth (0), + start (nullptr), end (nullptr), + writable (false), edit_count (0), max_ops (0), + blob (nullptr), + num_glyphs (65536), + num_glyphs_set (false) {} + + inline const char *get_name (void) { return "SANITIZE"; } + template + inline bool may_dispatch (const T *obj, const F *format) + { return format->sanitize (this); } + template + inline return_t dispatch (const T &obj) { return obj.sanitize (this); } + static return_t default_return_value (void) { return true; } + static return_t no_dispatch_return_value (void) { return false; } + bool stop_sublookup_iteration (const return_t r) const { return !r; } + + inline void init (hb_blob_t *b) + { + this->blob = hb_blob_reference (b); + this->writable = false; + } + + inline void set_num_glyphs (unsigned int num_glyphs_) + { + num_glyphs = num_glyphs_; + num_glyphs_set = true; + } + inline unsigned int get_num_glyphs (void) { return num_glyphs; } + + inline void start_processing (void) + { + this->start = hb_blob_get_data (this->blob, nullptr); + this->end = this->start + this->blob->length; + assert (this->start <= this->end); /* Must not overflow. */ + this->max_ops = MAX ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR, + (unsigned) HB_SANITIZE_MAX_OPS_MIN); + this->edit_count = 0; + this->debug_depth = 0; + + DEBUG_MSG_LEVEL (SANITIZE, start, 0, +1, + "start [%p..%p] (%lu bytes)", + this->start, this->end, + (unsigned long) (this->end - this->start)); + } + + inline void end_processing (void) + { + DEBUG_MSG_LEVEL (SANITIZE, this->start, 0, -1, + "end [%p..%p] %u edit requests", + this->start, this->end, this->edit_count); + + hb_blob_destroy (this->blob); + this->blob = nullptr; + this->start = this->end = nullptr; + } + + inline bool check_range (const void *base, unsigned int len) const + { + const char *p = (const char *) base; + bool ok = this->max_ops-- > 0 && + this->start <= p && + p <= this->end && + (unsigned int) (this->end - p) >= len; + + DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0, + "check_range [%p..%p] (%d bytes) in [%p..%p] -> %s", + p, p + len, len, + this->start, this->end, + ok ? "OK" : "OUT-OF-RANGE"); + + return likely (ok); + } + + inline bool check_array (const void *base, unsigned int record_size, unsigned int len) const + { + const char *p = (const char *) base; + bool overflows = hb_unsigned_mul_overflows (len, record_size); + unsigned int array_size = record_size * len; + bool ok = !overflows && this->check_range (base, array_size); + + DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0, + "check_array [%p..%p] (%d*%d=%d bytes) in [%p..%p] -> %s", + p, p + (record_size * len), record_size, len, (unsigned int) array_size, + this->start, this->end, + overflows ? "OVERFLOWS" : ok ? "OK" : "OUT-OF-RANGE"); + + return likely (ok); + } + + template + inline bool check_struct (const Type *obj) const + { + return likely (this->check_range (obj, obj->min_size)); + } + + inline bool may_edit (const void *base, unsigned int len) + { + if (this->edit_count >= HB_SANITIZE_MAX_EDITS) + return false; + + const char *p = (const char *) base; + this->edit_count++; + + DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0, + "may_edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s", + this->edit_count, + p, p + len, len, + this->start, this->end, + this->writable ? "GRANTED" : "DENIED"); + + return this->writable; + } + + template + inline bool try_set (const Type *obj, const ValueType &v) { + if (this->may_edit (obj, obj->static_size)) { + const_cast (obj)->set (v); + return true; + } + return false; + } + + template + inline hb_blob_t *sanitize_blob (hb_blob_t *blob) + { + bool sane; + + init (blob); + + retry: + DEBUG_MSG_FUNC (SANITIZE, start, "start"); + + start_processing (); + + if (unlikely (!start)) + { + end_processing (); + return blob; + } + + Type *t = CastP (const_cast (start)); + + sane = t->sanitize (this); + if (sane) + { + if (edit_count) + { + DEBUG_MSG_FUNC (SANITIZE, start, "passed first round with %d edits; going for second round", edit_count); + + /* sanitize again to ensure no toe-stepping */ + edit_count = 0; + sane = t->sanitize (this); + if (edit_count) { + DEBUG_MSG_FUNC (SANITIZE, start, "requested %d edits in second round; FAILLING", edit_count); + sane = false; + } + } + } + else + { + if (edit_count && !writable) { + start = hb_blob_get_data_writable (blob, nullptr); + end = start + blob->length; + + if (start) + { + writable = true; + /* ok, we made it writable by relocating. try again */ + DEBUG_MSG_FUNC (SANITIZE, start, "retry"); + goto retry; + } + } + } + + end_processing (); + + DEBUG_MSG_FUNC (SANITIZE, start, sane ? "PASSED" : "FAILED"); + if (sane) + { + blob->lock (); + return blob; + } + else + { + hb_blob_destroy (blob); + return hb_blob_get_empty (); + } + } + + template + inline hb_blob_t *reference_table (const hb_face_t *face, hb_tag_t tableTag = Type::tableTag) + { + if (!num_glyphs_set) + set_num_glyphs (face->get_num_glyphs ()); + return sanitize_blob (face->reference_table (tableTag)); + } + + mutable unsigned int debug_depth; + const char *start, *end; + private: + bool writable; + unsigned int edit_count; + mutable int max_ops; + hb_blob_t *blob; + unsigned int num_glyphs; + bool num_glyphs_set; +}; + + +/* + * Serialize + */ + +struct hb_serialize_context_t +{ + inline hb_serialize_context_t (void *start_, unsigned int size) + { + this->start = (char *) start_; + this->end = this->start + size; + + this->ran_out_of_room = false; + this->head = this->start; + this->debug_depth = 0; + } + + template + inline Type *start_serialize (void) + { + DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, +1, + "start [%p..%p] (%lu bytes)", + this->start, this->end, + (unsigned long) (this->end - this->start)); + + return start_embed (); + } + + inline void end_serialize (void) + { + DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, -1, + "end [%p..%p] serialized %d bytes; %s", + this->start, this->end, + (int) (this->head - this->start), + this->ran_out_of_room ? "RAN OUT OF ROOM" : "did not ran out of room"); + } + + template + inline Type *copy (void) + { + assert (!this->ran_out_of_room); + unsigned int len = this->head - this->start; + void *p = malloc (len); + if (p) + memcpy (p, this->start, len); + return reinterpret_cast (p); + } + + template + inline Type *allocate_size (unsigned int size) + { + if (unlikely (this->ran_out_of_room || this->end - this->head < ptrdiff_t (size))) { + this->ran_out_of_room = true; + return nullptr; + } + memset (this->head, 0, size); + char *ret = this->head; + this->head += size; + return reinterpret_cast (ret); + } + + template + inline Type *allocate_min (void) + { + return this->allocate_size (Type::min_size); + } + + template + inline Type *start_embed (void) + { + Type *ret = reinterpret_cast (this->head); + return ret; + } + + template + inline Type *embed (const Type &obj) + { + unsigned int size = obj.get_size (); + Type *ret = this->allocate_size (size); + if (unlikely (!ret)) return nullptr; + memcpy (ret, obj, size); + return ret; + } + + template + inline Type *extend_min (Type &obj) + { + unsigned int size = obj.min_size; + assert (this->start <= (char *) &obj && (char *) &obj <= this->head && (char *) &obj + size >= this->head); + if (unlikely (!this->allocate_size (((char *) &obj) + size - this->head))) return nullptr; + return reinterpret_cast (&obj); + } + + template + inline Type *extend (Type &obj) + { + unsigned int size = obj.get_size (); + assert (this->start < (char *) &obj && (char *) &obj <= this->head && (char *) &obj + size >= this->head); + if (unlikely (!this->allocate_size (((char *) &obj) + size - this->head))) return nullptr; + return reinterpret_cast (&obj); + } + + unsigned int debug_depth; + char *start, *end, *head; + bool ran_out_of_room; +}; + + +/* + * Supplier + */ + +template +struct Supplier +{ + inline Supplier (const Type *array, unsigned int len_, unsigned int stride_=sizeof(Type)) + { + head = array; + len = len_; + stride = stride_; + } + inline const Type operator [] (unsigned int i) const + { + if (unlikely (i >= len)) return Type (); + return * (const Type *) (const void *) ((const char *) head + stride * i); + } + + inline Supplier & operator += (unsigned int count) + { + if (unlikely (count > len)) + count = len; + len -= count; + head = (const Type *) (const void *) ((const char *) head + stride * count); + return *this; + } + + private: + inline Supplier (const Supplier &); /* Disallow copy */ + inline Supplier& operator= (const Supplier &); /* Disallow copy */ + + unsigned int len; + unsigned int stride; + const Type *head; +}; + + +/* + * Big-endian integers. + */ + +template struct BEInt; + +template +struct BEInt +{ + public: + inline void set (Type V) + { + v = V; + } + inline operator Type (void) const + { + return v; + } + private: uint8_t v; +}; +template +struct BEInt +{ + public: + inline void set (Type V) + { + v[0] = (V >> 8) & 0xFF; + v[1] = (V ) & 0xFF; + } + inline operator Type (void) const + { + return (v[0] << 8) + + (v[1] ); + } + private: uint8_t v[2]; +}; +template +struct BEInt +{ + public: + inline void set (Type V) + { + v[0] = (V >> 16) & 0xFF; + v[1] = (V >> 8) & 0xFF; + v[2] = (V ) & 0xFF; + } + inline operator Type (void) const + { + return (v[0] << 16) + + (v[1] << 8) + + (v[2] ); + } + private: uint8_t v[3]; +}; +template +struct BEInt +{ + public: + inline void set (Type V) + { + v[0] = (V >> 24) & 0xFF; + v[1] = (V >> 16) & 0xFF; + v[2] = (V >> 8) & 0xFF; + v[3] = (V ) & 0xFF; + } + inline operator Type (void) const + { + return (v[0] << 24) + + (v[1] << 16) + + (v[2] << 8) + + (v[3] ); + } + private: uint8_t v[4]; +}; + + +/* + * Lazy struct and blob loaders. + */ + +/* Logic is shared between hb_lazy_loader_t and hb_table_lazy_loader_t */ +template +struct hb_lazy_loader_t +{ + inline void init (hb_face_t *face_) + { + face = face_; + instance = nullptr; + } + + inline void fini (void) + { + if (instance && instance != &Null(T)) + { + instance->fini(); + free (instance); + } + } + + inline const T* get (void) const + { + retry: + T *p = (T *) hb_atomic_ptr_get (&instance); + if (unlikely (!p)) + { + p = (T *) calloc (1, sizeof (T)); + if (unlikely (!p)) + p = const_cast (&Null(T)); + else + p->init (face); + if (unlikely (!hb_atomic_ptr_cmpexch (const_cast(&instance), nullptr, p))) + { + if (p != &Null(T)) + p->fini (); + goto retry; + } + } + return p; + } + + inline const T* operator-> (void) const + { + return get (); + } + + private: + hb_face_t *face; + mutable T *instance; +}; + +/* Logic is shared between hb_lazy_loader_t and hb_table_lazy_loader_t */ +template +struct hb_table_lazy_loader_t +{ + inline void init (hb_face_t *face_) + { + face = face_; + blob = nullptr; + } + + inline void fini (void) + { + hb_blob_destroy (blob); + } + + inline hb_blob_t* get_blob (void) const + { + retry: + hb_blob_t *b = (hb_blob_t *) hb_atomic_ptr_get (&blob); + if (unlikely (!b)) + { + b = OT::hb_sanitize_context_t().reference_table (face); + if (!hb_atomic_ptr_cmpexch (&blob, nullptr, b)) + { + hb_blob_destroy (b); + goto retry; + } + blob = b; + } + return b; + } + + inline const T* get (void) const + { + hb_blob_t *b = get_blob (); + return b->as (); + } + + inline const T* operator-> (void) const + { + return get(); + } + + private: + hb_face_t *face; + mutable hb_blob_t *blob; +}; + + +} /* namespace OT */ + + +#endif /* HB_MACHINERY_PRIVATE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.cc index e3ddae41336..138a85612fc 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.cc @@ -157,8 +157,6 @@ hb_map_allocation_successful (const hb_map_t *map) * * * - * Return value: - * * Since: 1.7.7 **/ void @@ -188,7 +186,7 @@ hb_map_get (const hb_map_t *map, /** * hb_map_del: * @map: a map. - * @codepoint: + * @key: * * * @@ -204,7 +202,7 @@ hb_map_del (hb_map_t *map, /** * hb_map_has: * @map: a map. - * @codepoint: + * @key: * * * diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object-private.hh index 8199c4b8407..36d27a8913e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object-private.hh @@ -47,14 +47,14 @@ struct hb_reference_count_t { hb_atomic_int_t ref_count; - inline void init (int v) { ref_count.set_unsafe (v); } - inline int get_unsafe (void) const { return ref_count.get_unsafe (); } + inline void init (int v) { ref_count.set_relaxed (v); } + inline int get_relaxed (void) const { return ref_count.get_relaxed (); } inline int inc (void) { return ref_count.inc (); } inline int dec (void) { return ref_count.dec (); } - inline void fini (void) { ref_count.set_unsafe (HB_REFERENCE_COUNT_POISON_VALUE); } + inline void fini (void) { ref_count.set_relaxed (HB_REFERENCE_COUNT_POISON_VALUE); } - inline bool is_inert (void) const { return ref_count.get_unsafe () == HB_REFERENCE_COUNT_INERT_VALUE; } - inline bool is_valid (void) const { return ref_count.get_unsafe () > 0; } + inline bool is_inert (void) const { return ref_count.get_relaxed () == HB_REFERENCE_COUNT_INERT_VALUE; } + inline bool is_valid (void) const { return ref_count.get_relaxed () > 0; } }; @@ -111,7 +111,7 @@ static inline void hb_object_trace (const Type *obj, const char *function) DEBUG_MSG (OBJECT, (void *) obj, "%s refcount=%d", function, - obj ? obj->header.ref_count.get_unsafe () : 0); + obj ? obj->header.ref_count.get_relaxed () : 0); } template diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file-private.hh index 226c48f6a32..d47bff66e78 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file-private.hh @@ -484,8 +484,6 @@ struct ResourceForkHeader struct OpenTypeFontFile { - static const hb_tag_t tableTag = HB_TAG ('_','_','_','_'); /* Sanitizer needs this. */ - enum { CFFTag = HB_TAG ('O','T','T','O'), /* OpenType with Postscript outlines */ TrueTypeTag = HB_TAG ( 0 , 1 , 0 , 0 ), /* OpenType with TrueType outlines */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type-private.hh index f6113c33aaf..bae2eed81a6 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type-private.hh @@ -32,484 +32,12 @@ #include "hb-private.hh" #include "hb-blob-private.hh" #include "hb-face-private.hh" +#include "hb-machinery-private.hh" namespace OT { - -/* - * Casts - */ - -/* Cast to struct T, reference to reference */ -template -static inline const Type& CastR(const TObject &X) -{ return reinterpret_cast (X); } -template -static inline Type& CastR(TObject &X) -{ return reinterpret_cast (X); } - -/* Cast to struct T, pointer to pointer */ -template -static inline const Type* CastP(const TObject *X) -{ return reinterpret_cast (X); } -template -static inline Type* CastP(TObject *X) -{ return reinterpret_cast (X); } - -/* StructAtOffset(P,Ofs) returns the struct T& that is placed at memory - * location pointed to by P plus Ofs bytes. */ -template -static inline const Type& StructAtOffset(const void *P, unsigned int offset) -{ return * reinterpret_cast ((const char *) P + offset); } -template -static inline Type& StructAtOffset(void *P, unsigned int offset) -{ return * reinterpret_cast ((char *) P + offset); } - -/* StructAfter(X) returns the struct T& that is placed after X. - * Works with X of variable size also. X must implement get_size() */ -template -static inline const Type& StructAfter(const TObject &X) -{ return StructAtOffset(&X, X.get_size()); } -template -static inline Type& StructAfter(TObject &X) -{ return StructAtOffset(&X, X.get_size()); } - - - -/* - * Size checking - */ - -/* 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. */ \ - } -# define _DEFINE_INSTANCE_ASSERTION0(_line, _assertion) _DEFINE_INSTANCE_ASSERTION1 (_line, _assertion) -# define DEFINE_INSTANCE_ASSERTION(_assertion) _DEFINE_INSTANCE_ASSERTION0 (__LINE__, _assertion) - -/* Check that _code compiles in a method environment */ -#define _DEFINE_COMPILES_ASSERTION1(_line, _code) \ - inline void _compiles_assertion_on_line_##_line (void) const \ - { _code; } -# define _DEFINE_COMPILES_ASSERTION0(_line, _code) _DEFINE_COMPILES_ASSERTION1 (_line, _code) -# define DEFINE_COMPILES_ASSERTION(_code) _DEFINE_COMPILES_ASSERTION0 (__LINE__, _code) - - -#define DEFINE_SIZE_STATIC(size) \ - DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size)); \ - static const unsigned int static_size = (size); \ - static const unsigned int min_size = (size); \ - inline unsigned int get_size (void) const { return (size); } - -#define DEFINE_SIZE_UNION(size, _member) \ - 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)); \ - static const unsigned int min_size = (size) - -#define DEFINE_SIZE_ARRAY(size, array) \ - DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (array[0])); \ - DEFINE_COMPILES_ASSERTION ((void) array[0].static_size) \ - static const unsigned int min_size = (size) - -#define DEFINE_SIZE_ARRAY2(size, array1, array2) \ - 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) - - - -/* - * Dispatch - */ - -template -struct hb_dispatch_context_t -{ - static const unsigned int max_debug_depth = MaxDebugDepth; - typedef Return return_t; - template - inline bool may_dispatch (const T *obj, const F *format) { return true; } - static return_t no_dispatch_return_value (void) { return Context::default_return_value (); } -}; - - -/* - * Sanitize - */ - -/* This limits sanitizing time on really broken fonts. */ -#ifndef HB_SANITIZE_MAX_EDITS -#define HB_SANITIZE_MAX_EDITS 32 -#endif -#ifndef HB_SANITIZE_MAX_OPS_FACTOR -#define HB_SANITIZE_MAX_OPS_FACTOR 8 -#endif -#ifndef HB_SANITIZE_MAX_OPS_MIN -#define HB_SANITIZE_MAX_OPS_MIN 16384 -#endif - -struct hb_sanitize_context_t : - hb_dispatch_context_t -{ - inline hb_sanitize_context_t (void) : - debug_depth (0), - start (nullptr), end (nullptr), - writable (false), edit_count (0), max_ops (0), - blob (nullptr), - num_glyphs (0) {} - - inline const char *get_name (void) { return "SANITIZE"; } - template - inline bool may_dispatch (const T *obj, const F *format) - { return format->sanitize (this); } - template - inline return_t dispatch (const T &obj) { return obj.sanitize (this); } - static return_t default_return_value (void) { return true; } - static return_t no_dispatch_return_value (void) { return false; } - bool stop_sublookup_iteration (const return_t r) const { return !r; } - - inline void init (hb_blob_t *b) - { - this->blob = hb_blob_reference (b); - this->writable = false; - } - - inline void start_processing (void) - { - this->start = hb_blob_get_data (this->blob, nullptr); - this->end = this->start + this->blob->length; - assert (this->start <= this->end); /* Must not overflow. */ - this->max_ops = MAX ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR, - (unsigned) HB_SANITIZE_MAX_OPS_MIN); - this->edit_count = 0; - this->debug_depth = 0; - - DEBUG_MSG_LEVEL (SANITIZE, start, 0, +1, - "start [%p..%p] (%lu bytes)", - this->start, this->end, - (unsigned long) (this->end - this->start)); - } - - inline void end_processing (void) - { - DEBUG_MSG_LEVEL (SANITIZE, this->start, 0, -1, - "end [%p..%p] %u edit requests", - this->start, this->end, this->edit_count); - - hb_blob_destroy (this->blob); - this->blob = nullptr; - this->start = this->end = nullptr; - } - - inline bool check_range (const void *base, unsigned int len) const - { - const char *p = (const char *) base; - bool ok = this->max_ops-- > 0 && - this->start <= p && - p <= this->end && - (unsigned int) (this->end - p) >= len; - - DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0, - "check_range [%p..%p] (%d bytes) in [%p..%p] -> %s", - p, p + len, len, - this->start, this->end, - ok ? "OK" : "OUT-OF-RANGE"); - - return likely (ok); - } - - inline bool check_array (const void *base, unsigned int record_size, unsigned int len) const - { - const char *p = (const char *) base; - bool overflows = hb_unsigned_mul_overflows (len, record_size); - unsigned int array_size = record_size * len; - bool ok = !overflows && this->check_range (base, array_size); - - DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0, - "check_array [%p..%p] (%d*%d=%d bytes) in [%p..%p] -> %s", - p, p + (record_size * len), record_size, len, (unsigned int) array_size, - this->start, this->end, - overflows ? "OVERFLOWS" : ok ? "OK" : "OUT-OF-RANGE"); - - return likely (ok); - } - - template - inline bool check_struct (const Type *obj) const - { - return likely (this->check_range (obj, obj->min_size)); - } - - inline bool may_edit (const void *base, unsigned int len) - { - if (this->edit_count >= HB_SANITIZE_MAX_EDITS) - return false; - - const char *p = (const char *) base; - this->edit_count++; - - DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0, - "may_edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s", - this->edit_count, - p, p + len, len, - this->start, this->end, - this->writable ? "GRANTED" : "DENIED"); - - return this->writable; - } - - template - inline bool try_set (const Type *obj, const ValueType &v) { - if (this->may_edit (obj, obj->static_size)) { - const_cast (obj)->set (v); - return true; - } - return false; - } - - mutable unsigned int debug_depth; - const char *start, *end; - bool writable; - unsigned int edit_count; - mutable int max_ops; - hb_blob_t *blob; - unsigned int num_glyphs; -}; - - - -/* Template to sanitize an object. */ -template -struct Sanitizer -{ - inline Sanitizer (void) {} - - inline hb_blob_t *sanitize (hb_blob_t *blob) { - bool sane; - - /* TODO is_sane() stuff */ - - c->init (blob); - - retry: - DEBUG_MSG_FUNC (SANITIZE, c->start, "start"); - - c->start_processing (); - - if (unlikely (!c->start)) { - c->end_processing (); - return blob; - } - - Type *t = CastP (const_cast (c->start)); - - sane = t->sanitize (c); - if (sane) { - if (c->edit_count) { - DEBUG_MSG_FUNC (SANITIZE, c->start, "passed first round with %d edits; going for second round", c->edit_count); - - /* sanitize again to ensure no toe-stepping */ - c->edit_count = 0; - sane = t->sanitize (c); - if (c->edit_count) { - DEBUG_MSG_FUNC (SANITIZE, c->start, "requested %d edits in second round; FAILLING", c->edit_count); - sane = false; - } - } - } else { - unsigned int edit_count = c->edit_count; - if (edit_count && !c->writable) { - c->start = hb_blob_get_data_writable (blob, nullptr); - c->end = c->start + blob->length; - - if (c->start) { - c->writable = true; - /* ok, we made it writable by relocating. try again */ - DEBUG_MSG_FUNC (SANITIZE, c->start, "retry"); - goto retry; - } - } - } - - c->end_processing (); - - DEBUG_MSG_FUNC (SANITIZE, c->start, sane ? "PASSED" : "FAILED"); - if (sane) - { - blob->lock (); - return blob; - } - else - { - hb_blob_destroy (blob); - return hb_blob_get_empty (); - } - } - - inline void set_num_glyphs (unsigned int num_glyphs) { c->num_glyphs = num_glyphs; } - - private: - hb_sanitize_context_t c[1]; -}; - - - -/* - * Serialize - */ - - -struct hb_serialize_context_t -{ - inline hb_serialize_context_t (void *start_, unsigned int size) - { - this->start = (char *) start_; - this->end = this->start + size; - - this->ran_out_of_room = false; - this->head = this->start; - this->debug_depth = 0; - } - - template - inline Type *start_serialize (void) - { - DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, +1, - "start [%p..%p] (%lu bytes)", - this->start, this->end, - (unsigned long) (this->end - this->start)); - - return start_embed (); - } - - inline void end_serialize (void) - { - DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, -1, - "end [%p..%p] serialized %d bytes; %s", - this->start, this->end, - (int) (this->head - this->start), - this->ran_out_of_room ? "RAN OUT OF ROOM" : "did not ran out of room"); - - } - - template - inline Type *copy (void) - { - assert (!this->ran_out_of_room); - unsigned int len = this->head - this->start; - void *p = malloc (len); - if (p) - memcpy (p, this->start, len); - return reinterpret_cast (p); - } - - template - inline Type *allocate_size (unsigned int size) - { - if (unlikely (this->ran_out_of_room || this->end - this->head < ptrdiff_t (size))) { - this->ran_out_of_room = true; - return nullptr; - } - memset (this->head, 0, size); - char *ret = this->head; - this->head += size; - return reinterpret_cast (ret); - } - - template - inline Type *allocate_min (void) - { - return this->allocate_size (Type::min_size); - } - - template - inline Type *start_embed (void) - { - Type *ret = reinterpret_cast (this->head); - return ret; - } - - template - inline Type *embed (const Type &obj) - { - unsigned int size = obj.get_size (); - Type *ret = this->allocate_size (size); - if (unlikely (!ret)) return nullptr; - memcpy (ret, obj, size); - return ret; - } - - template - inline Type *extend_min (Type &obj) - { - unsigned int size = obj.min_size; - assert (this->start <= (char *) &obj && (char *) &obj <= this->head && (char *) &obj + size >= this->head); - if (unlikely (!this->allocate_size (((char *) &obj) + size - this->head))) return nullptr; - return reinterpret_cast (&obj); - } - - template - inline Type *extend (Type &obj) - { - unsigned int size = obj.get_size (); - assert (this->start < (char *) &obj && (char *) &obj <= this->head && (char *) &obj + size >= this->head); - if (unlikely (!this->allocate_size (((char *) &obj) + size - this->head))) return nullptr; - return reinterpret_cast (&obj); - } - - inline void truncate (void *new_head) - { - assert (this->start < new_head && new_head <= this->head); - this->head = (char *) new_head; - } - - unsigned int debug_depth; - char *start, *end, *head; - bool ran_out_of_room; -}; - -template -struct Supplier -{ - inline Supplier (const Type *array, unsigned int len_, unsigned int stride_=sizeof(Type)) - { - head = array; - len = len_; - stride = stride_; - } - inline const Type operator [] (unsigned int i) const - { - if (unlikely (i >= len)) return Type (); - return * (const Type *) (const void *) ((const char *) head + stride * i); - } - - inline Supplier & operator += (unsigned int count) - { - if (unlikely (count > len)) - count = len; - len -= count; - head = (const Type *) (const void *) ((const char *) head + stride * count); - return *this; - } - - private: - inline Supplier (const Supplier &); /* Disallow copy */ - inline Supplier& operator= (const Supplier &); /* Disallow copy */ - - unsigned int len; - unsigned int stride; - const Type *head; -}; - - /* * * The OpenType Font File: Data Types @@ -523,78 +51,6 @@ struct Supplier * Int types */ - -template struct BEInt; - -template -struct BEInt -{ - public: - inline void set (Type V) - { - v = V; - } - inline operator Type (void) const - { - return v; - } - private: uint8_t v; -}; -template -struct BEInt -{ - public: - inline void set (Type V) - { - v[0] = (V >> 8) & 0xFF; - v[1] = (V ) & 0xFF; - } - inline operator Type (void) const - { - return (v[0] << 8) - + (v[1] ); - } - private: uint8_t v[2]; -}; -template -struct BEInt -{ - public: - inline void set (Type V) - { - v[0] = (V >> 16) & 0xFF; - v[1] = (V >> 8) & 0xFF; - v[2] = (V ) & 0xFF; - } - inline operator Type (void) const - { - return (v[0] << 16) - + (v[1] << 8) - + (v[2] ); - } - private: uint8_t v[3]; -}; -template -struct BEInt -{ - public: - inline void set (Type V) - { - v[0] = (V >> 24) & 0xFF; - v[1] = (V >> 16) & 0xFF; - v[2] = (V >> 8) & 0xFF; - v[3] = (V ) & 0xFF; - } - inline operator Type (void) const - { - return (v[0] << 24) - + (v[1] << 16) - + (v[2] << 8) - + (v[3] ); - } - private: uint8_t v[4]; -}; - /* Integer types in big-endian order and no alignment requirement */ template struct IntType @@ -765,7 +221,6 @@ struct FixedVersion }; - /* * Template subclasses of Offset that do the dereferencing. * Use: (base+offset) @@ -831,7 +286,6 @@ static inline Type& operator + (Base &base, OffsetTo &offset) * Array Types */ - /* TODO Use it in ArrayOf, HeadlessArrayOf, and other places around the code base?? */ template struct UnsizedArrayOf @@ -913,7 +367,6 @@ struct UnsizedOffsetListOf : UnsizedOffsetArrayOf } }; - /* An array with a number of elements. */ template struct ArrayOf @@ -1066,7 +519,6 @@ struct OffsetListOf : OffsetArrayOf } }; - /* An array starting at second element. */ template struct HeadlessArrayOf @@ -1131,10 +583,7 @@ struct HeadlessArrayOf DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ); }; - -/* - * An array with sorted elements. Supports binary searching. - */ +/* An array with sorted elements. Supports binary searching. */ template struct SortedArrayOf : ArrayOf { @@ -1159,10 +608,7 @@ struct SortedArrayOf : ArrayOf } }; -/* - * Binary-search arrays - */ - +/* Binary-search arrays */ struct BinSearchHeader { inline operator uint32_t (void) const { return len; } @@ -1198,101 +644,6 @@ template struct BinSearchArrayOf : SortedArrayOf {}; -/* Lazy struct and blob loaders. */ - -/* Logic is shared between hb_lazy_loader_t and hb_table_lazy_loader_t */ -template -struct hb_lazy_loader_t -{ - inline void init (hb_face_t *face_) - { - face = face_; - instance = nullptr; - } - - inline void fini (void) - { - if (instance && instance != &Null(T)) - { - instance->fini(); - free (instance); - } - } - - inline const T* get (void) const - { - retry: - T *p = (T *) hb_atomic_ptr_get (&instance); - if (unlikely (!p)) - { - p = (T *) calloc (1, sizeof (T)); - if (unlikely (!p)) - p = const_cast (&Null(T)); - else - p->init (face); - if (unlikely (!hb_atomic_ptr_cmpexch (const_cast(&instance), nullptr, p))) - { - if (p != &Null(T)) - p->fini (); - goto retry; - } - } - return p; - } - - inline const T* operator-> (void) const - { - return get (); - } - - private: - hb_face_t *face; - mutable T *instance; -}; - -/* Logic is shared between hb_lazy_loader_t and hb_table_lazy_loader_t */ -template -struct hb_table_lazy_loader_t -{ - inline void init (hb_face_t *face_) - { - face = face_; - blob = nullptr; - } - - inline void fini (void) - { - hb_blob_destroy (blob); - } - - inline const T* get (void) const - { - retry: - hb_blob_t *blob_ = (hb_blob_t *) hb_atomic_ptr_get (&blob); - if (unlikely (!blob_)) - { - blob_ = OT::Sanitizer().sanitize (face->reference_table (T::tableTag)); - if (!hb_atomic_ptr_cmpexch (&blob, nullptr, blob_)) - { - hb_blob_destroy (blob_); - goto retry; - } - blob = blob_; - } - return blob_->as (); - } - - inline const T* operator-> (void) const - { - return get(); - } - - private: - hb_face_t *face; - mutable hb_blob_t *blob; -}; - - } /* namespace OT */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh index 0ea37209a5a..67a9c7dd96b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh @@ -37,6 +37,9 @@ */ #define HB_OT_TAG_cmap HB_TAG('c','m','a','p') +#ifndef HB_MAX_UNICODE_CODEPOINT_VALUE +#define HB_MAX_UNICODE_CODEPOINT_VALUE 0x10FFFF +#endif namespace OT { @@ -437,8 +440,10 @@ struct CmapSubtableLongSegmented { for (unsigned int i = 0; i < this->groups.len; i++) { hb_set_add_range (out, - this->groups[i].startCharCode, - this->groups[i].endCharCode); + MIN ((unsigned int) this->groups[i].startCharCode, + (unsigned int) HB_MAX_UNICODE_CODEPOINT_VALUE), + MIN ((unsigned int) this->groups[i].endCharCode, + (unsigned int) HB_MAX_UNICODE_CODEPOINT_VALUE)); } } @@ -800,37 +805,37 @@ struct cmap { hb_serialize_context_t c (dest, dest_sz); - OT::cmap *cmap = c.start_serialize (); - if (unlikely (!c.extend_min (*cmap))) + cmap *table = c.start_serialize (); + if (unlikely (!c.extend_min (*table))) { return false; } - cmap->version.set (0); + table->version.set (0); - if (unlikely (!cmap->encodingRecord.serialize (&c, /* numTables */ 3))) + if (unlikely (!table->encodingRecord.serialize (&c, /* numTables */ 3))) return false; // TODO(grieger): Convert the below to a for loop // Format 4, Plat 0 Encoding Record - EncodingRecord &format4_plat0_rec = cmap->encodingRecord[0]; + EncodingRecord &format4_plat0_rec = table->encodingRecord[0]; format4_plat0_rec.platformID.set (0); // Unicode format4_plat0_rec.encodingID.set (3); // Format 4, Plat 3 Encoding Record - EncodingRecord &format4_plat3_rec = cmap->encodingRecord[1]; + EncodingRecord &format4_plat3_rec = table->encodingRecord[1]; format4_plat3_rec.platformID.set (3); // Windows format4_plat3_rec.encodingID.set (1); // Unicode BMP // Format 12 Encoding Record - EncodingRecord &format12_rec = cmap->encodingRecord[2]; + EncodingRecord &format12_rec = table->encodingRecord[2]; format12_rec.platformID.set (3); // Windows format12_rec.encodingID.set (10); // Unicode UCS-4 // Write out format 4 sub table { - CmapSubtable &subtable = format4_plat0_rec.subtable.serialize (&c, cmap); + CmapSubtable &subtable = format4_plat0_rec.subtable.serialize (&c, table); format4_plat3_rec.subtable.set (format4_plat0_rec.subtable); subtable.u.format.set (4); @@ -841,7 +846,7 @@ struct cmap // Write out format 12 sub table. { - CmapSubtable &subtable = format12_rec.subtable.serialize (&c, cmap); + CmapSubtable &subtable = format12_rec.subtable.serialize (&c, table); subtable.u.format.set (12); CmapSubtableFormat12 &format12 = subtable.u.format12; @@ -894,57 +899,57 @@ struct cmap { inline void init (hb_face_t *face) { - this->blob = OT::Sanitizer().sanitize (face->reference_table (HB_OT_TAG_cmap)); - const OT::cmap *cmap = this->blob->as (); - const OT::CmapSubtable *subtable = nullptr; - const OT::CmapSubtableFormat14 *subtable_uvs = nullptr; + this->blob = hb_sanitize_context_t().reference_table (face); + const cmap *table = this->blob->as (); + const CmapSubtable *subtable = nullptr; + const CmapSubtableFormat14 *subtable_uvs = nullptr; bool symbol = false; /* 32-bit subtables. */ - if (!subtable) subtable = cmap->find_subtable (3, 10); - if (!subtable) subtable = cmap->find_subtable (0, 6); - if (!subtable) subtable = cmap->find_subtable (0, 4); + if (!subtable) subtable = table->find_subtable (3, 10); + if (!subtable) subtable = table->find_subtable (0, 6); + if (!subtable) subtable = table->find_subtable (0, 4); /* 16-bit subtables. */ - if (!subtable) subtable = cmap->find_subtable (3, 1); - if (!subtable) subtable = cmap->find_subtable (0, 3); - if (!subtable) subtable = cmap->find_subtable (0, 2); - if (!subtable) subtable = cmap->find_subtable (0, 1); - if (!subtable) subtable = cmap->find_subtable (0, 0); + if (!subtable) subtable = table->find_subtable (3, 1); + if (!subtable) subtable = table->find_subtable (0, 3); + if (!subtable) subtable = table->find_subtable (0, 2); + if (!subtable) subtable = table->find_subtable (0, 1); + if (!subtable) subtable = table->find_subtable (0, 0); if (!subtable) { - subtable = cmap->find_subtable (3, 0); + subtable = table->find_subtable (3, 0); if (subtable) symbol = true; } /* Meh. */ - if (!subtable) subtable = &Null(OT::CmapSubtable); + if (!subtable) subtable = &Null(CmapSubtable); /* UVS subtable. */ if (!subtable_uvs) { - const OT::CmapSubtable *st = cmap->find_subtable (0, 5); + const CmapSubtable *st = table->find_subtable (0, 5); if (st && st->u.format == 14) subtable_uvs = &st->u.format14; } /* Meh. */ - if (!subtable_uvs) subtable_uvs = &Null(OT::CmapSubtableFormat14); + if (!subtable_uvs) subtable_uvs = &Null(CmapSubtableFormat14); this->uvs_table = subtable_uvs; this->get_glyph_data = subtable; if (unlikely (symbol)) { - this->get_glyph_func = get_glyph_from_symbol; + this->get_glyph_func = get_glyph_from_symbol; this->get_all_codepoints_func = null_get_all_codepoints_func; } else { switch (subtable->u.format) { /* Accelerate format 4 and format 12. */ default: - this->get_glyph_func = get_glyph_from; + this->get_glyph_func = get_glyph_from; this->get_all_codepoints_func = null_get_all_codepoints_func; break; case 12: - this->get_glyph_func = get_glyph_from; - this->get_all_codepoints_func = get_all_codepoints_from; + this->get_glyph_func = get_glyph_from; + this->get_all_codepoints_func = get_all_codepoints_from; break; case 4: { @@ -977,9 +982,9 @@ struct cmap variation_selector, glyph)) { - case OT::GLYPH_VARIANT_NOT_FOUND: return false; - case OT::GLYPH_VARIANT_FOUND: return true; - case OT::GLYPH_VARIANT_USE_DEFAULT: break; + case GLYPH_VARIANT_NOT_FOUND: return false; + case GLYPH_VARIANT_FOUND: return true; + case GLYPH_VARIANT_USE_DEFAULT: break; } return get_nominal_glyph (unicode, glyph); @@ -1046,9 +1051,9 @@ struct cmap const void *get_glyph_data; hb_cmap_get_all_codepoints_func_t get_all_codepoints_func; - OT::CmapSubtableFormat4::accelerator_t format4_accel; + CmapSubtableFormat4::accelerator_t format4_accel; - const OT::CmapSubtableFormat14 *uvs_table; + const CmapSubtableFormat14 *uvs_table; hb_blob_t *blob; }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh index d1dd9de4771..21c2f477366 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh @@ -394,8 +394,8 @@ struct CBDT { upem = hb_face_get_upem (face); - cblc_blob = Sanitizer().sanitize (face->reference_table (HB_OT_TAG_CBLC)); - cbdt_blob = Sanitizer().sanitize (face->reference_table (HB_OT_TAG_CBDT)); + cblc_blob = hb_sanitize_context_t().reference_table (face); + cbdt_blob = hb_sanitize_context_t().reference_table (face); cbdt_len = hb_blob_get_length (cbdt_blob); if (hb_blob_get_length (cblc_blob) == 0) { diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh index 09a9517c48d..0461afa3298 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh @@ -68,7 +68,7 @@ struct SBIXStrike { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && - imageOffsetsZ.sanitize_shallow (c, c->num_glyphs + 1)); + imageOffsetsZ.sanitize_shallow (c, c->get_num_glyphs () + 1)); } protected: @@ -96,14 +96,9 @@ struct sbix { inline void init (hb_face_t *face) { - num_glyphs = hb_face_get_glyph_count (face); - - OT::Sanitizer sanitizer; - sanitizer.set_num_glyphs (num_glyphs); - sbix_blob = sanitizer.sanitize (face->reference_table (HB_OT_TAG_sbix)); + sbix_blob = hb_sanitize_context_t().reference_table (face); sbix_len = hb_blob_get_length (sbix_blob); - sbix_table = sbix_blob->as (); - + sbix_table = sbix_blob->as (); } inline void fini (void) @@ -134,7 +129,6 @@ struct sbix unsigned int sbix_len; unsigned int num_glyphs; - }; protected: diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh index ed6cf970820..3976694f844 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh @@ -96,11 +96,9 @@ struct SVG { inline void init (hb_face_t *face) { - OT::Sanitizer sanitizer; - svg_blob = sanitizer.sanitize (face->reference_table (HB_OT_TAG_SVG)); + svg_blob = hb_sanitize_context_t().reference_table (face); svg_len = hb_blob_get_length (svg_blob); - svg = svg_blob->as (); - + svg = svg_blob->as (); } inline void fini (void) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh index 89c867dfa52..ce6ee1e22f7 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh @@ -103,14 +103,14 @@ struct glyf static bool _add_head_and_set_loca_version (hb_subset_plan_t *plan, bool use_short_loca) { - hb_blob_t *head_blob = OT::Sanitizer().sanitize (hb_face_reference_table (plan->source, HB_OT_TAG_head)); + hb_blob_t *head_blob = hb_sanitize_context_t().reference_table (plan->source); hb_blob_t *head_prime_blob = hb_blob_copy_writable_or_fail (head_blob); hb_blob_destroy (head_blob); if (unlikely (!head_prime_blob)) return false; - OT::head *head_prime = (OT::head *) hb_blob_get_data_writable (head_prime_blob, nullptr); + head *head_prime = (head *) hb_blob_get_data_writable (head_prime_blob, nullptr); head_prime->indexToLocFormat.set (use_short_loca ? 0 : 1); bool success = plan->add_table (HB_OT_TAG_head, head_prime_blob); @@ -236,7 +236,7 @@ struct glyf { memset (this, 0, sizeof (accelerator_t)); - hb_blob_t *head_blob = Sanitizer().sanitize (face->reference_table (HB_OT_TAG_head)); + hb_blob_t *head_blob = hb_sanitize_context_t().reference_table (face); const head *head_table = head_blob->as (); if (head_table == &Null(head) || (unsigned int) head_table->indexToLocFormat > 1 || head_table->glyphDataFormat != 0) { @@ -247,9 +247,9 @@ struct glyf short_offset = 0 == head_table->indexToLocFormat; hb_blob_destroy (head_blob); - loca_blob = Sanitizer().sanitize (face->reference_table (HB_OT_TAG_loca)); + loca_blob = hb_sanitize_context_t().reference_table (face); loca_table = loca_blob->as (); - glyf_blob = Sanitizer().sanitize (face->reference_table (HB_OT_TAG_glyf)); + glyf_blob = hb_sanitize_context_t().reference_table (face); glyf_table = glyf_blob->as (); num_glyphs = MAX (1u, hb_blob_get_length (loca_blob) / (short_offset ? 2 : 4)) - 1; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh index 2c6266453a7..13fa9d6e092 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh @@ -69,7 +69,7 @@ struct hmtxvmtx inline bool subset_update_header (hb_subset_plan_t *plan, unsigned int num_hmetrics) const { - hb_blob_t *src_blob = OT::Sanitizer ().sanitize (plan->source->reference_table (H::tableTag)); + hb_blob_t *src_blob = hb_sanitize_context_t().reference_table (plan->source, H::tableTag); hb_blob_t *dest_blob = hb_blob_copy_writable_or_fail(src_blob); hb_blob_destroy (src_blob); @@ -195,7 +195,7 @@ struct hmtxvmtx bool got_font_extents = false; if (T::os2Tag) { - hb_blob_t *os2_blob = Sanitizer ().sanitize (face->reference_table (T::os2Tag)); + hb_blob_t *os2_blob = hb_sanitize_context_t().reference_table (face); const os2 *os2_table = os2_blob->as (); #define USE_TYPO_METRICS (1u<<7) if (0 != (os2_table->fsSelection & USE_TYPO_METRICS)) @@ -208,7 +208,7 @@ struct hmtxvmtx hb_blob_destroy (os2_blob); } - hb_blob_t *_hea_blob = Sanitizer ().sanitize (face->reference_table (H::tableTag)); + hb_blob_t *_hea_blob = hb_sanitize_context_t().reference_table (face); const H *_hea_table = _hea_blob->as (); num_advances = _hea_table->numberOfLongMetrics; if (!got_font_extents) @@ -222,7 +222,7 @@ struct hmtxvmtx has_font_extents = got_font_extents; - blob = Sanitizer ().sanitize (face->reference_table (T::tableTag)); + blob = hb_sanitize_context_t().reference_table (face, T::tableTag); /* Cap num_metrics() and num_advances() based on table length. */ unsigned int len = hb_blob_get_length (blob); @@ -240,7 +240,7 @@ struct hmtxvmtx } table = blob->as (); - var_blob = Sanitizer ().sanitize (face->reference_table (T::variationsTag)); + var_blob = hb_sanitize_context_t().reference_table (face, T::variationsTag); var_table = var_blob->as (); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh index b0fdea4a7e6..b4d81095282 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh @@ -362,7 +362,7 @@ struct kern { inline void init (hb_face_t *face) { - blob = Sanitizer().sanitize (face->reference_table (HB_OT_TAG_kern)); + blob = hb_sanitize_context_t().reference_table (face); table = blob->as (); table_length = blob->length; } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common-private.hh index 21a8382c3a8..2da6e315ca7 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common-private.hh @@ -41,6 +41,15 @@ #ifndef HB_MAX_CONTEXT_LENGTH #define HB_MAX_CONTEXT_LENGTH 64 #endif +#ifndef HB_CLOSURE_MAX_STAGES +/* + * The maximum number of times a lookup can be applied during shaping. + * Used to limit the number of iterations of the closure algorithm. + * This must be larger than the number of times add_pause() is + * called in a collect_features call of any shaper. + */ +#define HB_CLOSURE_MAX_STAGES 32 +#endif namespace OT { @@ -181,6 +190,11 @@ struct IndexArray : ArrayOf } return this->len; } + + inline void add_indexes_to (hb_set_t* output /* OUT */) const + { + output->add_array (arrayZ, len); + } }; @@ -199,6 +213,8 @@ struct LangSys unsigned int *feature_count /* IN/OUT */, unsigned int *feature_indexes /* OUT */) const { return featureIndex.get_indexes (start_offset, feature_count, feature_indexes); } + inline void add_feature_indexes_to (hb_set_t *feature_indexes) const + { featureIndex.add_indexes_to (feature_indexes); } inline bool has_required_feature (void) const { return reqFeatureIndex != 0xFFFFu; } inline unsigned int get_required_feature_index (void) const @@ -540,9 +556,6 @@ struct Feature c->try_set (&featureParams, new_offset) && !featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE)) return_trace (false); - - if (c->edit_count > 1) - c->edit_count--; /* This was a "legitimate" edit; don't contribute to error count. */ } return_trace (true); @@ -597,6 +610,14 @@ struct Lookup inline OffsetArrayOf& get_subtables (void) { return CastR > (subTable); } + inline unsigned int get_size (void) const + { + const HBUINT16 &markFilteringSet = StructAfter (subTable); + if (lookupFlag & LookupFlag::UseMarkFilteringSet) + return (const char *) &StructAfter (markFilteringSet) - (const char *) this; + return (const char *) &markFilteringSet - (const char *) this; + } + inline unsigned int get_type (void) const { return lookupType; } /* lookup_props is a 32-bit integer where the lower 16-bit is LookupFlag and @@ -639,6 +660,7 @@ struct Lookup if (unlikely (!subTable.serialize (c, num_subtables))) return_trace (false); if (lookupFlag & LookupFlag::UseMarkFilteringSet) { + if (unlikely (!c->extend (*this))) return_trace (false); HBUINT16 &markFilteringSet = StructAfter (subTable); markFilteringSet.set (lookup_props >> 16); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh index 91b898b63af..eef8dc5462a 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh @@ -47,7 +47,7 @@ struct SingleSubstFormat1 * https://github.com/harfbuzz/harfbuzz/issues/363 */ hb_codepoint_t glyph_id = iter.get_glyph (); if (c->glyphs->has (glyph_id)) - c->glyphs->add ((glyph_id + deltaGlyphID) & 0xFFFFu); + c->out->add ((glyph_id + deltaGlyphID) & 0xFFFFu); } } @@ -132,7 +132,7 @@ struct SingleSubstFormat2 if (unlikely (iter.get_coverage () >= count)) break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ if (c->glyphs->has (iter.get_glyph ())) - c->glyphs->add (substitute[iter.get_coverage ()]); + c->out->add (substitute[iter.get_coverage ()]); } } @@ -263,7 +263,7 @@ struct Sequence TRACE_CLOSURE (this); unsigned int count = substitute.len; for (unsigned int i = 0; i < count; i++) - c->glyphs->add (substitute[i]); + c->out->add (substitute[i]); } inline void collect_glyphs (hb_collect_glyphs_context_t *c) const @@ -464,7 +464,7 @@ struct AlternateSubstFormat1 const AlternateSet &alt_set = this+alternateSet[iter.get_coverage ()]; unsigned int count = alt_set.len; for (unsigned int i = 0; i < count; i++) - c->glyphs->add (alt_set[i]); + c->out->add (alt_set[i]); } } } @@ -605,7 +605,7 @@ struct Ligature for (unsigned int i = 1; i < count; i++) if (!c->glyphs->has (component[i])) return; - c->glyphs->add (ligGlyph); + c->out->add (ligGlyph); } inline void collect_glyphs (hb_collect_glyphs_context_t *c) const @@ -957,7 +957,7 @@ struct ReverseChainSingleSubstFormat1 if (unlikely (iter.get_coverage () >= count)) break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ if (c->glyphs->has (iter.get_glyph ())) - c->glyphs->add (substitute[iter.get_coverage ()]); + c->out->add (substitute[iter.get_coverage ()]); } } @@ -1163,7 +1163,12 @@ struct SubstLookup : Lookup return_trace (HB_VOID); c->set_recurse_func (dispatch_closure_recurse_func); - return_trace (dispatch (c)); + + hb_closure_context_t::return_t ret = dispatch (c); + + c->flush (); + + return_trace (ret); } inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const @@ -1265,7 +1270,12 @@ struct SubstLookup : Lookup { if (!c->should_visit_lookup (lookup_index)) return HB_VOID; - return dispatch_recurse_func (c, lookup_index); + + hb_closure_context_t::return_t ret = dispatch_recurse_func (c, lookup_index); + + c->flush (); + + return ret; } template diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos-private.hh index aed00f15121..747811e6a6b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos-private.hh @@ -69,12 +69,13 @@ struct hb_closure_context_t : bool is_lookup_done (unsigned int lookup_index) { - // Have we visited this lookup with the current set of glyphs? + /* Have we visited this lookup with the current set of glyphs? */ return done_lookups->get (lookup_index) == glyphs->get_population (); } hb_face_t *face; hb_set_t *glyphs; + hb_auto_t out[1]; recurse_func_t recurse_func; unsigned int nesting_level_left; unsigned int debug_depth; @@ -90,8 +91,19 @@ struct hb_closure_context_t : debug_depth (0), done_lookups (done_lookups_) {} + ~hb_closure_context_t (void) + { + flush (); + } + void set_recurse_func (recurse_func_t func) { recurse_func = func; } + void flush (void) + { + hb_set_union (glyphs, out); + hb_set_clear (out); + } + private: hb_map_t *done_lookups; }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-private.hh index b2f974b82e8..6fe673e9118 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-private.hh @@ -176,6 +176,7 @@ struct hb_ot_layout_t OT::hb_table_lazy_loader_t math; OT::hb_table_lazy_loader_t fvar; OT::hb_table_lazy_loader_t avar; + OT::hb_table_lazy_loader_t morx; unsigned int gsub_lookup_count; unsigned int gpos_lookup_count; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc index 655c36c1c28..c790c3ceb3d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc @@ -54,18 +54,19 @@ _hb_ot_layout_create (hb_face_t *face) if (unlikely (!layout)) return nullptr; - layout->gdef_blob = OT::Sanitizer().sanitize (face->reference_table (HB_OT_TAG_GDEF)); + layout->gdef_blob = OT::hb_sanitize_context_t().reference_table (face); layout->gdef = layout->gdef_blob->as (); - layout->gsub_blob = OT::Sanitizer().sanitize (face->reference_table (HB_OT_TAG_GSUB)); + layout->gsub_blob = OT::hb_sanitize_context_t().reference_table (face); layout->gsub = layout->gsub_blob->as (); - layout->gpos_blob = OT::Sanitizer().sanitize (face->reference_table (HB_OT_TAG_GPOS)); + layout->gpos_blob = OT::hb_sanitize_context_t().reference_table (face); layout->gpos = layout->gpos_blob->as (); layout->math.init (face); layout->fvar.init (face); layout->avar.init (face); + layout->morx.init (face); { /* @@ -215,6 +216,7 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout) layout->math.fini (); layout->fvar.fini (); layout->avar.fini (); + layout->morx.fini (); free (layout); } @@ -518,6 +520,19 @@ 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, @@ -656,12 +671,12 @@ _hb_ot_layout_collect_lookups_lookups (hb_face_t *face, } static void -_hb_ot_layout_collect_lookups_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 *lookup_indexes /* OUT */) +_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 */) { if (!features) { @@ -672,33 +687,14 @@ _hb_ot_layout_collect_lookups_features (hb_face_t *face, language_index, &required_feature_index, nullptr)) - _hb_ot_layout_collect_lookups_lookups (face, - table_tag, - required_feature_index, - lookup_indexes); + feature_indexes->add (required_feature_index); /* All features */ - unsigned int feature_indices[32]; - unsigned int offset, len; - - offset = 0; - do { - len = ARRAY_LENGTH (feature_indices); - hb_ot_layout_language_get_feature_indexes (face, - table_tag, - script_index, - language_index, - offset, &len, - feature_indices); - - for (unsigned int i = 0; i < len; i++) - _hb_ot_layout_collect_lookups_lookups (face, - table_tag, - feature_indices[i], - lookup_indexes); - - offset += len; - } while (len == ARRAY_LENGTH (feature_indices)); + _hb_ot_layout_language_add_feature_indexes_to (face, + table_tag, + script_index, + language_index, + feature_indexes); } else { @@ -711,28 +707,25 @@ _hb_ot_layout_collect_lookups_features (hb_face_t *face, language_index, *features, &feature_index)) - _hb_ot_layout_collect_lookups_lookups (face, - table_tag, - feature_index, - lookup_indexes); + feature_indexes->add (feature_index); } } } static void -_hb_ot_layout_collect_lookups_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 *lookup_indexes /* OUT */) +_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 */) { - _hb_ot_layout_collect_lookups_features (face, - table_tag, - script_index, - HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, - features, - lookup_indexes); + _hb_ot_layout_collect_features_features (face, + table_tag, + script_index, + HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, + features, + feature_indexes); if (!languages) { @@ -742,12 +735,12 @@ _hb_ot_layout_collect_lookups_languages (hb_face_t *face, script_index, 0, nullptr, nullptr); for (unsigned int language_index = 0; language_index < count; language_index++) - _hb_ot_layout_collect_lookups_features (face, - table_tag, - script_index, - language_index, - features, - lookup_indexes); + _hb_ot_layout_collect_features_features (face, + table_tag, + script_index, + language_index, + features, + feature_indexes); } else { @@ -759,28 +752,28 @@ _hb_ot_layout_collect_lookups_languages (hb_face_t *face, script_index, *languages, &language_index)) - _hb_ot_layout_collect_lookups_features (face, - table_tag, - script_index, - language_index, - features, - lookup_indexes); + _hb_ot_layout_collect_features_features (face, + table_tag, + script_index, + language_index, + features, + feature_indexes); } } } /** - * hb_ot_layout_collect_lookups: + * hb_ot_layout_collect_features: * - * Since: 0.9.8 + * Since: 1.8.5 **/ void -hb_ot_layout_collect_lookups (hb_face_t *face, - hb_tag_t table_tag, - const hb_tag_t *scripts, - const hb_tag_t *languages, - const hb_tag_t *features, - hb_set_t *lookup_indexes /* OUT */) +hb_ot_layout_collect_features (hb_face_t *face, + hb_tag_t table_tag, + const hb_tag_t *scripts, + const hb_tag_t *languages, + const hb_tag_t *features, + hb_set_t *feature_indexes /* OUT */) { if (!scripts) { @@ -789,12 +782,12 @@ hb_ot_layout_collect_lookups (hb_face_t *face, table_tag, 0, nullptr, nullptr); for (unsigned int script_index = 0; script_index < count; script_index++) - _hb_ot_layout_collect_lookups_languages (face, - table_tag, - script_index, - languages, - features, - lookup_indexes); + _hb_ot_layout_collect_features_languages (face, + table_tag, + script_index, + languages, + features, + feature_indexes); } else { @@ -805,16 +798,35 @@ hb_ot_layout_collect_lookups (hb_face_t *face, table_tag, *scripts, &script_index)) - _hb_ot_layout_collect_lookups_languages (face, - table_tag, - script_index, - languages, - features, - lookup_indexes); + _hb_ot_layout_collect_features_languages (face, + table_tag, + script_index, + languages, + features, + feature_indexes); } } } +/** + * hb_ot_layout_collect_lookups: + * + * Since: 0.9.8 + **/ +void +hb_ot_layout_collect_lookups (hb_face_t *face, + hb_tag_t table_tag, + const hb_tag_t *scripts, + const hb_tag_t *languages, + const hb_tag_t *features, + hb_set_t *lookup_indexes /* OUT */) +{ + 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); +} + /** * hb_ot_layout_lookup_collect_glyphs: * @@ -969,6 +981,7 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, OT::hb_closure_context_t c (face, glyphs, &done_lookups); const OT::GSUB& gsub = _get_gsub (face); + unsigned int iteration_count = 0; unsigned int glyphs_length; do { @@ -983,7 +996,9 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, for (unsigned int i = 0; i < gsub.get_lookup_count (); i++) gsub.get_lookup (i).closure (&c, i); } - } while (glyphs_length != glyphs->get_population ()); + iteration_count++; + } while (iteration_count <= HB_CLOSURE_MAX_STAGES + && glyphs_length != glyphs->get_population ()); } /* diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h index 0278796221d..586fb151751 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h @@ -194,6 +194,13 @@ HB_EXTERN unsigned int hb_ot_layout_table_get_lookup_count (hb_face_t *face, hb_tag_t table_tag); +HB_EXTERN void +hb_ot_layout_collect_features (hb_face_t *face, + hb_tag_t table_tag, + const hb_tag_t *scripts, + const hb_tag_t *languages, + const hb_tag_t *features, + hb_set_t *feature_indexes /* OUT */); HB_EXTERN void hb_ot_layout_collect_lookups (hb_face_t *face, diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh index 390b60d72fd..75aac4f44bb 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh @@ -100,14 +100,14 @@ struct maxp inline bool subset (hb_subset_plan_t *plan) const { - hb_blob_t *maxp_blob = OT::Sanitizer().sanitize (hb_face_reference_table (plan->source, HB_OT_TAG_maxp)); + hb_blob_t *maxp_blob = hb_sanitize_context_t().reference_table (plan->source); hb_blob_t *maxp_prime_blob = hb_blob_copy_writable_or_fail (maxp_blob); hb_blob_destroy (maxp_blob); if (unlikely (!maxp_prime_blob)) { return false; } - OT::maxp *maxp_prime = (OT::maxp *) hb_blob_get_data (maxp_prime_blob, nullptr); + maxp *maxp_prime = (maxp *) hb_blob_get_data (maxp_prime_blob, nullptr); maxp_prime->set_num_glyphs (plan->glyphs.len); if (plan->drop_hints) @@ -118,7 +118,7 @@ struct maxp return result; } - static inline void drop_hint_fields (hb_subset_plan_t *plan, OT::maxp *maxp_prime) + static inline void drop_hint_fields (hb_subset_plan_t *plan, maxp *maxp_prime) { if (maxp_prime->version.major == 1) { diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh index c52b7eb10bb..56bbab74118 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh @@ -51,12 +51,12 @@ struct os2 inline bool subset (hb_subset_plan_t *plan) const { - hb_blob_t *os2_blob = OT::Sanitizer().sanitize (hb_face_reference_table (plan->source, HB_OT_TAG_os2)); + hb_blob_t *os2_blob = hb_sanitize_context_t().reference_table (plan->source); hb_blob_t *os2_prime_blob = hb_blob_create_sub_blob (os2_blob, 0, -1); // TODO(grieger): move to hb_blob_copy_writable_or_fail hb_blob_destroy (os2_blob); - OT::os2 *os2_prime = (OT::os2 *) hb_blob_get_data_writable (os2_prime_blob, nullptr); + os2 *os2_prime = (os2 *) hb_blob_get_data_writable (os2_prime_blob, nullptr); if (unlikely (!os2_prime)) { hb_blob_destroy (os2_prime_blob); return false; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh index d05fc091c4e..9766f315244 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh @@ -85,7 +85,7 @@ struct post inline bool subset (hb_subset_plan_t *plan) const { unsigned int post_prime_length; - hb_blob_t *post_blob = OT::Sanitizer().sanitize (hb_face_reference_table (plan->source, HB_OT_TAG_post)); + hb_blob_t *post_blob = hb_sanitize_context_t().reference_table(plan->source); hb_blob_t *post_prime_blob = hb_blob_create_sub_blob (post_blob, 0, post::static_size); post *post_prime = (post *) hb_blob_get_data_writable (post_prime_blob, &post_prime_length); hb_blob_destroy (post_blob); @@ -110,7 +110,7 @@ struct post { index_to_offset.init (); - blob = Sanitizer().sanitize (face->reference_table (HB_OT_TAG_post)); + blob = hb_sanitize_context_t().reference_table (face); const post *table = blob->as (); unsigned int table_length = blob->length; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-private.hh index 9554994a0f6..bb7fff38414 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-private.hh @@ -300,7 +300,9 @@ static const hb_codepoint_t ra_chars[] = { 0x0CB0u, /* Kannada */ 0x0D30u, /* Malayalam */ /* No Reph, Logical Repha */ - 0x0DBBu, /* Sinhala */ /* Reph formed only with ZWJ */ + 0x0DBBu, /* Sinhala */ /* Reph formed only with ZWJ */ + + 0x179Au, /* Khmer */ }; static inline bool diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc index b8d9a3acf0a..b52656f44c6 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc @@ -251,10 +251,10 @@ struct indic_shape_plan_t { ASSERT_POD (); - inline bool get_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const + inline bool load_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const { - hb_codepoint_t glyph = virama_glyph; - if (unlikely (virama_glyph == (hb_codepoint_t) -1)) + hb_codepoint_t glyph = virama_glyph.get_relaxed (); + if (unlikely (glyph == (hb_codepoint_t) -1)) { if (!config->virama || !font->get_nominal_glyph (config->virama, &glyph)) glyph = 0; @@ -262,8 +262,8 @@ struct indic_shape_plan_t * Maybe one day... */ /* Our get_nominal_glyph() function needs a font, so we can't get the virama glyph - * during shape planning... Instead, overwrite it here. It's safe. Don't worry! */ - virama_glyph = glyph; + * during shape planning... Instead, overwrite it here. */ + virama_glyph.set_relaxed ((int) glyph); } *pglyph = glyph; @@ -273,7 +273,7 @@ struct indic_shape_plan_t const indic_config_t *config; bool is_old_spec; - mutable hb_codepoint_t virama_glyph; + mutable hb_atomic_int_t virama_glyph; would_substitute_feature_t rphf; would_substitute_feature_t pref; @@ -298,7 +298,7 @@ data_create_indic (const hb_ot_shape_plan_t *plan) } indic_plan->is_old_spec = indic_plan->config->has_old_spec && ((plan->map.chosen_script[0] & 0x000000FFu) != '2'); - indic_plan->virama_glyph = (hb_codepoint_t) -1; + indic_plan->virama_glyph.set_relaxed (-1); /* Use zero-context would_substitute() matching for new-spec of the main * Indic scripts, and scripts with one spec only, but not for old-specs. @@ -419,7 +419,7 @@ update_consonant_positions (const hb_ot_shape_plan_t *plan, return; hb_codepoint_t virama; - if (indic_plan->get_virama_glyph (font, &virama)) + if (indic_plan->load_virama_glyph (font, &virama)) { hb_face_t *face = font->face; unsigned int count = buffer->len; @@ -667,10 +667,10 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, * last consonant. * * Reports suggest that in some scripts Uniscribe does this only if there - * is *not* a Halant after last consonant already (eg. Kannada), while it - * does it unconditionally in other scripts (eg. Malayalam, Bengali). We - * don't currently know about other scripts, so we whitelist Malayalam and - * Bengali for now. + * is *not* a Halant after last consonant already. We know that is the + * case for Kannada, while it reorders unconditionally in other scripts, + * eg. Malayalam, Bengali, and Devanagari. We don't currently know about + * other scripts, so we blacklist Kannada. * * Kannada test case: * U+0C9A,U+0CCD,U+0C9A,U+0CCD @@ -681,15 +681,19 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, * U+0D38,U+0D4D,U+0D31,U+0D4D,U+0D31,U+0D4D * With lohit-ttf-20121122/Lohit-Malayalam.ttf * - * Bengali test case + * Bengali test case: * U+0998,U+09CD,U+09AF,U+09CD * With Windows XP vrinda.ttf * https://github.com/harfbuzz/harfbuzz/issues/1073 + * + * Devanagari test case: + * U+091F,U+094D,U+0930,U+094D + * With chandas.ttf + * https://github.com/harfbuzz/harfbuzz/issues/1071 */ if (indic_plan->is_old_spec) { - bool disallow_double_halants = buffer->props.script != HB_SCRIPT_MALAYALAM && - buffer->props.script != HB_SCRIPT_BENGALI; + bool disallow_double_halants = buffer->props.script == HB_SCRIPT_KANNADA; for (unsigned int i = base + 1; i < end; i++) if (info[i].indic_category() == OT_H) { @@ -1036,9 +1040,11 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, * phase, and that might have messed up our properties. Recover * from a particular case of that where we're fairly sure that a * class of OT_H is desired but has been lost. */ - if (indic_plan->virama_glyph) + /* We don't call load_virama_glyph(), since we know it's already + * loaded. */ + hb_codepoint_t virama_glyph = indic_plan->virama_glyph.get_relaxed (); + if (virama_glyph) { - unsigned int virama_glyph = indic_plan->virama_glyph; for (unsigned int i = start; i < end; i++) if (info[i].codepoint == virama_glyph && _hb_glyph_info_ligated (&info[i]) && diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.cc index 7876d366662..264515e86c4 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.cc @@ -42,7 +42,7 @@ khmer_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('p','r','e','f'), F_NONE}, {HB_TAG('b','l','w','f'), F_NONE}, @@ -51,9 +51,7 @@ khmer_features[] = {HB_TAG('c','f','a','r'), F_NONE}, /* * Other features. - * These features are applied all at once, after final_reordering. - * Default Bengali font in Windows for example has intermixed - * lookups for init,pres,abvs,blws features. + * These features are applied all at once. */ {HB_TAG('p','r','e','s'), F_GLOBAL}, {HB_TAG('a','b','v','s'), F_GLOBAL}, @@ -92,13 +90,9 @@ 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); -static void -final_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 clear_syllables (const hb_ot_shape_plan_t *plan, hb_font_t *font, @@ -111,20 +105,28 @@ collect_features_khmer (hb_ot_shape_planner_t *plan) /* Do this before any lookups have been applied. */ map->add_gsub_pause (setup_syllables); + map->add_gsub_pause (reorder); + /* Testing suggests that Uniscribe does NOT pause between basic + * features. Test with KhmerUI.ttf and the following three + * sequences: + * + * U+1789,U+17BC + * U+1789,U+17D2,U+1789 + * U+1789,U+17D2,U+1789,U+17BC + * + * https://github.com/harfbuzz/harfbuzz/issues/974 + */ map->add_global_bool_feature (HB_TAG('l','o','c','l')); - /* The Indic specs do not require ccmp, but we apply it here since if - * there is a use of it, it's typically at the beginning. */ map->add_global_bool_feature (HB_TAG('c','c','m','p')); - unsigned int i = 0; - map->add_gsub_pause (initial_reordering); for (; i < KHMER_BASIC_FEATURES; i++) { map->add_feature (khmer_features[i].tag, 1, khmer_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ); - map->add_gsub_pause (nullptr); } - map->add_gsub_pause (final_reordering); + + map->add_gsub_pause (clear_syllables); + for (; i < KHMER_NUM_FEATURES; i++) { map->add_feature (khmer_features[i].tag, 1, khmer_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ); } @@ -132,7 +134,6 @@ collect_features_khmer (hb_ot_shape_planner_t *plan) map->add_global_bool_feature (HB_TAG('c','a','l','t')); map->add_global_bool_feature (HB_TAG('c','l','i','g')); - map->add_gsub_pause (clear_syllables); } static void @@ -264,162 +265,58 @@ setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED, buffer->unsafe_to_break (start, end); } -static int -compare_khmer_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb) -{ - int a = pa->khmer_position(); - int b = pb->khmer_position(); - - return a < b ? -1 : a == b ? 0 : +1; -} - /* Rules from: * https://docs.microsoft.com/en-us/typography/script-development/devanagari */ static void -initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, - hb_face_t *face, - hb_buffer_t *buffer, - unsigned int start, unsigned int end) +reorder_consonant_syllable (const hb_ot_shape_plan_t *plan, + hb_face_t *face, + hb_buffer_t *buffer, + unsigned int start, unsigned int end) { const khmer_shape_plan_t *khmer_plan = (const khmer_shape_plan_t *) plan->data; hb_glyph_info_t *info = buffer->info; - /* 1. Khmer shaping assumes that a syllable will begin with a Cons, IndV, or Number. */ - - /* The first consonant is always the base. */ - unsigned int base = start; - info[base].khmer_position() = POS_BASE_C; - - /* Mark all subsequent consonants as below. */ - for (unsigned int i = base + 1; i < end; i++) - if (is_consonant_or_vowel (info[i])) - info[i].khmer_position() = POS_BELOW_C; - - /* Mark final consonants. A final consonant is one appearing after a matra, - * like in Khmer. */ - for (unsigned int i = base + 1; i < end; i++) - if (info[i].khmer_category() == OT_M) { - for (unsigned int j = i + 1; j < end; j++) - if (is_consonant_or_vowel (info[j])) { - info[j].khmer_position() = POS_FINAL_C; - break; - } - break; - } - - /* Attach misc marks to previous char to move with them. */ + /* Setup masks. */ { - khmer_position_t last_pos = POS_START; - for (unsigned int i = start; i < end; i++) - { - if ((FLAG_UNSAFE (info[i].khmer_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | FLAG (OT_Coeng)))) - { - info[i].khmer_position() = last_pos; - if (unlikely (info[i].khmer_category() == OT_Coeng && - info[i].khmer_position() == POS_PRE_M)) - { - /* - * Uniscribe doesn't move the Halant with Left Matra. - * TEST: U+092B,U+093F,U+094DE - * We follow. This is important for the Sinhala - * U+0DDA split matra since it decomposes to U+0DD9,U+0DCA - * where U+0DD9 is a left matra and U+0DCA is the virama. - * We don't want to move the virama with the left matra. - * TEST: U+0D9A,U+0DDA - */ - for (unsigned int j = i; j > start; j--) - if (info[j - 1].khmer_position() != POS_PRE_M) { - info[i].khmer_position() = info[j - 1].khmer_position(); - break; - } - } - } else if (info[i].khmer_position() != POS_SMVD) { - last_pos = (khmer_position_t) info[i].khmer_position(); - } - } - } - /* For post-base consonants let them own anything before them - * since the last consonant or matra. */ - { - unsigned int last = base; - for (unsigned int i = base + 1; i < end; i++) - if (is_consonant_or_vowel (info[i])) - { - for (unsigned int j = last + 1; j < i; j++) - if (info[j].khmer_position() < POS_SMVD) - info[j].khmer_position() = info[i].khmer_position(); - last = i; - } else if (info[i].khmer_category() == OT_M) - last = i; - } - - { - /* Use syllable() for sort accounting temporarily. */ - unsigned int syllable = info[start].syllable(); - for (unsigned int i = start; i < end; i++) - info[i].syllable() = i - start; - - /* Sit tight, rock 'n roll! */ - hb_stable_sort (info + start, end - start, compare_khmer_order); - /* Find base again */ - base = end; - for (unsigned int i = start; i < end; i++) - if (info[i].khmer_position() == POS_BASE_C) - { - base = i; - break; - } - - if (unlikely (end - start >= 127)) - buffer->merge_clusters (start, end); - else - /* Note! syllable() is a one-byte field. */ - for (unsigned int i = base; i < end; i++) - if (info[i].syllable() != 255) - { - unsigned int max = i; - unsigned int j = start + info[i].syllable(); - while (j != i) - { - max = MAX (max, j); - unsigned int next = start + info[j].syllable(); - info[j].syllable() = 255; /* So we don't process j later again. */ - j = next; - } - if (i != max) - buffer->merge_clusters (i, max + 1); - } - - /* Put syllable back in. */ - for (unsigned int i = start; i < end; i++) - info[i].syllable() = syllable; - } - - /* Setup masks now */ - - { - hb_mask_t mask; - /* Post-base */ - mask = khmer_plan->mask_array[BLWF] | khmer_plan->mask_array[ABVF] | khmer_plan->mask_array[PSTF]; - for (unsigned int i = base + 1; i < end; i++) + hb_mask_t mask = khmer_plan->mask_array[BLWF] | khmer_plan->mask_array[ABVF] | khmer_plan->mask_array[PSTF]; + for (unsigned int i = start + 1; i < end; i++) info[i].mask |= mask; } - unsigned int pref_len = 2; - if (khmer_plan->mask_array[PREF] && base + pref_len < end) + unsigned int num_coengs = 0; + for (unsigned int i = start + 1; i < end; i++) { - /* Find a Halant,Ra sequence and mark it for pre-base-reordering processing. */ - for (unsigned int i = base + 1; i + pref_len - 1 < end; i++) { - hb_codepoint_t glyphs[2]; - for (unsigned int j = 0; j < pref_len; j++) - glyphs[j] = info[i + j].codepoint; - if (khmer_plan->pref.would_substitute (glyphs, pref_len, face)) + /* """ + * When a COENG + (Cons | IndV) combination are found (and subscript count + * is less than two) the character combination is handled according to the + * subscript type of the character following the COENG. + * + * ... + * + * Subscript Type 2 - The COENG + RO characters are reordered to immediately + * before the base glyph. Then the COENG + RO characters are assigned to have + * the 'pref' OpenType feature applied to them. + * """ + */ + if (info[i].khmer_category() == OT_Coeng && num_coengs <= 2 && i + 1 < end) + { + num_coengs++; + + if (info[i + 1].khmer_category() == OT_Ra) { - for (unsigned int j = 0; j < pref_len; j++) - info[i++].mask |= khmer_plan->mask_array[PREF]; + for (unsigned int j = 0; j < 2; j++) + info[i + j].mask |= khmer_plan->mask_array[PREF]; + + /* Move the Coeng,Ro sequence to the start. */ + buffer->merge_clusters (start, i + 2); + hb_glyph_info_t t0 = info[i]; + hb_glyph_info_t t1 = info[i + 1]; + memmove (&info[start + 2], &info[start], (i - start) * sizeof (info[0])); + info[start] = t0; + info[start + 1] = t1; /* Mark the subsequent stuff with 'cfar'. Used in Khmer. * Read the feature spec. @@ -428,12 +325,22 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, * U+1784,U+17D2,U+1782,U+17D2,U+179A */ if (khmer_plan->mask_array[CFAR]) - for (; i < end; i++) - info[i].mask |= khmer_plan->mask_array[CFAR]; + for (unsigned int j = i + 2; j < end; j++) + info[j].mask |= khmer_plan->mask_array[CFAR]; - break; + num_coengs = 2; /* Done. */ } } + + /* Reorder left matra piece. */ + else if (info[i].khmer_position() == POS_PRE_M) + { + /* Move to the start. */ + buffer->merge_clusters (start, i + 1); + hb_glyph_info_t t = info[i]; + memmove (&info[start + 1], &info[start], (i - start) * sizeof (info[0])); + info[start] = t; + } } } @@ -448,7 +355,7 @@ initial_reordering_syllable (const hb_ot_shape_plan_t *plan, { case broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */ case consonant_syllable: - initial_reordering_consonant_syllable (plan, face, buffer, start, end); + reorder_consonant_syllable (plan, face, buffer, start, end); break; case non_khmer_cluster: @@ -518,263 +425,26 @@ 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_syllable (const hb_ot_shape_plan_t *plan, - hb_buffer_t *buffer, - unsigned int start, unsigned int end) -{ - const khmer_shape_plan_t *khmer_plan = (const khmer_shape_plan_t *) plan->data; - hb_glyph_info_t *info = buffer->info; - - - /* This function relies heavily on halant glyphs. Lots of ligation - * and possibly multiple substitutions happened prior to this - * phase, and that might have messed up our properties. Recover - * from a particular case of that where we're fairly sure that a - * class of OT_Coeng is desired but has been lost. */ - if (khmer_plan->virama_glyph) - { - unsigned int virama_glyph = khmer_plan->virama_glyph; - for (unsigned int i = start; i < end; i++) - if (info[i].codepoint == virama_glyph && - _hb_glyph_info_ligated (&info[i]) && - _hb_glyph_info_multiplied (&info[i])) - { - /* This will make sure that this glyph passes is_coeng() test. */ - info[i].khmer_category() = OT_Coeng; - _hb_glyph_info_clear_ligated_and_multiplied (&info[i]); - } - } - - - /* 4. Final reordering: - * - * After the localized forms and basic shaping forms GSUB features have been - * applied (see below), the shaping engine performs some final glyph - * reordering before applying all the remaining font features to the entire - * syllable. - */ - - bool try_pref = !!khmer_plan->mask_array[PREF]; - - /* Find base again */ - unsigned int base; - for (base = start; base < end; base++) - if (info[base].khmer_position() >= POS_BASE_C) - { - if (try_pref && base + 1 < end) - { - for (unsigned int i = base + 1; i < end; i++) - if ((info[i].mask & khmer_plan->mask_array[PREF]) != 0) - { - if (!(_hb_glyph_info_substituted (&info[i]) && - _hb_glyph_info_ligated_and_didnt_multiply (&info[i]))) - { - /* Ok, this was a 'pref' candidate but didn't form any. - * Base is around here... */ - base = i; - while (base < end && is_coeng (info[base])) - base++; - info[base].khmer_position() = POS_BASE_C; - - try_pref = false; - } - break; - } - } - - if (start < base && info[base].khmer_position() > POS_BASE_C) - base--; - break; - } - if (base == end && start < base && - is_one_of (info[base - 1], FLAG (OT_ZWJ))) - base--; - if (base < end) - while (start < base && - is_one_of (info[base], (FLAG (OT_N) | FLAG (OT_Coeng)))) - base--; - - - /* o Reorder matras: - * - * If a pre-base matra character had been reordered before applying basic - * features, the glyph can be moved closer to the main consonant based on - * whether half-forms had been formed. Actual position for the matra is - * defined as “after last standalone halant glyph, after initial matra - * position and before the main consonant”. If ZWJ or ZWNJ follow this - * halant, position is moved after it. - */ - - if (start + 1 < end && start < base) /* Otherwise there can't be any pre-base matra characters. */ - { - /* If we lost track of base, alas, position before last thingy. */ - unsigned int new_pos = base == end ? base - 2 : base - 1; - - while (new_pos > start && - !(is_one_of (info[new_pos], (FLAG (OT_M) | FLAG (OT_Coeng))))) - new_pos--; - - /* If we found no Halant we are done. - * Otherwise only proceed if the Halant does - * not belong to the Matra itself! */ - if (is_coeng (info[new_pos]) && - info[new_pos].khmer_position() != POS_PRE_M) - { - /* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */ - if (new_pos + 1 < end && is_joiner (info[new_pos + 1])) - new_pos++; - } - else - new_pos = start; /* No move. */ - - if (start < new_pos && info[new_pos].khmer_position () != POS_PRE_M) - { - /* Now go see if there's actually any matras... */ - for (unsigned int i = new_pos; i > start; i--) - if (info[i - 1].khmer_position () == POS_PRE_M) - { - unsigned int old_pos = i - 1; - if (old_pos < base && base <= new_pos) /* Shouldn't actually happen. */ - base--; - - hb_glyph_info_t tmp = info[old_pos]; - memmove (&info[old_pos], &info[old_pos + 1], (new_pos - old_pos) * sizeof (info[0])); - info[new_pos] = tmp; - - /* Note: this merge_clusters() is intentionally *after* the reordering. - * Indic matra reordering is special and tricky... */ - buffer->merge_clusters (new_pos, MIN (end, base + 1)); - - new_pos--; - } - } else { - for (unsigned int i = start; i < base; i++) - if (info[i].khmer_position () == POS_PRE_M) { - buffer->merge_clusters (i, MIN (end, base + 1)); - break; - } - } - } - - - /* o Reorder pre-base-reordering consonants: - * - * If a pre-base-reordering consonant is found, reorder it according to - * the following rules: - */ - - if (try_pref && base + 1 < end) /* Otherwise there can't be any pre-base-reordering Ra. */ - { - for (unsigned int i = base + 1; i < end; i++) - if ((info[i].mask & khmer_plan->mask_array[PREF]) != 0) - { - /* 1. Only reorder a glyph produced by substitution during application - * of the feature. (Note that a font may shape a Ra consonant with - * the feature generally but block it in certain contexts.) - */ - /* Note: We just check that something got substituted. We don't check that - * the feature actually did it... - * - * Reorder pref only if it ligated. */ - if (_hb_glyph_info_ligated_and_didnt_multiply (&info[i])) - { - /* - * 2. Try to find a target position the same way as for pre-base matra. - * If it is found, reorder pre-base consonant glyph. - * - * 3. If position is not found, reorder immediately before main - * consonant. - */ - - unsigned int new_pos = base; - while (new_pos > start && - !(is_one_of (info[new_pos - 1], FLAG(OT_M) | FLAG (OT_Coeng)))) - new_pos--; - - /* In Khmer coeng model, a H,Ra can go *after* matras. If it goes after a - * split matra, it should be reordered to *before* the left part of such matra. */ - if (new_pos > start && info[new_pos - 1].khmer_category() == OT_M) - { - unsigned int old_pos = i; - for (unsigned int j = base + 1; j < old_pos; j++) - if (info[j].khmer_category() == OT_M) - { - new_pos--; - break; - } - } - - if (new_pos > start && is_coeng (info[new_pos - 1])) - { - /* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */ - if (new_pos < end && is_joiner (info[new_pos])) - new_pos++; - } - - { - unsigned int old_pos = i; - - buffer->merge_clusters (new_pos, old_pos + 1); - hb_glyph_info_t tmp = info[old_pos]; - memmove (&info[new_pos + 1], &info[new_pos], (old_pos - new_pos) * sizeof (info[0])); - info[new_pos] = tmp; - - if (new_pos <= base && base < old_pos) - base++; - } - } - - break; - } - } - - - /* - * Finish off the clusters and go home! - */ - if (hb_options ().uniscribe_bug_compatible) - { - /* Uniscribe merges the entire syllable into a single cluster... Except for Tamil & Sinhala. - * This means, half forms are submerged into the main consonant's cluster. - * This is unnecessary, and makes cursor positioning harder, but that's what - * Uniscribe does. */ - buffer->merge_clusters (start, end); - } -} - - -static void -final_reordering (const hb_ot_shape_plan_t *plan, - hb_font_t *font HB_UNUSED, - hb_buffer_t *buffer) -{ - unsigned int count = buffer->len; - if (unlikely (!count)) return; - - foreach_syllable (buffer, start, end) - final_reordering_syllable (plan, buffer, start, end); HB_BUFFER_DEALLOCATE_VAR (buffer, khmer_category); HB_BUFFER_DEALLOCATE_VAR (buffer, khmer_position); } - static void 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/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-private.hh index ed6849bfab2..37a4d918b1d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-private.hh @@ -279,20 +279,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) return &_hb_ot_complex_shaper_indic; case HB_SCRIPT_KHMER: - /* A number of Khmer fonts in the wild don't have a 'pref' feature, - * and as such won't shape properly via the Indic shaper; - * however, they typically have 'liga' / 'clig' features that implement - * the necessary "reordering" by means of ligature substitutions. - * So we send such pref-less fonts through the generic shaper instead. */ - if (planner->map.found_script[0] && - hb_ot_layout_language_find_feature (planner->face, HB_OT_TAG_GSUB, - planner->map.script_index[0], - planner->map.language_index[0], - HB_TAG ('p','r','e','f'), - nullptr)) return &_hb_ot_complex_shaper_khmer; - else - return &_hb_ot_complex_shaper_default; case HB_SCRIPT_MYANMAR: if (planner->map.chosen_script[0] == HB_TAG ('m','y','m','2')) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc index 25f7bf42709..9c796f05182 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc @@ -510,8 +510,8 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11100 */ VMAbv, VMAbv, VMAbv, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11110 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11120 */ B, B, B, B, B, B, B, VAbv, VAbv, VAbv, VBlw, VBlw, VPre, VAbv, VAbv, VAbv, - /* 11130 */ VAbv, VBlw, VBlw, H, VAbv, O, B, B, B, B, B, B, B, B, B, B, + /* 11120 */ B, B, B, B, B, B, B, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VBlw, VAbv, VAbv, + /* 11130 */ VBlw, VAbv, VAbv, H, CMAbv, O, B, B, B, B, B, B, B, B, B, B, /* 11140 */ O, O, O, O, B, VPst, VPst, O, O, O, O, O, O, O, O, O, /* Mahajani */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc index 66b95711cf5..f8e86c9d6e6 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc @@ -560,25 +560,6 @@ reorder (const hb_ot_shape_plan_t *plan, HB_BUFFER_DEALLOCATE_VAR (buffer, use_category); } -static bool -decompose_use (const hb_ot_shape_normalize_context_t *c, - hb_codepoint_t ab, - hb_codepoint_t *a, - hb_codepoint_t *b) -{ - switch (ab) - { - /* Chakma: - * Special case where the Unicode decomp gives matras in the wrong order - * for cluster validation. - */ - case 0x1112Eu : *a = 0x11127u; *b= 0x11131u; return true; - case 0x1112Fu : *a = 0x11127u; *b= 0x11132u; return true; - } - - return (bool) c->unicode->decompose (ab, a, b); -} - static bool compose_use (const hb_ot_shape_normalize_context_t *c, hb_codepoint_t a, @@ -602,7 +583,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_use = nullptr, /* preprocess_text */ nullptr, /* postprocess_glyphs */ HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, - decompose_use, + nullptr, /* decompose */ compose_use, setup_masks_use, nullptr, /* disable_otl */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc index 1189b2075b2..e40a0e94a3d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc @@ -41,7 +41,7 @@ #include "hb-set-private.hh" #include "hb-ot-layout-gsubgpos-private.hh" -//#include "hb-aat-layout-private.hh" +#include "hb-aat-layout-private.hh" static hb_tag_t common_features[] = { HB_TAG('c','c','m','p'), @@ -194,7 +194,10 @@ _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan, if (plan->shaper->data_create) { plan->data = plan->shaper->data_create (plan); if (unlikely (!plan->data)) + { + free (plan); return nullptr; + } } return plan; @@ -623,8 +626,8 @@ hb_ot_substitute_complex (hb_ot_shape_context_t *c) c->plan->substitute (c->font, buffer); - /* XXX Call morx instead. */ - //hb_aat_layout_substitute (c->font, c->buffer); + if (0) /* XXX Call morx instead. */ + hb_aat_layout_substitute (c->font, c->buffer); } static inline void diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-private.hh index ddb256f80d5..32e1edffe31 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-private.hh @@ -161,7 +161,11 @@ struct _hb_alignof #ifndef HB_INTERNAL # if !defined(HB_NO_VISIBILITY) && !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(_MSC_VER) && !defined(__SUNPRO_CC) # define HB_INTERNAL __attribute__((__visibility__("hidden"))) -# else +# elif defined(__MINGW32__) + /* We use -export-symbols on mingw32, since it does not support visibility + * attribute. */ +# define HB_INTERNAL +#else # define HB_INTERNAL # define HB_NO_VISIBILITY 1 # endif @@ -375,16 +379,8 @@ typedef uint64_t hb_vector_size_impl_t; #define HB_NULL_POOL_SIZE 264 -#ifdef HB_NO_VISIBILITY -static -#else extern HB_INTERNAL -#endif -hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)] -#ifdef HB_NO_VISIBILITY -= {} -#endif -; +hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)]; /* Generic nul-content Null objects. */ template @@ -413,16 +409,8 @@ static_assert (Namespace::Type::min_size + 1 <= sizeof (_Null##Type), "Null pool * for correct operation. It only exist to catch and divert program logic bugs instead of * causing bad memory access. So, races there are not actually introducing incorrectness * in the code. Has ~12kb binary size overhead to have it, also clang build fails with it. */ -#ifdef HB_NO_VISIBILITY -static -#else extern HB_INTERNAL -#endif -/*thread_local*/ hb_vector_size_impl_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)] -#ifdef HB_NO_VISIBILITY -= {} -#endif -; +/*thread_local*/ hb_vector_size_impl_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)]; /* CRAP pool: Common Region for Access Protection. */ template @@ -537,34 +525,6 @@ hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3) #define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x)) -/* Global runtime options. */ - -struct hb_options_t -{ - unsigned int initialized : 1; - unsigned int uniscribe_bug_compatible : 1; -}; - -union hb_options_union_t { - unsigned int i; - hb_options_t opts; -}; -static_assert ((sizeof (int) == sizeof (hb_options_union_t)), ""); - -HB_INTERNAL void -_hb_options_init (void); - -extern HB_INTERNAL hb_options_union_t _hb_options; - -static inline hb_options_t -hb_options (void) -{ - if (unlikely (!_hb_options.i)) - _hb_options_init (); - - return _hb_options.opts; -} - /* Size signifying variable-sized array */ #define VAR 1 diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper-private.hh index ce2d9f28395..4bd36b5ba05 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper-private.hh @@ -49,21 +49,10 @@ HB_INTERNAL const hb_shaper_pair_t * _hb_shapers_get (void); -/* For embedding in face / font / ... */ -struct hb_shaper_data_t { -#define HB_SHAPER_IMPLEMENT(shaper) void *shaper; -#include "hb-shaper-list.hh" -#undef HB_SHAPER_IMPLEMENT -}; - -#define HB_SHAPERS_COUNT (sizeof (hb_shaper_data_t) / sizeof (void *)) - /* Means: succeeded, but don't need to keep any data. */ #define HB_SHAPER_DATA_SUCCEEDED ((void *) +1) - /* Means: tried but failed to create. */ #define HB_SHAPER_DATA_INVALID ((void *) -1) -#define HB_SHAPER_DATA_IS_INVALID(data) ((void *) (data) == HB_SHAPER_DATA_INVALID) #define HB_SHAPER_DATA_TYPE_NAME(shaper, object) hb_##shaper##_shaper_##object##_data_t #define HB_SHAPER_DATA_TYPE(shaper, object) struct HB_SHAPER_DATA_TYPE_NAME(shaper, object) @@ -97,6 +86,10 @@ HB_SHAPER_DATA_ENSURE_FUNC(shaper, object) (hb_##object##_t *object) \ retry: \ HB_SHAPER_DATA_TYPE (shaper, object) *data = (HB_SHAPER_DATA_TYPE (shaper, object) *) hb_atomic_ptr_get (&HB_SHAPER_DATA (shaper, object)); \ if (likely (data) && !(condition)) { \ + /* Note that evaluating condition above can be dangerous if another thread \ + * got here first and destructed data. That's, as always, bad use pattern. \ + * If you modify the font (change font size), other threads must not be \ + * using it at the same time. */ \ /* Drop and recreate. */ \ /* If someone dropped it in the mean time, throw it away and don't touch it. \ * Otherwise, destruct it. */ \ @@ -117,8 +110,17 @@ HB_SHAPER_DATA_ENSURE_FUNC(shaper, object) (hb_##object##_t *object) \ goto retry; \ } \ } \ - return data != nullptr && !HB_SHAPER_DATA_IS_INVALID (data); \ + return data != nullptr && (void *) data != HB_SHAPER_DATA_INVALID; \ } +/* For embedding in face / font / ... */ +struct hb_shaper_data_t { +#define HB_SHAPER_IMPLEMENT(shaper) void *shaper; +#include "hb-shaper-list.hh" +#undef HB_SHAPER_IMPLEMENT +}; +#define HB_SHAPERS_COUNT (sizeof (hb_shaper_data_t) / sizeof (void *)) + + #endif /* HB_SHAPER_PRIVATE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc index ee17cd3481c..e6920e7e01c 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc @@ -25,8 +25,34 @@ */ #include "hb-private.hh" +#include "hb-face-private.hh" +#include "hb-open-type-private.hh" +#include "hb-ot-head-table.hh" +#include "hb-ot-maxp-table.hh" #ifndef HB_NO_VISIBILITY + hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)] = {}; /*thread_local*/ hb_vector_size_impl_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)] = {}; + +void +hb_face_t::load_num_glyphs (void) const +{ + OT::hb_sanitize_context_t c = OT::hb_sanitize_context_t(); + c.set_num_glyphs (0); /* So we don't recurse ad infinitum. */ + hb_blob_t *maxp_blob = c.reference_table (this); + const OT::maxp *maxp_table = maxp_blob->as (); + num_glyphs = maxp_table->get_num_glyphs (); + hb_blob_destroy (maxp_blob); +} + +void +hb_face_t::load_upem (void) const +{ + hb_blob_t *head_blob = OT::hb_sanitize_context_t().reference_table (this); + const OT::head *head_table = head_blob->as (); + upem = head_table->get_upem (); + hb_blob_destroy (head_blob); +} + #endif diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.cc index c8fa39be807..2b97a010a19 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.cc @@ -292,7 +292,7 @@ hb_subset_glyf_and_loca (hb_subset_plan_t *plan, hb_blob_t **glyf_prime, /* OUT */ hb_blob_t **loca_prime /* OUT */) { - hb_blob_t *glyf_blob = OT::Sanitizer().sanitize (plan->source->reference_table (HB_OT_TAG_glyf)); + hb_blob_t *glyf_blob = OT::hb_sanitize_context_t().reference_table (plan->source); const char *glyf_data = hb_blob_get_data(glyf_blob, nullptr); OT::glyf::accelerator_t glyf; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc index 55c4e3f6193..12566827251 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc @@ -56,11 +56,15 @@ _add_gid_and_children (const OT::glyf::accelerator_t &glyf, static void _gsub_closure (hb_face_t *face, hb_set_t *gids_to_retain) { - // TODO(grieger): This uses all lookups, instead collect - // the set of lookups that are relevant. - // See fontTools implementation. + hb_auto_t lookup_indices; + hb_ot_layout_collect_lookups (face, + HB_OT_TAG_GSUB, + nullptr, + nullptr, + nullptr, + &lookup_indices); hb_ot_layout_lookups_substitute_closure (face, - nullptr, + &lookup_indices, gids_to_retain); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc index a65b58d26f7..308c7eb21c9 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc @@ -78,9 +78,7 @@ template static bool _subset (hb_subset_plan_t *plan) { - OT::Sanitizer sanitizer; - - hb_blob_t *source_blob = sanitizer.sanitize (plan->source->reference_table (TableType::tableTag)); + hb_blob_t *source_blob = OT::hb_sanitize_context_t().reference_table (plan->source); const TableType *table = source_blob->as (); hb_tag_t tag = TableType::tableTag; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc index b17fa31ca27..0199e65f864 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc @@ -358,7 +358,7 @@ _hb_rename_font (hb_blob_t *blob, wchar_t *new_name) * full, PS. All of them point to the same name data with our unique name. */ - blob = OT::Sanitizer().sanitize (blob); + blob = OT::hb_sanitize_context_t().sanitize_blob (blob); unsigned int length, new_length, name_str_len; const char *orig_sfnt_data = hb_blob_get_data (blob, &length); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc index 873d240a362..c6e05fc3780 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc @@ -51,8 +51,7 @@ main (int argc, char **argv) const char *font_data = hb_blob_get_data (blob, &len); printf ("Opened font file %s: %d bytes long\n", argv[1], len); - Sanitizer sanitizer; - hb_blob_t *font_blob = sanitizer.sanitize (blob); + hb_blob_t *font_blob = hb_sanitize_context_t().sanitize_blob (blob); const OpenTypeFontFile* sanitized = font_blob->as (); if (sanitized == &Null(OpenTypeFontFile)) { diff --git a/Build/source/libs/harfbuzz/version.ac b/Build/source/libs/harfbuzz/version.ac index d3f0c25996f..8e2a1b62840 100644 --- a/Build/source/libs/harfbuzz/version.ac +++ b/Build/source/libs/harfbuzz/version.ac @@ -8,4 +8,4 @@ dnl dnl -------------------------------------------------------- dnl dnl m4-include this file to define the current harfbuzz version -m4_define([harfbuzz_version], [1.8.4]) +m4_define([harfbuzz_version], [1.8.5]) -- cgit v1.2.3