From 1574815ed78c28a3881dd35100d988b0c5093868 Mon Sep 17 00:00:00 2001 From: Akira Kakuto Date: Fri, 19 Feb 2016 14:02:02 +0000 Subject: libs/harfbuzz: HarfBuzz 1.2.0 git-svn-id: svn://tug.org/texlive/trunk@39781 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/libs/README | 2 +- Build/source/libs/harfbuzz/ChangeLog | 5 + Build/source/libs/harfbuzz/configure | 22 +- .../libs/harfbuzz/harfbuzz-PATCHES/ChangeLog | 5 + .../libs/harfbuzz/harfbuzz-PATCHES/TL-Changes | 3 +- Build/source/libs/harfbuzz/harfbuzz-src/BUILD.md | 4 +- Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog | 679 +++++++++++++++++ .../source/libs/harfbuzz/harfbuzz-src/Makefile.am | 2 +- Build/source/libs/harfbuzz/harfbuzz-src/NEWS | 20 + Build/source/libs/harfbuzz/harfbuzz-src/README | 1 + .../source/libs/harfbuzz/harfbuzz-src/config.h.in | 6 + .../source/libs/harfbuzz/harfbuzz-src/configure.ac | 29 +- .../libs/harfbuzz/harfbuzz-src/src/Makefile.am | 172 +---- .../harfbuzz/harfbuzz-src/src/Makefile.sources | 150 ++++ .../libs/harfbuzz/harfbuzz-src/src/hb-blob.cc | 1 - .../harfbuzz/harfbuzz-src/src/hb-buffer-private.hh | 3 +- .../libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc | 2 + .../libs/harfbuzz/harfbuzz-src/src/hb-common.cc | 2 +- .../harfbuzz/harfbuzz-src/src/hb-directwrite.cc | 827 +++++++++++++++++++++ .../harfbuzz/harfbuzz-src/src/hb-directwrite.h | 34 + .../libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc | 71 +- .../src/hb-ot-layout-common-private.hh | 30 +- .../harfbuzz-src/src/hb-ot-layout-gpos-table.hh | 138 ++-- .../harfbuzz-src/src/hb-ot-layout-gsub-table.hh | 6 - .../src/hb-ot-layout-gsubgpos-private.hh | 2 +- .../harfbuzz-src/src/hb-ot-layout-private.hh | 34 +- .../libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc | 136 ++-- .../src/hb-ot-shape-complex-default.cc | 2 +- .../harfbuzz-src/src/hb-ot-shape-complex-indic.cc | 2 +- .../src/hb-ot-shape-complex-myanmar.cc | 2 +- .../src/hb-ot-shape-complex-private.hh | 2 - .../harfbuzz-src/src/hb-ot-shape-complex-thai.cc | 2 +- .../src/hb-ot-shape-complex-tibetan.cc | 2 +- .../harfbuzz-src/src/hb-ot-shape-complex-use.cc | 4 +- .../libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc | 49 +- .../libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc | 2 +- .../harfbuzz-src/src/hb-unicode-private.hh | 5 +- Build/source/libs/harfbuzz/version.ac | 2 +- 38 files changed, 2085 insertions(+), 375 deletions(-) create mode 100644 Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources create mode 100644 Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc create mode 100644 Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.h (limited to 'Build') diff --git a/Build/source/libs/README b/Build/source/libs/README index b5490d61afc..2f3cd975003 100644 --- a/Build/source/libs/README +++ b/Build/source/libs/README @@ -24,7 +24,7 @@ gmp 6.1.0 - checked 28dec15 graphite2 1.3.5 - checked 20jan16 http://sourceforge.net/projects/silgraphite/files/graphite2/ -harfbuzz 1.1.3 - checked 12jan16 +harfbuzz 1.2.0 - checked 19feb16 http://www.freedesktop.org/software/harfbuzz/release/ icu 56.1 (release) - checked 8oct15 diff --git a/Build/source/libs/harfbuzz/ChangeLog b/Build/source/libs/harfbuzz/ChangeLog index be0ba4ff36c..0c493798b1a 100644 --- a/Build/source/libs/harfbuzz/ChangeLog +++ b/Build/source/libs/harfbuzz/ChangeLog @@ -1,3 +1,8 @@ +2016-02-19 Akira Kakuto + + Import harfbuzz-1.2.0. + * version.ac: Adjusted. + 2016-02-15 Karl Berry * harfbuzz-PATCHES: rename from harfbuzz-src-PATCHES. diff --git a/Build/source/libs/harfbuzz/configure b/Build/source/libs/harfbuzz/configure index 18828edecb0..3e0d5b307e3 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.1.3. +# Generated by GNU Autoconf 2.69 for harfbuzz (TeX Live) 1.2.0. # # 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.1.3' -PACKAGE_STRING='harfbuzz (TeX Live) 1.1.3' +PACKAGE_VERSION='1.2.0' +PACKAGE_STRING='harfbuzz (TeX Live) 1.2.0' PACKAGE_BUGREPORT='tex-k@tug.org' PACKAGE_URL='' @@ -1312,7 +1312,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.1.3 to adapt to many kinds of systems. +\`configure' configures harfbuzz (TeX Live) 1.2.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1383,7 +1383,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of harfbuzz (TeX Live) 1.1.3:";; + short | recursive ) echo "Configuration of harfbuzz (TeX Live) 1.2.0:";; esac cat <<\_ACEOF @@ -1490,7 +1490,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -harfbuzz (TeX Live) configure 1.1.3 +harfbuzz (TeX Live) configure 1.2.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2080,7 +2080,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.1.3, which was +It was created by harfbuzz (TeX Live) $as_me 1.2.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -4003,7 +4003,7 @@ fi # Define the identity of the package. PACKAGE='harfbuzz--tex-live-' - VERSION='1.1.3' + VERSION='1.2.0' cat >>confdefs.h <<_ACEOF @@ -4207,7 +4207,7 @@ WARNING_CFLAGS=$kpse_cv_warning_cflags HB_VERSION_MAJOR=1 HB_VERSION_MINOR=1 HB_VERSION_MICRO=3 -HB_VERSION=1.1.3 +HB_VERSION=1.2.0 ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -6866,7 +6866,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.1.3, which was +This file was extended by harfbuzz (TeX Live) $as_me 1.2.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -6932,7 +6932,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.1.3 +harfbuzz (TeX Live) config.status 1.2.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/Build/source/libs/harfbuzz/harfbuzz-PATCHES/ChangeLog b/Build/source/libs/harfbuzz/harfbuzz-PATCHES/ChangeLog index c0434328266..8c2534f3e70 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-PATCHES/ChangeLog +++ b/Build/source/libs/harfbuzz/harfbuzz-PATCHES/ChangeLog @@ -1,3 +1,8 @@ +2016-02-19 Akira Kakuto + + Imported harfbuzz-1.2.0 source tree from: + http://www.freedesktop.org/software/harfbuzz/release/ + 2016-01-12 Akira Kakuto Imported harfbuzz-1.1.3 source tree from: diff --git a/Build/source/libs/harfbuzz/harfbuzz-PATCHES/TL-Changes b/Build/source/libs/harfbuzz/harfbuzz-PATCHES/TL-Changes index 817d2eeed7b..d0ccd5585d8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-PATCHES/TL-Changes +++ b/Build/source/libs/harfbuzz/harfbuzz-PATCHES/TL-Changes @@ -1,4 +1,4 @@ -Changes applied to the harfbuzz-1.1.3/ tree as obtained from: +Changes applied to the harfbuzz-1.2.0/ tree as obtained from: http://www.freedesktop.org/software/harfbuzz/release/ Removed: @@ -24,4 +24,5 @@ Removed unused dirs: m4 test util + win32 src/hb-ucdn diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/BUILD.md b/Build/source/libs/harfbuzz/harfbuzz-src/BUILD.md index e9d7d4d5da3..86285c64858 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/BUILD.md +++ b/Build/source/libs/harfbuzz/harfbuzz-src/BUILD.md @@ -15,7 +15,9 @@ or using Homebrew: If you are using a tarball, you can now proceed to running configure and make as with any other standard package. That should leave you with a shared library in src/, and a few utility programs including hb-view and hb-shape -under util/. +under util/. From the tarball, NMake Makefiles are also provided in win32/, +which supports building HarfBuzz using Visual Studio, with a README.txt that +gives instructions on building using NMake. If you are bootstraping from git, you need a few more tools before you can run autogen.sh for the first time. Namely, pkg-config and ragel. Again, on Ubuntu / Debian: diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog b/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog index 22424f26fdc..50611730e1b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog +++ b/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog @@ -1,3 +1,682 @@ +commit c3731559042e1730e85d19574321ad850010f7de +Author: Behdad Esfahbod +Date: Fri Feb 19 15:13:07 2016 +0700 + + [fuzzing] Add test for recent fix + + Test from https://github.com/behdad/harfbuzz/issues/223 + + I forgot that we do run hb-fuzzer on tests in + shaping/tests/fuzzed.tests. + + .../sha1sum/205edd09bd3d141cc9580f650109556cc28b22cb.ttf | Bin 0 -> + 1966 bytes + test/shaping/fonts/sha1sum/MANIFEST | 1 + + test/shaping/tests/fuzzed.tests | 1 + + 3 files changed, 2 insertions(+) + +commit aa33cb72ab29c31e87f0cca9a0e72fe3a68247b7 +Author: Behdad Esfahbod +Date: Fri Feb 19 15:12:24 2016 +0700 + + [fuzzing] Make test runner actually work + + test/fuzzing/Makefile.am | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +commit 2735555c6b0c95db7dfc2b391f92a1a5c06084c4 +Author: Behdad Esfahbod +Date: Fri Feb 19 15:12:16 2016 +0700 + + [fuzzing] Add TODO item + + test/fuzzing/hb-fuzzer.cc | 1 + + 1 file changed, 1 insertion(+) + +commit b87e36f6f119fac80b8fd55f3abae563c2c5b798 +Author: Behdad Esfahbod +Date: Fri Feb 19 14:52:31 2016 +0700 + + Avoid buffer->move_to() in case of buffer error + + Fixes https://github.com/behdad/harfbuzz/issues/223 + + Right now we cannot test this because it has to be tested using + hb-fuzzer. + We should move all fuzzing tests from test/shaping/tests/fuzzed.tests + to + test/fuzzing/ and have its own test runner. At that point, should add + test from this issue as well. + + src/hb-buffer.cc | 2 ++ + src/hb-ot-layout-gsubgpos-private.hh | 2 +- + 2 files changed, 3 insertions(+), 1 deletion(-) + +commit 7e76bbabbaa56af314abff8ddba8866c634919cd +Author: Behdad Esfahbod +Date: Fri Feb 19 14:43:39 2016 +0700 + + [fuzzing] Make "make hb-fuzzer" build lib dependency + + Not going to do with util/, but is convenient here. + + test/fuzzing/Makefile.am | 3 +++ + 1 file changed, 3 insertions(+) + +commit 568a0c60e8695a6ad8a93ec60d55b137c48890cb +Author: Behdad Esfahbod +Date: Thu Feb 18 19:31:51 2016 +0700 + + Remove pointless overflow check in pointer math + + Fixes https://github.com/behdad/harfbuzz/issues/227 + + src/hb-blob.cc | 1 - + 1 file changed, 1 deletion(-) + +commit aae2847099cbf05bf0668fbe526fc58736837c1b +Author: Behdad Esfahbod +Date: Thu Feb 18 17:06:25 2016 +0700 + + Emoji skin tone modifiers need to be treated as combining marks + + Fixes https://github.com/behdad/harfbuzz/issues/169 + + src/hb-ot-layout-private.hh | 15 ++++++++++++++- + src/hb-unicode-private.hh | 5 +++-- + 2 files changed, 17 insertions(+), 3 deletions(-) + +commit da41e48f0a1a6af6d44ef25185d2421a29bd4166 +Author: Behdad Esfahbod +Date: Tue Feb 16 17:16:33 2016 +0700 + + [USE] Zero mark advances by GDEF early + + This is what Microsoft's implementation does. Marks that need advance + need to add it back using 'dist' or other feature in GPOS. + Update tests to + match. + + src/hb-ot-shape-complex-use.cc | 2 +- + test/shaping/fonts/sha1sum/MANIFEST | 1 + + .../sha1sum/f518eb6f6b5eec2946c9fbbbde44e45d46f5e2ac.ttf | Bin 0 -> + 1356 bytes + test/shaping/tests/context-matching.tests | 2 +- + test/shaping/tests/use.tests | 2 ++ + 5 files changed, 5 insertions(+), 2 deletions(-) + +commit 86c68c7a2c971efe8e35b1f1bd99401dc8b688d2 +Author: Behdad Esfahbod +Date: Tue Feb 16 16:07:20 2016 +0700 + + [GPOS] Fix interaction of mark attachments and cursive chaining + + Fixes https://github.com/behdad/harfbuzz/issues/211 + + What happens in that bug is that a mark is attached to base first, + then a second mark is cursive-chained to the first mark. This only + "works" because it's in the Indic shaper where mark advances are + not zeroed. + + Before, we didn't allow cursive to run on marks at all. Fix that. + We also where updating mark major offsets at the end of GPOS, such + that changes in advance of base will not change the mark attachment + position. That was superior to the alternative (which is what + Uniscribe + does BTW), but made it hard to apply cursive to the mark after it + was positioned. We could track major-direction offset changes and + apply that to cursive in the post process, but that's a much trickier + thing to do than the fix here, which is to immediately apply the + major-direction advance-width offsets... Ie.: + + https://github.com/behdad/harfbuzz/issues/211#issuecomment-183194739 + + If this breaks any fonts, the font should be fixed to do mark + attachment + after all the advances are set up first (kerning, etc). + + Finally, this, still doesn't make us match Uniscribe, for I explained + in that bug. Looks like Uniscribe applies minor-direction cursive + adjustment immediate as well. We don't, and we like it our way, at + least for now. Eg. the sequence in the test case does this: + + - The first subscript attaches with mark-to-base, moving in x only, + - The second subscript attaches with cursive attachment to first + subscript + moving in x only, + - A final context rule moves the first subscript up by 104 units. + + The way we do, the final shift-up, also shifts up the second subscript + mark because it's cursively-attached. Uniscribe doesn't. We get: + + [ttaorya=0+1307|casubscriptorya=0@-242,104+-231|casubscriptnarroworya=0@20,104+507] + + while Uniscribe gets: + + [ttaorya=0+1307|casubscriptorya=0@-242,104+-211|casubscriptnarroworya=0+487] + + note the different y-offset of the last glyph. In our view, + after cursive, + things move together, period. + + src/hb-ot-layout-gpos-table.hh | 31 + +++++++++++---------- + .../706c5d7b625f207bc0d874c67237aad6f1e9cd6f.ttf | Bin 0 -> 3868 bytes + test/shaping/fonts/sha1sum/MANIFEST | 1 + + test/shaping/tests/cursive-positioning.tests | 1 + + 4 files changed, 18 insertions(+), 15 deletions(-) + +commit 80c8855cfeffa028d74a25df884d0e5577c95c6c +Author: Behdad Esfahbod +Date: Fri Feb 12 12:50:17 2016 +0700 + + Minor + + src/hb-common.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 6ab920224c32e38072a0bec5e84d4b0d58b74167 +Author: Behdad Esfahbod +Date: Thu Feb 11 16:57:52 2016 +0700 + + [GPOS] Minor + + No effect. + + src/hb-ot-layout-gpos-table.hh | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit cbc3a76c5a38ab24f72e80357377711bd3f54d56 +Author: Behdad Esfahbod +Date: Thu Feb 11 16:48:13 2016 +0700 + + [GPOS] Merge fixing of offsets for cursive and mark attachments + + Part of fixing https://github.com/behdad/harfbuzz/issues/211 + + src/hb-buffer-private.hh | 3 +- + src/hb-ot-layout-gpos-table.hh | 73 + ++++++++++++++++++------------------------ + 2 files changed, 33 insertions(+), 43 deletions(-) + +commit 7d8d58ac81fe267e29ea68cdc6f4a4fa8c22d40f +Author: Behdad Esfahbod +Date: Thu Feb 11 16:34:28 2016 +0700 + + [GPOS] Divide position_finish() into two phases, for advances + and offsets + + Right now the position_finish_advances() is empty. To be used for + spacing attachments proposal later. + + src/hb-ot-layout-gpos-table.hh | 11 +++++++++-- + src/hb-ot-layout-gsub-table.hh | 6 ------ + src/hb-ot-layout-private.hh | 19 +++++++++---------- + src/hb-ot-layout.cc | 16 ++++++++-------- + src/hb-ot-shape.cc | 7 +++---- + 5 files changed, 29 insertions(+), 30 deletions(-) + +commit 8474231567a08873cc5e0aa08fea60316a04c27e +Author: Behdad Esfahbod +Date: Thu Feb 11 16:27:41 2016 +0700 + + [ot] Minor shuffling code around + + src/hb-ot-layout-gpos-table.hh | 2 -- + src/hb-ot-shape.cc | 13 ++++++++----- + 2 files changed, 8 insertions(+), 7 deletions(-) + +commit b0b11614e9fb9ecd1faae28b0ed71ac6bf5c1266 +Author: Behdad Esfahbod +Date: Thu Feb 11 15:28:55 2016 +0700 + + [GPOS] Add harmless recursion in fix_mark_attachment() + + Will do nothing. Just useful for merging two functions. + + src/hb-ot-layout-gpos-table.hh | 2 ++ + 1 file changed, 2 insertions(+) + +commit 686567baab5a32ffea843538643e01de2885fa4f +Author: Behdad Esfahbod +Date: Thu Feb 11 15:25:28 2016 +0700 + + [GPOS] Merge attach_chain() and cursive_chain() + + Differentiate, using new attach_type(). + + src/hb-ot-layout-gpos-table.hh | 50 + +++++++++++++++++++++++++++--------------- + 1 file changed, 32 insertions(+), 18 deletions(-) + +commit 806ad8dc65931ab7893bff7d5592a67a9bd237ca +Author: Behdad Esfahbod +Date: Thu Feb 11 14:53:11 2016 +0700 + + [GPOS] Minor shuffling + + src/hb-ot-layout-gpos-table.hh | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +commit 0f6278d1fbb75856132f1fa2d29648979f033316 +Author: Behdad Esfahbod +Date: Thu Feb 11 14:49:10 2016 +0700 + + [GPOS] Negate sign of attach_lookback(), and rename it to + attach_chain() + + No behavior change. Preparing to unify how cursive and mark + attachments + work. + + src/hb-ot-layout-gpos-table.hh | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +commit 5b5dc2c0406d8180e72d97a54334c722fda325b1 +Author: Behdad Esfahbod +Date: Thu Feb 11 12:15:38 2016 +0700 + + [tests] Add test for advance zeroing of an ASCII letter marked as + mark in GDEF + + test/shaping/fonts/sha1sum/MANIFEST | 1 + + .../sha1sum/a98e908e2ed21b22228ea59ebcc0f05034c86f2e.ttf | Bin 0 -> + 1016 bytes + test/shaping/tests/zero-width-marks.tests | 1 + + 3 files changed, 2 insertions(+) + +commit 660c9d3fc21172e8dc340b017122c084dac6334c +Author: Behdad Esfahbod +Date: Thu Feb 11 12:14:27 2016 +0700 + + Remove font-dependent ASCII-only perf hack + + Is confusing. I already hit it myself. Remove. We can optimize + ASCII based on Unicode properties. But should not do based on + assumptions on the font. + + src/hb-ot-shape.cc | 4 ---- + 1 file changed, 4 deletions(-) + +commit 3fe0cf10401875f1e9b8b5fbaf59826e64ea61d2 +Author: Behdad Esfahbod +Date: Wed Feb 10 18:43:43 2016 +0700 + + Fix previous commit! + + test/shaping/fonts/sha1sum/MANIFEST | 6 +++--- + test/shaping/tests/zero-width-marks.tests | 6 +++--- + 2 files changed, 6 insertions(+), 6 deletions(-) + +commit 293a210eee0a53b59f4b33298f42ec6e59d785e0 +Author: Behdad Esfahbod +Date: Wed Feb 10 18:39:59 2016 +0700 + + [tests] Fix fonts in cc4a78bf22c4a735b84c89b04be3bb531f42135e + + They had an invalid LookupFlag (32). + + .../sha1sum/0dd3a51c3ea50997cb1f72515d1060408f8b4b59.ttf | Bin 1412 -> + 0 bytes + .../sha1sum/56cfd0e18d07f41c38e9598545a6d369127fc6f9.ttf | Bin 0 -> + 1412 bytes + .../sha1sum/828114d00931885bc25abf7cdb878b2914a2e743.ttf | Bin 1448 -> + 0 bytes + .../sha1sum/894e96a367f00c196d82e6243673a1d4414f4f6a.ttf | Bin 1448 -> + 0 bytes + .../sha1sum/cc5f3d2d717fb6bd4dfae1c16d48a2cb8e12233b.ttf | Bin 0 -> + 1448 bytes + .../sha1sum/ffa0f5d2d9025486d8469d8b1fdd983e7632499b.ttf | Bin 0 -> + 1448 bytes + 6 files changed, 0 insertions(+), 0 deletions(-) + +commit eaadcbbc53e02838c847e53ef214a55d6915d677 +Author: Behdad Esfahbod +Date: Wed Feb 10 18:29:54 2016 +0700 + + Remove now-unused mark zeroing BY_UNICODE + + src/hb-ot-shape-complex-private.hh | 2 -- + src/hb-ot-shape.cc | 29 ----------------------------- + 2 files changed, 31 deletions(-) + +commit cc4a78bf22c4a735b84c89b04be3bb531f42135e +Author: Behdad Esfahbod +Date: Wed Feb 10 18:24:08 2016 +0700 + + [tests] Add tests for Latin mark zeroing + + .../sha1sum/0dd3a51c3ea50997cb1f72515d1060408f8b4b59.ttf | Bin 0 -> + 1412 bytes + .../sha1sum/828114d00931885bc25abf7cdb878b2914a2e743.ttf | Bin 0 -> + 1448 bytes + .../sha1sum/894e96a367f00c196d82e6243673a1d4414f4f6a.ttf | Bin 0 -> + 1448 bytes + test/shaping/fonts/sha1sum/MANIFEST | 4 ++++ + .../sha1sum/fcdcffbdf1c4c97c05308d7600e4c283eb47dbca.ttf | Bin 0 -> + 1344 bytes + test/shaping/tests/zero-width-marks.tests | 4 ++++ + 6 files changed, 8 insertions(+) + +commit 55ff34b9c157a839d026465af8f30424ce7f891b +Author: Behdad Esfahbod +Date: Wed Feb 10 18:20:02 2016 +0700 + + [tests] Add tests for Thai mark zeroing + + .../sha1sum/45855bc8d46332b39c4ab9e2ee1a26b1f896da6b.ttf | Bin 0 -> + 1088 bytes + .../sha1sum/7a37dc4d5bf018456aea291cee06daf004c0221c.ttf | Bin 0 -> + 1080 bytes + .../sha1sum/8099955657a54e9ee38a6ba1d6f950ce58e3cc25.ttf | Bin 0 -> + 1024 bytes + test/shaping/fonts/sha1sum/MANIFEST | 4 ++++ + .../sha1sum/bb0c53752e85c3d28973ebc913287b8987d3dfe8.ttf | Bin 0 -> + 976 bytes + test/shaping/tests/zero-width-marks.tests | 4 ++++ + 6 files changed, 8 insertions(+) + +commit b3582a8ee82942a931130a83b2867b239f8ca71a +Author: Behdad Esfahbod +Date: Wed Feb 10 18:10:15 2016 +0700 + + Change default mark advance zeroing behavior from Unicode to GDEF + + See thread at: + https://lists.freedesktop.org/archives/harfbuzz/2016-February/005462.html + + src/hb-ot-shape-complex-default.cc | 2 +- + src/hb-ot-shape-complex-thai.cc | 2 +- + src/hb-ot-shape-complex-tibetan.cc | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +commit 43bb2b8fb00705c3334730a58ade7984181018b2 +Author: Behdad Esfahbod +Date: Wed Feb 10 14:11:43 2016 +0700 + + Minor + + test/shaping/hb_test_tools.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit bdaa784bb610ec65626d63cc068a0958ff5005fc +Merge: a168db4 f6ffba6 +Author: Behdad Esfahbod +Date: Wed Feb 10 11:11:36 2016 +0700 + + Merge pull request #164 from fanc999/msvc.build + + Enable Build of HarfBuzz under Visual Studio using NMake Makefiles + +commit a168db4739148459bc33c7dae88e73efa0153d72 +Author: Behdad Esfahbod +Date: Wed Feb 10 11:10:08 2016 +0700 + + [README] Add ABI Tracker link + + README | 1 + + 1 file changed, 1 insertion(+) + +commit f6ffba634bb33d6d4b051abce9c23fcae280c3fe +Author: Chun-wei Fan +Date: Wed Dec 9 14:57:15 2015 +0800 + + MSVC builds: Add support to build DirectWrite shaping backend + + Add into the NMake Makefiles to build the DirectWrite shaping backend, + but as PR #134 mentions, this is considered to be in an experimental + state, + so don't include this in the build by default for now. This is + most probably + going to replace the Uniscribe backend eventually, since DirectWrite + is meant + to be Uniscribe's replacement, and is needed for Windows Store apps + if a + system shaping API is to be used. + + win32/README.txt | 4 ++++ + win32/config-msvc.mak | 10 ++++++++++ + win32/config.h.win32.in | 3 +++ + win32/info-msvc.mak | 7 +++++++ + 4 files changed, 24 insertions(+) + +commit c6792854557ca104948e8f0b142c9384105b0d05 +Author: Chun-wei Fan +Date: Wed Feb 3 18:31:23 2016 +0800 + + build: Build the DirectWrite sources if requested + + This adds to the autotools build system so that the (experimental) + DirectWrite support for HarfBuzz is built (and dist'ed). + + configure.ac | 25 +++++++++++++++++++++++++ + src/Makefile.am | 7 +++++++ + src/Makefile.sources | 3 +++ + 3 files changed, 35 insertions(+) + +commit d7b6636e5ebf1ddf7d7a04007ffbc411cf7e462e +Author: Chun-wei Fan +Date: Tue Nov 3 19:00:42 2015 +0800 + + build: Support Visual Studio builds using NMake + + This adds a set of NMake Makefiles that can be used to build + HarfBuzz, from + the standard basic build building the minimal HarfBuzz DLL (consisting + of OpenType, fallback and Uniscribe support only), to a full + fledged build + consisting of GLib and FreeType support, as well as building the + utilities, + the test programs in src/ and test/api, and HarfBuzz-ICU and + HarfBuzz-GObject, and up to building the introspection files. + This means a + flexible build mechanism is supported here, so anything that is + supported + for a Windows build (code-wise), should all be supported by this build + system. + + As in an earlier commit, the source listings are shared with the + autotools + builds with the various Makefile.sources in src/, src/hb-ucdn and + util/, and + this set of NMake Makefiles will transform these lists into the + form they + want. + + In the current form, all the test programs in test/api pass, and + this has + been checked successfully with 'make -j8 distcheck'. + + BUILD.md | 4 +- + Makefile.am | 2 +- + configure.ac | 2 + + win32/Makefile.am | 14 +++ + win32/Makefile.vc | 52 +++++++++++ + win32/README.txt | 75 ++++++++++++++++ + win32/build-rules-msvc.mak | 140 ++++++++++++++++++++++++++++++ + win32/config-msvc.mak | 188 + ++++++++++++++++++++++++++++++++++++++++ + win32/create-lists-msvc.mak | 151 ++++++++++++++++++++++++++++++++ + win32/create-lists.bat | 42 +++++++++ + win32/detectenv-msvc.mak | 136 +++++++++++++++++++++++++++++ + win32/generate-msvc.mak | 26 ++++++ + win32/hb-introspection-msvc.mak | 42 +++++++++ + win32/info-msvc.mak | 130 +++++++++++++++++++++++++++ + win32/install.mak | 29 +++++++ + win32/introspection-msvc.mak | 73 ++++++++++++++++ + 16 files changed, 1104 insertions(+), 2 deletions(-) + +commit 5c3e7260bcb4999b8b7cb9afb26e6eaff867634b +Author: Chun-wei Fan +Date: Tue Nov 3 18:52:46 2015 +0800 + + MSVC builds: Add a pre-configured config.h(.win32) template + + This adds a pre-configured config.h template that can be used + for Visual + Studio builds, where autotools is not normally available. This has + the + configs that are suitable for Visual Studio builds, as well as all the + features used for Windows builds enabled (HAVE_OT, HAVE_FALLBACK and + HAVE_UNISCRIBE). + + Note that the optional features are not enabled here, they are + enabled by + /D's (or -D's) in the NMake Makefiles as requested. + + win32/config.h.win32.in | 155 + ++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 155 insertions(+) + +commit 35ded3af74a5bc4b038a07308354d5f7501ae3c7 +Author: Chun-wei Fan +Date: Tue Nov 3 16:56:27 2015 +0800 + + build: Move source listings into separate Makefile snippets + + This moves all the source listings in src/Makefile.am, + src/hb-ucdn/Makefile.am and util/Makefile.am into separate Makefile + snippets, so that they may be shared between different Makefile-based + build systems, such as NMake for Visual Studio. + + src/Makefile.am | 165 + +++++++++---------------------------------- + src/Makefile.sources | 147 ++++++++++++++++++++++++++++++++++++++ + src/hb-ucdn/Makefile.am | 6 +- + src/hb-ucdn/Makefile.sources | 4 ++ + util/Makefile.am | 34 ++------- + util/Makefile.sources | 32 +++++++++ + 6 files changed, 223 insertions(+), 165 deletions(-) + +commit b894a85ad1e7c3ecfb6d3732a7c9779f5462fe70 +Author: Behdad Esfahbod +Date: Tue Feb 2 16:39:19 2016 +0800 + + Fix more hangs in case of buffer allocation errors + + Hopefully + fixes https://github.com/behdad/harfbuzz/issues/214 + + src/hb-ot-shape-complex-indic.cc | 2 +- + src/hb-ot-shape-complex-myanmar.cc | 2 +- + src/hb-ot-shape-complex-use.cc | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +commit b693992ea160b66541f678dc9be29b513c77a30b +Merge: 9a6a33c 498574e +Author: Behdad Esfahbod +Date: Tue Feb 2 12:33:32 2016 +0800 + + Merge pull request #222 from n8willis/master + + Add usermanual chapter on cluster levels + +commit 498574e6c1a83bbd2768925af6e39806fe1ea8bb +Author: n8willis +Date: Thu Jan 28 12:21:32 2016 -0600 + + Update Makefile.am + + docs/Makefile.am | 1 + + 1 file changed, 1 insertion(+) + +commit e12fc666994573dbabb6928a8b2e8698667088ce +Author: n8willis +Date: Thu Jan 28 12:14:12 2016 -0600 + + Added initial usermanual chapter on cluster levels. + + docs/harfbuzz-docs.xml | 1 + + docs/usermanual-clusters.xml | 304 + +++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 305 insertions(+) + +commit 9a6a33ccbea8a2e23e779bd955958fa41974c1c7 +Merge: d05b783 146fe25 +Author: Behdad Esfahbod +Date: Mon Jan 18 12:47:18 2016 +0100 + + Merge pull request #216 from mhosken/master + + Refactor graphite2 to make ovleraps into negative width spaces + +commit 146fe252c3ebd0253344ce20981554e40926497b +Author: Martin Hosken +Date: Sat Jan 16 17:24:00 2016 -0600 + + Refactor graphite2 to make ovleraps into negative width spaces + + src/hb-graphite2.cc | 71 + ++++++++++++++++++++++++++++++++--------------------- + 1 file changed, 43 insertions(+), 28 deletions(-) + +commit d05b783322d90208b2ddf06a5ebffc7c301be3d7 +Author: Behdad Esfahbod +Date: Tue Jan 12 16:17:21 2016 +0000 + + Fix compiler warning + + Fixes https://github.com/behdad/harfbuzz/issues/212 + + src/hb-ot-tag.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit d163dc18e66c9e2f404d09310482464245cae704 +Author: Behdad Esfahbod +Date: Tue Jan 12 13:05:01 2016 +0000 + + Minor + + src/hb-ot-layout-common-private.hh | 30 +++++++++++++++--------------- + 1 file changed, 15 insertions(+), 15 deletions(-) + +commit 505b7d4732c6a8c423f43c0de46e05dc583e82c0 +Author: Behdad Esfahbod +Date: Mon Jan 11 18:31:04 2016 +0000 + + [fuzzing] Fuzz input text + + Very rudimentary right now, but will get kcc's bot going. + + From + https://github.com/behdad/harfbuzz/issues/139#issuecomment-163580783 + + test/fuzzing/hb-fuzzer.cc | 25 +++++++++++++++++++------ + 1 file changed, 19 insertions(+), 6 deletions(-) + +commit 3e704521f67e021fb51cda7319925fd39eba4f97 +Author: Behdad Esfahbod +Date: Mon Jan 11 17:38:41 2016 +0000 + + [OT] Get list of lookup subtables once and loop through them + + This speeds up shaping the Amiri font by over 15%. + + This was primarily needed for my work on OpenType GX, since + we will be collecting only sublookups that are "active" for + current font instance; but it's a nice boost in general as + well. + + We might, in the future, collect subtables in the lookup_accel. + That would also allow us to do a per-subtbale set-digest, which + should speed things up some more, specially for ContextChainFormat3 + lookups... Amiri, for example, contains one lookup with 53 + subtables! + + src/hb-ot-layout.cc | 120 + +++++++++++++++++++++++++++++++++++----------------- + 1 file changed, 81 insertions(+), 39 deletions(-) + +commit 11441291bbf4326dca9b14ec3e9cad3d4d229303 +Author: Behdad Esfahbod +Date: Mon Jan 11 13:16:35 2016 +0000 + + 1.1.3 + + NEWS | 29 +++++++++++++++++++++++++++++ + configure.ac | 2 +- + 2 files changed, 30 insertions(+), 1 deletion(-) + commit 97624d9244de0fdb9c03f60e03fe242028efa8a1 Author: Behdad Esfahbod Date: Mon Jan 11 12:58:45 2016 +0000 diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/Makefile.am b/Build/source/libs/harfbuzz/harfbuzz-src/Makefile.am index 3c1e7a27cee..8987d5749e8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/Makefile.am +++ b/Build/source/libs/harfbuzz/harfbuzz-src/Makefile.am @@ -4,7 +4,7 @@ NULL = ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = src util test docs +SUBDIRS = src util test docs win32 EXTRA_DIST = \ autogen.sh \ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/NEWS b/Build/source/libs/harfbuzz/harfbuzz-src/NEWS index 698256d4c52..d8daee76dba 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/NEWS +++ b/Build/source/libs/harfbuzz/harfbuzz-src/NEWS @@ -1,3 +1,23 @@ +Overview of changes leading to 1.2.0 +Friday, February 19, 2016 +==================================== + +- Fix various issues (hangs mostly) in case of memory allocation failure. +- Change mark zeroing types of most shapers from BY_UNICODE_LATE to + BY_GDEF_LATE. This seems to be what Uniscribe does. +- Change mark zeroing of USE shaper from NONE to BY_GDEF_EARLY. That's + what Windows does. +- Allow GPOS cursive connection on marks, and fix the interaction with + mark attachment. This work resulted in some changes to how mark + attachments work. See: + https://github.com/behdad/harfbuzz/issues/211 + https://github.com/behdad/harfbuzz/commit/86c68c7a2c971efe8e35b1f1bd99401dc8b688d2 +- Graphite2 shaper: improved negative advance handling (eg. Nastaliq). +- Add nmake-based build system for Windows. +- Minor speedup. +- Misc. improvements. + + Overview of changes leading to 1.1.3 Monday, January 11, 2016 ==================================== diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/README b/Build/source/libs/harfbuzz/harfbuzz-src/README index d34bc74f997..3fcdfb4c338 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/README +++ b/Build/source/libs/harfbuzz/harfbuzz-src/README @@ -1,5 +1,6 @@ [![Build Status](https://travis-ci.org/behdad/harfbuzz.svg)](https://travis-ci.org/behdad/harfbuzz) [![Coverage Status](https://img.shields.io/coveralls/behdad/harfbuzz.svg)](https://coveralls.io/r/behdad/harfbuzz) +[ABI Tracker](http://abi-laboratory.pro/tracker/timeline/harfbuzz/) This is HarfBuzz, a text shaping library. diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/config.h.in b/Build/source/libs/harfbuzz/harfbuzz-src/config.h.in index 8937bd644d6..4053a8b88fa 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/config.h.in +++ b/Build/source/libs/harfbuzz/harfbuzz-src/config.h.in @@ -15,9 +15,15 @@ /* Have Core Text backend */ #undef HAVE_CORETEXT +/* Have DirectWrite library */ +#undef HAVE_DIRECTWRITE + /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H +/* Define to 1 if you have the header file. */ +#undef HAVE_DWRITE_H + /* Have simple TrueType Layout backend */ #undef HAVE_FALLBACK diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac b/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac index 764211553dc..d4c8f953807 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.1.3], + [1.2.0], [http://bugs.freedesktop.org/enter_bug.cgi?product=harfbuzz], [harfbuzz], [http://harfbuzz.org/]) @@ -356,6 +356,30 @@ AM_CONDITIONAL(HAVE_UNISCRIBE, $have_uniscribe) dnl =========================================================================== +AC_ARG_WITH(directwrite, + [AS_HELP_STRING([--with-directwrite=@<:@yes/no/auto@:>@], + [Use the DirectWrite library (experimental) @<:@default=no@:>@])],, + [with_directwrite=no]) +have_directwrite=false +AC_LANG_PUSH([C++]) +if test "x$with_directwrite" = "xyes" -o "x$with_directwrite" = "xauto"; then + AC_CHECK_HEADERS(dwrite.h, have_directwrite=true) +fi +AC_LANG_POP([C++]) +if test "x$with_directwrite" = "xyes" -a "x$have_directwrite" != "xtrue"; then + AC_MSG_ERROR([directwrite support requested but not found]) +fi +if $have_directwrite; then + DIRECTWRITE_CXXFLAGS= + DIRECTWRITE_LIBS="-ldwrite" + AC_SUBST(DIRECTWRITE_CXXFLAGS) + AC_SUBST(DIRECTWRITE_LIBS) + AC_DEFINE(HAVE_DIRECTWRITE, 1, [Have DirectWrite library]) +fi +AM_CONDITIONAL(HAVE_DIRECTWRITE, $have_directwrite) + +dnl =========================================================================== + AC_ARG_WITH(coretext, [AS_HELP_STRING([--with-coretext=@<:@yes/no/auto@:>@], [Use CoreText @<:@default=no@:>@])],, @@ -444,6 +468,8 @@ test/fuzzing/Makefile test/shaping/Makefile docs/Makefile docs/version.xml +win32/Makefile +win32/config.h.win32 ]) AC_OUTPUT @@ -470,6 +496,7 @@ Additional shapers (the more the better): Platform shapers (not normally needed): CoreText: ${have_coretext} Uniscribe: ${have_uniscribe} + DirectWrite: ${have_directwrite} Other features: Documentation: ${have_gtk_doc} diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am index 3d013ebaaf2..bb085ad0030 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am @@ -1,6 +1,5 @@ # Process this file with automake to produce Makefile.in -NULL = SUBDIRS = DIST_SUBDIRS = BUILT_SOURCES = @@ -19,121 +18,23 @@ fuzzing: $(BUILT_SOURCES) libharfbuzz-fuzzing.la lib_LTLIBRARIES = libharfbuzz.la +include Makefile.sources + HBCFLAGS = HBLIBS = HBNONPCLIBS = HBDEPS = -HBSOURCES = \ - hb-atomic-private.hh \ - hb-blob.cc \ - hb-buffer-deserialize-json.hh \ - hb-buffer-deserialize-text.hh \ - hb-buffer-private.hh \ - hb-buffer-serialize.cc \ - hb-buffer.cc \ - hb-cache-private.hh \ - hb-common.cc \ - hb-face-private.hh \ - hb-face.cc \ - hb-font-private.hh \ - hb-font.cc \ - hb-mutex-private.hh \ - hb-object-private.hh \ - hb-open-file-private.hh \ - hb-open-type-private.hh \ - hb-ot-cmap-table.hh \ - hb-ot-glyf-table.hh \ - hb-ot-head-table.hh \ - hb-ot-hhea-table.hh \ - hb-ot-hmtx-table.hh \ - hb-ot-maxp-table.hh \ - hb-ot-name-table.hh \ - hb-ot-os2-table.hh \ - hb-ot-tag.cc \ - hb-private.hh \ - hb-set-private.hh \ - hb-set.cc \ - hb-shape.cc \ - hb-shape-plan-private.hh \ - hb-shape-plan.cc \ - hb-shaper-list.hh \ - hb-shaper-impl-private.hh \ - hb-shaper-private.hh \ - hb-shaper.cc \ - hb-unicode-private.hh \ - hb-unicode.cc \ - hb-utf-private.hh \ - hb-warning.cc \ - $(NULL) -HBHEADERS = \ - hb.h \ - hb-blob.h \ - hb-buffer.h \ - hb-common.h \ - hb-deprecated.h \ - hb-face.h \ - hb-font.h \ - hb-set.h \ - hb-shape.h \ - hb-shape-plan.h \ - hb-unicode.h \ - $(NULL) -HBNODISTHEADERS = \ - hb-version.h \ - $(NULL) +HBSOURCES = $(HB_BASE_sources) +HBHEADERS = $(HB_BASE_headers) +HBNODISTHEADERS = $(HB_NODIST_headers) if HAVE_OT -HBSOURCES += \ - hb-ot-font.cc \ - hb-ot-layout.cc \ - hb-ot-layout-common-private.hh \ - hb-ot-layout-gdef-table.hh \ - hb-ot-layout-gpos-table.hh \ - hb-ot-layout-gsubgpos-private.hh \ - hb-ot-layout-gsub-table.hh \ - hb-ot-layout-jstf-table.hh \ - hb-ot-layout-private.hh \ - hb-ot-map.cc \ - hb-ot-map-private.hh \ - hb-ot-shape.cc \ - hb-ot-shape-complex-arabic.cc \ - hb-ot-shape-complex-arabic-fallback.hh \ - hb-ot-shape-complex-arabic-private.hh \ - hb-ot-shape-complex-arabic-table.hh \ - hb-ot-shape-complex-arabic-win1256.hh \ - hb-ot-shape-complex-default.cc \ - hb-ot-shape-complex-hangul.cc \ - hb-ot-shape-complex-hebrew.cc \ - hb-ot-shape-complex-indic.cc \ - hb-ot-shape-complex-indic-machine.hh \ - hb-ot-shape-complex-indic-private.hh \ - hb-ot-shape-complex-indic-table.cc \ - hb-ot-shape-complex-myanmar.cc \ - hb-ot-shape-complex-myanmar-machine.hh \ - hb-ot-shape-complex-thai.cc \ - hb-ot-shape-complex-tibetan.cc \ - hb-ot-shape-complex-use.cc \ - hb-ot-shape-complex-use-machine.hh \ - hb-ot-shape-complex-use-private.hh \ - hb-ot-shape-complex-use-table.cc \ - hb-ot-shape-complex-private.hh \ - hb-ot-shape-normalize-private.hh \ - hb-ot-shape-normalize.cc \ - hb-ot-shape-fallback-private.hh \ - hb-ot-shape-fallback.cc \ - hb-ot-shape-private.hh \ - $(NULL) -HBHEADERS += \ - hb-ot.h \ - hb-ot-font.h \ - hb-ot-layout.h \ - hb-ot-shape.h \ - hb-ot-tag.h \ - $(NULL) +HBSOURCES += $(HB_OT_sources) +HBHEADERS += $(HB_OT_headers) endif if HAVE_FALLBACK -HBSOURCES += hb-fallback-shape.cc +HBSOURCES += $(HB_FALLBACK_sources) endif if HAVE_PTHREAD @@ -145,8 +46,8 @@ if HAVE_GLIB HBCFLAGS += $(GLIB_CFLAGS) HBLIBS += $(GLIB_LIBS) HBDEPS += $(GLIB_DEPS) -HBSOURCES += hb-glib.cc -HBHEADERS += hb-glib.h +HBSOURCES += $(HB_GLIB_sources) +HBHEADERS += $(HB_GLIB_headers) endif if HAVE_FREETYPE @@ -158,37 +59,44 @@ HBLIBS += $(FREETYPE_LIBS) # fine but pkg-config 0.26 as shipped in Ubuntu 14.04 crashes. Remove # in a year or two, or otherwise work around it... #HBDEPS += $(FREETYPE_DEPS) -HBSOURCES += hb-ft.cc -HBHEADERS += hb-ft.h +HBSOURCES += $(HB_FT_sources) +HBHEADERS += $(HB_FT_headers) endif if HAVE_GRAPHITE2 HBCFLAGS += $(GRAPHITE2_CFLAGS) HBLIBS += $(GRAPHITE2_LIBS) HBDEPS += $(GRAPHITE2_DEPS) -HBSOURCES += hb-graphite2.cc -HBHEADERS += hb-graphite2.h +HBSOURCES += $(HB_GRAPHITE2_sources) +HBHEADERS += $(HB_GRAPHITE2_headers) endif if HAVE_UNISCRIBE HBCFLAGS += $(UNISCRIBE_CFLAGS) HBNONPCLIBS += $(UNISCRIBE_LIBS) -HBSOURCES += hb-uniscribe.cc -HBHEADERS += hb-uniscribe.h +HBSOURCES += $(HB_UNISCRIBE_sources) +HBHEADERS += $(HB_UNISCRIBE_headers) +endif + +if HAVE_DIRECTWRITE +HBCFLAGS += $(DIRECTWRITE_CXXFLAGS) +HBNONPCLIBS += $(DIRECTWRITE_LIBS) +HBSOURCES += $(HB_DIRECTWRITE_sources) +HBHEADERS += $(HB_DIRECTWRITE_headers) endif if HAVE_CORETEXT HBCFLAGS += $(CORETEXT_CFLAGS) HBNONPCLIBS += $(CORETEXT_LIBS) -HBSOURCES += hb-coretext.cc -HBHEADERS += hb-coretext.h +HBSOURCES += $(HB_CORETEXT_sources) +HBHEADERS += $(HB_CORETEXT_headers) endif if HAVE_UCDN SUBDIRS += hb-ucdn HBCFLAGS += -I$(srcdir)/hb-ucdn HBLIBS += hb-ucdn/libhb-ucdn.la -HBSOURCES += hb-ucdn.cc +HBSOURCES += $(HB_UCDN_sources) endif DIST_SUBDIRS += hb-ucdn @@ -239,33 +147,33 @@ CLEANFILES += libharfbuzz-fuzzing.la if HAVE_ICU lib_LTLIBRARIES += libharfbuzz-icu.la -libharfbuzz_icu_la_SOURCES = hb-icu.cc +libharfbuzz_icu_la_SOURCES = $(HB_ICU_sources) libharfbuzz_icu_la_CPPFLAGS = $(ICU_CFLAGS) libharfbuzz_icu_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(HB_LIBTOOL_VERSION_INFO) -no-undefined libharfbuzz_icu_la_LIBADD = $(ICU_LIBS) libharfbuzz.la -pkginclude_HEADERS += hb-icu.h +pkginclude_HEADERS += $(HB_ICU_headers) pkgconfig_DATA += harfbuzz-icu.pc endif EXTRA_DIST += harfbuzz-icu.pc.in if HAVE_GOBJECT lib_LTLIBRARIES += libharfbuzz-gobject.la -libharfbuzz_gobject_la_SOURCES = hb-gobject-structs.cc -nodist_libharfbuzz_gobject_la_SOURCES = hb-gobject-enums.cc +libharfbuzz_gobject_la_SOURCES = $(HB_GOBJECT_sources) +nodist_libharfbuzz_gobject_la_SOURCES = $(HB_GOBJECT_ENUM_sources) libharfbuzz_gobject_la_CPPFLAGS = $(GOBJECT_CFLAGS) libharfbuzz_gobject_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(HB_LIBTOOL_VERSION_INFO) -no-undefined libharfbuzz_gobject_la_LIBADD = $(GOBJECT_LIBS) libharfbuzz.la -pkginclude_HEADERS += hb-gobject.h hb-gobject-structs.h -nodist_pkginclude_HEADERS += hb-gobject-enums.h +pkginclude_HEADERS += $(HB_GOBJECT_headers) +nodist_pkginclude_HEADERS += $(HB_GOBJECT_ENUM_headers) pkgconfig_DATA += harfbuzz-gobject.pc BUILT_SOURCES += \ - hb-gobject-enums.cc \ - hb-gobject-enums.h \ + $(HB_GOBJECT_ENUM_sources) \ + $(HB_GOBJECT_ENUM_headers) \ $(NULL) DISTCLEANFILES += \ - hb-gobject-enums.cc \ - hb-gobject-enums.h \ + $(HB_GOBJECT_ENUM_sources) \ + $(HB_GOBJECT_ENUM_headers) \ $(NULL) hb-gobject-enums.%: hb-gobject-enums.%.tmpl $(HBHEADERS) $(AM_V_GEN) $(GLIB_MKENUMS) \ @@ -437,10 +345,10 @@ HarfBuzz_0_0_gir_FILES = \ $(HBHEADERS) \ $(HBNODISTHEADERS) \ $(HBSOURCES) \ - hb-gobject-enums.cc \ - hb-gobject-enums.h \ - hb-gobject-structs.cc \ - hb-gobject-structs.h \ + $(HB_GOBJECT_ENUM_sources) \ + $(HB_GOBJECT_ENUM_headers) \ + $(HB_GOBJECT_sources) \ + $(HB_GOBJECT_STRUCTS_headers) \ $(NULL) girdir = $(datadir)/gir-1.0 diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources new file mode 100644 index 00000000000..171c513587d --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources @@ -0,0 +1,150 @@ +NULL = + +# Base and default-included sources and headers + +HB_BASE_sources = \ + hb-atomic-private.hh \ + hb-blob.cc \ + hb-buffer-deserialize-json.hh \ + hb-buffer-deserialize-text.hh \ + hb-buffer-private.hh \ + hb-buffer-serialize.cc \ + hb-buffer.cc \ + hb-cache-private.hh \ + hb-common.cc \ + hb-face-private.hh \ + hb-face.cc \ + hb-font-private.hh \ + hb-font.cc \ + hb-mutex-private.hh \ + hb-object-private.hh \ + hb-open-file-private.hh \ + hb-open-type-private.hh \ + hb-ot-cmap-table.hh \ + hb-ot-glyf-table.hh \ + hb-ot-head-table.hh \ + hb-ot-hhea-table.hh \ + hb-ot-hmtx-table.hh \ + hb-ot-maxp-table.hh \ + hb-ot-name-table.hh \ + hb-ot-os2-table.hh \ + hb-ot-tag.cc \ + hb-private.hh \ + hb-set-private.hh \ + hb-set.cc \ + hb-shape.cc \ + hb-shape-plan-private.hh \ + hb-shape-plan.cc \ + hb-shaper-list.hh \ + hb-shaper-impl-private.hh \ + hb-shaper-private.hh \ + hb-shaper.cc \ + hb-unicode-private.hh \ + hb-unicode.cc \ + hb-utf-private.hh \ + hb-warning.cc \ + $(NULL) + +HB_BASE_headers = \ + hb.h \ + hb-blob.h \ + hb-buffer.h \ + hb-common.h \ + hb-deprecated.h \ + hb-face.h \ + hb-font.h \ + hb-set.h \ + hb-shape.h \ + hb-shape-plan.h \ + hb-unicode.h \ + $(NULL) + +HB_NODIST_headers = \ + hb-version.h \ + $(NULL) + +HB_FALLBACK_sources = hb-fallback-shape.cc + +HB_OT_sources = \ + hb-ot-font.cc \ + hb-ot-layout.cc \ + hb-ot-layout-common-private.hh \ + hb-ot-layout-gdef-table.hh \ + hb-ot-layout-gpos-table.hh \ + hb-ot-layout-gsubgpos-private.hh \ + hb-ot-layout-gsub-table.hh \ + hb-ot-layout-jstf-table.hh \ + hb-ot-layout-private.hh \ + hb-ot-map.cc \ + hb-ot-map-private.hh \ + hb-ot-shape.cc \ + hb-ot-shape-complex-arabic.cc \ + hb-ot-shape-complex-arabic-fallback.hh \ + hb-ot-shape-complex-arabic-private.hh \ + hb-ot-shape-complex-arabic-table.hh \ + hb-ot-shape-complex-arabic-win1256.hh \ + hb-ot-shape-complex-default.cc \ + hb-ot-shape-complex-hangul.cc \ + hb-ot-shape-complex-hebrew.cc \ + hb-ot-shape-complex-indic.cc \ + hb-ot-shape-complex-indic-machine.hh \ + hb-ot-shape-complex-indic-private.hh \ + hb-ot-shape-complex-indic-table.cc \ + hb-ot-shape-complex-myanmar.cc \ + hb-ot-shape-complex-myanmar-machine.hh \ + hb-ot-shape-complex-thai.cc \ + hb-ot-shape-complex-tibetan.cc \ + hb-ot-shape-complex-use.cc \ + hb-ot-shape-complex-use-machine.hh \ + hb-ot-shape-complex-use-private.hh \ + hb-ot-shape-complex-use-table.cc \ + hb-ot-shape-complex-private.hh \ + hb-ot-shape-normalize-private.hh \ + hb-ot-shape-normalize.cc \ + hb-ot-shape-fallback-private.hh \ + hb-ot-shape-fallback.cc \ + hb-ot-shape-private.hh \ + $(NULL) + +HB_OT_headers = \ + hb-ot.h \ + hb-ot-font.h \ + hb-ot-layout.h \ + hb-ot-shape.h \ + hb-ot-tag.h \ + $(NULL) + +# Optional Sources and Headers with external deps + +HB_FT_sources = hb-ft.cc +HB_FT_headers = hb-ft.h + +HB_GLIB_sources = hb-glib.cc +HB_GLIB_headers = hb-glib.h + +HB_GRAPHITE2_sources = hb-graphite2.cc +HB_GRAPHITE2_headers = hb-graphite2.h + +# System-dependent sources and headers + +HB_CORETEXT_sources = hb-coretext.cc +HB_CORETEXT_headers = hb-coretext.h + +HB_DIRECTWRITE_sources = hb-directwrite.cc +HB_DIRECTWRITE_headers = hb-directwrite.h + +HB_UNISCRIBE_sources = hb-uniscribe.cc +HB_UNISCRIBE_headers = hb-uniscribe.h + +# Additional supplemental sources +HB_UCDN_sources = hb-ucdn.cc + +# Sources for libharfbuzz-gobject and libharfbuzz-icu +HB_ICU_sources = hb-icu.cc +HB_ICU_headers = hb-icu.h + +HB_GOBJECT_sources = hb-gobject-structs.cc +HB_GOBJECT_STRUCTS_headers = hb-gobject-structs.h +HB_GOBJECT_headers = hb-gobject.h $(HB_GOBJECT_STRUCTS_headers) +HB_GOBJECT_ENUM_sources = hb-gobject-enums.cc +HB_GOBJECT_ENUM_headers = hb-gobject-enums.h diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc index a6870dc06e4..fb48f03cabe 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc @@ -104,7 +104,6 @@ hb_blob_create (const char *data, if (!length || length >= 1u << 31 || - data + length < data /* overflows */ || !(blob = hb_object_create ())) { if (destroy) destroy (user_data); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-private.hh index 4983f849f2d..c8eec3c1780 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-private.hh @@ -56,8 +56,7 @@ enum hb_buffer_scratch_flags_t { HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII = 0x00000001u, HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES = 0x00000002u, HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK = 0x00000004u, - HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_CURSIVE = 0x00000008u, - HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT = 0x00000010u, + HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT = 0x00000008u, /* Reserved for complex shapers' internal use. */ HB_BUFFER_SCRATCH_FLAG_COMPLEX0 = 0x01000000u, HB_BUFFER_SCRATCH_FLAG_COMPLEX1 = 0x02000000u, diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc index c731ed189fd..5f320bd7eb6 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc @@ -407,6 +407,8 @@ hb_buffer_t::move_to (unsigned int i) idx = i; return true; } + if (unlikely (in_error)) + return false; assert (i <= out_len + (len - idx)); 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 e0911900911..140ee0a5737 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc @@ -540,7 +540,7 @@ hb_user_data_array_t::set (hb_user_data_key_t *key, void * hb_user_data_array_t::get (hb_user_data_key_t *key) { - hb_user_data_item_t item = {NULL }; + hb_user_data_item_t item = {NULL, NULL, NULL}; return items.find (key, &item, lock) ? item.data : NULL; } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc new file mode 100644 index 00000000000..af0fd3da0f7 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc @@ -0,0 +1,827 @@ +/* + * Copyright © 2015 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. + */ + +#define HB_SHAPER directwrite +#include "hb-shaper-impl-private.hh" + +#include + +#include "hb-directwrite.h" + +#include "hb-open-file-private.hh" +#include "hb-ot-name-table.hh" +#include "hb-ot-tag.h" + + +#ifndef HB_DEBUG_DIRECTWRITE +#define HB_DEBUG_DIRECTWRITE (HB_DEBUG+0) +#endif + +HB_SHAPER_DATA_ENSURE_DECLARE(directwrite, face) +HB_SHAPER_DATA_ENSURE_DECLARE(directwrite, font) + +/* +* shaper face data +*/ + +struct hb_directwrite_shaper_face_data_t { + HANDLE fh; + wchar_t face_name[LF_FACESIZE]; +}; + +/* face_name should point to a wchar_t[LF_FACESIZE] object. */ +static void +_hb_generate_unique_face_name(wchar_t *face_name, unsigned int *plen) +{ + /* We'll create a private name for the font from a UUID using a simple, + * somewhat base64-like encoding scheme */ + const char *enc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-"; + UUID id; + UuidCreate ((UUID*)&id); + ASSERT_STATIC (2 + 3 * (16 / 2) < LF_FACESIZE); + unsigned int name_str_len = 0; + face_name[name_str_len++] = 'F'; + face_name[name_str_len++] = '_'; + unsigned char *p = (unsigned char *)&id; + for (unsigned int i = 0; i < 16; i += 2) + { + /* Spread the 16 bits from two bytes of the UUID across three chars of face_name, + * using the bits in groups of 5,5,6 to select chars from enc. + * This will generate 24 characters; with the 'F_' prefix we already provided, + * the name will be 26 chars (plus the NUL terminator), so will always fit within + * face_name (LF_FACESIZE = 32). */ + face_name[name_str_len++] = enc[p[i] >> 3]; + face_name[name_str_len++] = enc[((p[i] << 2) | (p[i + 1] >> 6)) & 0x1f]; + face_name[name_str_len++] = enc[p[i + 1] & 0x3f]; + } + face_name[name_str_len] = 0; + if (plen) + *plen = name_str_len; +} + +/* Destroys blob. */ +static hb_blob_t * +_hb_rename_font(hb_blob_t *blob, wchar_t *new_name) +{ + /* Create a copy of the font data, with the 'name' table replaced by a + * table that names the font with our private F_* name created above. + * For simplicity, we just append a new 'name' table and update the + * sfnt directory; the original table is left in place, but unused. + * + * The new table will contain just 5 name IDs: family, style, unique, + * full, PS. All of them point to the same name data with our unique name. + */ + + blob = OT::Sanitizer::sanitize (blob); + + unsigned int length, new_length, name_str_len; + const char *orig_sfnt_data = hb_blob_get_data (blob, &length); + + _hb_generate_unique_face_name (new_name, &name_str_len); + + static const uint16_t name_IDs[] = { 1, 2, 3, 4, 6 }; + + unsigned int name_table_length = OT::name::min_size + + ARRAY_LENGTH(name_IDs) * OT::NameRecord::static_size + + name_str_len * 2; /* for name data in UTF16BE form */ + unsigned int name_table_offset = (length + 3) & ~3; + + new_length = name_table_offset + ((name_table_length + 3) & ~3); + void *new_sfnt_data = calloc(1, new_length); + if (!new_sfnt_data) + { + hb_blob_destroy (blob); + return NULL; + } + + memcpy(new_sfnt_data, orig_sfnt_data, length); + + OT::name &name = OT::StructAtOffset (new_sfnt_data, name_table_offset); + name.format.set (0); + name.count.set (ARRAY_LENGTH (name_IDs)); + name.stringOffset.set (name.get_size()); + for (unsigned int i = 0; i < ARRAY_LENGTH (name_IDs); i++) + { + OT::NameRecord &record = name.nameRecord[i]; + record.platformID.set(3); + record.encodingID.set(1); + record.languageID.set(0x0409u); /* English */ + record.nameID.set(name_IDs[i]); + record.length.set(name_str_len * 2); + record.offset.set(0); + } + + /* Copy string data from new_name, converting wchar_t to UTF16BE. */ + unsigned char *p = &OT::StructAfter(name); + for (unsigned int i = 0; i < name_str_len; i++) + { + *p++ = new_name[i] >> 8; + *p++ = new_name[i] & 0xff; + } + + /* Adjust name table entry to point to new name table */ + const OT::OpenTypeFontFile &file = *(OT::OpenTypeFontFile *) (new_sfnt_data); + unsigned int face_count = file.get_face_count (); + for (unsigned int face_index = 0; face_index < face_count; face_index++) + { + /* Note: doing multiple edits (ie. TTC) can be unsafe. There may be + * toe-stepping. But we don't really care. */ + const OT::OpenTypeFontFace &face = file.get_face (face_index); + unsigned int index; + if (face.find_table_index (HB_OT_TAG_name, &index)) + { + OT::TableRecord &record = const_cast (face.get_table (index)); + record.checkSum.set_for_data (&name, name_table_length); + record.offset.set (name_table_offset); + record.length.set (name_table_length); + } + else if (face_index == 0) /* Fail if first face doesn't have 'name' table. */ + { + free (new_sfnt_data); + hb_blob_destroy (blob); + return NULL; + } + } + + /* The checkSumAdjustment field in the 'head' table is now wrong, + * but that doesn't actually seem to cause any problems so we don't + * bother. */ + + hb_blob_destroy (blob); + return hb_blob_create ((const char *)new_sfnt_data, new_length, + HB_MEMORY_MODE_WRITABLE, NULL, free); +} + +hb_directwrite_shaper_face_data_t * +_hb_directwrite_shaper_face_data_create(hb_face_t *face) +{ + hb_directwrite_shaper_face_data_t *data = (hb_directwrite_shaper_face_data_t *)calloc(1, sizeof (hb_directwrite_shaper_face_data_t)); + if (unlikely (!data)) + return NULL; + + hb_blob_t *blob = hb_face_reference_blob (face); + if (unlikely (!hb_blob_get_length (blob))) + DEBUG_MSG(DIRECTWRITE, face, "Face has empty blob"); + + blob = _hb_rename_font (blob, data->face_name); + if (unlikely (!blob)) + { + free(data); + return NULL; + } + + DWORD num_fonts_installed; + data->fh = AddFontMemResourceEx ((void *)hb_blob_get_data(blob, NULL), + hb_blob_get_length (blob), + 0, &num_fonts_installed); + if (unlikely (!data->fh)) + { + DEBUG_MSG (DIRECTWRITE, face, "Face AddFontMemResourceEx() failed"); + free (data); + return NULL; + } + + return data; +} + +void +_hb_directwrite_shaper_face_data_destroy(hb_directwrite_shaper_face_data_t *data) +{ + RemoveFontMemResourceEx(data->fh); + free(data); +} + + +/* + * shaper font data + */ + +struct hb_directwrite_shaper_font_data_t { + HDC hdc; + LOGFONTW log_font; + HFONT hfont; +}; + +static bool +populate_log_font (LOGFONTW *lf, + hb_font_t *font) +{ + memset (lf, 0, sizeof (*lf)); + lf->lfHeight = -font->y_scale; + lf->lfCharSet = DEFAULT_CHARSET; + + hb_face_t *face = font->face; + hb_directwrite_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); + + memcpy (lf->lfFaceName, face_data->face_name, sizeof (lf->lfFaceName)); + + return true; +} + +hb_directwrite_shaper_font_data_t * +_hb_directwrite_shaper_font_data_create (hb_font_t *font) +{ + if (unlikely (!hb_directwrite_shaper_face_data_ensure (font->face))) return NULL; + + hb_directwrite_shaper_font_data_t *data = (hb_directwrite_shaper_font_data_t *) calloc (1, sizeof (hb_directwrite_shaper_font_data_t)); + if (unlikely (!data)) + return NULL; + + data->hdc = GetDC (NULL); + + if (unlikely (!populate_log_font (&data->log_font, font))) { + DEBUG_MSG (DIRECTWRITE, font, "Font populate_log_font() failed"); + _hb_directwrite_shaper_font_data_destroy (data); + return NULL; + } + + data->hfont = CreateFontIndirectW (&data->log_font); + if (unlikely (!data->hfont)) { + DEBUG_MSG (DIRECTWRITE, font, "Font CreateFontIndirectW() failed"); + _hb_directwrite_shaper_font_data_destroy (data); + return NULL; + } + + if (!SelectObject (data->hdc, data->hfont)) { + DEBUG_MSG (DIRECTWRITE, font, "Font SelectObject() failed"); + _hb_directwrite_shaper_font_data_destroy (data); + return NULL; + } + + return data; +} + +void +_hb_directwrite_shaper_font_data_destroy (hb_directwrite_shaper_font_data_t *data) +{ + if (data->hdc) + ReleaseDC (NULL, data->hdc); + if (data->hfont) + DeleteObject (data->hfont); + free (data); +} + +LOGFONTW * +hb_directwrite_font_get_logfontw (hb_font_t *font) +{ + if (unlikely (!hb_directwrite_shaper_font_data_ensure (font))) return NULL; + hb_directwrite_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font); + return &font_data->log_font; +} + +HFONT +hb_directwrite_font_get_hfont (hb_font_t *font) +{ + if (unlikely (!hb_directwrite_shaper_font_data_ensure (font))) return NULL; + hb_directwrite_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font); + return font_data->hfont; +} + + +/* + * shaper shape_plan data + */ + +struct hb_directwrite_shaper_shape_plan_data_t {}; + +hb_directwrite_shaper_shape_plan_data_t * +_hb_directwrite_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED, + const hb_feature_t *user_features HB_UNUSED, + unsigned int num_user_features HB_UNUSED) +{ + return (hb_directwrite_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; +} + +void +_hb_directwrite_shaper_shape_plan_data_destroy (hb_directwrite_shaper_shape_plan_data_t *data HB_UNUSED) +{ +} + +// Most of here TextAnalysis is originally written by Bas Schouten for Mozilla project +// but now is relicensed to MIT for HarfBuzz use +class TextAnalysis + : public IDWriteTextAnalysisSource, public IDWriteTextAnalysisSink +{ +public: + + IFACEMETHOD(QueryInterface)(IID const& iid, OUT void** ppObject) { return S_OK; } + IFACEMETHOD_(ULONG, AddRef)() { return 1; } + IFACEMETHOD_(ULONG, Release)() { return 1; } + + // A single contiguous run of characters containing the same analysis + // results. + struct Run + { + UINT32 mTextStart; // starting text position of this run + UINT32 mTextLength; // number of contiguous code units covered + UINT32 mGlyphStart; // starting glyph in the glyphs array + UINT32 mGlyphCount; // number of glyphs associated with this run of + // text + DWRITE_SCRIPT_ANALYSIS mScript; + UINT8 mBidiLevel; + bool mIsSideways; + + inline bool ContainsTextPosition(UINT32 aTextPosition) const + { + return aTextPosition >= mTextStart + && aTextPosition < mTextStart + mTextLength; + } + + Run *nextRun; + }; + +public: + TextAnalysis(const wchar_t* text, + UINT32 textLength, + const wchar_t* localeName, + DWRITE_READING_DIRECTION readingDirection) + : mText(text) + , mTextLength(textLength) + , mLocaleName(localeName) + , mReadingDirection(readingDirection) + , mCurrentRun(NULL) { }; + + ~TextAnalysis() { + // delete runs, except mRunHead which is part of the TextAnalysis object + for (Run *run = mRunHead.nextRun; run;) { + Run *origRun = run; + run = run->nextRun; + delete origRun; + } + } + + STDMETHODIMP GenerateResults(IDWriteTextAnalyzer* textAnalyzer, + Run **runHead) { + // Analyzes the text using the script analyzer and returns + // the result as a series of runs. + + HRESULT hr = S_OK; + + // Initially start out with one result that covers the entire range. + // This result will be subdivided by the analysis processes. + mRunHead.mTextStart = 0; + mRunHead.mTextLength = mTextLength; + mRunHead.mBidiLevel = + (mReadingDirection == DWRITE_READING_DIRECTION_RIGHT_TO_LEFT); + mRunHead.nextRun = NULL; + mCurrentRun = &mRunHead; + + // Call each of the analyzers in sequence, recording their results. + if (SUCCEEDED(hr = textAnalyzer->AnalyzeScript(this, + 0, + mTextLength, + this))) { + *runHead = &mRunHead; + } + + return hr; + } + + // IDWriteTextAnalysisSource implementation + + IFACEMETHODIMP GetTextAtPosition(UINT32 textPosition, + OUT WCHAR const** textString, + OUT UINT32* textLength) + { + if (textPosition >= mTextLength) { + // No text at this position, valid query though. + *textString = NULL; + *textLength = 0; + } + else { + *textString = mText + textPosition; + *textLength = mTextLength - textPosition; + } + return S_OK; + } + + IFACEMETHODIMP GetTextBeforePosition(UINT32 textPosition, + OUT WCHAR const** textString, + OUT UINT32* textLength) + { + if (textPosition == 0 || textPosition > mTextLength) { + // Either there is no text before here (== 0), or this + // is an invalid position. The query is considered valid thouh. + *textString = NULL; + *textLength = 0; + } + else { + *textString = mText; + *textLength = textPosition; + } + return S_OK; + } + + IFACEMETHODIMP_(DWRITE_READING_DIRECTION) + GetParagraphReadingDirection() { return mReadingDirection; } + + IFACEMETHODIMP GetLocaleName(UINT32 textPosition, + UINT32* textLength, + WCHAR const** localeName) { + return S_OK; + } + + IFACEMETHODIMP + GetNumberSubstitution(UINT32 textPosition, + OUT UINT32* textLength, + OUT IDWriteNumberSubstitution** numberSubstitution) + { + // We do not support number substitution. + *numberSubstitution = NULL; + *textLength = mTextLength - textPosition; + + return S_OK; + } + + // IDWriteTextAnalysisSink implementation + + IFACEMETHODIMP + SetScriptAnalysis(UINT32 textPosition, + UINT32 textLength, + DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis) + { + SetCurrentRun(textPosition); + SplitCurrentRun(textPosition); + while (textLength > 0) { + Run *run = FetchNextRun(&textLength); + run->mScript = *scriptAnalysis; + } + + return S_OK; + } + + IFACEMETHODIMP + SetLineBreakpoints(UINT32 textPosition, + UINT32 textLength, + const DWRITE_LINE_BREAKPOINT* lineBreakpoints) { return S_OK; } + + IFACEMETHODIMP SetBidiLevel(UINT32 textPosition, + UINT32 textLength, + UINT8 explicitLevel, + UINT8 resolvedLevel) { return S_OK; } + + IFACEMETHODIMP + SetNumberSubstitution(UINT32 textPosition, + UINT32 textLength, + IDWriteNumberSubstitution* numberSubstitution) { return S_OK; } + +protected: + Run *FetchNextRun(IN OUT UINT32* textLength) + { + // Used by the sink setters, this returns a reference to the next run. + // Position and length are adjusted to now point after the current run + // being returned. + + Run *origRun = mCurrentRun; + // Split the tail if needed (the length remaining is less than the + // current run's size). + if (*textLength < mCurrentRun->mTextLength) { + SplitCurrentRun(mCurrentRun->mTextStart + *textLength); + } + else { + // Just advance the current run. + mCurrentRun = mCurrentRun->nextRun; + } + *textLength -= origRun->mTextLength; + + // Return a reference to the run that was just current. + return origRun; + } + + void SetCurrentRun(UINT32 textPosition) + { + // Move the current run to the given position. + // Since the analyzers generally return results in a forward manner, + // this will usually just return early. If not, find the + // corresponding run for the text position. + + if (mCurrentRun && mCurrentRun->ContainsTextPosition(textPosition)) { + return; + } + + for (Run *run = &mRunHead; run; run = run->nextRun) { + if (run->ContainsTextPosition(textPosition)) { + mCurrentRun = run; + return; + } + } + //NS_NOTREACHED("We should always be able to find the text position in one \ + // of our runs"); + } + + void SplitCurrentRun(UINT32 splitPosition) + { + if (!mCurrentRun) { + //NS_ASSERTION(false, "SplitCurrentRun called without current run."); + // Shouldn't be calling this when no current run is set! + return; + } + // Split the current run. + if (splitPosition <= mCurrentRun->mTextStart) { + // No need to split, already the start of a run + // or before it. Usually the first. + return; + } + Run *newRun = new Run; + + *newRun = *mCurrentRun; + + // Insert the new run in our linked list. + newRun->nextRun = mCurrentRun->nextRun; + mCurrentRun->nextRun = newRun; + + // Adjust runs' text positions and lengths. + UINT32 splitPoint = splitPosition - mCurrentRun->mTextStart; + newRun->mTextStart += splitPoint; + newRun->mTextLength -= splitPoint; + mCurrentRun->mTextLength = splitPoint; + mCurrentRun = newRun; + } + +protected: + // Input + // (weak references are fine here, since this class is a transient + // stack-based helper that doesn't need to copy data) + UINT32 mTextLength; + const WCHAR* mText; + const WCHAR* mLocaleName; + DWRITE_READING_DIRECTION mReadingDirection; + + // Current processing state. + Run *mCurrentRun; + + // Output is a list of runs starting here + Run mRunHead; +}; + + +/* + * shaper + */ + +hb_bool_t +_hb_directwrite_shape(hb_shape_plan_t *shape_plan, + hb_font_t *font, + hb_buffer_t *buffer, + const hb_feature_t *features, + unsigned int num_features) +{ + hb_face_t *face = font->face; + hb_directwrite_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); + hb_directwrite_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font); + + // factory probably should be cached + IDWriteFactory* dwriteFactory; + DWriteCreateFactory( + DWRITE_FACTORY_TYPE_SHARED, + __uuidof(IDWriteFactory), + reinterpret_cast(&dwriteFactory) + ); + + IDWriteGdiInterop *gdiInterop; + dwriteFactory->GetGdiInterop (&gdiInterop); + IDWriteFontFace* fontFace; + gdiInterop->CreateFontFaceFromHdc (font_data->hdc, &fontFace); + + IDWriteTextAnalyzer* analyzer; + dwriteFactory->CreateTextAnalyzer (&analyzer); + + unsigned int scratch_size; + hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size); +#define ALLOCATE_ARRAY(Type, name, len) \ + Type *name = (Type *) scratch; \ + { \ + unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \ + assert (_consumed <= scratch_size); \ + scratch += _consumed; \ + scratch_size -= _consumed; \ + } + +#define utf16_index() var1.u32 + + ALLOCATE_ARRAY(WCHAR, pchars, buffer->len * 2); + + unsigned int chars_len = 0; + for (unsigned int i = 0; i < buffer->len; i++) + { + hb_codepoint_t c = buffer->info[i].codepoint; + buffer->info[i].utf16_index() = chars_len; + if (likely(c <= 0xFFFFu)) + pchars[chars_len++] = c; + else if (unlikely(c > 0x10FFFFu)) + pchars[chars_len++] = 0xFFFDu; + else { + pchars[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10); + pchars[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1 << 10) - 1)); + } + } + + ALLOCATE_ARRAY(WORD, log_clusters, chars_len); + if (num_features) + { + /* Need log_clusters to assign features. */ + chars_len = 0; + for (unsigned int i = 0; i < buffer->len; i++) + { + hb_codepoint_t c = buffer->info[i].codepoint; + unsigned int cluster = buffer->info[i].cluster; + log_clusters[chars_len++] = cluster; + if (hb_in_range(c, 0x10000u, 0x10FFFFu)) + log_clusters[chars_len++] = cluster; /* Surrogates. */ + } + } + + HRESULT hr; + // TODO: Handle TEST_DISABLE_OPTIONAL_LIGATURES + + DWRITE_READING_DIRECTION readingDirection = buffer->props.direction ? + DWRITE_READING_DIRECTION_RIGHT_TO_LEFT : + DWRITE_READING_DIRECTION_LEFT_TO_RIGHT; + + /* + * There's an internal 16-bit limit on some things inside the analyzer, + * but we never attempt to shape a word longer than 64K characters + * in a single gfxShapedWord, so we cannot exceed that limit. + */ + UINT32 length = buffer->len; + + TextAnalysis analysis(pchars, length, NULL, readingDirection); + TextAnalysis::Run *runHead; + hr = analysis.GenerateResults(analyzer, &runHead); + + if (FAILED(hr)) { + //NS_WARNING("Analyzer failed to generate results."); + return false; + } + + UINT32 maxGlyphs = 3 * length / 2 + 16; + +#define INITIAL_GLYPH_SIZE 400 + UINT16* clusters = (UINT16*)malloc(INITIAL_GLYPH_SIZE * sizeof(UINT16)); + UINT16* glyphs = (UINT16*)malloc(INITIAL_GLYPH_SIZE * sizeof(UINT16)); + DWRITE_SHAPING_TEXT_PROPERTIES* textProperties = (DWRITE_SHAPING_TEXT_PROPERTIES*) + malloc(INITIAL_GLYPH_SIZE * sizeof(DWRITE_SHAPING_TEXT_PROPERTIES)); + DWRITE_SHAPING_GLYPH_PROPERTIES* glyphProperties = (DWRITE_SHAPING_GLYPH_PROPERTIES*) + malloc(INITIAL_GLYPH_SIZE * sizeof(DWRITE_SHAPING_GLYPH_PROPERTIES)); + + UINT32 actualGlyphs; + + bool backward = HB_DIRECTION_IS_BACKWARD(buffer->props.direction); + + wchar_t lang[4]; + mbstowcs(lang, hb_language_to_string(buffer->props.language), 4); + hr = analyzer->GetGlyphs(pchars, length, + fontFace, FALSE, + buffer->props.direction, + &runHead->mScript, (const wchar_t*)lang, NULL, NULL, NULL, 0, + maxGlyphs, clusters, textProperties, + glyphs, glyphProperties, &actualGlyphs); + + if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) { + free(clusters); + free(glyphs); + free(textProperties); + free(glyphProperties); + + clusters = (UINT16*)malloc(INITIAL_GLYPH_SIZE * sizeof(UINT16)); + glyphs = (UINT16*)malloc(INITIAL_GLYPH_SIZE * sizeof(UINT16)); + textProperties = (DWRITE_SHAPING_TEXT_PROPERTIES*) + malloc(INITIAL_GLYPH_SIZE * sizeof(DWRITE_SHAPING_TEXT_PROPERTIES)); + glyphProperties = (DWRITE_SHAPING_GLYPH_PROPERTIES*) + malloc(INITIAL_GLYPH_SIZE * sizeof(DWRITE_SHAPING_GLYPH_PROPERTIES)); + + hr = analyzer->GetGlyphs(pchars, length, + fontFace, FALSE, + buffer->props.direction, + &runHead->mScript, (const wchar_t*)lang, NULL, NULL, NULL, 0, + maxGlyphs, clusters, textProperties, + glyphs, glyphProperties, &actualGlyphs); + } + if (FAILED(hr)) { + //NS_WARNING("Analyzer failed to get glyphs."); + return false; + } + + FLOAT advances[400]; + DWRITE_GLYPH_OFFSET offsets[400]; + + + /* The -2 in the following is to compensate for possible + * alignment needed after the WORD array. sizeof(WORD) == 2. */ + unsigned int glyphs_size = (scratch_size * sizeof (int)-2) + / (sizeof (WORD) + + 4 + // sizeof (SCRIPT_GLYPHPROP) + + sizeof (int) + + 8 + // sizeof (GOFFSET) + + sizeof (uint32_t)); + ALLOCATE_ARRAY(uint32_t, vis_clusters, glyphs_size); + +#undef ALLOCATE_ARRAY + + hr = analyzer->GetGlyphPlacements(pchars, + clusters, + textProperties, + length, + glyphs, + glyphProperties, + actualGlyphs, + fontFace, + face->get_upem(), + FALSE, + FALSE, + &runHead->mScript, + NULL, + NULL, + NULL, + 0, + advances, + offsets); + + if (FAILED(hr)) { + //NS_WARNING("Analyzer failed to get glyph placements."); + return false; + } + + unsigned int glyphs_len = actualGlyphs; + + /* Ok, we've got everything we need, now compose output buffer, + * very, *very*, carefully! */ + + /* Calculate visual-clusters. That's what we ship. */ + for (unsigned int i = 0; i < glyphs_len; i++) + vis_clusters[i] = -1; + for (unsigned int i = 0; i < buffer->len; i++) { + uint32_t *p = &vis_clusters[log_clusters[buffer->info[i].utf16_index()]]; + //*p = MIN (*p, buffer->info[i].cluster); + } + for (unsigned int i = 1; i < glyphs_len; i++) + if (vis_clusters[i] == -1) + vis_clusters[i] = vis_clusters[i - 1]; + +#undef utf16_index + + //if (unlikely (!buffer->ensure (glyphs_len))) + // FAIL ("Buffer in error"); + +#undef FAIL + + /* Set glyph infos */ + buffer->len = 0; + for (unsigned int i = 0; i < glyphs_len; i++) + { + hb_glyph_info_t *info = &buffer->info[buffer->len++]; + + info->codepoint = glyphs[i]; + info->cluster = vis_clusters[i]; + + /* The rest is crap. Let's store position info there for now. */ + info->mask = advances[i]; + info->var1.u32 = offsets[i].ascenderOffset; + info->var2.u32 = -offsets[i].advanceOffset; + } + + free(clusters); + free(glyphs); + free(textProperties); + free(glyphProperties); + + /* Set glyph positions */ + buffer->clear_positions (); + for (unsigned int i = 0; i < glyphs_len; i++) + { + hb_glyph_info_t *info = &buffer->info[i]; + hb_glyph_position_t *pos = &buffer->pos[i]; + + /* TODO vertical */ + pos->x_advance = info->mask; + pos->x_offset = backward ? -info->var1.u32 : info->var1.u32; + pos->y_offset = info->var2.u32; + } + + if (backward) + hb_buffer_reverse (buffer); + + /* Wow, done! */ + return true; +} diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.h new file mode 100644 index 00000000000..adf33dfe9f0 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.h @@ -0,0 +1,34 @@ +/* + * Copyright © 2015 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_DIRECTWRITE_H +#define HB_DIRECTWRITE_H + +#include "hb.h" + +HB_BEGIN_DECLS + +HB_END_DECLS + +#endif /* HB_UNISCRIBE_H */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc index f41093ae713..c32318d2799 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc @@ -216,6 +216,7 @@ struct hb_graphite2_cluster_t { unsigned int base_glyph; unsigned int num_glyphs; unsigned int cluster; + float advance; }; hb_bool_t @@ -310,6 +311,12 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan, hb_codepoint_t *pg = gids; clusters[0].cluster = buffer->info[0].cluster; + float curradv = HB_DIRECTION_IS_BACKWARD(buffer->props.direction) ? gr_slot_origin_X(gr_seg_first_slot(seg)) : 0.; + if (HB_DIRECTION_IS_BACKWARD(buffer->props.direction)) + { + curradv = gr_slot_origin_X(gr_seg_first_slot(seg)); + clusters[0].advance = gr_seg_advance_X(seg) - curradv; + } for (is = gr_seg_first_slot (seg), ic = 0; is; is = gr_slot_next_in_segment (is), ic++) { unsigned int before = gr_slot_before (is); @@ -320,6 +327,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan, { clusters[ci-1].num_chars += clusters[ci].num_chars; clusters[ci-1].num_glyphs += clusters[ci].num_glyphs; + clusters[ci-1].advance += clusters[ci].advance; ci--; } @@ -331,13 +339,24 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan, c->num_chars = before - c->base_char; c->base_glyph = ic; c->num_glyphs = 0; - ci++; + if (HB_DIRECTION_IS_BACKWARD(buffer->props.direction)) + { + ci++; + clusters[ci].advance = curradv - gr_slot_origin_X(is); + } else { + clusters[ci].advance = gr_slot_origin_X(is) - curradv; + ci++; + } + curradv = gr_slot_origin_X(is); } clusters[ci].num_glyphs++; if (clusters[ci].base_char + clusters[ci].num_chars < after + 1) clusters[ci].num_chars = after + 1 - clusters[ci].base_char; } + + if (!HB_DIRECTION_IS_BACKWARD(buffer->props.direction)) + clusters[ci].advance = gr_seg_advance_X(seg) - curradv; ci++; for (unsigned int i = 0; i < ci; ++i) @@ -347,6 +366,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan, hb_glyph_info_t *info = &buffer->info[clusters[i].base_glyph + j]; info->codepoint = gids[clusters[i].base_glyph + j]; info->cluster = clusters[i].cluster; + info->var1.i32 = clusters[i].advance; // all glyphs in the cluster get the same advance } } buffer->len = glyph_count; @@ -355,49 +375,44 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan, /* Positioning. */ if (!HB_DIRECTION_IS_BACKWARD(buffer->props.direction)) { - hb_glyph_position_t *pPos; - for (pPos = hb_buffer_get_glyph_positions (buffer, NULL), is = gr_seg_first_slot (seg); - is; pPos++, is = gr_slot_next_in_segment (is)) + int currclus = -1; + const hb_glyph_info_t *info = buffer->info; + hb_glyph_position_t *pPos = hb_buffer_get_glyph_positions (buffer, NULL); + curradvx = 0; + for (is = gr_seg_first_slot (seg); is; pPos++, ++info, is = gr_slot_next_in_segment (is)) { pPos->x_offset = gr_slot_origin_X (is) - curradvx; pPos->y_offset = gr_slot_origin_Y (is) * yscale - curradvy; - pPos->x_advance = gr_slot_advance_X (is, grface, grfont); + if (info->cluster != currclus) { + pPos->x_advance = info->var1.i32; + curradvx += pPos->x_advance; + currclus = info->cluster; + } else + pPos->x_advance = 0.; + pPos->y_advance = gr_slot_advance_Y (is, grface, grfont) * yscale; - curradvx += pPos->x_advance; curradvy += pPos->y_advance; } - pPos[-1].x_advance += gr_seg_advance_X(seg) - curradvx; } else { - hb_glyph_position_t *pPos = hb_buffer_get_glyph_positions (buffer, NULL) + buffer->len - 1; - const hb_glyph_info_t *info = buffer->info + buffer->len - 1; - const hb_glyph_info_t *tinfo; - const gr_slot *tis; int currclus = -1; - float clusx = 0., clusy = 0.; - for (is = gr_seg_last_slot (seg); is; pPos--, info--, is = gr_slot_prev_in_segment (is)) + const hb_glyph_info_t *info = buffer->info; + hb_glyph_position_t *pPos = hb_buffer_get_glyph_positions (buffer, NULL); + curradvx = gr_seg_advance_X(seg); + for (is = gr_seg_first_slot (seg); is; pPos++, info++, is = gr_slot_next_in_segment (is)) { if (info->cluster != currclus) { - curradvx += clusx; - curradvy += clusy; + pPos->x_advance = info->var1.i32; + if (currclus != -1) curradvx -= info[-1].var1.i32; currclus = info->cluster; - clusx = 0.; - clusy = 0.; - for (tis = is, tinfo = info; tis && tinfo->cluster == currclus; tis = gr_slot_prev_in_segment (tis), tinfo--) - { - clusx += gr_slot_advance_X (tis, grface, grfont); - clusy += gr_slot_advance_Y (tis, grface, grfont) * yscale; - } - curradvx += clusx; - curradvy += clusy; - } - pPos->x_advance = gr_slot_advance_X (is, grface, grfont); + } else + pPos->x_advance = 0.; + pPos->y_advance = gr_slot_advance_Y (is, grface, grfont) * yscale; - curradvx -= pPos->x_advance; curradvy -= pPos->y_advance; - pPos->x_offset = gr_slot_origin_X (is) - curradvx; + pPos->x_offset = gr_slot_origin_X (is) - curradvx + pPos->x_advance; pPos->y_offset = gr_slot_origin_Y (is) * yscale - curradvy; } hb_buffer_reverse_clusters (buffer); 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 64829ac784c..6c7bac098b4 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 @@ -1170,6 +1170,21 @@ struct Device inline hb_position_t get_y_delta (hb_font_t *font) const { return get_delta (font->y_ppem, font->y_scale); } + inline unsigned int get_size (void) const + { + unsigned int f = deltaFormat; + if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * USHORT::static_size; + return USHORT::static_size * (4 + ((endSize - startSize) >> (4 - f))); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && c->check_range (this, this->get_size ())); + } + + private: + inline int get_delta (unsigned int ppem, int scale) const { if (!ppem) return 0; @@ -1180,8 +1195,6 @@ struct Device return (int) (pixels * (int64_t) scale / ppem); } - - inline int get_delta_pixels (unsigned int ppem_size) const { unsigned int f = deltaFormat; @@ -1205,19 +1218,6 @@ struct Device return delta; } - inline unsigned int get_size (void) const - { - unsigned int f = deltaFormat; - if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * USHORT::static_size; - return USHORT::static_size * (4 + ((endSize - startSize) >> (4 - f))); - } - - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && c->check_range (this, this->get_size ())); - } - protected: USHORT startSize; /* Smallest size to correct--in ppem */ USHORT endSize; /* Largest size to correct--in ppem */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh index 5ea70fbbdec..59dddcf73cb 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh @@ -36,8 +36,17 @@ namespace OT { /* buffer **position** var allocations */ -#define attach_lookback() var.u16[0] /* number of glyphs to go back to attach this glyph to its base */ -#define cursive_chain() var.i16[1] /* character to which this connects, may be positive or negative */ +#define attach_chain() var.i16[0] /* glyph to which this attaches to, relative to current glyphs; negative for going back, positive for forward. */ +#define attach_type() var.u8[2] /* attachment type */ +/* Note! if attach_chain() is zero, the value of attach_type() is irrelevant. */ + +enum attach_type_t { + ATTACH_TYPE_NONE = 0X00, + + /* Each attachment should be either a mark or a cursive; can't be both. */ + ATTACH_TYPE_MARK = 0X01, + ATTACH_TYPE_CURSIVE = 0X02, +}; /* Shared Tables: ValueRecord, Anchor Table, and MarkArray */ @@ -425,8 +434,25 @@ struct MarkArray : ArrayOf /* Array of MarkRecords--in Coverage orde hb_glyph_position_t &o = buffer->cur_pos(); o.x_offset = base_x - mark_x; o.y_offset = base_y - mark_y; - o.attach_lookback() = buffer->idx - glyph_pos; + o.attach_type() = ATTACH_TYPE_MARK; + o.attach_chain() = (int) glyph_pos - (int) buffer->idx; buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; + { + unsigned int i = buffer->idx; + unsigned int j = glyph_pos; + hb_glyph_position_t *pos = buffer->pos; + assert (j < i); + if (HB_DIRECTION_IS_FORWARD (c->direction)) + for (unsigned int k = j; k < i; k++) { + pos[i].x_offset -= pos[k].x_advance; + pos[i].y_offset -= pos[k].y_advance; + } + else + for (unsigned int k = j + 1; k < i + 1; k++) { + pos[i].x_offset += pos[k].x_advance; + pos[i].y_offset += pos[k].y_advance; + } + } buffer->idx++; return_trace (true); @@ -907,9 +933,6 @@ struct CursivePosFormat1 TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; - /* We don't handle mark glyphs here. */ - if (unlikely (_hb_glyph_info_is_mark (&buffer->cur()))) return_trace (false); - const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)]; if (!this_record.exitAnchor) return_trace (false); @@ -993,8 +1016,9 @@ struct CursivePosFormat1 */ reverse_cursive_minor_offset (pos, child, c->direction, parent); - pos[child].cursive_chain() = parent - child; - buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_CURSIVE; + pos[child].attach_type() = ATTACH_TYPE_CURSIVE; + pos[child].attach_chain() = (int) parent - (int) child; + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) pos[child].y_offset = y_offset; else @@ -1069,7 +1093,7 @@ struct MarkBasePosFormat1 unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint); if (likely (mark_index == NOT_COVERED)) return_trace (false); - /* now we search backwards for a non-mark glyph */ + /* Now we search backwards for a non-mark glyph */ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset (buffer->idx, 1); skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); @@ -1081,7 +1105,7 @@ struct MarkBasePosFormat1 } while (1); /* Checking that matched glyph is actually a base glyph by GDEF is too strong; disabled */ - if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { /*return_trace (false);*/ } + //if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { return_trace (false); } unsigned int base_index = (this+baseCoverage).get_coverage (buffer->info[skippy_iter.idx].codepoint); if (base_index == NOT_COVERED) return_trace (false); @@ -1170,14 +1194,14 @@ struct MarkLigPosFormat1 unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint); if (likely (mark_index == NOT_COVERED)) return_trace (false); - /* now we search backwards for a non-mark glyph */ + /* Now we search backwards for a non-mark glyph */ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset (buffer->idx, 1); skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); if (!skippy_iter.prev ()) return_trace (false); /* Checking that matched glyph is actually a ligature by GDEF is too strong; disabled */ - if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { /*return_trace (false);*/ } + //if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { return_trace (false); } unsigned int j = skippy_iter.idx; unsigned int lig_index = (this+ligatureCoverage).get_coverage (buffer->info[j].codepoint); @@ -1501,7 +1525,8 @@ struct GPOS : GSUBGPOS { return CastR (GSUBGPOS::get_lookup (i)); } static inline void position_start (hb_font_t *font, hb_buffer_t *buffer); - static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer); + static inline void position_finish_advances (hb_font_t *font, hb_buffer_t *buffer); + static inline void position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer); inline bool sanitize (hb_sanitize_context_t *c) const { @@ -1518,13 +1543,13 @@ struct GPOS : GSUBGPOS static void reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, unsigned int new_parent) { - unsigned int j = pos[i].cursive_chain(); - if (likely (!j)) + int chain = pos[i].attach_chain(), type = pos[i].attach_type(); + if (likely (!chain || 0 == (type & ATTACH_TYPE_CURSIVE))) return; - j += i; + pos[i].attach_chain() = 0; - pos[i].cursive_chain() = 0; + unsigned int j = (int) i + chain; /* Stop if we see new parent in the chain. */ if (j == new_parent) @@ -1537,62 +1562,56 @@ reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direc else pos[j].x_offset = -pos[i].x_offset; - pos[j].cursive_chain() = i - j; + pos[j].attach_chain() = -chain; + pos[j].attach_type() = type; } static void -fix_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction) +propagate_attachment_offsets (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction) { - unsigned int j = pos[i].cursive_chain(); - if (likely (!j)) + /* Adjusts offsets of attached glyphs (both cursive and mark) to accumulate + * offset of glyph they are attached to. */ + int chain = pos[i].attach_chain(), type = pos[i].attach_type(); + if (likely (!chain)) return; - j += i; - - pos[i].cursive_chain() = 0; + unsigned int j = (int) i + chain; - fix_cursive_minor_offset (pos, j, direction); - - if (HB_DIRECTION_IS_HORIZONTAL (direction)) - pos[i].y_offset += pos[j].y_offset; - else - pos[i].x_offset += pos[j].x_offset; -} - -static void -fix_mark_attachment (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction) -{ - if (likely (!(pos[i].attach_lookback()))) - return; + pos[i].attach_chain() = 0; - unsigned int j = i - pos[i].attach_lookback(); + propagate_attachment_offsets (pos, j, direction); - pos[i].x_offset += pos[j].x_offset; - pos[i].y_offset += pos[j].y_offset; + assert (!!(type & ATTACH_TYPE_MARK) ^ !!(type & ATTACH_TYPE_CURSIVE)); - if (HB_DIRECTION_IS_FORWARD (direction)) - for (unsigned int k = j; k < i; k++) { - pos[i].x_offset -= pos[k].x_advance; - pos[i].y_offset -= pos[k].y_advance; - } - else - for (unsigned int k = j + 1; k < i + 1; k++) { - pos[i].x_offset += pos[k].x_advance; - pos[i].y_offset += pos[k].y_advance; - } + if (type & ATTACH_TYPE_CURSIVE) + { + if (HB_DIRECTION_IS_HORIZONTAL (direction)) + pos[i].y_offset += pos[j].y_offset; + else + pos[i].x_offset += pos[j].x_offset; + } + else /*if (type & ATTACH_TYPE_MARK)*/ + { + pos[i].x_offset += pos[j].x_offset; + pos[i].y_offset += pos[j].y_offset; + } } void GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) { - buffer->clear_positions (); - unsigned int count = buffer->len; for (unsigned int i = 0; i < count; i++) - buffer->pos[i].attach_lookback() = buffer->pos[i].cursive_chain() = 0; + buffer->pos[i].attach_chain() = buffer->pos[i].attach_type() = 0; } void -GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) +GPOS::position_finish_advances (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) +{ + //_hb_buffer_assert_gsubgpos_vars (buffer); +} + +void +GPOS::position_finish_offsets (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) { _hb_buffer_assert_gsubgpos_vars (buffer); @@ -1600,15 +1619,10 @@ GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len); hb_direction_t direction = buffer->props.direction; - /* Handle cursive connections */ - if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_CURSIVE) - for (unsigned int i = 0; i < len; i++) - fix_cursive_minor_offset (pos, i, direction); - /* Handle attachments */ if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT) for (unsigned int i = 0; i < len; i++) - fix_mark_attachment (pos, i, direction); + propagate_attachment_offsets (pos, i, direction); } @@ -1637,8 +1651,8 @@ template } -#undef attach_lookback -#undef cursive_chain +#undef attach_chain +#undef attach_type } /* namespace OT */ 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 459a1a3dd5c..38c2c6405a3 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 @@ -1268,7 +1268,6 @@ struct GSUB : GSUBGPOS { return CastR (GSUBGPOS::get_lookup (i)); } static inline void substitute_start (hb_font_t *font, hb_buffer_t *buffer); - static inline void substitute_finish (hb_font_t *font, hb_buffer_t *buffer); inline bool sanitize (hb_sanitize_context_t *c) const { @@ -1297,11 +1296,6 @@ GSUB::substitute_start (hb_font_t *font, hb_buffer_t *buffer) } } -void -GSUB::substitute_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer HB_UNUSED) -{ -} - /* Out-of-class implementation for methods recursing */ 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 d6db00566da..3f9d9ca9df7 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 @@ -971,7 +971,7 @@ static inline bool apply_lookup (hb_apply_context_t *c, match_positions[j] += delta; } - for (unsigned int i = 0; i < lookupCount; i++) + for (unsigned int i = 0; i < lookupCount && !buffer->in_error; i++) { unsigned int idx = lookupRecord[i].sequenceIndex; if (idx >= count) 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 f48184fd394..094db957071 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 @@ -99,21 +99,20 @@ hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c, const hb_ot_layout_lookup_accelerator_t &accel); -/* Should be called after all the substitute_lookup's are done */ -HB_INTERNAL void -hb_ot_layout_substitute_finish (hb_font_t *font, - hb_buffer_t *buffer); - - -/* Should be called before all the position_lookup's are done. Resets positions to zero. */ +/* Should be called before all the position_lookup's are done. */ HB_INTERNAL void hb_ot_layout_position_start (hb_font_t *font, hb_buffer_t *buffer); -/* Should be called after all the position_lookup's are done */ +/* Should be called after all the position_lookup's are done, to finish advances. */ +HB_INTERNAL void +hb_ot_layout_position_finish_advances (hb_font_t *font, + hb_buffer_t *buffer); + +/* Should be called after hb_ot_layout_position_finish_advances, to finish offsets. */ HB_INTERNAL void -hb_ot_layout_position_finish (hb_font_t *font, - hb_buffer_t *buffer); +hb_ot_layout_position_finish_offsets (hb_font_t *font, + hb_buffer_t *buffer); @@ -257,8 +256,11 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer) if (u == 0x200Cu) props |= UPROPS_MASK_ZWNJ; if (u == 0x200Du) props |= UPROPS_MASK_ZWJ; } - else if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK (gen_cat))) + else if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK_OR_MODIFIER_SYMBOL (gen_cat))) { + /* The above check is just an optimization to let in only things we need further + * processing on. */ + /* Only Mn and Mc can have non-zero ccc: * http://www.unicode.org/policies/stability_policy.html#Property_Value * """ @@ -273,6 +275,16 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer) * the "else if". */ props |= unicode->modified_combining_class (info->codepoint)<<8; + + /* Recategorize emoji skin-tone modifiers as Unicode mark, so they + * behave correctly in non-native directionality. They originally + * are MODIFIER_SYMBOL. Fixes: + * https://github.com/behdad/harfbuzz/issues/169 + */ + if (unlikely (hb_in_range (u, 0x1F3FBu, 0x1F3FFu))) + { + props = gen_cat = HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK; + } } } 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 9fc88f6c862..adf232bf119 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 @@ -771,12 +771,6 @@ hb_ot_layout_substitute_start (hb_font_t *font, hb_buffer_t *buffer) OT::GSUB::substitute_start (font, buffer); } -void -hb_ot_layout_substitute_finish (hb_font_t *font, hb_buffer_t *buffer) -{ - OT::GSUB::substitute_finish (font, buffer); -} - /** * hb_ot_layout_lookup_substitute_closure: * @@ -811,9 +805,15 @@ hb_ot_layout_position_start (hb_font_t *font, hb_buffer_t *buffer) } void -hb_ot_layout_position_finish (hb_font_t *font, hb_buffer_t *buffer) +hb_ot_layout_position_finish_advances (hb_font_t *font, hb_buffer_t *buffer) +{ + OT::GPOS::position_finish_advances (font, buffer); +} + +void +hb_ot_layout_position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer) { - OT::GPOS::position_finish (font, buffer); + OT::GPOS::position_finish_offsets (font, buffer); } /** @@ -902,20 +902,79 @@ struct GPOSProxy }; -template +struct hb_get_subtables_context_t : + OT::hb_dispatch_context_t +{ + template + static inline bool apply_to (const void *obj, OT::hb_apply_context_t *c) + { + const Type *typed_obj = (const Type *) obj; + return typed_obj->apply (c); + } + + typedef bool (*hb_apply_func_t) (const void *obj, OT::hb_apply_context_t *c); + + struct hb_applicable_t + { + inline void init (const void *obj_, hb_apply_func_t apply_func_) + { + obj = obj_; + apply_func = apply_func_; + } + + inline bool apply (OT::hb_apply_context_t *c) const { return apply_func (obj, c); } + + private: + const void *obj; + hb_apply_func_t apply_func; + }; + + typedef hb_auto_array_t array_t; + + /* Dispatch interface. */ + inline const char *get_name (void) { return "GET_SUBTABLES"; } + template + inline return_t dispatch (const T &obj) + { + hb_applicable_t *entry = array.push(); + if (likely (entry)) + entry->init (&obj, apply_to); + return HB_VOID; + } + static return_t default_return_value (void) { return HB_VOID; } + bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; } + + hb_get_subtables_context_t (array_t &array_) : + array (array_), + debug_depth (0) {} + + array_t &array; + unsigned int debug_depth; +}; + static inline bool apply_forward (OT::hb_apply_context_t *c, - const Obj &obj, - const hb_ot_layout_lookup_accelerator_t &accel) + const hb_ot_layout_lookup_accelerator_t &accel, + const hb_get_subtables_context_t::array_t &subtables) { bool ret = false; hb_buffer_t *buffer = c->buffer; while (buffer->idx < buffer->len && !buffer->in_error) { + bool applied = false; if (accel.may_have (buffer->cur().codepoint) && (buffer->cur().mask & c->lookup_mask) && - c->check_glyph_property (&buffer->cur(), c->lookup_props) && - obj.apply (c)) + c->check_glyph_property (&buffer->cur(), c->lookup_props)) + { + for (unsigned int i = 0; i < subtables.len; i++) + if (subtables[i].apply (c)) + { + applied = true; + break; + } + } + + if (applied) ret = true; else buffer->next_glyph (); @@ -923,11 +982,10 @@ apply_forward (OT::hb_apply_context_t *c, return ret; } -template static inline bool apply_backward (OT::hb_apply_context_t *c, - const Obj &obj, - const hb_ot_layout_lookup_accelerator_t &accel) + const hb_ot_layout_lookup_accelerator_t &accel, + const hb_get_subtables_context_t::array_t &subtables) { bool ret = false; hb_buffer_t *buffer = c->buffer; @@ -935,9 +993,15 @@ apply_backward (OT::hb_apply_context_t *c, { if (accel.may_have (buffer->cur().codepoint) && (buffer->cur().mask & c->lookup_mask) && - c->check_glyph_property (&buffer->cur(), c->lookup_props) && - obj.apply (c)) - ret = true; + c->check_glyph_property (&buffer->cur(), c->lookup_props)) + { + for (unsigned int i = 0; i < subtables.len; i++) + if (subtables[i].apply (c)) + { + ret = true; + break; + } + } /* The reverse lookup doesn't "advance" cursor (for good reason). */ buffer->idx--; @@ -946,26 +1010,6 @@ apply_backward (OT::hb_apply_context_t *c, return ret; } -struct hb_apply_forward_context_t : - OT::hb_dispatch_context_t -{ - inline const char *get_name (void) { return "APPLY_FWD"; } - template - inline return_t dispatch (const T &obj) { return apply_forward (c, obj, accel); } - static return_t default_return_value (void) { return false; } - bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return true; } - - hb_apply_forward_context_t (OT::hb_apply_context_t *c_, - const hb_ot_layout_lookup_accelerator_t &accel_) : - c (c_), - accel (accel_), - debug_depth (0) {} - - OT::hb_apply_context_t *c; - const hb_ot_layout_lookup_accelerator_t &accel; - unsigned int debug_depth; -}; - template static inline void apply_string (OT::hb_apply_context_t *c, @@ -979,6 +1023,10 @@ apply_string (OT::hb_apply_context_t *c, c->set_lookup_props (lookup.get_props ()); + hb_get_subtables_context_t::array_t subtables; + hb_get_subtables_context_t c_get_subtables (subtables); + lookup.dispatch (&c_get_subtables); + if (likely (!lookup.is_reverse ())) { /* in/out forward substitution/positioning */ @@ -987,13 +1035,7 @@ apply_string (OT::hb_apply_context_t *c, buffer->idx = 0; bool ret; - if (lookup.get_subtable_count () == 1) - { - hb_apply_forward_context_t c_forward (c, accel); - ret = lookup.dispatch (&c_forward); - } - else - ret = apply_forward (c, lookup, accel); + ret = apply_forward (c, accel, subtables); if (ret) { if (!Proxy::inplace) @@ -1009,7 +1051,7 @@ apply_string (OT::hb_apply_context_t *c, buffer->remove_output (); buffer->idx = buffer->len - 1; - apply_backward (c, lookup, accel); + apply_backward (c, accel, subtables); } } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-default.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-default.cc index 5cf0a1886ca..be60e56feb8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-default.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-default.cc @@ -40,6 +40,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default = NULL, /* decompose */ NULL, /* compose */ NULL, /* setup_masks */ - HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE, + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, true, /* fallback_position */ }; 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 880aa918f89..21256dec517 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 @@ -1246,7 +1246,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, /* TODO Set glyph_props? */ /* Insert dottedcircle after possible Repha. */ - while (buffer->idx < buffer->len && + while (buffer->idx < buffer->len && !buffer->in_error && last_syllable == buffer->cur().syllable() && buffer->cur().indic_category() == OT_Repha) buffer->next_glyph (); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc index 4d3446892ca..7b043440e8a 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc @@ -451,7 +451,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, buffer->idx = 0; unsigned int last_syllable = 0; - while (buffer->idx < buffer->len) + while (buffer->idx < buffer->len && !buffer->in_error) { unsigned int syllable = buffer->cur().syllable(); syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F); 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 b5da69b3fc3..b3372bd295e 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 @@ -41,8 +41,6 @@ enum hb_ot_shape_zero_width_marks_type_t { HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, -// HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY, - HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE, HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY, HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-thai.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-thai.cc index bd7c5e14274..58392b6a9e1 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-thai.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-thai.cc @@ -377,6 +377,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai = NULL, /* decompose */ NULL, /* compose */ NULL, /* setup_masks */ - HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE, + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, false,/* fallback_position */ }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-tibetan.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-tibetan.cc index 03bcfee3365..a77b531daa5 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-tibetan.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-tibetan.cc @@ -57,6 +57,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_tibetan = NULL, /* decompose */ NULL, /* compose */ NULL, /* setup_masks */ - HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE, + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, true, /* fallback_position */ }; 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 0f667833916..6fbfe2b5eac 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 @@ -522,7 +522,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, /* TODO Set glyph_props? */ /* Insert dottedcircle after possible Repha. */ - while (buffer->idx < buffer->len && + while (buffer->idx < buffer->len && !buffer->in_error && last_syllable == buffer->cur().syllable() && buffer->cur().use_category() == USE_R) buffer->next_glyph (); @@ -583,6 +583,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_use = NULL, /* decompose */ compose_use, setup_masks_use, - HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY, false, /* fallback_position */ }; 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 1d9783e33bf..0b02328989f 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 @@ -584,8 +584,6 @@ hb_ot_substitute_complex (hb_ot_shape_context_t *c) c->plan->substitute (c->font, buffer); - hb_ot_layout_substitute_finish (c->font, buffer); - return; } @@ -615,30 +613,9 @@ zero_mark_width (hb_glyph_position_t *pos) pos->y_advance = 0; } -static inline void -zero_mark_widths_by_unicode (hb_buffer_t *buffer, bool adjust_offsets) -{ - if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII)) - return; - - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 0; i < count; i++) - if (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) - { - if (adjust_offsets) - adjust_mark_offsets (&buffer->pos[i]); - zero_mark_width (&buffer->pos[i]); - } -} - static inline void zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets) { - /* This one is a hack; Technically GDEF can mark ASCII glyphs as marks, but we don't listen. */ - if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII)) - return; - unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; for (unsigned int i = 0; i < count; i++) @@ -686,9 +663,12 @@ hb_ot_position_default (hb_ot_shape_context_t *c) static inline bool hb_ot_position_complex (hb_ot_shape_context_t *c) { + hb_ot_layout_position_start (c->font, c->buffer); + bool ret = false; unsigned int count = c->buffer->len; bool has_positioning = (bool) hb_ot_layout_has_positioning (c->face); + /* If the font has no GPOS, AND, no fallback positioning will * happen, AND, direction is forward, then when zeroing mark * widths, we shift the mark with it, such that the mark @@ -707,15 +687,8 @@ hb_ot_position_complex (hb_ot_shape_context_t *c) zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing); break; - /* Not currently used for any shaper: - case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: - zero_mark_widths_by_unicode (c->buffer, adjust_offsets_when_zeroing); - break; - */ - default: case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: - case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: break; } @@ -748,37 +721,33 @@ hb_ot_position_complex (hb_ot_shape_context_t *c) switch (c->plan->shaper->zero_width_marks) { - case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: - zero_mark_widths_by_unicode (c->buffer, adjust_offsets_when_zeroing); - break; - case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing); break; default: case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: - //case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: break; } + /* Finishing off GPOS has to follow a certain order. */ + hb_ot_layout_position_finish_advances (c->font, c->buffer); + hb_ot_zero_width_default_ignorables (c); + hb_ot_layout_position_finish_offsets (c->font, c->buffer); + return ret; } static inline void hb_ot_position (hb_ot_shape_context_t *c) { - hb_ot_layout_position_start (c->font, c->buffer); + c->buffer->clear_positions (); hb_ot_position_default (c); hb_bool_t fallback = !hb_ot_position_complex (c); - hb_ot_zero_width_default_ignorables (c); - - hb_ot_layout_position_finish (c->font, c->buffer); - if (fallback && c->plan->shaper->fallback_position) _hb_ot_shape_fallback_position (c->plan, c->font, c->buffer); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc index 01ce92038fa..9a6a1207b46 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc @@ -927,6 +927,7 @@ hb_ot_tag_to_language (hb_tag_t tag) } } +#ifdef MAIN static inline void test_langs_sorted (void) { @@ -942,7 +943,6 @@ test_langs_sorted (void) } } -#ifdef MAIN int main (void) { diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode-private.hh index ecbec513cfa..44fbe582e93 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode-private.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode-private.hh @@ -357,9 +357,10 @@ extern HB_INTERNAL const hb_unicode_funcs_t _hb_unicode_funcs_nil; FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | \ FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK))) -#define HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK(gen_cat) \ +#define HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK_OR_MODIFIER_SYMBOL(gen_cat) \ (FLAG_SAFE (gen_cat) & \ (FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK) | \ - FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK))) + FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) | \ + FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL))) #endif /* HB_UNICODE_PRIVATE_HH */ diff --git a/Build/source/libs/harfbuzz/version.ac b/Build/source/libs/harfbuzz/version.ac index ebe09c36f73..c7951bf054c 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.1.3]) +m4_define([harfbuzz_version], [1.2.0]) -- cgit v1.2.3