summaryrefslogtreecommitdiff
path: root/Build/source/libs/harfbuzz
diff options
context:
space:
mode:
authorAkira Kakuto <kakuto@fuk.kindai.ac.jp>2019-10-28 23:44:53 +0000
committerAkira Kakuto <kakuto@fuk.kindai.ac.jp>2019-10-28 23:44:53 +0000
commit65b88a70ed4a3b2ee8da094d317b3d8119aec1d7 (patch)
tree9b8c76c1afc603f7bcb0377efabd7b06cdd43e5d /Build/source/libs/harfbuzz
parent1631aaed733bf2365f99084b46113a982d918ebc (diff)
harfbuzz-2.6.3
git-svn-id: svn://tug.org/texlive/trunk@52560 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/harfbuzz')
-rw-r--r--Build/source/libs/harfbuzz/ChangeLog5
-rw-r--r--Build/source/libs/harfbuzz/Makefile.am2
-rw-r--r--Build/source/libs/harfbuzz/Makefile.in12
-rw-r--r--Build/source/libs/harfbuzz/TLpatches/ChangeLog5
-rw-r--r--Build/source/libs/harfbuzz/TLpatches/TL-Changes2
-rwxr-xr-xBuild/source/libs/harfbuzz/configure24
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog854
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/NEWS8
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/README9
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/README.md9
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/TESTING.md11
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/configure.ac2
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources2
-rwxr-xr-xBuild/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py3
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc1
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh4
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh10
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh53
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh16
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh25
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc5
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh5
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-common.hh11
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h15
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc23
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h12
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh8
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh70
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh25
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file.hh2
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh10
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff-common.hh14
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.cc23
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh26
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc12
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh6
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh16
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh2
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh15
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face-table-list.hh1
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc28
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh1073
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh58
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh12
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh553
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh145
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh59
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh233
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc2
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh4
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh4
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc4
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc2
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh734
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh13
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc4
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.cc3
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh4
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff1.cc2
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff2.cc2
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc31
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc8
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.h20
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh4
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-warning.cc37
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc37
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/test-iter.cc2
-rw-r--r--Build/source/libs/harfbuzz/version.ac2
68 files changed, 3580 insertions, 858 deletions
diff --git a/Build/source/libs/harfbuzz/ChangeLog b/Build/source/libs/harfbuzz/ChangeLog
index 737ad49db32..494524dcf9b 100644
--- a/Build/source/libs/harfbuzz/ChangeLog
+++ b/Build/source/libs/harfbuzz/ChangeLog
@@ -1,3 +1,8 @@
+2019-10-29 Akira Kakuto <kakuto@w32tex.org>
+
+ Import harfbuzz-2.6.3.
+ * Makefile.am, version.ac: Adjusted.
+
2019-10-01 Akira Kakuto <kakuto@w32tex.org>
Import harfbuzz-2.6.2.
diff --git a/Build/source/libs/harfbuzz/Makefile.am b/Build/source/libs/harfbuzz/Makefile.am
index 071afb227eb..a8b9c05817f 100644
--- a/Build/source/libs/harfbuzz/Makefile.am
+++ b/Build/source/libs/harfbuzz/Makefile.am
@@ -129,7 +129,6 @@ libharfbuzz_a_SOURCES = \
@HARFBUZZ_TREE@/src/hb-unicode-emoji-table.hh \
@HARFBUZZ_TREE@/src/hb-vector.hh \
@HARFBUZZ_TREE@/src/hb-utf.hh \
- @HARFBUZZ_TREE@/src/hb-warning.cc \
@HARFBUZZ_TREE@/src/hb-buffer-deserialize-json.hh \
@HARFBUZZ_TREE@/src/hb-buffer-deserialize-text.hh \
@HARFBUZZ_TREE@/src/hb-fallback-shape.cc \
@@ -208,6 +207,7 @@ libharfbuzz_a_SOURCES += \
@HARFBUZZ_TREE@/src/hb-ot-var.cc \
@HARFBUZZ_TREE@/src/hb-ot-var-avar-table.hh \
@HARFBUZZ_TREE@/src/hb-ot-var-fvar-table.hh \
+ @HARFBUZZ_TREE@/src/hb-ot-var-gvar-table.hh \
@HARFBUZZ_TREE@/src/hb-ot-var-hvar-table.hh \
@HARFBUZZ_TREE@/src/hb-ot-var-mvar-table.hh \
@HARFBUZZ_TREE@/src/hb-ot-vorg-table.hh \
diff --git a/Build/source/libs/harfbuzz/Makefile.in b/Build/source/libs/harfbuzz/Makefile.in
index 861fbbae639..64a55fa8d60 100644
--- a/Build/source/libs/harfbuzz/Makefile.in
+++ b/Build/source/libs/harfbuzz/Makefile.in
@@ -142,7 +142,6 @@ am_libharfbuzz_a_OBJECTS = @HARFBUZZ_TREE@/src/hb-blob.$(OBJEXT) \
@HARFBUZZ_TREE@/src/hb-subset-cff2.$(OBJEXT) \
@HARFBUZZ_TREE@/src/hb-ucd.$(OBJEXT) \
@HARFBUZZ_TREE@/src/hb-unicode.$(OBJEXT) \
- @HARFBUZZ_TREE@/src/hb-warning.$(OBJEXT) \
@HARFBUZZ_TREE@/src/hb-fallback-shape.$(OBJEXT) \
@HARFBUZZ_TREE@/src/hb-aat-layout.$(OBJEXT) \
@HARFBUZZ_TREE@/src/hb-aat-map.$(OBJEXT) \
@@ -243,8 +242,7 @@ am__depfiles_remade = ./$(DEPDIR)/hbtest-dummy.Po \
@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff1.Po \
@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff2.Po \
@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ucd.Po \
- @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-unicode.Po \
- @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-warning.Po
+ @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-unicode.Po
am__mv = mv -f
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -798,7 +796,6 @@ libharfbuzz_a_SOURCES = @HARFBUZZ_TREE@/src/hb-algs.hh \
@HARFBUZZ_TREE@/src/hb-unicode.cc \
@HARFBUZZ_TREE@/src/hb-unicode-emoji-table.hh \
@HARFBUZZ_TREE@/src/hb-vector.hh @HARFBUZZ_TREE@/src/hb-utf.hh \
- @HARFBUZZ_TREE@/src/hb-warning.cc \
@HARFBUZZ_TREE@/src/hb-buffer-deserialize-json.hh \
@HARFBUZZ_TREE@/src/hb-buffer-deserialize-text.hh \
@HARFBUZZ_TREE@/src/hb-fallback-shape.cc \
@@ -874,6 +871,7 @@ libharfbuzz_a_SOURCES = @HARFBUZZ_TREE@/src/hb-algs.hh \
@HARFBUZZ_TREE@/src/hb-ot-var.cc \
@HARFBUZZ_TREE@/src/hb-ot-var-avar-table.hh \
@HARFBUZZ_TREE@/src/hb-ot-var-fvar-table.hh \
+ @HARFBUZZ_TREE@/src/hb-ot-var-gvar-table.hh \
@HARFBUZZ_TREE@/src/hb-ot-var-hvar-table.hh \
@HARFBUZZ_TREE@/src/hb-ot-var-mvar-table.hh \
@HARFBUZZ_TREE@/src/hb-ot-vorg-table.hh \
@@ -1036,9 +1034,6 @@ clean-noinstLIBRARIES:
@HARFBUZZ_TREE@/src/hb-unicode.$(OBJEXT): \
@HARFBUZZ_TREE@/src/$(am__dirstamp) \
@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
-@HARFBUZZ_TREE@/src/hb-warning.$(OBJEXT): \
- @HARFBUZZ_TREE@/src/$(am__dirstamp) \
- @HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
@HARFBUZZ_TREE@/src/hb-fallback-shape.$(OBJEXT): \
@HARFBUZZ_TREE@/src/$(am__dirstamp) \
@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
@@ -1189,7 +1184,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff2.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ucd.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-unicode.Po@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-warning.Po@am__quote@ # am--include-marker
$(am__depfiles_remade):
@$(MKDIR_P) $(@D)
@@ -1833,7 +1827,6 @@ distclean: distclean-recursive
-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff2.Po
-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ucd.Po
-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-unicode.Po
- -rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-warning.Po
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-hdr distclean-tags
@@ -1933,7 +1926,6 @@ maintainer-clean: maintainer-clean-recursive
-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff2.Po
-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ucd.Po
-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-unicode.Po
- -rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-warning.Po
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
diff --git a/Build/source/libs/harfbuzz/TLpatches/ChangeLog b/Build/source/libs/harfbuzz/TLpatches/ChangeLog
index 29bc18d0ddd..d94995c93b2 100644
--- a/Build/source/libs/harfbuzz/TLpatches/ChangeLog
+++ b/Build/source/libs/harfbuzz/TLpatches/ChangeLog
@@ -1,3 +1,8 @@
+2019-10-29 Akira Kakuto <kakuto@w32tex.org>
+
+ Imported harfbuzz-2.6.3 source tree from:
+ http://www.freedesktop.org/software/harfbuzz/release/
+
2019-10-01 Akira Kakuto <kakuto@w32tex.org>
Imported harfbuzz-2.6.2 source tree from:
diff --git a/Build/source/libs/harfbuzz/TLpatches/TL-Changes b/Build/source/libs/harfbuzz/TLpatches/TL-Changes
index 0151695d887..fff802a49a0 100644
--- a/Build/source/libs/harfbuzz/TLpatches/TL-Changes
+++ b/Build/source/libs/harfbuzz/TLpatches/TL-Changes
@@ -1,4 +1,4 @@
-Changes applied to the harfbuzz-2.6.2/ tree as obtained from:
+Changes applied to the harfbuzz-2.6.3/ tree as obtained from:
http://www.freedesktop.org/software/harfbuzz/release/
Removed:
diff --git a/Build/source/libs/harfbuzz/configure b/Build/source/libs/harfbuzz/configure
index ebf0c8f118c..3b0e698ad41 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) 2.6.2.
+# Generated by GNU Autoconf 2.69 for harfbuzz (TeX Live) 2.6.3.
#
# Report bugs to <tex-k@tug.org>.
#
@@ -580,8 +580,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='harfbuzz (TeX Live)'
PACKAGE_TARNAME='harfbuzz--tex-live-'
-PACKAGE_VERSION='2.6.2'
-PACKAGE_STRING='harfbuzz (TeX Live) 2.6.2'
+PACKAGE_VERSION='2.6.3'
+PACKAGE_STRING='harfbuzz (TeX Live) 2.6.3'
PACKAGE_BUGREPORT='tex-k@tug.org'
PACKAGE_URL=''
@@ -1311,7 +1311,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) 2.6.2 to adapt to many kinds of systems.
+\`configure' configures harfbuzz (TeX Live) 2.6.3 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1382,7 +1382,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of harfbuzz (TeX Live) 2.6.2:";;
+ short | recursive ) echo "Configuration of harfbuzz (TeX Live) 2.6.3:";;
esac
cat <<\_ACEOF
@@ -1487,7 +1487,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-harfbuzz (TeX Live) configure 2.6.2
+harfbuzz (TeX Live) configure 2.6.3
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2123,7 +2123,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 2.6.2, which was
+It was created by harfbuzz (TeX Live) $as_me 2.6.3, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -4047,7 +4047,7 @@ fi
# Define the identity of the package.
PACKAGE='harfbuzz--tex-live-'
- VERSION='2.6.2'
+ VERSION='2.6.3'
# Some tools Automake needs.
@@ -4241,8 +4241,8 @@ WARNING_CFLAGS=$kpse_cv_warning_cflags
HB_VERSION_MAJOR=2
HB_VERSION_MINOR=6
-HB_VERSION_MICRO=2
-HB_VERSION=2.6.2
+HB_VERSION_MICRO=3
+HB_VERSION=2.6.3
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
@@ -7919,7 +7919,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 2.6.2, which was
+This file was extended by harfbuzz (TeX Live) $as_me 2.6.3, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -7985,7 +7985,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 2.6.2
+harfbuzz (TeX Live) config.status 2.6.3
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog b/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog
index 5432e12cb63..84dc3cceefc 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog
@@ -1,3 +1,831 @@
+commit ce11df1b5b8e49712bef249de19bc4768f3a691c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date: Mon Oct 28 14:45:31 2019 -0700
+
+ 2.6.3
+
+ NEWS | 8 ++++++++
+ configure.ac | 2 +-
+ src/hb-font.cc | 2 +-
+ src/hb-version.h | 4 ++--
+ 4 files changed, 12 insertions(+), 4 deletions(-)
+
+commit 5a59de2b983ed7a1c639ea3e4d23c341134cd6d5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date: Mon Oct 28 14:02:47 2019 -0700
+
+ Actually add +hb_font_get_nominal_glyphs()
+
+ New API:
+ +hb_font_get_nominal_glyphs()
+
+ src/hb-font.cc | 23 +++++++++++++++++++++++
+ src/hb-font.h | 8 ++++++++
+ 2 files changed, 31 insertions(+)
+
+commit 03028a5fe512978a8f8e2396001cf8e425b44f72
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date: Mon Oct 28 13:46:56 2019 -0700
+
+ Revert "Don't include codepoint 0 in the results of collect_unicodes."
+
+ This reverts commit 14ad96ffbf77c33d8d33d2686d17c2375381989e.
+
+ This was wrong. My bad!
+
+ https://github.com/harfbuzz/harfbuzz/issues/2031
+
+ src/hb-ot-cmap-table.hh | 8 +-------
+ 1 file changed, 1 insertion(+), 7 deletions(-)
+
+commit 2714dc31b8d0ffe3c043935dd7619be0dd7b7635
+Merge: aca63902 14ad96ff
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date: Mon Oct 28 13:01:34 2019 -0700
+
+ Merge pull request #2032 from googlefonts/collect_unicodes
+
+ Don't include codepoint 0 in the results of collect_unicodes.
+
+commit 14ad96ffbf77c33d8d33d2686d17c2375381989e
+Author: Garret Rieger <grieger@google.com>
+Date: Mon Oct 28 12:56:04 2019 -0700
+
+ Don't include codepoint 0 in the results of collect_unicodes.
+ It is always assumed to be the notdef glyph.
+
+ src/hb-ot-cmap-table.hh | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+commit aca63902814748b36bf6939421cfa95eed3a1ca7
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Tue Oct 22 00:06:46 2019 +0330
+
+ [gpos] Don't move pointer when match_glyph_data is not set
+
+ src/hb-ot-layout-gsubgpos.hh | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit defe9b6da018bc85750c999454c51fde0cadb9b2
+Author: Qunxin Liu <qxliu@google.com>
+Date: Fri Oct 25 10:07:26 2019 -0700
+
+ crash fix : Heap-buffer-overflow READ 2
+ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=18513
+
+ src/hb-ot-layout-gpos-table.hh | 12 ++++++------
+ ...z-testcase-minimized-hb-subset-fuzzer-5677906231033856 | Bin 0 -> 938 bytes
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+commit b2fcca6e14afc8085cc1c2491b2d7c780dad1450
+Author: Qunxin Liu <qxliu@google.com>
+Date: Thu Oct 24 15:15:26 2019 -0700
+
+ fuzzer crash fix
+ https://oss-fuzz.com/testcase-detail/5643107869917184
+
+ src/hb-ot-layout-gsubgpos.hh | 11 +++++++----
+ ...-testcase-minimized-hb-subset-fuzzer-5643107869917184 | Bin 0 -> 3232 bytes
+ 2 files changed, 7 insertions(+), 4 deletions(-)
+
+commit 9815ca0338b47c6ea4e82f2fbd39d70e3456aca1
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Thu Oct 24 21:05:38 2019 +0330
+
+ [ci] Use custom subset fuzzer timeout for failing sanitizer bots
+
+ .circleci/config.yml | 8 ++++----
+ test/fuzzing/run-shape-fuzzer-tests.py | 3 ++-
+ test/fuzzing/run-subset-fuzzer-tests.py | 3 ++-
+ 3 files changed, 8 insertions(+), 6 deletions(-)
+
+commit b03b62cb304279195569180061cde745e0c9880a
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Wed Oct 23 12:18:21 2019 +0330
+
+ [ci] Add HB_NO_MT on non HB_TINY no-build-system builds
+
+ .circleci/config.yml | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 5e489670e15329f5eced16e5a76145c6149a265f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date: Tue Oct 22 15:03:47 2019 -0700
+
+ Remove hb-warning.cc
+
+ Fixes https://github.com/harfbuzz/harfbuzz/issues/2005
+
+ src/Makefile.sources | 1 -
+ src/harfbuzz.cc | 1 -
+ src/hb-atomic.hh | 16 +++++-----------
+ src/hb-mutex.hh | 25 ++++++-------------------
+ src/hb-warning.cc | 37 -------------------------------------
+ 5 files changed, 11 insertions(+), 69 deletions(-)
+
+commit 05bcdb39d8648c49f7984c404aee096f2ad1d655
+Author: Garret Rieger <grieger@google.com>
+Date: Mon Oct 21 16:10:06 2019 -0700
+
+ Add a specialization of array_t:hash for hb_bytes_t and hb_ubytes_t.
+
+ src/hb-array.hh | 34 ++++++++++++++++++++++++----------
+ src/hb-ot-layout-gsubgpos.hh | 2 --
+ 2 files changed, 24 insertions(+), 12 deletions(-)
+
+commit 95ab110cd9a6083a854e538211618b2733aba643
+Author: Garret Rieger <grieger@google.com>
+Date: Mon Oct 21 13:15:46 2019 -0700
+
+ Optimize intersects_array to fix fuzzer timeout.
+
+ src/hb-ot-layout-gsubgpos.hh | 10 +++++-----
+ ...estcase-minimized-hb-subset-fuzzer-5763024094232576 | Bin 0 -> 125681 bytes
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+commit be5cdcdfa21a2d956fc8c445452a78e77ede95fb
+Author: Garret Rieger <grieger@google.com>
+Date: Tue Oct 22 11:55:04 2019 -0700
+
+ Store the hash value of a key in item_t in hb_map to reduce the number of hash computations.
+
+ src/hb-map.hh | 70 ++++++++++++++++++++++++++++++++++-------------------------
+ 1 file changed, 40 insertions(+), 30 deletions(-)
+
+commit b33a0d628e5e76992fdd02fd4178906137e6153c
+Author: Qunxin Liu <qxliu@google.com>
+Date: Mon Oct 21 13:24:52 2019 -0700
+
+ fuzzer crash fix: Null-dereference WRITE
+ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=18363
+
+ src/hb-ot-layout-common.hh | 4 +++-
+ ...z-testcase-minimized-hb-subset-fuzzer-5659903036751872 | Bin 0 -> 781 bytes
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+commit cf414e361a99decd9c1710f1012236bffd067878
+Author: Garret Rieger <grieger@google.com>
+Date: Fri Sep 27 09:55:17 2019 -0700
+
+ Added profiling instructions to TESTING.md
+
+ TESTING.md | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+commit 1f0a9d9be979de01527c05f4dbe6fbc62799597c
+Author: Qunxin Liu <qxliu@google.com>
+Date: Tue Sep 17 11:10:08 2019 -0700
+
+ [subset] GPOS Lookup Type 2: PairPos
+
+ src/hb-ot-layout-gpos-table.hh | 131 ++++++++++++++++++++-
+ test/subset/data/Makefile.am | 1 +
+ test/subset/data/Makefile.sources | 1 +
+ ...s2_1_font7.keep-layout-retain-gids.21,23,25.otf | Bin 0 -> 1764 bytes
+ ...gpos2_1_font7.keep-layout-retain-gids.21,23.otf | Bin 0 -> 1632 bytes
+ ...eep-layout-retain-gids.retain-all-codepoint.otf | Bin 0 -> 3688 bytes
+ .../gpos2_1_font7.keep-layout.21,23,25.otf | Bin 0 -> 1428 bytes
+ .../gpos2_1_font7.keep-layout.21,23.otf | Bin 0 -> 1308 bytes
+ ...s2_1_font7.keep-layout.retain-all-codepoint.otf | Bin 0 -> 3688 bytes
+ ...s2_2_font5.keep-layout-retain-gids.21,23,25.otf | Bin 0 -> 1776 bytes
+ ...gpos2_2_font5.keep-layout-retain-gids.21,23.otf | Bin 0 -> 1644 bytes
+ ...eep-layout-retain-gids.retain-all-codepoint.otf | Bin 0 -> 3684 bytes
+ .../gpos2_2_font5.keep-layout.21,23,25.otf | Bin 0 -> 1440 bytes
+ .../gpos2_2_font5.keep-layout.21,23.otf | Bin 0 -> 1320 bytes
+ ...s2_2_font5.keep-layout.retain-all-codepoint.otf | Bin 0 -> 3684 bytes
+ test/subset/data/fonts/gpos2_1_font7.otf | Bin 0 -> 4584 bytes
+ test/subset/data/fonts/gpos2_2_font5.otf | Bin 0 -> 4580 bytes
+ test/subset/data/tests/layout.gpos2.tests | 12 ++
+ 18 files changed, 139 insertions(+), 6 deletions(-)
+
+commit e766783152b91fb20baf0c657586628fd7959b1b
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Mon Oct 21 22:17:06 2019 +0330
+
+ [fuzz] Add https://crbug.com/oss-fuzz/17898 testcase
+
+ ...sterfuzz-testcase-hb-subset-fuzzer-5717414645334016 | Bin 0 -> 310324 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit b66094ada0ae7e69d5d08ee8423554629eabccaf
+Author: Qunxin Liu <qxliu@google.com>
+Date: Mon Sep 30 16:19:18 2019 -0700
+
+ [subset] GSUB Lookup Type 6: ChainContextSubst
+
+ src/hb-ot-layout-common.hh | 260 ++++++++++++++-------
+ src/hb-ot-layout-gsubgpos.hh | 218 ++++++++++++++++-
+ test/subset/data/Makefile.am | 1 +
+ test/subset/data/Makefile.sources | 1 +
+ ...ules_f1.keep-layout-retain-gids.30,31,32,33.otf | Bin 0 -> 2380 bytes
+ ...eep-layout-retain-gids.retain-all-codepoint.otf | Bin 0 -> 3748 bytes
+ ...ultiple_subrules_f1.keep-layout.30,31,32,33.otf | Bin 0 -> 1916 bytes
+ ...ubrules_f1.keep-layout.retain-all-codepoint.otf | Bin 0 -> 3748 bytes
+ ...ules_f1.keep-layout-retain-gids.30,31,32,33.otf | Bin 0 -> 2408 bytes
+ ...eep-layout-retain-gids.retain-all-codepoint.otf | Bin 0 -> 3780 bytes
+ ...ultiple_subrules_f1.keep-layout.30,31,32,33.otf | Bin 0 -> 1944 bytes
+ ...ubrules_f1.keep-layout.retain-all-codepoint.otf | Bin 0 -> 3780 bytes
+ ...mple_f2.keep-layout-retain-gids.30,31,32,33.otf | Bin 0 -> 2368 bytes
+ ...eep-layout-retain-gids.retain-all-codepoint.otf | Bin 0 -> 3716 bytes
+ ...chaining3_simple_f2.keep-layout.30,31,32,33.otf | Bin 0 -> 1904 bytes
+ ..._simple_f2.keep-layout.retain-all-codepoint.otf | Bin 0 -> 3716 bytes
+ .../fonts/gsub_chaining1_multiple_subrules_f1.otf | Bin 0 -> 4700 bytes
+ .../fonts/gsub_chaining2_multiple_subrules_f1.otf | Bin 0 -> 4780 bytes
+ .../subset/data/fonts/gsub_chaining3_simple_f2.otf | Bin 0 -> 4668 bytes
+ test/subset/data/tests/layout.gsub6.tests | 12 +
+ 20 files changed, 405 insertions(+), 87 deletions(-)
+
+commit eff91bbb4b1e6f4cc8401b1915d5ddad64e053bb
+Author: Garret Rieger <grieger@google.com>
+Date: Wed Oct 16 16:58:57 2019 -0700
+
+ Add missing pop() for the failure case of script subsetting.
+
+ src/hb-ot-layout-common.hh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit eab191fd9c851cb7881163ddd5e11a2ebc58cef4
+Author: Garret Rieger <grieger@google.com>
+Date: Wed Oct 2 14:28:53 2019 -0700
+
+ Rewrite hash and == function for hb_array_t as a plain loop.
+
+ Profling showed that the current implementation were accounting for nearly all processing time in some cases. These implementations look to be about 10x faster.
+
+ src/hb-array.hh | 21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+commit 831daf4c76aed87d229b1edfb59a0a37caa8e581
+Author: Garret Rieger <grieger@google.com>
+Date: Tue Oct 1 17:46:27 2019 -0700
+
+ Enforce HB_MAX_LANGSYS limit during layout subsetting.
+
+ src/hb-ot-layout-common.hh | 68 +++++++++++++--------
+ ...ase-minimized-hb-subset-fuzzer-5721073428987904 | Bin 0 -> 349561 bytes
+ 2 files changed, 41 insertions(+), 27 deletions(-)
+
+commit 9871461bce9a1557807f69615300e5df4f6ae322
+Author: Garret Rieger <grieger@google.com>
+Date: Tue Oct 1 16:29:24 2019 -0700
+
+ Enforce HB_MAX_SCRIPTS during subsetting of the script table.
+
+ src/hb-ot-layout-common.hh | 46 +++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 41 insertions(+), 5 deletions(-)
+
+commit 029775bcbd0a25ee1cdb6c0653a2ce189774490a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date: Wed Oct 9 11:00:09 2019 +0700
+
+ [buffer] Minor; improve HB_NO_BUFFER_MESSAGE
+
+ src/hb-buffer.cc | 2 ++
+ src/hb-buffer.hh | 2 +-
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+commit 9a68e6b901967da14a5da5acb535c944794627b8
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Wed Oct 16 13:28:15 2019 +0330
+
+ [doc] minor
+
+ Addresses https://github.com/harfbuzz/harfbuzz/pull/2013/files#r335196908
+
+ src/hb-common.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b0b8551afc2ff86d027fdb380210601cb465af41
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Sat Oct 12 21:12:19 2019 +0330
+
+ [glyf] Use range_checker_t in composite_iter_t
+
+ src/hb-ot-glyf-table.hh | 12 +++++++-----
+ src/hb-ot-var-gvar-table.hh | 19 +++++++++----------
+ 2 files changed, 16 insertions(+), 15 deletions(-)
+
+commit 06e35ce052388e7ce079c0250db62428ae0c5bc8
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Sat Oct 12 15:16:31 2019 +0330
+
+ [glyf] minor
+
+ src/hb-ot-glyf-table.hh | 128 +++++++++++++++++++++++++-----------------------
+ 1 file changed, 67 insertions(+), 61 deletions(-)
+
+commit d13bb4bd94a6ba8cdd4a03d40d8089a8f8b3a7ec
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Sat Oct 12 12:13:57 2019 +0330
+
+ [glyf] other cleanups
+
+ src/hb-ot-glyf-table.hh | 338 +++++++++++++++++++++++-------------------------
+ 1 file changed, 160 insertions(+), 178 deletions(-)
+
+commit e7aa8c5d22b034f3d7bcf187a63cdec27732fa8a
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Sat Oct 12 11:25:32 2019 +0330
+
+ [glyf] Introduce glyf::Glyph, a hb_bytes_t/GlyphHeader pair
+
+ src/hb-ot-glyf-table.hh | 177 +++++++++++++++++++++++++-----------------------
+ 1 file changed, 91 insertions(+), 86 deletions(-)
+
+commit 546ffc9faf869b4971765e9a4fd232cfe0eecaea
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Sat Oct 12 09:51:57 2019 +0330
+
+ [glyf] minor
+
+ src/hb-ot-glyf-table.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit 4299ea266e03b64db4e8a132983fed9fd0a967ee
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Sat Oct 12 09:51:27 2019 +0330
+
+ [glyf] Move get_contour_points to GlyphHeader
+
+ src/hb-ot-glyf-table.hh | 260 ++++++++++++++++++++++++++----------------------
+ 1 file changed, 141 insertions(+), 119 deletions(-)
+
+commit b918cd8c76a6333e43b9be23178afc9e74e17024
+Author: Ben Wagner <bungeman@chromium.org>
+Date: Thu Oct 10 15:30:48 2019 -0400
+
+ Document hb_feature_t.
+
+ This documents hb_feature_t. This is motivated mostly by the ambiguity
+ of the units for 'start' and 'end' (clusters) and whether they are
+ inclusive or exclusive. This also documents that for lookup type 3 the
+ value is the one based index into the alternates and that in a list of
+ features later feature values override previous feature values with the
+ same tag.
+
+ src/hb-common.h | 15 +++++++++++++++
+ src/hb-shape.cc | 4 +++-
+ 2 files changed, 18 insertions(+), 1 deletion(-)
+
+commit e637a4b3de2fb8bdbc1b82e822f4a6cc579e794b
+Merge: 670fec23 e4464f44
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date: Fri Oct 11 10:28:58 2019 +0700
+
+ Merge pull request #2012 from harfbuzz/lepcha-oo
+
+ Reorder U+1C29 LEPCHA VOWEL SIGN OO
+
+commit 670fec231d31bf7417de590efd3485f337a7330f
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Thu Oct 10 09:21:08 2019 +0330
+
+ Minor, add a zero length tolerant memset, hb_memset
+
+ src/hb-algs.hh | 10 +++++++++-
+ src/hb-buffer.cc | 3 +--
+ 2 files changed, 10 insertions(+), 3 deletions(-)
+
+commit e4464f4484009b4efe7144570384d836cb6bbac8
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date: Wed Oct 9 20:55:52 2019 -0400
+
+ Reorder U+1C29 LEPCHA VOWEL SIGN OO
+
+ src/gen-use-table.py | 3 +++
+ src/hb-ot-shape-complex-use-table.cc | 2 +-
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+commit e17e7443007fc0debc4a26e5cf37d5d76c747fbf
+Author: Garret Rieger <grieger@google.com>
+Date: Wed Oct 9 11:45:42 2019 -0700
+
+ Convert existing uses of serialize_append in gsub subsetting to use subset_offset_array.
+
+ src/hb-ot-layout-gsub-table.hh | 44 +++---------------------------------------
+ 1 file changed, 3 insertions(+), 41 deletions(-)
+
+commit 36f18cecbbaf8635a2179a827242ca99d5283666
+Author: Garret Rieger <grieger@google.com>
+Date: Mon Oct 7 14:02:31 2019 -0700
+
+ Add subset_offset_array helper function which simplifies subsetting offset arrays during stream operations.
+
+ src/hb-ot-layout-common.hh | 54 ++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-layout-gsub-table.hh | 15 +-----------
+ 2 files changed, 55 insertions(+), 14 deletions(-)
+
+commit dc45f225212da7b8eca0ddcb3c9cd66e65983605
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Tue Oct 8 23:27:37 2019 +0330
+
+ [ot-metrics] Don't use mixed scaled and not scaled for generating extents
+
+ src/hb-ot-cff1-table.cc | 4 ++--
+ src/hb-ot-cff2-table.cc | 4 ++--
+ src/hb-ot-color-sbix-table.hh | 7 +++++++
+ src/hb-ot-glyf-table.hh | 6 +++---
+ test/api/test-ot-extents-cff.c | 6 +++---
+ 5 files changed, 17 insertions(+), 10 deletions(-)
+
+commit b068e25f8f89d9b07963dddd5d5e14f61539556f
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Tue Oct 8 16:29:15 2019 +0330
+
+ [glyf] Address Behdad's reviews
+
+ Addresses https://github.com/harfbuzz/harfbuzz/pull/1999#issuecomment-539298559
+ * Don't check against Null pool
+ * Remove cryptic _tt suffix
+
+ src/hb-ot-font.cc | 4 ++--
+ src/hb-ot-hmtx-table.hh | 16 ++++++++--------
+ 2 files changed, 10 insertions(+), 10 deletions(-)
+
+commit 6961766db2c53ea813079c61e4d996234ae8be4f
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Tue Oct 8 16:26:48 2019 +0330
+
+ [glyf] fix scaling direction
+
+ src/hb-ot-glyf-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 0527fda4c75e4354198df79275526d4726a3aacc
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Tue Oct 8 16:19:39 2019 +0330
+
+ minor
+
+ src/hb-subset-cff-common.cc | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit b2628f1a3e3a6875dcdf7cb89f5b10a4ae76e6f9
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Tue Oct 8 15:09:09 2019 +0330
+
+ [glyf] Move glyph bytes drop hints logic to GlyphHeader
+
+ src/hb-ot-glyf-table.hh | 92 ++++++++++++++++++++-----------------------------
+ 1 file changed, 37 insertions(+), 55 deletions(-)
+
+commit 1fb9c3b6463fdee9eb4dac697beab4d3d7a5fdcf
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Tue Oct 8 13:50:16 2019 +0330
+
+ [glyf] Implement depth limit for add_gid_and_children
+
+ src/hb-ot-glyf-table.hh | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+commit be0eddd41896824cb093024c2b4929b612ee1fae
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Tue Oct 8 13:46:55 2019 +0330
+
+ [glyf] Move add_gid_and_children to glyf table
+
+ src/hb-ot-glyf-table.hh | 14 ++++++++++++++
+ src/hb-subset-plan.cc | 19 +------------------
+ 2 files changed, 15 insertions(+), 18 deletions(-)
+
+commit c7621cf21115aa563ee4fb9d2fcb601984848494
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Tue Oct 8 13:24:26 2019 +0330
+
+ Minor, replace hb_set_add with private API
+
+ src/hb-ot-map.cc | 2 +-
+ src/hb-subset-cff-common.hh | 2 +-
+ src/hb-subset-cff1.cc | 2 +-
+ src/hb-subset-cff2.cc | 2 +-
+ src/hb-subset-plan.cc | 10 +++++-----
+ 5 files changed, 9 insertions(+), 9 deletions(-)
+
+commit ad86806dcb702b25fac6a3364cf0f85e1b8f4b2a
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Tue Oct 8 12:14:14 2019 +0330
+
+ [glyf] Move subset related methods inside GlyphHeader
+
+ src/hb-ot-glyf-table.hh | 428 ++++++++++++++++++++++++------------------------
+ src/hb-subset-plan.cc | 4 +-
+ 2 files changed, 214 insertions(+), 218 deletions(-)
+
+commit 7839e23558344f206175b5a798149e0f04f38266
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Mon Oct 7 11:14:26 2019 +0330
+
+ [glyf] minor
+
+ src/hb-ot-glyf-table.hh | 38 +++++++++++++++-----------------------
+ 1 file changed, 15 insertions(+), 23 deletions(-)
+
+commit cbefbb2439c1a2f4c20877e611f8986b3933234e
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Mon Oct 7 10:15:18 2019 +0330
+
+ [glyf] Move padding removal logic to GlyphHeader
+
+ src/hb-ot-glyf-table.hh | 219 +++++++++++++++++++++++-------------------------
+ 1 file changed, 105 insertions(+), 114 deletions(-)
+
+commit 1ab8f9aa7a182fa078f6c6a5a78ef95686b1ac54
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Mon Oct 7 08:24:12 2019 +0330
+
+ [glyf] minor
+
+ src/hb-ot-glyf-table.hh | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+commit 13fb5612ad545b419ca217f031864dde1b71c43f
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Sun Oct 6 23:24:06 2019 +0330
+
+ [glyf] Aggregate get_offsets uses
+
+ src/hb-ot-glyf-table.hh | 29 +++++++----------------------
+ 1 file changed, 7 insertions(+), 22 deletions(-)
+
+commit 5179b96958f2db71c315c1d8c224bab87e2f4ae8
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Tue Oct 8 11:09:12 2019 +0330
+
+ [cff] minor on number_t
+
+ src/hb-cff-interp-common.hh | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+commit d73cdcf3612ae6114a0f828e0f667d447ed1a964
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Sun Oct 6 18:09:14 2019 +0330
+
+ [ot-font] Apply font scaling before turning to int
+
+ src/hb-ot-cff1-table.cc | 12 ++++-----
+ src/hb-ot-cff1-table.hh | 2 +-
+ src/hb-ot-cff2-table.cc | 8 +++---
+ src/hb-ot-color-cbdt-table.hh | 14 +++++-----
+ src/hb-ot-color-sbix-table.hh | 8 +++---
+ src/hb-ot-font.cc | 12 +++------
+ src/hb-ot-glyf-table.hh | 58 ++++++++++++++++++++----------------------
+ src/hb-ot-hmtx-table.hh | 2 +-
+ src/hb-ot-var-hvar-table.hh | 5 ++--
+ test/api/test-ot-extents-cff.c | 20 +++++++--------
+ 10 files changed, 66 insertions(+), 75 deletions(-)
+
+commit f2339964b713815c8e0e33699bf34ee24db12215
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Sun Oct 6 16:41:52 2019 +0330
+
+ [glyf] minor, remove GlyphHeader::simple_* helpers
+
+ src/hb-ot-glyf-table.hh | 16 +++-------------
+ 1 file changed, 3 insertions(+), 13 deletions(-)
+
+commit 2d7ca6a76a754a42ec09a66319ac3e4ab5efc618
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Sun Oct 6 16:31:29 2019 +0330
+
+ [glyf] Move get_instruction_length inside GlyphHeader struct
+
+ src/hb-ot-glyf-table.hh | 153 ++++++++++++++++++++++++++----------------------
+ 1 file changed, 84 insertions(+), 69 deletions(-)
+
+commit 50aef4d7f80b6c8a19481ad3d0fa89c7c7f222c2
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Sun Oct 6 14:00:07 2019 +0330
+
+ [glyf] cleanup
+
+ src/hb-ot-glyf-table.hh | 128 +++++++++++++++++++++---------------------------
+ 1 file changed, 55 insertions(+), 73 deletions(-)
+
+commit ee3f4630d70099c42fd9c84796b29a236f6135b6
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Sun Oct 6 13:56:35 2019 +0330
+
+ [glyf] Remove get_composite_iter and refactor bytes_for_glyph for shape uses
+
+ src/hb-ot-glyf-table.hh | 42 ++++++++++++++++--------------------------
+ src/hb-subset-plan.cc | 2 +-
+ 2 files changed, 17 insertions(+), 27 deletions(-)
+
+commit 8378ab96e28fa34f154583850ff1c2c672a4310d
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Sun Oct 6 13:49:45 2019 +0330
+
+ [glyf] Rewrite composite iterator to new iterators convention
+
+ src/hb-ot-glyf-table.hh | 201 ++++++++++++++++++++----------------------------
+ src/hb-subset-plan.cc | 10 +--
+ 2 files changed, 85 insertions(+), 126 deletions(-)
+
+commit b7684fa9f42dffa6bd81acfade163123b30800b8
+Merge: 79ec65ae 21c80d95
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Sun Oct 6 09:00:48 2019 +0330
+
+ Merge pull request #1999 from ebraminio/glyf-var
+
+ Implement gvar table and variable glyf
+
+commit 21c80d955f69c1242c77e0ec7ccd852360dd54dd
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Sat Oct 5 23:58:52 2019 +0330
+
+ [gvar] minor
+
+ src/hb-ot-var-gvar-table.hh | 43 +++++++++++++++++++++----------------------
+ 1 file changed, 21 insertions(+), 22 deletions(-)
+
+commit 5752863640cf4292dec313edebb57aecd47496f3
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Sat Oct 5 23:51:50 2019 +0330
+
+ [glyf][gvar] Make HB_NO_VAR buildable
+
+ src/hb-ot-font.cc | 2 ++
+ src/hb-ot-glyf-table.hh | 6 ++++++
+ src/hb-ot-hmtx-table.hh | 8 ++++++++
+ 3 files changed, 16 insertions(+)
+
+commit 8e33510343d151afe49730f3a0b263a2853822b8
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Fri Oct 4 01:11:03 2019 +0330
+
+ [gvar] minor
+
+ src/hb-ot-var-gvar-table.hh | 132 ++++++++++++++++++++++----------------------
+ 1 file changed, 66 insertions(+), 66 deletions(-)
+
+commit b3afa8164460d63031a80d399200bcaa769c0fa1
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Fri Oct 4 00:32:04 2019 +0330
+
+ [glyf] Use common convention of other tables access, format
+
+ src/hb-ot-face-table-list.hh | 1 +
+ src/hb-ot-glyf-table.hh | 65 +++++++++++++++++++-------------------------
+ 2 files changed, 29 insertions(+), 37 deletions(-)
+
+commit 88bd342c0ff686daad88bb6b4f2968bbd8b01a24
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Thu Oct 3 22:45:37 2019 +0330
+
+ [glyf] minor
+
+ src/hb-ot-glyf-table.hh | 247 +++++++++++++++++++++++---------------------
+ src/hb-ot-var-gvar-table.hh | 54 +++++-----
+ 2 files changed, 155 insertions(+), 146 deletions(-)
+
+commit ee7610181cee5bbc0b5dc291228fbe032097bde4
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Thu Oct 3 15:59:45 2019 +0330
+
+ [hmtx] Use more conventional internal API style
+
+ src/Makefile.sources | 1 -
+ src/harfbuzz.cc | 1 -
+ src/hb-ot-font.cc | 12 ++++++++++++
+ src/hb-ot-hmtx-table.cc | 42 ------------------------------------------
+ src/hb-ot-hmtx-table.hh | 18 ++++++++++--------
+ 5 files changed, 22 insertions(+), 52 deletions(-)
+
+commit c9577a630fd5bd08482ee7b94bc03c91fcf366c7
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Thu Oct 3 15:48:35 2019 +0330
+
+ [hmtx] Use more optimal way to access glyf table
+
+ src/hb-ot-hmtx-table.cc | 20 ++++----------------
+ src/hb-ot-hmtx-table.hh | 4 ++--
+ 2 files changed, 6 insertions(+), 18 deletions(-)
+
+commit b9ff43c162e8f61cff8e48d3dcbf7c1fe263d625
+Author: Michiharu Ariza <ariza@typekit.com>
+Date: Tue Oct 1 16:13:40 2019 +0330
+
+ Implement gvar table and variable glyf
+
+ Split from Ariza's "[subset] TrueType/CFF2 variable font" work on #1594
+
+ src/Makefile.sources | 2 +
+ src/harfbuzz.cc | 1 +
+ src/hb-ot-font.cc | 4 +-
+ src/hb-ot-glyf-table.hh | 618 ++++++++++++++---
+ src/hb-ot-hmtx-table.cc | 54 ++
+ src/hb-ot-hmtx-table.hh | 33 +-
+ src/hb-ot-var-gvar-table.hh | 734 +++++++++++++++++++++
+ test/api/Makefile.am | 1 +
+ .../SourceSansVariable-Roman-nohvar-41,C1.ttf | Bin 0 -> 4696 bytes
+ test/api/fonts/SourceSansVariable-Roman.anchor.ttf | Bin 0 -> 4708 bytes
+ .../api/fonts/SourceSansVariable-Roman.modcomp.ttf | Bin 0 -> 3252 bytes
+ .../fonts/SourceSerifVariable-Roman-VVAR.abc.ttf | Bin 0 -> 5632 bytes
+ test/api/test-ot-metrics-tt-var.c | 250 +++++++
+ 13 files changed, 1588 insertions(+), 109 deletions(-)
+
+commit 79ec65ae10f959aeddaa1e39eba5226c604a8c87
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Thu Oct 3 14:27:51 2019 +0330
+
+ [ot-font] Use var vmtx side bearing in calculating v-origin
+
+ src/hb-ot-font.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 3fd555be543a3e9bf9fee509327dbbc9a7b51cdb
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Thu Oct 3 13:02:41 2019 +0330
+
+ [hmtx] Prepare to fix and minor fixes
+
+ src/hb-ot-hmtx-table.hh | 41 ++++++++++++++++-------------------------
+ src/hb-ot-var-hvar-table.hh | 9 +++++----
+ 2 files changed, 21 insertions(+), 29 deletions(-)
+
+commit 6d09b5a8a0f6ed7a2a92d91ac3d027bd54c452be
+Author: Michiharu Ariza <ariza@typekit.com>
+Date: Thu Oct 3 12:01:39 2019 +0330
+
+ Implement hmtx/vmtx metrics read from hvar/vvar
+
+ src/hb-ot-hmtx-table.hh | 46 ++++++++++++++++++++++++++++++++++++++++-----
+ src/hb-ot-var-hvar-table.hh | 19 +++++++++++++------
+ 2 files changed, 54 insertions(+), 11 deletions(-)
+
+commit cfafee52e4ff0441a33530847533f1b1f6019006
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Wed Oct 2 09:22:46 2019 +0330
+
+ Add Repology badges by @luzpaz
+
+ fixes #2002
+ to track downstream packaging of harfbuzz
+
+ README.md | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+commit 2d7221a0e3552b1d902629d4ab6c0ce22db983a6
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Tue Oct 1 15:05:02 2019 +0330
+
+ [cff] minor
+
+ src/hb-ot-cff-common.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 0558413f27e9a18188c0e3d55f5ee57ea42b1548
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Tue Oct 1 13:49:55 2019 +0330
+
+ Minor, tweak spaces
+
+ src/hb-aat-layout-kerx-table.hh | 4 ++--
+ src/hb-array.hh | 4 ++--
+ src/hb-buffer.hh | 3 +--
+ src/hb-font.h | 4 ++--
+ src/hb-font.hh | 8 ++++----
+ src/hb-open-file.hh | 2 +-
+ src/hb-open-type.hh | 10 +++++-----
+ src/hb-ot-cff-common.hh | 4 ++--
+ src/hb-ot-cff1-table.cc | 11 +++++------
+ src/hb-ot-cff1-table.hh | 24 ++++++++++++------------
+ src/hb-ot-cff2-table.cc | 4 ++--
+ src/hb-ot-cmap-table.hh | 6 ++----
+ src/hb-ot-color-cbdt-table.hh | 2 +-
+ src/hb-ot-color-cpal-table.hh | 2 +-
+ src/hb-ot-kern-table.hh | 12 ++++++------
+ src/hb-ot-layout-common.hh | 2 +-
+ src/hb-ot-layout-gpos-table.hh | 14 +++++++-------
+ src/hb-ot-os2-table.hh | 4 ++--
+ src/hb-ot-shape-complex-myanmar.cc | 4 ++--
+ src/hb-subset-cff-common.hh | 2 +-
+ src/hb-unicode.cc | 8 ++++----
+ src/hb-unicode.h | 20 ++++++++++----------
+ src/hb-vector.hh | 4 ++--
+ src/main.cc | 37 +++++++++++++++++++++++--------------
+ src/test-iter.cc | 2 +-
+ 25 files changed, 101 insertions(+), 96 deletions(-)
+
+commit 51b720f686adf45bc1b6db3aa76b7d2e62ad1304
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date: Tue Oct 1 12:06:22 2019 +0330
+
+ Fix -Wsizeof-array-div clang warning
+
+ src/hb-ot-shape-complex-arabic-fallback.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit faace9437ea09d89ef5f5f9c9fc3ce0dbc672142
+Merge: e48ef080 f0dd724c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date: Mon Sep 30 13:34:05 2019 -0700
+
+ Merge pull request #1807 from harfbuzz/subset-varstore
+
+ VariationStore serializer
+
commit e48ef0804ad7e4abd35ff3646fa6ed10ad32f1ef
Author: Behdad Esfahbod <behdad@behdad.org>
Date: Mon Sep 30 12:39:06 2019 -0700
@@ -2250,6 +3078,13 @@ Date: Sat Jul 27 14:56:18 2019 +0430
src/hb-aat-layout-lcar-table.hh | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
+commit f0dd724c1e091f42f289efbebd2c50e830e59c6e
+Merge: 68ac767e 4e1da6bb
+Author: blueshade7 <ariza@typekit.com>
+Date: Mon Jul 29 14:21:05 2019 -0700
+
+ Merge branch 'master' into subset-varstore
+
commit 4e1da6bb612b0c6386ab143dbb4ca19ff25bc2ba
Author: Ebrahim Byagowi <ebrahim@gnu.org>
Date: Mon Jul 29 22:03:56 2019 +0430
@@ -3050,6 +3885,16 @@ Date: Wed Jun 26 13:23:24 2019 -0700
util/options.cc | 44 ++++++++++++---------
14 files changed, 48 insertions(+), 24 deletions(-)
+commit 68ac767e430c4dfe4c556b2c4f962cc3dfc5d3e4
+Author: blueshade7 <ariza@typekit.com>
+Date: Fri Jul 12 23:02:29 2019 -0700
+
+ added skip(), get_next_value() to inc_bimap to subset VarStore with retain-gids
+
+ src/hb-bimap.hh | 25 ++++++++++++++++++++++++-
+ src/hb-ot-layout-common.hh | 14 +++++++-------
+ 2 files changed, 31 insertions(+), 8 deletions(-)
+
commit 4730b350b7ee90338caf3e962343af42412ce3df
Author: Behdad Esfahbod <behdad@behdad.org>
Date: Fri Jul 12 15:38:35 2019 -0700
@@ -3455,6 +4300,15 @@ Date: Tue Jul 2 14:18:38 2019 -0700
src/gen-ucd-table.py | 8 +++++---
2 files changed, 20 insertions(+), 11 deletions(-)
+commit 634390ecaf600176245e3354edd8dfdcb7f64cc5
+Author: blueshade7 <ariza@typekit.com>
+Date: Mon Jul 1 18:52:57 2019 -0700
+
+ added VariationStore serializer to be used by HVAR/VVAR subsetters
+
+ src/hb-ot-layout-common.hh | 165 ++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 163 insertions(+), 2 deletions(-)
+
commit 040b261deeed8924edcb087e27a61392d1f85023
Author: Michiharu Ariza <ariza@typekit.com>
Date: Sun Jun 30 16:13:07 2019 -0700
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/NEWS b/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
index 30fa8c3976c..6cae06dcdcd 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
@@ -1,3 +1,11 @@
+Overview of changes leading to 2.6.3
+Monday, October 28, 2019
+====================================
+- Misc small fixes, mostly to build-related issues.
+- New API:
++hb_font_get_nominal_glyphs()
+
+
Overview of changes leading to 2.6.2
Monday, September 30, 2019
====================================
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/README b/Build/source/libs/harfbuzz/harfbuzz-src/README
index c3cc0c26e94..e0ef93576be 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/README
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/README
@@ -6,6 +6,7 @@
[![Codacy Code Health](https://api.codacy.com/project/badge/Grade/f17f1708783c447488bc8dd317150eaa)](https://app.codacy.com/app/behdad/harfbuzz)
[![Codecov Code Coverage](https://codecov.io/gh/harfbuzz/harfbuzz/branch/master/graph/badge.svg)](https://codecov.io/gh/harfbuzz/harfbuzz)
[![Coverals Code Coverage](https://img.shields.io/coveralls/harfbuzz/harfbuzz.svg)](https://coveralls.io/r/harfbuzz/harfbuzz)
+[![Packaging status](https://repology.org/badge/tiny-repos/harfbuzz.svg)](https://repology.org/project/harfbuzz/versions)
[ABI Tracker](http://abi-laboratory.pro/tracker/timeline/harfbuzz/)
This is HarfBuzz, a text shaping library.
@@ -23,3 +24,11 @@ For custom configurations, see [CONFIG.md](CONFIG.md).
For test execution, see [TESTING.md](TESTING.md).
Documentation: https://harfbuzz.github.io
+
+
+<details>
+ <summary>Packaging status of HarfBuzz</summary
+
+[![Packaging status](https://repology.org/badge/vertical-allrepos/harfbuzz.svg?header=harfbuzz)](https://repology.org/project/harfbuzz/versions)
+
+</details>
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/README.md b/Build/source/libs/harfbuzz/harfbuzz-src/README.md
index c3cc0c26e94..e0ef93576be 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/README.md
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/README.md
@@ -6,6 +6,7 @@
[![Codacy Code Health](https://api.codacy.com/project/badge/Grade/f17f1708783c447488bc8dd317150eaa)](https://app.codacy.com/app/behdad/harfbuzz)
[![Codecov Code Coverage](https://codecov.io/gh/harfbuzz/harfbuzz/branch/master/graph/badge.svg)](https://codecov.io/gh/harfbuzz/harfbuzz)
[![Coverals Code Coverage](https://img.shields.io/coveralls/harfbuzz/harfbuzz.svg)](https://coveralls.io/r/harfbuzz/harfbuzz)
+[![Packaging status](https://repology.org/badge/tiny-repos/harfbuzz.svg)](https://repology.org/project/harfbuzz/versions)
[ABI Tracker](http://abi-laboratory.pro/tracker/timeline/harfbuzz/)
This is HarfBuzz, a text shaping library.
@@ -23,3 +24,11 @@ For custom configurations, see [CONFIG.md](CONFIG.md).
For test execution, see [TESTING.md](TESTING.md).
Documentation: https://harfbuzz.github.io
+
+
+<details>
+ <summary>Packaging status of HarfBuzz</summary
+
+[![Packaging status](https://repology.org/badge/vertical-allrepos/harfbuzz.svg?header=harfbuzz)](https://repology.org/project/harfbuzz/versions)
+
+</details>
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/TESTING.md b/Build/source/libs/harfbuzz/harfbuzz-src/TESTING.md
index 4efc64ca5a9..94be3a0a7f7 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/TESTING.md
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/TESTING.md
@@ -73,3 +73,14 @@ sudo python infra/helper.py build_image harfbuzz
sudo python infra/helper.py build_fuzzers --sanitizer address harfbuzz
sudo python infra/helper.py run_fuzzer harfbuzz hb-subset-fuzzer
```
+
+## Profiling
+
+```
+make clean
+./configure CXXFLAGS="-fno-omit-frame-pointer -g"
+make
+perf record -o <perf output file> -g <command to run>
+perf report -i<perf output file>
+```
+
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac b/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac
index c88cffea63c..38d9e07404f 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],
- [2.6.2],
+ [2.6.3],
[https://github.com/harfbuzz/harfbuzz/issues/new],
[harfbuzz],
[http://harfbuzz.org/])
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources
index eff0ad347df..cbbad90d22f 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources
@@ -136,6 +136,7 @@ HB_BASE_sources = \
hb-ot-tag.cc \
hb-ot-var-avar-table.hh \
hb-ot-var-fvar-table.hh \
+ hb-ot-var-gvar-table.hh \
hb-ot-var-hvar-table.hh \
hb-ot-var-mvar-table.hh \
hb-ot-var.cc \
@@ -162,7 +163,6 @@ HB_BASE_sources = \
hb-unicode.hh \
hb-utf.hh \
hb-vector.hh \
- hb-warning.cc \
hb.hh \
$(NULL)
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py
index a8a03a77b84..4523fb8ed76 100755
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py
@@ -383,6 +383,9 @@ def map_to_use(data):
# TODO: In USE's override list but not in Unicode 12.0
if U == 0x103C: UIPC = Left
+ # TODO: https://github.com/harfbuzz/harfbuzz/pull/2012
+ if U == 0x1C29: UIPC = Left
+
# TODO: These are not in USE's override list that we have, nor are they in Unicode 12.0
if 0xA926 <= U <= 0xA92A: UIPC = Top
# TODO: https://github.com/harfbuzz/harfbuzz/pull/1037
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc
index fe1c3602321..251a0654dc4 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc
@@ -44,7 +44,6 @@
#include "hb-static.cc"
#include "hb-ucd.cc"
#include "hb-unicode.cc"
-#include "hb-warning.cc"
#include "hb-glib.cc"
#include "hb-ft.cc"
#include "hb-graphite2.cc"
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh
index 8026b4ef1a2..be1b339aa3c 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh
@@ -733,8 +733,8 @@ struct KerxSubTableHeader
{
typedef ExtendedTypes Types;
- unsigned int tuple_count () const { return tupleCount; }
- bool is_horizontal () const { return !(coverage & Vertical); }
+ unsigned tuple_count () const { return tupleCount; }
+ bool is_horizontal () const { return !(coverage & Vertical); }
enum Coverage
{
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh
index c57481bfef0..042e1c20d58 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh
@@ -588,10 +588,18 @@ hb_memcmp (const void *a, const void *b, unsigned int len)
/* It's illegal to pass NULL to memcmp(), even if len is zero.
* So, wrap it.
* https://sourceware.org/bugzilla/show_bug.cgi?id=23878 */
- if (!len) return 0;
+ if (unlikely (!len)) return 0;
return memcmp (a, b, len);
}
+static inline void *
+hb_memset (void *s, int c, unsigned int n)
+{
+ /* It's illegal to pass NULL to memset(), even if n is zero. */
+ if (unlikely (!n)) return 0;
+ return memset (s, c, n);
+}
+
static inline bool
hb_unsigned_mul_overflows (unsigned int count, unsigned int size)
{
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh
index 6efaf5fa558..09d10b47c39 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh
@@ -99,7 +99,14 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
template <typename T> operator T * () const { return arrayZ; }
HB_INTERNAL bool operator == (const hb_array_t &o) const;
- HB_INTERNAL uint32_t hash () const;
+
+ uint32_t hash () const {
+ uint32_t current = 0;
+ for (unsigned int i = 0; i < this->length; i++) {
+ current = current * 31 + hb_hash (this->arrayZ[i]);
+ }
+ return current;
+ }
/*
* Compare, Sort, and Search.
@@ -281,8 +288,8 @@ struct hb_sorted_array_t :
}
template <typename T>
bool bfind (const T &x, unsigned int *i = nullptr,
- hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
- unsigned int to_store = (unsigned int) -1) const
+ hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
+ unsigned int to_store = (unsigned int) -1) const
{
int min = 0, max = (int) this->length - 1;
const Type *array = this->arrayZ;
@@ -332,27 +339,35 @@ hb_sorted_array (T (&array_)[length_])
template <typename T>
bool hb_array_t<T>::operator == (const hb_array_t<T> &o) const
{
- return length == o.length &&
- + hb_zip (*this, o)
- | hb_map ([] (hb_pair_t<T&, T&> &&_) { return _.first == _.second; })
- | hb_all
- ;
+ if (o.length != this->length) return false;
+ for (unsigned int i = 0; i < this->length; i++) {
+ if (this->arrayZ[i] != o.arrayZ[i]) return false;
+ }
+ return true;
}
-template <typename T>
-uint32_t hb_array_t<T>::hash () const
-{
- return
- + hb_iter (*this)
- | hb_map (hb_hash)
- | hb_reduce ([] (uint32_t a, uint32_t b) { return a * 31 + b; }, 0)
- ;
+
+/* TODO Specialize opeator== for hb_bytes_t and hb_ubytes_t. */
+
+template <>
+inline uint32_t hb_array_t<const char>::hash () const {
+ uint32_t current = 0;
+ for (unsigned int i = 0; i < this->length; i++)
+ current = current * 31 + (uint32_t) (this->arrayZ[i] * 2654435761u);
+ return current;
+}
+
+template <>
+inline uint32_t hb_array_t<const unsigned char>::hash () const {
+ uint32_t current = 0;
+ for (unsigned int i = 0; i < this->length; i++)
+ current = current * 31 + (uint32_t) (this->arrayZ[i] * 2654435761u);
+ return current;
}
+
typedef hb_array_t<const char> hb_bytes_t;
typedef hb_array_t<const unsigned char> hb_ubytes_t;
-/* TODO Specialize opeator==/hash() for hb_bytes_t and hb_ubytes_t. */
-//template <>
-//uint32_t hb_array_t<const char>::hash () const { return 0; }
+
#endif /* HB_ARRAY_HH */
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh
index 09d88937c23..b3fb296b4e1 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh
@@ -212,25 +212,19 @@ static inline bool _hb_compare_and_swaplp (long *P, long O, long N)
static_assert ((sizeof (long) == sizeof (void *)), "");
-#elif !defined(HB_NO_MT)
+#elif defined(HB_NO_MT)
-#define HB_ATOMIC_INT_NIL 1 /* Warn that fallback implementation is in use. */
+#define hb_atomic_int_impl_add(AI, V) ((*(AI) += (V)) - (V))
#define _hb_memory_barrier() do {} while (0)
-#define hb_atomic_int_impl_add(AI, V) ((*(AI) += (V)) - (V))
-
#define hb_atomic_ptr_impl_cmpexch(P,O,N) (* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false)
-#else /* HB_NO_MT */
-
-#define hb_atomic_int_impl_add(AI, V) ((*(AI) += (V)) - (V))
-
-#define _hb_memory_barrier() do {} while (0)
-
-#define hb_atomic_ptr_impl_cmpexch(P,O,N) (* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false)
+#else
+#error "Could not find any system to define atomic_int macros."
+#error "Check hb-atomic.hh for possible resolutions."
#endif
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh
index a773951abdf..cae0a4dea44 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh
@@ -94,6 +94,14 @@ struct hb_bimap_t
/* Inremental bimap: only lhs is given, rhs is incrementally assigned */
struct hb_inc_bimap_t : hb_bimap_t
{
+ hb_inc_bimap_t () { init (); }
+
+ void init ()
+ {
+ hb_bimap_t::init ();
+ next_value = 0;
+ }
+
/* Add a mapping from lhs to rhs with a unique value if lhs is unknown.
* Return the rhs value as the result.
*/
@@ -102,12 +110,24 @@ struct hb_inc_bimap_t : hb_bimap_t
hb_codepoint_t rhs = forw_map[lhs];
if (rhs == HB_MAP_VALUE_INVALID)
{
- rhs = get_population ();
+ rhs = next_value++;
set (lhs, rhs);
}
return rhs;
}
+ hb_codepoint_t skip ()
+ { return next_value++; }
+
+ hb_codepoint_t get_next_value () const
+ { return next_value; }
+
+ void add_set (const hb_set_t *set)
+ {
+ hb_codepoint_t i = HB_SET_VALUE_INVALID;
+ while (hb_set_next (set, &i)) add (i);
+ }
+
/* Create an identity map. */
bool identity (unsigned int size)
{
@@ -138,6 +158,9 @@ struct hb_inc_bimap_t : hb_bimap_t
for (hb_codepoint_t rhs = 0; rhs < count; rhs++)
set (work[rhs], rhs);
}
+
+ protected:
+ unsigned int next_value;
};
#endif /* HB_BIMAP_HH */
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 bb7f3c7c1d9..6131c861773 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc
@@ -324,8 +324,7 @@ hb_buffer_t::clear_positions ()
out_len = 0;
out_info = info;
- if (likely (len))
- memset (pos, 0, sizeof (pos[0]) * len);
+ hb_memset (pos, 0, sizeof (pos[0]) * len);
}
void
@@ -777,8 +776,10 @@ hb_buffer_destroy (hb_buffer_t *buffer)
free (buffer->info);
free (buffer->pos);
+#ifndef HB_NO_BUFFER_MESSAGE
if (buffer->message_destroy)
buffer->message_destroy (buffer->message_data);
+#endif
free (buffer);
}
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh
index de0655de3e4..b5596d94577 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh
@@ -126,9 +126,9 @@ struct hb_buffer_t
/* Debugging API */
#ifndef HB_NO_BUFFER_MESSAGE
hb_buffer_message_func_t message_func;
-#endif
void *message_data;
hb_destroy_func_t message_destroy;
+#endif
/* Internal debugging. */
/* The bits here reflect current allocations of the bytes in glyph_info_t's var1 and var2. */
@@ -408,8 +408,7 @@ struct hb_buffer_t
}
}
- void unsafe_to_break_all ()
- { unsafe_to_break_impl (0, len); }
+ void unsafe_to_break_all () { unsafe_to_break_impl (0, len); }
void safe_to_break_all ()
{
for (unsigned int i = 0; i < len; i++)
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-common.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-common.hh
index fdc5c683ab4..780f61892d7 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-common.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-common.hh
@@ -220,18 +220,15 @@ struct number_t
void init () { set_real (0.0); }
void fini () {}
- void set_int (int v) { value = (double) v; }
- int to_int () const { return (int) value; }
+ void set_int (int v) { value = v; }
+ int to_int () const { return value; }
void set_fixed (int32_t v) { value = v / 65536.0; }
- int32_t to_fixed () const { return (int32_t) (value * 65536.0); }
+ int32_t to_fixed () const { return value * 65536.0; }
void set_real (double v) { value = v; }
double to_real () const { return value; }
- int ceil () const { return (int) ::ceil (value); }
- int floor () const { return (int) ::floor (value); }
-
bool in_int_range () const
{ return ((double) (int16_t) to_int () == value); }
@@ -248,7 +245,7 @@ struct number_t
}
protected:
- double value;
+ double value;
};
/* byte string */
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h
index 9f1764bdc83..037e50880e5 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h
@@ -425,6 +425,21 @@ typedef void (*hb_destroy_func_t) (void *user_data);
*/
#define HB_FEATURE_GLOBAL_END ((unsigned int) -1)
+/**
+ * hb_feature_t:
+ * @tag: a feature tag
+ * @value: 0 disables the feature, non-zero (usually 1) enables the feature.
+ * For features implemented as lookup type 3 (like 'salt') the @value is a one
+ * based index into the alternates.
+ * @start: the cluster to start applying this feature setting (inclusive).
+ * @end: the cluster to end applying this feature setting (exclusive).
+ *
+ * The #hb_feature_t is the structure that holds information about requested
+ * feature application. The feature will be applied with the given value to all
+ * glyphs which are in clusters between @start (inclusive) and @end (exclusive).
+ * Setting start to @HB_FEATURE_GLOBAL_START and end to @HB_FEATURE_GLOBAL_END
+ * specifies that the feature always applies to the entire buffer.
+ */
typedef struct hb_feature_t {
hb_tag_t tag;
uint32_t value;
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc
index ee35966c1cc..e89ad697efd 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc
@@ -792,6 +792,29 @@ hb_font_get_nominal_glyph (hb_font_t *font,
}
/**
+ * hb_font_get_nominal_glyphs:
+ * @font: a font.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 2.6.3
+ **/
+unsigned int
+hb_font_get_nominal_glyphs (hb_font_t *font,
+ unsigned int count,
+ const hb_codepoint_t *first_unicode,
+ unsigned int unicode_stride,
+ hb_codepoint_t *first_glyph,
+ unsigned int glyph_stride)
+{
+ return font->get_nominal_glyphs (count,
+ first_unicode, unicode_stride,
+ first_glyph, glyph_stride);
+}
+
+/**
* hb_font_get_variation_glyph:
* @font: a font.
* @unicode:
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h
index 9b6518791e1..01ff201aeec 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h
@@ -459,6 +459,14 @@ hb_font_get_variation_glyph (hb_font_t *font,
hb_codepoint_t unicode, hb_codepoint_t variation_selector,
hb_codepoint_t *glyph);
+HB_EXTERN unsigned int
+hb_font_get_nominal_glyphs (hb_font_t *font,
+ unsigned int count,
+ const hb_codepoint_t *first_unicode,
+ unsigned int unicode_stride,
+ hb_codepoint_t *first_glyph,
+ unsigned int glyph_stride);
+
HB_EXTERN hb_position_t
hb_font_get_glyph_h_advance (hb_font_t *font,
hb_codepoint_t glyph);
@@ -649,8 +657,8 @@ hb_font_set_funcs (hb_font_t *font,
/* Be *very* careful with this function! */
HB_EXTERN void
hb_font_set_funcs_data (hb_font_t *font,
- void *font_data,
- hb_destroy_func_t destroy);
+ void *font_data,
+ hb_destroy_func_t destroy);
HB_EXTERN void
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh
index 4adf6ae99a9..b1e8e6440cc 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh
@@ -216,7 +216,7 @@ struct hb_font_t
}
hb_bool_t get_nominal_glyph (hb_codepoint_t unicode,
- hb_codepoint_t *glyph)
+ hb_codepoint_t *glyph)
{
*glyph = 0;
return klass->get.f.nominal_glyph (this, user_data,
@@ -286,7 +286,7 @@ struct hb_font_t
}
hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph,
- hb_position_t *x, hb_position_t *y)
+ hb_position_t *x, hb_position_t *y)
{
*x = *y = 0;
return klass->get.f.glyph_h_origin (this, user_data,
@@ -328,7 +328,7 @@ struct hb_font_t
}
hb_bool_t get_glyph_extents (hb_codepoint_t glyph,
- hb_glyph_extents_t *extents)
+ hb_glyph_extents_t *extents)
{
memset (extents, 0, sizeof (*extents));
return klass->get.f.glyph_extents (this, user_data,
@@ -499,7 +499,7 @@ struct hb_font_t
}
void subtract_glyph_h_origin (hb_codepoint_t glyph,
- hb_position_t *x, hb_position_t *y)
+ hb_position_t *x, hb_position_t *y)
{
hb_position_t origin_x, origin_y;
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh
index 26e4930a5f7..8c8db4d520b 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh
@@ -46,16 +46,13 @@ struct hb_hashmap_t
static_assert (hb_is_integral (K) || hb_is_pointer (K), "");
static_assert (hb_is_integral (V) || hb_is_pointer (V), "");
- /* TODO If key type is a pointer, keep hash in item_t and use to:
- * 1. avoid rehashing when resizing table, and
- * 2. compare hash before comparing keys, for speed.
- */
struct item_t
{
K key;
V value;
+ uint32_t hash;
- void clear () { key = kINVALID; value = vINVALID; }
+ void clear () { key = kINVALID; value = vINVALID; hash = 0; }
bool operator == (K o) { return hb_deref (key) == hb_deref (o); }
bool operator == (const item_t &o) { return *this == o.key; }
@@ -137,7 +134,9 @@ struct hb_hashmap_t
if (old_items)
for (unsigned int i = 0; i < old_size; i++)
if (old_items[i].is_real ())
- set (old_items[i].key, old_items[i].value);
+ set_with_hash (old_items[i].key,
+ old_items[i].hash,
+ old_items[i].value);
free (old_items);
@@ -146,29 +145,9 @@ struct hb_hashmap_t
void set (K key, V value)
{
- if (unlikely (!successful)) return;
- if (unlikely (key == kINVALID)) return;
- if ((occupancy + occupancy / 2) >= mask && !resize ()) return;
- unsigned int i = bucket_for (key);
-
- if (value == vINVALID && items[i].key != key)
- return; /* Trying to delete non-existent key. */
-
- if (!items[i].is_unused ())
- {
- occupancy--;
- if (items[i].is_tombstone ())
- population--;
- }
-
- items[i].key = key;
- items[i].value = value;
-
- occupancy++;
- if (!items[i].is_tombstone ())
- population++;
-
+ set_with_hash (key, hb_hash (key), value);
}
+
V get (K key) const
{
if (unlikely (!items)) return vINVALID;
@@ -237,14 +216,45 @@ struct hb_hashmap_t
protected:
+ void set_with_hash (K key, uint32_t hash, V value)
+ {
+ if (unlikely (!successful)) return;
+ if (unlikely (key == kINVALID)) return;
+ if ((occupancy + occupancy / 2) >= mask && !resize ()) return;
+ unsigned int i = bucket_for_hash (key, hash);
+
+ if (value == vINVALID && items[i].key != key)
+ return; /* Trying to delete non-existent key. */
+
+ if (!items[i].is_unused ())
+ {
+ occupancy--;
+ if (items[i].is_tombstone ())
+ population--;
+ }
+
+ items[i].key = key;
+ items[i].value = value;
+ items[i].hash = hash;
+
+ occupancy++;
+ if (!items[i].is_tombstone ())
+ population++;
+ }
+
unsigned int bucket_for (K key) const
{
- unsigned int i = hb_hash (key) % prime;
+ return bucket_for_hash (key, hb_hash (key));
+ }
+
+ unsigned int bucket_for_hash (K key, uint32_t hash) const
+ {
+ unsigned int i = hash % prime;
unsigned int step = 0;
unsigned int tombstone = (unsigned) -1;
while (!items[i].is_unused ())
{
- if (items[i] == key)
+ if (items[i].hash == hash && items[i] == key)
return i;
if (tombstone == (unsigned) -1 && items[i].is_tombstone ())
tombstone = i;
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh
index e1362673180..e7f8b1c434b 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh
@@ -92,25 +92,7 @@ typedef volatile int hb_mutex_impl_t;
#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END
-#elif !defined(HB_NO_MT)
-
-#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_YIELD)
-# include <sched.h>
-# define HB_SCHED_YIELD() sched_yield ()
-#else
-# define HB_SCHED_YIELD() HB_STMT_START {} HB_STMT_END
-#endif
-
-#define HB_MUTEX_INT_NIL 1 /* Warn that fallback implementation is in use. */
-typedef volatile int hb_mutex_impl_t;
-#define HB_MUTEX_IMPL_INIT 0
-#define hb_mutex_impl_init(M) *(M) = 0
-#define hb_mutex_impl_lock(M) HB_STMT_START { while (*(M)) HB_SCHED_YIELD (); (*(M))++; } HB_STMT_END
-#define hb_mutex_impl_unlock(M) (*(M))--
-#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END
-
-
-#else /* HB_NO_MT */
+#elif defined(HB_NO_MT)
typedef int hb_mutex_impl_t;
#define HB_MUTEX_IMPL_INIT 0
@@ -120,6 +102,11 @@ typedef int hb_mutex_impl_t;
#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END
+#else
+
+#error "Could not find any system to define mutex macros."
+#error "Check hb-mutex.hh for possible resolutions."
+
#endif
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file.hh
index b05393647ea..cb1fdf1c998 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file.hh
@@ -287,7 +287,7 @@ struct ResourceRecord
{ return CastR<OpenTypeFontFace> ((data_base+offset).arrayZ); }
bool sanitize (hb_sanitize_context_t *c,
- const void *data_base) const
+ const void *data_base) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh
index fce55910326..af242ece12e 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh
@@ -264,8 +264,8 @@ struct _hb_has_null
template <typename Type>
struct _hb_has_null<Type, true>
{
- static const Type *get_null () { return &Null(Type); }
- static Type *get_crap () { return &Crap(Type); }
+ static const Type *get_null () { return &Null (Type); }
+ static Type *get_crap () { return &Crap (Type); }
};
template <typename Type, typename OffsetType=HBUINT16, bool has_null=true>
@@ -423,7 +423,7 @@ struct UnsizedArrayOf
{ return hb_array (arrayZ, len); }
hb_array_t<const Type> as_array (unsigned int len) const
{ return hb_array (arrayZ, len); }
- operator hb_array_t<Type> () { return as_array (); }
+ operator hb_array_t< Type> () { return as_array (); }
operator hb_array_t<const Type> () const { return as_array (); }
template <typename T>
@@ -902,8 +902,8 @@ struct SortedArrayOf : ArrayOf<Type, LenType>
{ return *as_array ().bsearch (x, &not_found); }
template <typename T>
bool bfind (const T &x, unsigned int *i = nullptr,
- hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
- unsigned int to_store = (unsigned int) -1) const
+ hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
+ unsigned int to_store = (unsigned int) -1) const
{ return as_array ().bfind (x, i, not_found, to_store); }
};
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff-common.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff-common.hh
index f4c4fe85778..6735c74be49 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff-common.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff-common.hh
@@ -564,13 +564,13 @@ struct FDSelect3_4
if (glyph < ranges[i].first)
break;
- return (hb_codepoint_t)ranges[i - 1].fd;
+ return (hb_codepoint_t) ranges[i - 1].fd;
}
- GID_TYPE &nRanges () { return ranges.len; }
- GID_TYPE nRanges () const { return ranges.len; }
- GID_TYPE &sentinel () { return StructAfter<GID_TYPE> (ranges[nRanges () - 1]); }
- const GID_TYPE &sentinel () const { return StructAfter<GID_TYPE> (ranges[nRanges () - 1]); }
+ GID_TYPE &nRanges () { return ranges.len; }
+ GID_TYPE nRanges () const { return ranges.len; }
+ GID_TYPE &sentinel () { return StructAfter<GID_TYPE> (ranges[nRanges () - 1]); }
+ const GID_TYPE &sentinel () const { return StructAfter<GID_TYPE> (ranges[nRanges () - 1]); }
ArrayOf<FDSelect3_4_Range<GID_TYPE, FD_TYPE>, GID_TYPE> ranges;
/* GID_TYPE sentinel */
@@ -608,8 +608,8 @@ struct FDSelect
hb_codepoint_t get_fd (hb_codepoint_t glyph) const
{
- if (this == &Null (FDSelect))
- return 0;
+ if (this == &Null (FDSelect)) return 0;
+
switch (format)
{
case 0: return u.format0.get_fd (glyph);
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.cc
index 3e4fc204f34..d1e46256265 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.cc
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.cc
@@ -203,8 +203,7 @@ struct bounds_t
}
}
- bool empty () const
- { return (min.x >= max.x) || (min.y >= max.y); }
+ bool empty () const { return (min.x >= max.x) || (min.y >= max.y); }
point_t min;
point_t max;
@@ -219,12 +218,12 @@ struct cff1_extents_param_t
bounds.init ();
}
- void start_path () { path_open = true; }
- void end_path () { path_open = false; }
+ void start_path () { path_open = true; }
+ void end_path () { path_open = false; }
bool is_path_open () const { return path_open; }
- bool path_open;
- bounds_t bounds;
+ bool path_open;
+ bounds_t bounds;
const OT::cff1::accelerator_t *cff;
};
@@ -307,14 +306,14 @@ bool _get_bounds (const OT::cff1::accelerator_t *cff, hb_codepoint_t glyph, boun
return true;
}
-bool OT::cff1::accelerator_t::get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
+bool OT::cff1::accelerator_t::get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
{
#ifdef HB_NO_OT_FONT_CFF
/* XXX Remove check when this code moves to .hh file. */
return true;
#endif
- bounds_t bounds;
+ bounds_t bounds;
if (!_get_bounds (this, glyph, bounds))
return false;
@@ -326,8 +325,8 @@ bool OT::cff1::accelerator_t::get_extents (hb_codepoint_t glyph, hb_glyph_extent
}
else
{
- extents->x_bearing = (int32_t)bounds.min.x.floor ();
- extents->width = (int32_t)bounds.max.x.ceil () - extents->x_bearing;
+ extents->x_bearing = font->em_scalef_x (bounds.min.x.to_real ());
+ extents->width = font->em_scalef_x (bounds.max.x.to_real () - bounds.min.x.to_real ());
}
if (bounds.min.y >= bounds.max.y)
{
@@ -336,8 +335,8 @@ bool OT::cff1::accelerator_t::get_extents (hb_codepoint_t glyph, hb_glyph_extent
}
else
{
- extents->y_bearing = (int32_t)bounds.max.y.ceil ();
- extents->height = (int32_t)bounds.min.y.floor () - extents->y_bearing;
+ extents->y_bearing = font->em_scalef_y (bounds.max.y.to_real ());
+ extents->height = font->em_scalef_x (bounds.min.y.to_real () - bounds.max.y.to_real ());
}
return true;
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh
index 882250f269d..ad206511c1e 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh
@@ -1155,7 +1155,7 @@ struct cff1
}
bool is_valid () const { return blob != nullptr; }
- bool is_CID () const { return topDict.is_CID (); }
+ bool is_CID () const { return topDict.is_CID (); }
bool is_predef_charset () const { return topDict.CharsetOffset <= ExpertSubsetCharset; }
@@ -1196,7 +1196,7 @@ struct cff1
struct accelerator_t : accelerator_templ_t<cff1_private_dict_opset_t, cff1_private_dict_values_t>
{
- HB_INTERNAL bool get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const;
+ HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const;
HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const;
};
@@ -1225,25 +1225,25 @@ struct cff1
bool is_predef_encoding () const { return topDict.EncodingOffset <= ExpertEncoding; }
- hb_codepoint_t glyph_to_code (hb_codepoint_t glyph) const
+ hb_codepoint_t glyph_to_code (hb_codepoint_t glyph) const
{
if (encoding != &Null(Encoding))
return encoding->get_code (glyph);
else
{
- hb_codepoint_t sid = glyph_to_sid (glyph);
+ hb_codepoint_t sid = glyph_to_sid (glyph);
if (sid == 0) return 0;
- hb_codepoint_t code = 0;
+ hb_codepoint_t code = 0;
switch (topDict.EncodingOffset)
{
- case StandardEncoding:
- code = lookup_standard_encoding_for_code (sid);
- break;
- case ExpertEncoding:
- code = lookup_expert_encoding_for_code (sid);
- break;
- default:
- break;
+ case StandardEncoding:
+ code = lookup_standard_encoding_for_code (sid);
+ break;
+ case ExpertEncoding:
+ code = lookup_expert_encoding_for_code (sid);
+ break;
+ default:
+ break;
}
return code;
}
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc
index 0251efac8b5..a2242b76fb9 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc
@@ -44,8 +44,8 @@ struct cff2_extents_param_t
max_y.set_int (INT_MIN);
}
- void start_path () { path_open = true; }
- void end_path () { path_open = false; }
+ void start_path () { path_open = true; }
+ void end_path () { path_open = false; }
bool is_path_open () const { return path_open; }
void update_bounds (const point_t &pt)
@@ -125,8 +125,8 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font,
}
else
{
- extents->x_bearing = (int32_t)param.min_x.floor ();
- extents->width = (int32_t)param.max_x.ceil () - extents->x_bearing;
+ extents->x_bearing = font->em_scalef_x (param.min_x.to_real ());
+ extents->width = font->em_scalef_x (param.max_x.to_real () - param.min_x.to_real ());
}
if (param.min_y >= param.max_y)
{
@@ -135,8 +135,8 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font,
}
else
{
- extents->y_bearing = (int32_t)param.max_y.ceil ();
- extents->height = (int32_t)param.min_y.floor () - extents->y_bearing;
+ extents->y_bearing = font->em_scalef_y (param.max_y.to_real ());
+ extents->height = font->em_scalef_y (param.min_y.to_real () - param.max_y.to_real ());
}
return true;
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh
index eb6f2406bd3..e6646152978 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh
@@ -736,9 +736,7 @@ struct DefaultUVS : SortedArrayOf<UnicodeValueRange, HBUINT32>
struct UVSMapping
{
int cmp (const hb_codepoint_t &codepoint) const
- {
- return unicodeValue.cmp (codepoint);
- }
+ { return unicodeValue.cmp (codepoint); }
bool sanitize (hb_sanitize_context_t *c) const
{
@@ -1170,7 +1168,7 @@ struct cmap
return true;
return false;
- })
+ })
;
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh
index 2a873594a94..3498d3b360d 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh
@@ -51,12 +51,12 @@ struct SmallGlyphMetrics
return_trace (c->check_struct (this));
}
- void get_extents (hb_glyph_extents_t *extents) const
+ void get_extents (hb_font_t *font, hb_glyph_extents_t *extents) const
{
- extents->x_bearing = bearingX;
- extents->y_bearing = bearingY;
- extents->width = width;
- extents->height = - (hb_position_t) height;
+ extents->x_bearing = font->em_scale_x (bearingX);
+ extents->y_bearing = font->em_scale_y (bearingY);
+ extents->width = font->em_scale_x (width);
+ extents->height = font->em_scale_y (-height);
}
HBUINT8 height;
@@ -424,7 +424,7 @@ struct CBDT
return false;
const GlyphBitmapDataFormat17& glyphFormat17 =
StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset);
- glyphFormat17.glyphMetrics.get_extents (extents);
+ glyphFormat17.glyphMetrics.get_extents (font, extents);
break;
}
case 18: {
@@ -432,7 +432,7 @@ struct CBDT
return false;
const GlyphBitmapDataFormat18& glyphFormat18 =
StructAtOffset<GlyphBitmapDataFormat18> (this->cbdt, image_offset);
- glyphFormat18.glyphMetrics.get_extents (extents);
+ glyphFormat18.glyphMetrics.get_extents (font, extents);
break;
}
default:
@@ -453,7 +453,7 @@ struct CBDT
}
hb_blob_t* reference_png (hb_font_t *font,
- hb_codepoint_t glyph) const
+ hb_codepoint_t glyph) const
{
const void *base;
const BitmapSizeTable &strike = this->cblc->choose_strike (font);
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh
index 76df889517b..1b3c7fc0b88 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh
@@ -115,7 +115,7 @@ struct CPAL
{ return min_size + numPalettes * sizeof (colorRecordIndicesZ[0]); }
unsigned int get_palette_count () const { return numPalettes; }
- unsigned int get_color_count () const { return numColors; }
+ unsigned int get_color_count () const { return numColors; }
hb_ot_color_palette_flags_t get_palette_flags (unsigned int palette_index) const
{ return v1 ().get_palette_flags (this, palette_index, numPalettes); }
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh
index 6089027f873..35d3fd51056 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh
@@ -243,10 +243,17 @@ struct sbix
if (strike_ppem)
{
float scale = font->face->get_upem () / (float) strike_ppem;
- extents->x_bearing = roundf (extents->x_bearing * scale);
- extents->y_bearing = roundf (extents->y_bearing * scale);
- extents->width = roundf (extents->width * scale);
- extents->height = roundf (extents->height * scale);
+ extents->x_bearing = font->em_scalef_x (extents->x_bearing * scale);
+ extents->y_bearing = font->em_scalef_y (extents->y_bearing * scale);
+ extents->width = font->em_scalef_x (extents->width * scale);
+ extents->height = font->em_scalef_y (extents->height * scale);
+ }
+ else
+ {
+ extents->x_bearing = font->em_scale_x (extents->x_bearing);
+ extents->y_bearing = font->em_scale_y (extents->y_bearing);
+ extents->width = font->em_scale_x (extents->width);
+ extents->height = font->em_scale_y (extents->height);
}
hb_blob_destroy (blob);
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face-table-list.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face-table-list.hh
index 30bab5cb54d..6fa9baf1356 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face-table-list.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face-table-list.hh
@@ -84,6 +84,7 @@ HB_OT_TABLE (OT, VORG)
#ifndef HB_NO_VAR
HB_OT_TABLE (OT, fvar)
HB_OT_TABLE (OT, avar)
+HB_OT_ACCELERATOR (OT, gvar)
HB_OT_TABLE (OT, MVAR)
#endif
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc
index e6288b44545..96f94e4a9ec 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc
@@ -160,11 +160,11 @@ hb_ot_get_glyph_v_origin (hb_font_t *font,
#endif
hb_glyph_extents_t extents = {0};
- if (ot_face->glyf->get_extents (glyph, &extents))
+ if (ot_face->glyf->get_extents (font, glyph, &extents))
{
const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
- hb_position_t tsb = vmtx.get_side_bearing (glyph);
- *y = font->em_scale_y (extents.y_bearing + tsb);
+ hb_position_t tsb = vmtx.get_side_bearing (font, glyph);
+ *y = extents.y_bearing + font->em_scale_y (tsb);
return true;
}
@@ -188,9 +188,9 @@ hb_ot_get_glyph_extents (hb_font_t *font,
#if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR)
if (!ret) ret = ot_face->sbix->get_extents (font, glyph, extents);
#endif
- if (!ret) ret = ot_face->glyf->get_extents (glyph, extents);
+ if (!ret) ret = ot_face->glyf->get_extents (font, glyph, extents);
#ifndef HB_NO_OT_FONT_CFF
- if (!ret) ret = ot_face->cff1->get_extents (glyph, extents);
+ if (!ret) ret = ot_face->cff1->get_extents (font, glyph, extents);
if (!ret) ret = ot_face->cff2->get_extents (font, glyph, extents);
#endif
#if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR)
@@ -198,10 +198,6 @@ hb_ot_get_glyph_extents (hb_font_t *font,
#endif
// TODO Hook up side-bearings variations.
- extents->x_bearing = font->em_scale_x (extents->x_bearing);
- extents->y_bearing = font->em_scale_y (extents->y_bearing);
- extents->width = font->em_scale_x (extents->width);
- extents->height = font->em_scale_y (extents->height);
return ret;
}
@@ -315,5 +311,19 @@ hb_ot_font_set_funcs (hb_font_t *font)
nullptr);
}
+#ifndef HB_NO_VAR
+int
+_glyf_get_side_bearing_var (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical)
+{
+ return font->face->table.glyf->get_side_bearing_var (font, glyph, is_vertical);
+}
+
+unsigned
+_glyf_get_advance_var (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical)
+{
+ return font->face->table.glyf->get_advance_var (font, glyph, is_vertical);
+}
+#endif
+
#endif
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh
index 9a791bbf031..f5a64b050e8 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh
@@ -1,5 +1,6 @@
/*
* Copyright © 2015 Google, Inc.
+ * Copyright © 2019 Adobe Inc.
* Copyright © 2019 Ebrahim Byagowi
*
* This is part of HarfBuzz, a text shaping library.
@@ -23,6 +24,7 @@
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Google Author(s): Behdad Esfahbod, Garret Rieger, Roderick Sheeter
+ * Adobe Author(s): Michiharu Ariza
*/
#ifndef HB_OT_GLYF_TABLE_HH
@@ -30,6 +32,10 @@
#include "hb-open-type.hh"
#include "hb-ot-head-table.hh"
+#include "hb-ot-hmtx-table.hh"
+#include "hb-ot-var-gvar-table.hh"
+
+#include <float.h>
namespace OT {
@@ -57,7 +63,7 @@ struct loca
UnsizedArrayOf<HBUINT8>
dataZ; /* Location data. */
public:
- DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always
+ DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always
* check the size externally, allow Null() object of it by
* defining it _MIN instead. */
};
@@ -77,8 +83,7 @@ struct glyf
bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const
{
TRACE_SANITIZE (this);
- /* We don't check for anything specific here. The users of the
- * struct do all the hard work... */
+ /* Runtime checks as eager sanitizing each glyph is costy */
return_trace (true);
}
@@ -111,7 +116,7 @@ struct glyf
free);
bool result = plan->add_table (HB_OT_TAG_loca, loca_blob)
- && _add_head_and_set_loca_version(plan, use_short_loca);
+ && _add_head_and_set_loca_version (plan, use_short_loca);
hb_blob_destroy (loca_blob);
return result;
@@ -136,7 +141,7 @@ struct glyf
;
}
- // requires source of SubsetGlyph complains the identifier isn't declared
+ /* requires source of SubsetGlyph complains the identifier isn't declared */
template <typename Iterator>
bool serialize (hb_serialize_context_t *c,
Iterator it,
@@ -147,6 +152,9 @@ struct glyf
return_trace (true);
}
+ /* Byte region(s) per glyph to output
+ unpadded, hints removed if so requested
+ If we fail to process a glyph we produce an empty (0-length) glyph */
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
@@ -154,9 +162,6 @@ struct glyf
glyf *glyf_prime = c->serializer->start_embed <glyf> ();
if (unlikely (!c->serializer->check_success (glyf_prime))) return_trace (false);
- // Byte region(s) per glyph to output
- // unpadded, hints removed if so requested
- // If we fail to process a glyph we produce an empty (0-length) glyph
hb_vector_t<SubsetGlyph> glyphs;
_populate_subset_glyphs (c->plan, &glyphs);
@@ -174,8 +179,8 @@ struct glyf
template <typename SubsetGlyph>
void
- _populate_subset_glyphs (const hb_subset_plan_t * plan,
- hb_vector_t<SubsetGlyph> * glyphs /* OUT */) const
+ _populate_subset_glyphs (const hb_subset_plan_t *plan,
+ hb_vector_t<SubsetGlyph> *glyphs /* OUT */) const
{
OT::glyf::accelerator_t glyf;
glyf.init (plan->source);
@@ -186,14 +191,13 @@ struct glyf
SubsetGlyph subset_glyph = {0};
subset_glyph.new_gid = new_gid;
- // should never fail: all old gids should be mapped
+ /* should never fail: all old gids should be mapped */
if (!plan->old_gid_for_new_gid (new_gid, &subset_glyph.old_gid))
return subset_glyph;
- subset_glyph.source_glyph = glyf.bytes_for_glyph ((const char *) this,
- subset_glyph.old_gid);
- if (plan->drop_hints) subset_glyph.drop_hints (glyf);
- else subset_glyph.dest_start = subset_glyph.source_glyph;
+ subset_glyph.source_glyph = glyf.glyph_for_gid (subset_glyph.old_gid, true);
+ if (plan->drop_hints) subset_glyph.drop_hints_bytes ();
+ else subset_glyph.dest_start = subset_glyph.source_glyph.get_bytes ();
return subset_glyph;
})
@@ -203,58 +207,6 @@ struct glyf
glyf.fini ();
}
- static void
- _fix_component_gids (const hb_subset_plan_t *plan,
- hb_bytes_t glyph)
- {
- OT::glyf::CompositeGlyphHeader::Iterator iterator;
- if (OT::glyf::CompositeGlyphHeader::get_iterator (&glyph,
- glyph.length,
- &iterator))
- {
- do
- {
- hb_codepoint_t new_gid;
- if (!plan->new_gid_for_old_gid (iterator.current->glyphIndex,
- &new_gid))
- continue;
- ((OT::glyf::CompositeGlyphHeader *) iterator.current)->glyphIndex = new_gid;
- } while (iterator.move_to_next ());
- }
- }
-
- static void
- _zero_instruction_length (hb_bytes_t glyph)
- {
- const GlyphHeader &glyph_header = *glyph.as<GlyphHeader> ();
- if (!glyph_header.is_simple_glyph ()) return; // only for simple glyphs
-
- unsigned int instruction_len_offset = glyph_header.simple_instruction_len_offset ();
- const HBUINT16 &instruction_len = StructAtOffset<HBUINT16> (&glyph,
- instruction_len_offset);
- (HBUINT16 &) instruction_len = 0;
- }
-
- static bool _remove_composite_instruction_flag (hb_bytes_t glyph)
- {
- const GlyphHeader &glyph_header = *glyph.as<GlyphHeader> ();
- if (!glyph_header.is_composite_glyph ()) return true; // only for composites
-
- /* remove WE_HAVE_INSTRUCTIONS from flags in dest */
- OT::glyf::CompositeGlyphHeader::Iterator composite_it;
- if (unlikely (!OT::glyf::CompositeGlyphHeader::get_iterator (&glyph, glyph.length,
- &composite_it)))
- return false;
- const OT::glyf::CompositeGlyphHeader *composite_header;
- do
- {
- composite_header = composite_it.current;
- OT::HBUINT16 *flags = const_cast<OT::HBUINT16 *> (&composite_header->flags);
- *flags = (uint16_t) *flags & ~OT::glyf::CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS;
- } while (composite_it.move_to_next ());
- return true;
- }
-
static bool
_add_head_and_set_loca_version (hb_subset_plan_t *plan, bool use_short_loca)
{
@@ -273,41 +225,7 @@ struct glyf
return success;
}
- struct GlyphHeader
- {
- unsigned int simple_instruction_len_offset () const
- { return static_size + 2 * numberOfContours; }
-
- unsigned int simple_length (unsigned int instruction_len) const
- { return simple_instruction_len_offset () + 2 + instruction_len; }
-
- bool is_composite_glyph () const { return numberOfContours < 0; }
- bool is_simple_glyph () const { return numberOfContours > 0; }
-
- void get_extents (hb_glyph_extents_t *extents) const
- {
- extents->x_bearing = hb_min (xMin, xMax);
- extents->y_bearing = hb_max (yMin, yMax);
- extents->width = hb_max (xMin, xMax) - extents->x_bearing;
- extents->height = hb_min (yMin, yMax) - extents->y_bearing;
- }
-
- bool has_data () const { return numberOfContours; }
-
- protected:
- HBINT16 numberOfContours;/* If the number of contours is
- * greater than or equal to zero,
- * this is a simple glyph; if negative,
- * this is a composite glyph. */
- FWORD xMin; /* Minimum x for coordinate data. */
- FWORD yMin; /* Minimum y for coordinate data. */
- FWORD xMax; /* Maximum x for coordinate data. */
- FWORD yMax; /* Maximum y for coordinate data. */
- public:
- DEFINE_SIZE_STATIC (10);
- };
-
- struct CompositeGlyphHeader
+ struct CompositeGlyphChain
{
enum composite_glyph_flag_t
{
@@ -325,180 +243,248 @@ struct glyf
UNSCALED_COMPONENT_OFFSET = 0x1000
};
- HBUINT16 flags;
- HBGlyphID glyphIndex;
-
unsigned int get_size () const
{
unsigned int size = min_size;
- // arg1 and 2 are int16
+ /* arg1 and 2 are int16 */
if (flags & ARG_1_AND_2_ARE_WORDS) size += 4;
- // arg1 and 2 are int8
+ /* arg1 and 2 are int8 */
else size += 2;
- // One x 16 bit (scale)
+ /* One x 16 bit (scale) */
if (flags & WE_HAVE_A_SCALE) size += 2;
- // Two x 16 bit (xscale, yscale)
+ /* Two x 16 bit (xscale, yscale) */
else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) size += 4;
- // Four x 16 bit (xscale, scale01, scale10, yscale)
+ /* Four x 16 bit (xscale, scale01, scale10, yscale) */
else if (flags & WE_HAVE_A_TWO_BY_TWO) size += 8;
return size;
}
- // TODO rewrite using new iterator framework if possible
- struct Iterator
+ bool is_use_my_metrics () const { return flags & USE_MY_METRICS; }
+ bool is_anchored () const { return !(flags & ARGS_ARE_XY_VALUES); }
+ void get_anchor_points (unsigned int &point1, unsigned int &point2) const
{
- const char *glyph_start;
- const char *glyph_end;
- const CompositeGlyphHeader *current;
+ const HBUINT8 *p = &StructAfter<const HBUINT8> (glyphIndex);
+ if (flags & ARG_1_AND_2_ARE_WORDS)
+ {
+ point1 = ((const HBUINT16 *) p)[0];
+ point2 = ((const HBUINT16 *) p)[1];
+ }
+ else
+ {
+ point1 = p[0];
+ point2 = p[1];
+ }
+ }
- bool move_to_next ()
+ void transform_points (contour_point_vector_t &points) const
+ {
+ float matrix[4];
+ contour_point_t trans;
+ if (get_transformation (matrix, trans))
{
- if (current->flags & CompositeGlyphHeader::MORE_COMPONENTS)
+ if (scaled_offsets ())
{
- const CompositeGlyphHeader *possible =
- &StructAfter<CompositeGlyphHeader, CompositeGlyphHeader> (*current);
- if (!in_range (possible))
- return false;
- current = possible;
- return true;
+ points.translate (trans);
+ points.transform (matrix);
+ }
+ else
+ {
+ points.transform (matrix);
+ points.translate (trans);
}
- return false;
}
+ }
- bool in_range (const CompositeGlyphHeader *composite) const
- {
- return (const char *) composite >= glyph_start
- && ((const char *) composite + CompositeGlyphHeader::min_size) <= glyph_end
- && ((const char *) composite + composite->get_size ()) <= glyph_end;
- }
- };
+ protected:
+ bool scaled_offsets () const
+ { return (flags & (SCALED_COMPONENT_OFFSET | UNSCALED_COMPONENT_OFFSET)) == SCALED_COMPONENT_OFFSET; }
- static bool get_iterator (const char * glyph_data,
- unsigned int length,
- CompositeGlyphHeader::Iterator *iterator /* OUT */)
+ bool get_transformation (float (&matrix)[4], contour_point_t &trans) const
{
- const GlyphHeader &glyph_header = *hb_bytes_t (glyph_data, length).as<GlyphHeader> ();
- if (!glyph_header.has_data ()) return false; /* Empty glyph; zero extents. */
+ matrix[0] = matrix[3] = 1.f;
+ matrix[1] = matrix[2] = 0.f;
- if (glyph_header.is_composite_glyph ())
+ int tx, ty;
+ const HBINT8 *p = &StructAfter<const HBINT8> (glyphIndex);
+ if (flags & ARG_1_AND_2_ARE_WORDS)
{
- const CompositeGlyphHeader *possible =
- &StructAfter<CompositeGlyphHeader, GlyphHeader> (glyph_header);
-
- iterator->glyph_start = glyph_data;
- iterator->glyph_end = (const char *) glyph_data + length;
- if (!iterator->in_range (possible))
- return false;
- iterator->current = possible;
- return true;
+ tx = *(const HBINT16 *) p;
+ p += HBINT16::static_size;
+ ty = *(const HBINT16 *) p;
+ p += HBINT16::static_size;
+ }
+ else
+ {
+ tx = *p++;
+ ty = *p++;
}
+ if (is_anchored ()) tx = ty = 0;
- return false;
+ trans.init ((float) tx, (float) ty);
+
+ {
+ const F2DOT14 *points = (const F2DOT14 *) p;
+ if (flags & WE_HAVE_A_SCALE)
+ {
+ matrix[0] = matrix[3] = points[0].to_float ();
+ return true;
+ }
+ else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
+ {
+ matrix[0] = points[0].to_float ();
+ matrix[3] = points[1].to_float ();
+ return true;
+ }
+ else if (flags & WE_HAVE_A_TWO_BY_TWO)
+ {
+ matrix[0] = points[0].to_float ();
+ matrix[1] = points[1].to_float ();
+ matrix[2] = points[2].to_float ();
+ matrix[3] = points[3].to_float ();
+ return true;
+ }
+ }
+ return tx || ty;
}
+ public:
+ HBUINT16 flags;
+ HBGlyphID glyphIndex;
+ public:
DEFINE_SIZE_MIN (4);
};
- struct accelerator_t
+ struct composite_iter_t : hb_iter_with_fallback_t<composite_iter_t, const CompositeGlyphChain &>
{
- void init (hb_face_t *face)
+ typedef const CompositeGlyphChain *__item_t__;
+ composite_iter_t (hb_bytes_t glyph_, __item_t__ current_) :
+ glyph (glyph_), current (current_), checker (range_checker_t (glyph.arrayZ, glyph.length))
+ { if (!in_range (current)) current = nullptr; }
+ composite_iter_t () : glyph (hb_bytes_t ()), current (nullptr), checker (range_checker_t (nullptr, 0)) {}
+
+ const CompositeGlyphChain &__item__ () const { return *current; }
+ bool __more__ () const { return current; }
+ void __next__ ()
{
- memset (this, 0, sizeof (accelerator_t));
-
- const OT::head &head = *face->table.head;
- if (head.indexToLocFormat > 1 || head.glyphDataFormat != 0)
- /* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */
- return;
- short_offset = 0 == head.indexToLocFormat;
-
- loca_table = hb_sanitize_context_t ().reference_table<loca> (face);
- glyf_table = hb_sanitize_context_t ().reference_table<glyf> (face);
+ if (!(current->flags & CompositeGlyphChain::MORE_COMPONENTS)) { current = nullptr; return; }
- num_glyphs = hb_max (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1;
+ const CompositeGlyphChain *possible = &StructAfter<CompositeGlyphChain,
+ CompositeGlyphChain> (*current);
+ if (!in_range (possible)) { current = nullptr; return; }
+ current = possible;
}
+ bool operator != (const composite_iter_t& o) const
+ { return glyph != o.glyph || current != o.current; }
- void fini ()
+ bool in_range (const CompositeGlyphChain *composite) const
{
- loca_table.destroy ();
- glyf_table.destroy ();
+ return checker.in_range (composite, CompositeGlyphChain::min_size)
+ && checker.in_range (composite, composite->get_size ());
}
- /*
- * Returns true if the referenced glyph is a valid glyph and a composite glyph.
- * If true is returned a pointer to the composite glyph will be written into
- * composite.
- */
- bool get_composite (hb_codepoint_t glyph,
- CompositeGlyphHeader::Iterator *composite /* OUT */) const
+ private:
+ hb_bytes_t glyph;
+ __item_t__ current;
+ range_checker_t checker;
+ };
+
+ struct Glyph
+ {
+ private:
+ struct GlyphHeader
{
- if (unlikely (!num_glyphs))
- return false;
+ bool has_data () const { return numberOfContours; }
- unsigned int start_offset, end_offset;
- if (!get_offsets (glyph, &start_offset, &end_offset))
- return false; /* glyph not found */
+ bool get_extents (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const
+ {
+ /* Undocumented rasterizer behavior: shift glyph to the left by (lsb - xMin), i.e., xMin = lsb */
+ /* extents->x_bearing = hb_min (glyph_header.xMin, glyph_header.xMax); */
+ extents->x_bearing = font->em_scale_x (font->face->table.hmtx->get_side_bearing (gid));
+ extents->y_bearing = font->em_scale_y (hb_max (yMin, yMax));
+ extents->width = font->em_scale_x (hb_max (xMin, xMax) - hb_min (xMin, xMax));
+ extents->height = font->em_scale_y (hb_min (yMin, yMax) - hb_max (yMin, yMax));
- return CompositeGlyphHeader::get_iterator ((const char *) this->glyf_table + start_offset,
- end_offset - start_offset,
- composite);
- }
+ return true;
+ }
- enum simple_glyph_flag_t
- {
- FLAG_ON_CURVE = 0x01,
- FLAG_X_SHORT = 0x02,
- FLAG_Y_SHORT = 0x04,
- FLAG_REPEAT = 0x08,
- FLAG_X_SAME = 0x10,
- FLAG_Y_SAME = 0x20,
- FLAG_RESERVED1 = 0x40,
- FLAG_RESERVED2 = 0x80
+ HBINT16 numberOfContours;
+ /* If the number of contours is
+ * greater than or equal to zero,
+ * this is a simple glyph; if negative,
+ * this is a composite glyph. */
+ FWORD xMin; /* Minimum x for coordinate data. */
+ FWORD yMin; /* Minimum y for coordinate data. */
+ FWORD xMax; /* Maximum x for coordinate data. */
+ FWORD yMax; /* Maximum y for coordinate data. */
+ public:
+ DEFINE_SIZE_STATIC (10);
};
- /* based on FontTools _g_l_y_f.py::trim */
- bool remove_padding (unsigned int start_offset,
- unsigned int *end_offset) const
+ struct SimpleGlyph
{
- const char *glyph = ((const char *) glyf_table) + start_offset;
- unsigned int glyph_length = *end_offset - start_offset;
- const GlyphHeader &glyph_header = *hb_bytes_t (glyph, glyph_length).as<GlyphHeader> ();
- if (!glyph_header.has_data ()) return true;
+ const GlyphHeader &header;
+ hb_bytes_t bytes;
+ SimpleGlyph (const GlyphHeader &header_, hb_bytes_t bytes_) :
+ header (header_), bytes (bytes_) {}
- const char *glyph_end = glyph + glyph_length;
- if (glyph_header.is_composite_glyph ())
- /* Trimming for composites not implemented.
- * If removing hints it falls out of that. */
- return true;
- else
+ unsigned int instruction_len_offset () const
+ { return GlyphHeader::static_size + 2 * header.numberOfContours; }
+
+ unsigned int length (unsigned int instruction_len) const
+ { return instruction_len_offset () + 2 + instruction_len; }
+
+ unsigned int instructions_length () const
+ {
+ unsigned int instruction_length_offset = instruction_len_offset ();
+ if (unlikely (instruction_length_offset + 2 > bytes.length)) return 0;
+
+ const HBUINT16 &instructionLength = StructAtOffset<HBUINT16> (&bytes, instruction_length_offset);
+ /* Out of bounds of the current glyph */
+ if (unlikely (length (instructionLength) > bytes.length)) return 0;
+ return instructionLength;
+ }
+
+ enum simple_glyph_flag_t
{
+ FLAG_ON_CURVE = 0x01,
+ FLAG_X_SHORT = 0x02,
+ FLAG_Y_SHORT = 0x04,
+ FLAG_REPEAT = 0x08,
+ FLAG_X_SAME = 0x10,
+ FLAG_Y_SAME = 0x20,
+ FLAG_RESERVED1 = 0x40,
+ FLAG_RESERVED2 = 0x80
+ };
+
+ const Glyph trim_padding () const
+ {
+ /* based on FontTools _g_l_y_f.py::trim */
+ const char *glyph = bytes.arrayZ;
+ const char *glyph_end = glyph + bytes.length;
/* simple glyph w/contours, possibly trimmable */
- glyph += glyph_header.simple_instruction_len_offset ();
+ glyph += instruction_len_offset ();
- if (unlikely (glyph + 2 >= glyph_end)) return false;
- uint16_t nCoordinates = (uint16_t) StructAtOffset<HBUINT16> (glyph - 2, 0) + 1;
- uint16_t nInstructions = (uint16_t) StructAtOffset<HBUINT16> (glyph, 0);
+ if (unlikely (glyph + 2 >= glyph_end)) return Glyph ();
+ unsigned int num_coordinates = StructAtOffset<HBUINT16> (glyph - 2, 0) + 1;
+ unsigned int num_instructions = StructAtOffset<HBUINT16> (glyph, 0);
- glyph += 2 + nInstructions;
- if (unlikely (glyph + 2 >= glyph_end)) return false;
+ glyph += 2 + num_instructions;
+ if (unlikely (glyph + 2 >= glyph_end)) return Glyph ();
- unsigned int coordBytes = 0;
- unsigned int coordsWithFlags = 0;
+ unsigned int coord_bytes = 0;
+ unsigned int coords_with_flags = 0;
while (glyph < glyph_end)
{
- uint8_t flag = (uint8_t) *glyph;
+ uint8_t flag = *glyph;
glyph++;
unsigned int repeat = 1;
if (flag & FLAG_REPEAT)
{
- if (glyph >= glyph_end)
- {
- DEBUG_MSG (SUBSET, nullptr, "Bad flag");
- return false;
- }
- repeat = ((uint8_t) *glyph) + 1;
+ if (unlikely (glyph >= glyph_end)) return Glyph ();
+ repeat = *glyph + 1;
glyph++;
}
@@ -510,141 +496,553 @@ struct glyf
if (flag & FLAG_Y_SHORT) yBytes = 1;
else if ((flag & FLAG_Y_SAME) == 0) yBytes = 2;
- coordBytes += (xBytes + yBytes) * repeat;
- coordsWithFlags += repeat;
- if (coordsWithFlags >= nCoordinates)
- break;
+ coord_bytes += (xBytes + yBytes) * repeat;
+ coords_with_flags += repeat;
+ if (coords_with_flags >= num_coordinates) break;
}
- if (coordsWithFlags != nCoordinates)
+ if (unlikely (coords_with_flags != num_coordinates)) return Glyph ();
+ return Glyph (bytes.sub_array (0, bytes.length + coord_bytes - (glyph_end - glyph)));
+ }
+
+ /* zero instruction length */
+ void drop_hints ()
+ {
+ GlyphHeader &glyph_header = const_cast<GlyphHeader &> (header);
+ (HBUINT16 &) StructAtOffset<HBUINT16> (&glyph_header, instruction_len_offset ()) = 0;
+ }
+
+ void drop_hints_bytes (hb_bytes_t &dest_start, hb_bytes_t &dest_end) const
+ {
+ unsigned int instructions_len = instructions_length ();
+ unsigned int glyph_length = length (instructions_len);
+ dest_start = bytes.sub_array (0, glyph_length - instructions_len);
+ dest_end = bytes.sub_array (glyph_length, bytes.length - glyph_length);
+ }
+
+ struct x_setter_t
+ {
+ void set (contour_point_t &point, float v) const { point.x = v; }
+ bool is_short (uint8_t flag) const { return flag & FLAG_X_SHORT; }
+ bool is_same (uint8_t flag) const { return flag & FLAG_X_SAME; }
+ };
+
+ struct y_setter_t
+ {
+ void set (contour_point_t &point, float v) const { point.y = v; }
+ bool is_short (uint8_t flag) const { return flag & FLAG_Y_SHORT; }
+ bool is_same (uint8_t flag) const { return flag & FLAG_Y_SAME; }
+ };
+
+ template <typename T>
+ static bool read_points (const HBUINT8 *&p /* IN/OUT */,
+ contour_point_vector_t &points_ /* IN/OUT */,
+ const range_checker_t &checker)
+ {
+ T coord_setter;
+ float v = 0;
+ for (unsigned int i = 0; i < points_.length - PHANTOM_COUNT; i++)
{
- DEBUG_MSG (SUBSET, nullptr, "Expect %d coords to have flags, got flags for %d",
- nCoordinates, coordsWithFlags);
- return false;
+ uint8_t flag = points_[i].flag;
+ if (coord_setter.is_short (flag))
+ {
+ if (unlikely (!checker.in_range (p))) return false;
+ if (coord_setter.is_same (flag))
+ v += *p++;
+ else
+ v -= *p++;
+ }
+ else
+ {
+ if (!coord_setter.is_same (flag))
+ {
+ if (unlikely (!checker.in_range ((const HBUINT16 *) p))) return false;
+ v += *(const HBINT16 *) p;
+ p += HBINT16::static_size;
+ }
+ }
+ coord_setter.set (points_[i], v);
}
- glyph += coordBytes;
+ return true;
+ }
+
+ bool get_contour_points (contour_point_vector_t &points_ /* OUT */,
+ hb_vector_t<unsigned int> &end_points_ /* OUT */,
+ const bool phantom_only=false) const
+ {
+ const HBUINT16 *endPtsOfContours = &StructAfter<HBUINT16> (header);
+ range_checker_t checker (bytes.arrayZ, bytes.length);
+ int num_contours = header.numberOfContours;
+ if (unlikely (!checker.in_range (&endPtsOfContours[num_contours + 1]))) return false;
+ unsigned int num_points = endPtsOfContours[num_contours - 1] + 1;
+
+ points_.resize (num_points + PHANTOM_COUNT);
+ for (unsigned int i = 0; i < points_.length; i++) points_[i].init ();
+ if (phantom_only) return true;
- if (glyph < glyph_end)
- *end_offset -= glyph_end - glyph;
+ /* Read simple glyph points if !phantom_only */
+ end_points_.resize (num_contours);
+
+ for (int i = 0; i < num_contours; i++)
+ end_points_[i] = endPtsOfContours[i];
+
+ /* Skip instructions */
+ const HBUINT8 *p = &StructAtOffset<HBUINT8> (&endPtsOfContours[num_contours + 1],
+ endPtsOfContours[num_contours]);
+
+ /* Read flags */
+ for (unsigned int i = 0; i < num_points; i++)
+ {
+ if (unlikely (!checker.in_range (p))) return false;
+ uint8_t flag = *p++;
+ points_[i].flag = flag;
+ if (flag & FLAG_REPEAT)
+ {
+ if (unlikely (!checker.in_range (p))) return false;
+ unsigned int repeat_count = *p++;
+ while ((repeat_count-- > 0) && (++i < num_points))
+ points_[i].flag = flag;
+ }
+ }
+
+ /* Read x & y coordinates */
+ return (read_points<x_setter_t> (p, points_, checker) &&
+ read_points<y_setter_t> (p, points_, checker));
}
- return true;
- }
+ };
- bool get_offsets (hb_codepoint_t glyph,
- unsigned int *start_offset /* OUT */,
- unsigned int *end_offset /* OUT */) const
+ struct CompositeGlyph
{
- if (unlikely (glyph >= num_glyphs))
- return false;
+ const GlyphHeader &header;
+ hb_bytes_t bytes;
+ CompositeGlyph (const GlyphHeader &header_, hb_bytes_t bytes_) :
+ header (header_), bytes (bytes_) {}
- if (short_offset)
+ composite_iter_t get_iterator () const
+ { return composite_iter_t (bytes, &StructAfter<CompositeGlyphChain, GlyphHeader> (header)); }
+
+ unsigned int instructions_length (hb_bytes_t bytes) const
{
- const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataZ.arrayZ;
- *start_offset = 2 * offsets[glyph];
- *end_offset = 2 * offsets[glyph + 1];
+ unsigned int start = bytes.length;
+ unsigned int end = bytes.length;
+ const CompositeGlyphChain *last = nullptr;
+ for (auto &item : get_iterator ())
+ last = &item;
+ if (unlikely (!last)) return 0;
+
+ if ((uint16_t) last->flags & CompositeGlyphChain::WE_HAVE_INSTRUCTIONS)
+ start = (char *) last - &bytes + last->get_size ();
+ if (unlikely (start > end)) return 0;
+ return end - start;
}
- else
+
+ /* Trimming for composites not implemented.
+ * If removing hints it falls out of that. */
+ const Glyph trim_padding () const { return Glyph (bytes); }
+
+ /* remove WE_HAVE_INSTRUCTIONS flag from composite glyph */
+ void drop_hints ()
{
- const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataZ.arrayZ;
+ for (const auto &_ : get_iterator ())
+ *const_cast<OT::HBUINT16 *> (&_.flags) = (uint16_t) _.flags & ~OT::glyf::CompositeGlyphChain::WE_HAVE_INSTRUCTIONS;
+ }
+
+ /* Chop instructions off the end */
+ void drop_hints_bytes (hb_bytes_t &dest_start) const
+ { dest_start = bytes.sub_array (0, bytes.length - instructions_length (bytes)); }
+
+ bool get_contour_points (contour_point_vector_t &points_ /* OUT */,
+ hb_vector_t<unsigned int> &end_points_ /* OUT */,
+ const bool phantom_only=false) const
+ {
+ /* add one pseudo point for each component in composite glyph */
+ unsigned int num_points = hb_len (get_iterator ());
+ points_.resize (num_points + PHANTOM_COUNT);
+ for (unsigned int i = 0; i < points_.length; i++) points_[i].init ();
+ return true;
+ }
+ };
+
+ enum glyph_type_t { EMPTY, SIMPLE, COMPOSITE };
- *start_offset = offsets[glyph];
- *end_offset = offsets[glyph + 1];
+ enum phantom_point_index_t
+ {
+ PHANTOM_LEFT = 0,
+ PHANTOM_RIGHT = 1,
+ PHANTOM_TOP = 2,
+ PHANTOM_BOTTOM = 3,
+ PHANTOM_COUNT = 4
+ };
+
+ public:
+ composite_iter_t get_composite_iterator () const
+ {
+ if (type != COMPOSITE) return composite_iter_t ();
+ return CompositeGlyph (*header, bytes).get_iterator ();
+ }
+
+ const Glyph trim_padding () const
+ {
+ switch (type) {
+ case COMPOSITE: return CompositeGlyph (*header, bytes).trim_padding ();
+ case SIMPLE: return SimpleGlyph (*header, bytes).trim_padding ();
+ default: return bytes;
}
+ }
- if (*start_offset > *end_offset || *end_offset > glyf_table.get_length ())
- return false;
+ void drop_hints ()
+ {
+ switch (type) {
+ case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints (); return;
+ case SIMPLE: SimpleGlyph (*header, bytes).drop_hints (); return;
+ default: return;
+ }
+ }
- return true;
+ void drop_hints_bytes (hb_bytes_t &dest_start, hb_bytes_t &dest_end) const
+ {
+ switch (type) {
+ case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints_bytes (dest_start); return;
+ case SIMPLE: SimpleGlyph (*header, bytes).drop_hints_bytes (dest_start, dest_end); return;
+ default: return;
+ }
+ }
+
+ /* for a simple glyph, return contour end points, flags, along with coordinate points
+ * for a composite glyph, return pseudo component points
+ * in both cases points trailed with four phantom points
+ */
+ bool get_contour_points (contour_point_vector_t &points_ /* OUT */,
+ hb_vector_t<unsigned int> &end_points_ /* OUT */,
+ const bool phantom_only=false) const
+ {
+ switch (type) {
+ case COMPOSITE: return CompositeGlyph (*header, bytes).get_contour_points (points_, end_points_, phantom_only);
+ case SIMPLE: return SimpleGlyph (*header, bytes).get_contour_points (points_, end_points_, phantom_only);
+ default:
+ /* empty glyph */
+ points_.resize (PHANTOM_COUNT);
+ for (unsigned int i = 0; i < points_.length; i++) points_[i].init ();
+ return true;
+ }
}
- bool get_instruction_length (hb_bytes_t glyph,
- unsigned int * length /* OUT */) const
+ bool is_simple_glyph () const { return type == SIMPLE; }
+ bool is_composite_glyph () const { return type == COMPOSITE; }
+
+ bool get_extents (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const
{
- const GlyphHeader &glyph_header = *glyph.as<GlyphHeader> ();
- /* Empty glyph; no instructions. */
- if (!glyph_header.has_data ())
+ if (type == EMPTY) return true; /* Empty glyph; zero extents. */
+ return header->get_extents (font, gid, extents);
+ }
+
+ hb_bytes_t get_bytes () const { return bytes; }
+ const GlyphHeader &get_header () const { return *header; }
+
+ Glyph (hb_bytes_t bytes_ = hb_bytes_t ()) :
+ bytes (bytes_), header (bytes.as<GlyphHeader> ())
+ {
+ int num_contours = header->numberOfContours;
+ if (unlikely (num_contours == 0)) type = EMPTY;
+ else if (num_contours > 0) type = SIMPLE;
+ else type = COMPOSITE; /* negative numbers */
+ }
+
+ protected:
+ hb_bytes_t bytes;
+ const GlyphHeader *header;
+ unsigned type;
+ };
+
+ struct accelerator_t
+ {
+ void init (hb_face_t *face_)
+ {
+ short_offset = false;
+ num_glyphs = 0;
+ loca_table = nullptr;
+ glyf_table = nullptr;
+ face = face_;
+ const OT::head &head = *face->table.head;
+ if (head.indexToLocFormat > 1 || head.glyphDataFormat > 0)
+ /* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */
+ return;
+ short_offset = 0 == head.indexToLocFormat;
+
+ loca_table = hb_sanitize_context_t ().reference_table<loca> (face);
+ glyf_table = hb_sanitize_context_t ().reference_table<glyf> (face);
+
+ num_glyphs = hb_max (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1;
+ }
+
+ void fini ()
+ {
+ loca_table.destroy ();
+ glyf_table.destroy ();
+ }
+
+ enum phantom_point_index_t
+ {
+ PHANTOM_LEFT = 0,
+ PHANTOM_RIGHT = 1,
+ PHANTOM_TOP = 2,
+ PHANTOM_BOTTOM = 3,
+ PHANTOM_COUNT = 4
+ };
+
+ protected:
+
+ void init_phantom_points (hb_codepoint_t gid, hb_array_t<contour_point_t> &phantoms /* IN/OUT */) const
+ {
+ const Glyph &glyph = glyph_for_gid (gid);
+ int h_delta = (int) glyph.get_header ().xMin - face->table.hmtx->get_side_bearing (gid);
+ int v_orig = (int) glyph.get_header ().yMax + face->table.vmtx->get_side_bearing (gid);
+ unsigned int h_adv = face->table.hmtx->get_advance (gid);
+ unsigned int v_adv = face->table.vmtx->get_advance (gid);
+
+ phantoms[PHANTOM_LEFT].x = h_delta;
+ phantoms[PHANTOM_RIGHT].x = h_adv + h_delta;
+ phantoms[PHANTOM_TOP].y = v_orig;
+ phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv;
+ }
+
+ struct contour_bounds_t
+ {
+ contour_bounds_t () { min.x = min.y = FLT_MAX; max.x = max.y = -FLT_MAX; }
+
+ void add (const contour_point_t &p)
{
- *length = 0;
- // only 0 byte glyphs are healthy when missing GlyphHeader
- return glyph.length == 0;
+ min.x = hb_min (min.x, p.x);
+ min.y = hb_min (min.y, p.y);
+ max.x = hb_max (max.x, p.x);
+ max.y = hb_max (max.y, p.y);
}
- if (glyph_header.is_composite_glyph ())
+
+ bool empty () const { return (min.x >= max.x) || (min.y >= max.y); }
+
+ contour_point_t min;
+ contour_point_t max;
+ };
+
+#ifndef HB_NO_VAR
+ /* Note: Recursively calls itself.
+ * all_points includes phantom points
+ */
+ bool get_points_var (hb_codepoint_t gid,
+ const int *coords, unsigned int coord_count,
+ contour_point_vector_t &all_points /* OUT */,
+ unsigned int depth = 0) const
+ {
+ if (unlikely (depth++ > HB_MAX_NESTING_LEVEL)) return false;
+ contour_point_vector_t points;
+ hb_vector_t<unsigned int> end_points;
+ const Glyph &glyph = glyph_for_gid (gid);
+ if (unlikely (!glyph.get_contour_points (points, end_points))) return false;
+ hb_array_t<contour_point_t> phantoms = points.sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT);
+ init_phantom_points (gid, phantoms);
+ if (unlikely (!face->table.gvar->apply_deltas_to_points (gid, coords, coord_count, points.as_array (), end_points.as_array ()))) return false;
+
+ unsigned int comp_index = 0;
+ if (glyph.is_simple_glyph ())
+ all_points.extend (points.as_array ());
+ else if (glyph.is_composite_glyph ())
{
- unsigned int start = glyph.length;
- unsigned int end = glyph.length;
- unsigned int glyph_offset = &glyph - glyf_table;
- CompositeGlyphHeader::Iterator composite_it;
- if (unlikely (!CompositeGlyphHeader::get_iterator (&glyph, glyph.length,
- &composite_it)))
- return false;
- const CompositeGlyphHeader *last;
- do
+ for (auto &item : glyph.get_composite_iterator ())
{
- last = composite_it.current;
- } while (composite_it.move_to_next ());
+ contour_point_vector_t comp_points;
+ if (unlikely (!get_points_var (item.glyphIndex, coords, coord_count,
+ comp_points, depth))
+ || comp_points.length < PHANTOM_COUNT)
+ return false;
- if ((uint16_t) last->flags & CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS)
- start = ((char *) last - (char *) glyf_table->dataZ.arrayZ)
- + last->get_size () - glyph_offset;
- if (unlikely (start > end))
- {
- DEBUG_MSG (SUBSET, nullptr, "Invalid instruction offset, %d is outside "
- "%d byte buffer", start, glyph.length);
- return false;
+ /* Copy phantom points from component if USE_MY_METRICS flag set */
+ if (item.is_use_my_metrics ())
+ for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
+ phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i];
+
+ /* Apply component transformation & translation */
+ item.transform_points (comp_points);
+
+ /* Apply translatation from gvar */
+ comp_points.translate (points[comp_index]);
+
+ if (item.is_anchored ())
+ {
+ unsigned int p1, p2;
+ item.get_anchor_points (p1, p2);
+ if (likely (p1 < all_points.length && p2 < comp_points.length))
+ {
+ contour_point_t delta;
+ delta.init (all_points[p1].x - comp_points[p2].x,
+ all_points[p1].y - comp_points[p2].y);
+
+ comp_points.translate (delta);
+ }
+ }
+
+ all_points.extend (comp_points.sub_array (0, comp_points.length - PHANTOM_COUNT));
+
+ comp_index++;
}
- *length = end - start;
+
+ all_points.extend (phantoms);
}
- else
+ else return false;
+
+ return true;
+ }
+
+ bool get_points_bearing_applied (hb_font_t *font, hb_codepoint_t gid, contour_point_vector_t &all_points) const
+ {
+ if (unlikely (!get_points_var (gid, font->coords, font->num_coords, all_points) ||
+ all_points.length < PHANTOM_COUNT)) return false;
+
+ /* Undocumented rasterizer behavior:
+ * Shift points horizontally by the updated left side bearing
+ */
+ contour_point_t delta;
+ delta.init (-all_points[all_points.length - PHANTOM_COUNT + PHANTOM_LEFT].x, 0.f);
+ if (delta.x) all_points.translate (delta);
+ return true;
+ }
+
+ protected:
+
+ bool get_var_extents_and_phantoms (hb_font_t *font, hb_codepoint_t gid,
+ hb_glyph_extents_t *extents=nullptr /* OUT */,
+ contour_point_vector_t *phantoms=nullptr /* OUT */) const
+ {
+ contour_point_vector_t all_points;
+ if (!unlikely (get_points_bearing_applied (font, gid, all_points))) return false;
+ if (extents)
{
- unsigned int instruction_len_offset = glyph_header.simple_instruction_len_offset ();
- if (unlikely (instruction_len_offset + 2 > glyph.length))
+ contour_bounds_t bounds;
+ for (unsigned int i = 0; i + PHANTOM_COUNT < all_points.length; i++)
+ bounds.add (all_points[i]);
+
+ if (bounds.min.x > bounds.max.x)
{
- DEBUG_MSG (SUBSET, nullptr, "Glyph size is too short, missing field "
- "instructionLength.");
- return false;
+ extents->width = 0;
+ extents->x_bearing = 0;
}
-
- const HBUINT16 &instruction_len = StructAtOffset<HBUINT16> (&glyph,
- instruction_len_offset);
- /* Out of bounds of the current glyph */
- if (unlikely (glyph_header.simple_length (instruction_len) > glyph.length))
+ else
+ {
+ extents->x_bearing = font->em_scalef_x (bounds.min.x);
+ extents->width = font->em_scalef_x (bounds.max.x - bounds.min.x);
+ }
+ if (bounds.min.y > bounds.max.y)
+ {
+ extents->height = 0;
+ extents->y_bearing = 0;
+ }
+ else
{
- DEBUG_MSG (SUBSET, nullptr, "The instructions array overruns the "
- "glyph's boundaries.");
- return false;
+ extents->y_bearing = font->em_scalef_y (bounds.max.y);
+ extents->height = font->em_scalef_y (bounds.min.y - bounds.max.y);
}
- *length = (uint16_t) instruction_len;
}
+ if (phantoms)
+ for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
+ (*phantoms)[i] = all_points[all_points.length - PHANTOM_COUNT + i];
return true;
}
- bool get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
+ bool get_var_metrics (hb_font_t *font, hb_codepoint_t gid,
+ contour_point_vector_t &phantoms) const
+ { return get_var_extents_and_phantoms (font, gid, nullptr, &phantoms); }
+
+ bool get_extents_var (hb_font_t *font, hb_codepoint_t gid,
+ hb_glyph_extents_t *extents) const
+ { return get_var_extents_and_phantoms (font, gid, extents); }
+#endif
+
+ public:
+#ifndef HB_NO_VAR
+ unsigned int get_advance_var (hb_font_t *font, hb_codepoint_t gid,
+ bool is_vertical) const
{
- unsigned int start_offset, end_offset;
- if (!get_offsets (glyph, &start_offset, &end_offset))
- return false;
+ bool success = false;
+ contour_point_vector_t phantoms;
+ phantoms.resize (PHANTOM_COUNT);
- hb_bytes_t ((const char *) glyf_table + start_offset,
- end_offset - start_offset).as<GlyphHeader> ()->get_extents (extents);
- return true;
+ if (likely (font->num_coords == face->table.gvar->get_axis_count ()))
+ success = get_var_metrics (font, gid, phantoms);
+
+ if (unlikely (!success))
+ return is_vertical ? face->table.vmtx->get_advance (gid) : face->table.hmtx->get_advance (gid);
+
+ if (is_vertical)
+ return roundf (phantoms[PHANTOM_TOP].y - phantoms[PHANTOM_BOTTOM].y);
+ else
+ return roundf (phantoms[PHANTOM_RIGHT].x - phantoms[PHANTOM_LEFT].x);
}
- hb_bytes_t bytes_for_glyph (const char *glyf, hb_codepoint_t gid)
+ int get_side_bearing_var (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const
+ {
+ hb_glyph_extents_t extents;
+ contour_point_vector_t phantoms;
+ phantoms.resize (PHANTOM_COUNT);
+
+ if (unlikely (!get_var_extents_and_phantoms (font, gid, &extents, &phantoms)))
+ return is_vertical ? face->table.vmtx->get_side_bearing (gid) : face->table.hmtx->get_side_bearing (gid);
+
+ return is_vertical ? ceil (phantoms[PHANTOM_TOP].y) - extents.y_bearing : floor (phantoms[PHANTOM_LEFT].x);
+ }
+#endif
+
+ bool get_extents (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const
+ {
+#ifndef HB_NO_VAR
+ unsigned int coord_count;
+ const int *coords = hb_font_get_var_coords_normalized (font, &coord_count);
+ if (coords && coord_count > 0 && coord_count == face->table.gvar->get_axis_count ())
+ return get_extents_var (font, gid, extents);
+#endif
+
+ if (unlikely (gid >= num_glyphs)) return false;
+
+ return glyph_for_gid (gid).get_extents (font, gid, extents);
+ }
+
+ const Glyph
+ glyph_for_gid (hb_codepoint_t gid, bool needs_padding_removal = false) const
{
unsigned int start_offset, end_offset;
- if (unlikely (!(get_offsets (gid, &start_offset, &end_offset) &&
- remove_padding (start_offset, &end_offset))))
+ if (unlikely (gid >= num_glyphs)) return Glyph ();
+
+ if (short_offset)
{
- DEBUG_MSG (SUBSET, nullptr, "Unable to get offset or remove padding for %d", gid);
- return hb_bytes_t ();
+ const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataZ.arrayZ;
+ start_offset = 2 * offsets[gid];
+ end_offset = 2 * offsets[gid + 1];
}
- hb_bytes_t glyph_bytes = hb_bytes_t (glyf + start_offset, end_offset - start_offset);
- if (!glyph_bytes.as<GlyphHeader> ()->has_data ())
+ else
{
- DEBUG_MSG (SUBSET, nullptr, "Empty or invalid glyph size, %d", gid);
- return hb_bytes_t ();
+ const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataZ.arrayZ;
+ start_offset = offsets[gid];
+ end_offset = offsets[gid + 1];
}
- return glyph_bytes;
+
+ if (unlikely (start_offset > end_offset || end_offset > glyf_table.get_length ()))
+ return Glyph ();
+
+ Glyph glyph (hb_bytes_t ((const char *) this->glyf_table + start_offset,
+ end_offset - start_offset));
+ return needs_padding_removal ? glyph.trim_padding () : glyph;
+ }
+
+ void
+ add_gid_and_children (hb_codepoint_t gid, hb_set_t *gids_to_retain,
+ unsigned int depth = 0) const
+ {
+ if (unlikely (depth++ > HB_MAX_NESTING_LEVEL)) return;
+ /* Check if is already visited */
+ if (gids_to_retain->has (gid)) return;
+
+ gids_to_retain->add (gid);
+
+ for (auto &item : glyph_for_gid (gid).get_composite_iterator ())
+ add_gid_and_children (item.glyphIndex, gids_to_retain, depth);
}
private:
@@ -652,13 +1050,14 @@ struct glyf
unsigned int num_glyphs;
hb_blob_ptr_t<loca> loca_table;
hb_blob_ptr_t<glyf> glyf_table;
+ hb_face_t *face;
};
struct SubsetGlyph
{
hb_codepoint_t new_gid;
hb_codepoint_t old_gid;
- hb_bytes_t source_glyph;
+ Glyph source_glyph;
hb_bytes_t dest_start; /* region of source_glyph to copy first */
hb_bytes_t dest_end; /* region of source_glyph to copy second */
@@ -670,8 +1069,7 @@ struct glyf
hb_bytes_t dest_glyph = dest_start.copy (c);
dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + dest_end.copy (c).length);
unsigned int pad_length = padding ();
- DEBUG_MSG (SUBSET, nullptr, "serialize %d byte glyph, width %d pad %d",
- dest_glyph.length, dest_glyph.length + pad_length, pad_length);
+ DEBUG_MSG (SUBSET, nullptr, "serialize %d byte glyph, width %d pad %d", dest_glyph.length, dest_glyph.length + pad_length, pad_length);
HBUINT8 pad;
pad = 0;
@@ -681,56 +1079,27 @@ struct glyf
pad_length--;
}
- if (dest_glyph.length)
+ if (!unlikely (dest_glyph.length)) return_trace (true);
+
+ /* update components gids */
+ for (auto &_ : Glyph (dest_glyph).get_composite_iterator ())
{
- _fix_component_gids (plan, dest_glyph);
- if (plan->drop_hints)
- {
- _zero_instruction_length (dest_glyph);
- c->check_success (_remove_composite_instruction_flag (dest_glyph));
- }
+ hb_codepoint_t new_gid;
+ if (plan->new_gid_for_old_gid (_.glyphIndex, &new_gid))
+ ((OT::glyf::CompositeGlyphChain *) &_)->glyphIndex = new_gid;
}
+ if (plan->drop_hints) Glyph (dest_glyph).drop_hints ();
+
return_trace (true);
}
- void drop_hints (const OT::glyf::accelerator_t& glyf)
- {
- if (source_glyph.length == 0) return;
-
- unsigned int instruction_len = 0;
- if (!glyf.get_instruction_length (source_glyph, &instruction_len))
- {
- DEBUG_MSG (SUBSET, nullptr, "Unable to read instruction length for new_gid %d",
- new_gid);
- return ;
- }
-
- const GlyphHeader& header = *source_glyph.as<GlyphHeader> ();
- DEBUG_MSG (SUBSET, nullptr, "new_gid %d drop %d instruction bytes "
- "from %d byte source glyph",
- new_gid, instruction_len, source_glyph.length);
- if (header.is_composite_glyph ())
- {
- /* just chop instructions off the end for composite glyphs */
- dest_start = hb_bytes_t (&source_glyph, source_glyph.length - instruction_len);
- }
- else
- {
- unsigned int glyph_length = header.simple_length (instruction_len);
- dest_start = hb_bytes_t (&source_glyph, glyph_length - instruction_len);
- dest_end = hb_bytes_t (&source_glyph + glyph_length,
- source_glyph.length - glyph_length);
- DEBUG_MSG (SUBSET, nullptr, "source_len %d start len %d glyph_len %d "
- "instruction_len %d end len %d",
- source_glyph.length, dest_start.length, glyph_length,
- instruction_len, dest_end.length);
- }
- }
+ void drop_hints_bytes ()
+ { source_glyph.drop_hints_bytes (dest_start, dest_end); }
- unsigned int length () const { return dest_start.length + dest_end.length; }
+ unsigned int length () const { return dest_start.length + dest_end.length; }
/* pad to 2 to ensure 2-byte loca will be ok */
- unsigned int padding () const { return length () % 2; }
+ unsigned int padding () const { return length () % 2; }
unsigned int padded_size () const { return length () + padding (); }
};
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh
index 6b2cc866265..e20b3726226 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh
@@ -42,6 +42,13 @@
#define HB_OT_TAG_vmtx HB_TAG('v','m','t','x')
+HB_INTERNAL int
+_glyf_get_side_bearing_var (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical);
+
+HB_INTERNAL unsigned
+_glyf_get_advance_var (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical);
+
+
namespace OT {
@@ -53,6 +60,7 @@ struct LongMetric
DEFINE_SIZE_STATIC (4);
};
+
template <typename T, typename H>
struct hmtxvmtx
{
@@ -128,13 +136,12 @@ struct hmtxvmtx
auto it =
+ hb_range (c->plan->num_output_glyphs ())
| hb_map ([c, &_mtx] (unsigned _)
- {
- hb_codepoint_t old_gid;
- if (c->plan->old_gid_for_new_gid (_, &old_gid))
- return hb_pair (_mtx.get_advance (old_gid), _mtx.get_side_bearing (old_gid));
- else
- return hb_pair (0u, 0u);
- })
+ {
+ hb_codepoint_t old_gid;
+ if (!c->plan->old_gid_for_new_gid (_, &old_gid))
+ return hb_pair (0u, 0);
+ return hb_pair (_mtx.get_advance (old_gid), _mtx.get_side_bearing (old_gid));
+ })
;
table_prime->serialize (c->serializer, it, num_advances);
@@ -146,9 +153,7 @@ struct hmtxvmtx
// Amend header num hmetrics
if (unlikely (!subset_update_header (c->plan, num_advances)))
- {
return_trace (false);
- }
return_trace (true);
}
@@ -190,8 +195,7 @@ struct hmtxvmtx
var_table.destroy ();
}
- /* TODO Add variations version. */
- unsigned int get_side_bearing (hb_codepoint_t glyph) const
+ int get_side_bearing (hb_codepoint_t glyph) const
{
if (glyph < num_advances)
return table->longMetricZ[glyph].sb;
@@ -203,6 +207,23 @@ struct hmtxvmtx
return bearings[glyph - num_advances];
}
+ int get_side_bearing (hb_font_t *font, hb_codepoint_t glyph) const
+ {
+ int side_bearing = get_side_bearing (glyph);
+
+#ifndef HB_NO_VAR
+ if (unlikely (glyph >= num_metrics) || !font->num_coords)
+ return side_bearing;
+
+ if (var_table.get_length ())
+ return side_bearing + var_table->get_side_bearing_var (glyph, font->coords, font->num_coords); // TODO Optimize?!
+
+ return _glyf_get_side_bearing_var (font, glyph, T::tableTag == HB_OT_TAG_vmtx);
+#else
+ return side_bearing;
+#endif
+ }
+
unsigned int get_advance (hb_codepoint_t glyph) const
{
if (unlikely (glyph >= num_metrics))
@@ -223,11 +244,18 @@ struct hmtxvmtx
hb_font_t *font) const
{
unsigned int advance = get_advance (glyph);
- if (likely (glyph < num_metrics))
- {
- advance += (font->num_coords ? var_table->get_advance_var (glyph, font->coords, font->num_coords) : 0); // TODO Optimize?!
- }
+
+#ifndef HB_NO_VAR
+ if (unlikely (glyph >= num_metrics) || !font->num_coords)
+ return advance;
+
+ if (var_table.get_length ())
+ return advance + roundf (var_table->get_advance_var (font, glyph)); // TODO Optimize?!
+
+ return _glyf_get_advance_var (font, glyph, T::tableTag == HB_OT_TAG_vmtx);
+#else
return advance;
+#endif
}
unsigned int num_advances_for_subset (const hb_subset_plan_t *plan) const
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh
index 7dfb207b2dc..36e5a358e6a 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh
@@ -167,8 +167,8 @@ struct KernOTSubTableHeader
static constexpr bool apple = false;
typedef AAT::ObsoleteTypes Types;
- unsigned int tuple_count () const { return 0; }
- bool is_horizontal () const { return (coverage & Horizontal); }
+ unsigned tuple_count () const { return 0; }
+ bool is_horizontal () const { return (coverage & Horizontal); }
enum Coverage
{
@@ -222,8 +222,8 @@ struct KernAATSubTableHeader
static constexpr bool apple = true;
typedef AAT::ObsoleteTypes Types;
- unsigned int tuple_count () const { return 0; }
- bool is_horizontal () const { return !(coverage & Vertical); }
+ unsigned tuple_count () const { return 0; }
+ bool is_horizontal () const { return !(coverage & Vertical); }
enum Coverage
{
@@ -275,8 +275,8 @@ struct kern
{
static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
- bool has_data () const { return u.version32; }
- unsigned int get_type () const { return u.major; }
+ bool has_data () const { return u.version32; }
+ unsigned get_type () const { return u.major; }
bool has_state_machine () const
{
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh
index 73c28caabd5..fa08140f565 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh
@@ -33,6 +33,7 @@
#include "hb-ot-layout.hh"
#include "hb-open-type.hh"
#include "hb-set.hh"
+#include "hb-bimap.hh"
#ifndef HB_MAX_NESTING_LEVEL
@@ -66,6 +67,76 @@ namespace OT {
#define NOT_COVERED ((unsigned int) -1)
+template<typename Iterator>
+static inline void Coverage_serialize (hb_serialize_context_t *c,
+ Iterator it);
+
+template<typename Iterator>
+static inline void ClassDef_serialize (hb_serialize_context_t *c,
+ Iterator it);
+
+static void ClassDef_remap_and_serialize (hb_serialize_context_t *c,
+ const hb_set_t &glyphset,
+ const hb_map_t &gid_klass_map,
+ hb_sorted_vector_t<HBGlyphID> glyphs,
+ hb_sorted_vector_t<unsigned> klasses,
+ hb_map_t *klass_map /*INOUT*/);
+
+
+template<typename OutputArray>
+struct subset_offset_array_t
+{
+ subset_offset_array_t
+ (hb_subset_context_t *subset_context,
+ OutputArray& out,
+ const void *src_base,
+ const void *dest_base)
+ : _subset_context(subset_context), _out (out), _src_base (src_base), _dest_base (dest_base) {}
+
+ template <typename T>
+ bool
+ operator ()
+ (T&& offset)
+ {
+ auto *o = _out.serialize_append (_subset_context->serializer);
+ if (unlikely (!o)) return false;
+ auto snap = _subset_context->serializer->snapshot ();
+ bool ret = o->serialize_subset (_subset_context, offset, _src_base, _dest_base);
+ if (!ret)
+ {
+ _out.pop ();
+ _subset_context->serializer->revert (snap);
+ }
+ return ret;
+ }
+
+ private:
+ hb_subset_context_t *_subset_context;
+ OutputArray &_out;
+ const void *_src_base;
+ const void *_dest_base;
+};
+
+/*
+ * Helper to subset an array of offsets. Subsets the thing pointed to by each offset
+ * and discards the offset in the array if the subset operation results in an empty
+ * thing.
+ */
+struct
+{
+ template<typename OutputArray>
+ subset_offset_array_t<OutputArray>
+ operator ()
+ (hb_subset_context_t *subset_context,
+ OutputArray& out,
+ const void *src_base,
+ const void *dest_base) const
+ {
+ return subset_offset_array_t<OutputArray> (subset_context, out, src_base, dest_base);
+ }
+}
+HB_FUNCOBJ (subset_offset_array);
+
/*
*
* OpenType Layout Common Table Formats
@@ -82,6 +153,26 @@ struct Record_sanitize_closure_t {
const void *list_base;
};
+struct RecordList_subset_context_t {
+
+ RecordList_subset_context_t() : script_count (0), langsys_count (0)
+ {}
+
+ bool visitScript ()
+ {
+ return script_count++ < HB_MAX_SCRIPTS;
+ }
+
+ bool visitLangSys ()
+ {
+ return langsys_count++ < HB_MAX_LANGSYS;
+ }
+
+ private:
+ unsigned int script_count;
+ unsigned int langsys_count;
+};
+
template <typename Type>
struct Record
{
@@ -138,11 +229,26 @@ struct RecordListOf : RecordArrayOf<Type>
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
- auto *out = c->serializer->embed (*this);
- if (unlikely (!out)) return_trace (false);
+ auto *out = c->serializer->start_embed (*this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+ RecordList_subset_context_t record_list_context;
+
unsigned int count = this->len;
for (unsigned int i = 0; i < count; i++)
- out->get_offset (i).serialize_subset (c, this->get_offset (i), this, out);
+ {
+ auto *record = out->serialize_append (c->serializer);
+ if (unlikely (!record)) return false;
+ auto snap = c->serializer->snapshot ();
+ if (record->offset.serialize_subset (c, this->get_offset (i), this, out, &record_list_context))
+ {
+ record->tag = this->get_tag(i);
+ continue;
+ }
+ out->pop ();
+ c->serializer->revert (snap);
+ }
+
return_trace (true);
}
@@ -207,7 +313,6 @@ struct Script;
struct LangSys;
struct Feature;
-
struct LangSys
{
unsigned int get_feature_count () const
@@ -274,15 +379,33 @@ struct Script
bool has_default_lang_sys () const { return defaultLangSys != 0; }
const LangSys& get_default_lang_sys () const { return this+defaultLangSys; }
- bool subset (hb_subset_context_t *c) const
+ bool subset (hb_subset_context_t *c, RecordList_subset_context_t *record_list_context) const
{
TRACE_SUBSET (this);
- auto *out = c->serializer->embed (*this);
- if (unlikely (!out)) return_trace (false);
+ if (!record_list_context->visitScript ()) return_trace (false);
+
+ auto *out = c->serializer->start_embed (*this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
out->defaultLangSys.serialize_copy (c->serializer, defaultLangSys, this, out);
- unsigned int count = langSys.len;
- for (unsigned int i = 0; i < count; i++)
- out->langSys.arrayZ[i].offset.serialize_copy (c->serializer, langSys[i].offset, this, out);
+
+ for (const auto &src: langSys)
+ {
+ if (!record_list_context->visitLangSys ()) {
+ continue;
+ }
+
+ auto snap = c->serializer->snapshot ();
+ auto *lang_sys = c->serializer->embed (src);
+
+ if (likely(lang_sys)
+ && lang_sys->offset.serialize_copy (c->serializer, src.offset, this, out))
+ {
+ out->langSys.len++;
+ continue;
+ }
+ c->serializer->revert (snap);
+ }
return_trace (true);
}
@@ -559,7 +682,7 @@ struct Feature
const FeatureParams &get_feature_params () const
{ return this+featureParams; }
- bool subset (hb_subset_context_t *c) const
+ bool subset (hb_subset_context_t *c, RecordList_subset_context_t *r) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (*this);
@@ -1072,6 +1195,23 @@ struct Coverage
}
}
+ bool subset (hb_subset_context_t *c) const
+ {
+ TRACE_SUBSET (this);
+ const hb_set_t &glyphset = *c->plan->glyphset ();
+ const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+ auto it =
+ + iter ()
+ | hb_filter (glyphset)
+ | hb_map_retains_sorting (glyph_map)
+ ;
+
+ bool ret = bool (it);
+ Coverage_serialize (c->serializer, it);
+ return_trace (ret);
+ }
+
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -1190,15 +1330,51 @@ struct Coverage
DEFINE_SIZE_UNION (2, format);
};
+template<typename Iterator>
+static inline void
+Coverage_serialize (hb_serialize_context_t *c,
+ Iterator it)
+{ c->start_embed<Coverage> ()->serialize (c, it); }
+
+static void ClassDef_remap_and_serialize (hb_serialize_context_t *c,
+ const hb_set_t &glyphset,
+ const hb_map_t &gid_klass_map,
+ hb_sorted_vector_t<HBGlyphID> glyphs,
+ hb_sorted_vector_t<unsigned> klasses,
+ hb_map_t *klass_map /*INOUT*/)
+{
+ bool has_no_match = glyphset.get_population () > gid_klass_map.get_population ();
+
+ hb_map_t m;
+ if (!klass_map) klass_map = &m;
+
+ if (has_no_match) klass_map->set (0, 0);
+ unsigned idx = klass_map->has (0) ? 1 : 0;
+ for (const unsigned k: klasses.iter ())
+ {
+ if (klass_map->has (k)) continue;
+ klass_map->set (k, idx);
+ idx++;
+ }
+
+ auto it =
+ + glyphs.iter ()
+ | hb_map_retains_sorting ([&] (const HBGlyphID& gid) -> hb_pair_t<hb_codepoint_t, HBUINT16>
+ {
+ HBUINT16 new_klass;
+ new_klass = klass_map->get (gid_klass_map[gid]);
+ return hb_pair ((hb_codepoint_t)gid, new_klass);
+ })
+ ;
+
+ c->propagate_error (glyphs, klasses);
+ ClassDef_serialize (c, it);
+}
/*
* Class Definition Table
*/
-static inline void ClassDef_serialize (hb_serialize_context_t *c,
- hb_array_t<const HBGlyphID> glyphs,
- hb_array_t<const HBUINT16> klasses);
-
struct ClassDefFormat1
{
friend struct ClassDef;
@@ -1209,53 +1385,53 @@ struct ClassDefFormat1
return classValue[(unsigned int) (glyph_id - startGlyph)];
}
+ template<typename Iterator,
+ hb_requires (hb_is_iterator (Iterator))>
bool serialize (hb_serialize_context_t *c,
- hb_array_t<const HBGlyphID> glyphs,
- hb_array_t<const HBUINT16> klasses)
+ Iterator it)
{
TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (*this))) return_trace (false);
- if (unlikely (!glyphs))
+ if (unlikely (!it))
{
startGlyph = 0;
classValue.len = 0;
return_trace (true);
}
- hb_codepoint_t glyph_min = +glyphs | hb_reduce (hb_min, 0xFFFFu);
- hb_codepoint_t glyph_max = +glyphs | hb_reduce (hb_max, 0u);
-
- startGlyph = glyph_min;
- c->check_assign (classValue.len, glyph_max - glyph_min + 1);
- if (unlikely (!c->extend (classValue))) return_trace (false);
-
- for (unsigned int i = 0; i < glyphs.length; i++)
- classValue[glyphs[i] - glyph_min] = klasses[i];
-
+ startGlyph = (*it).first;
+ classValue.serialize (c, + it
+ | hb_map (hb_second));
return_trace (true);
}
- bool subset (hb_subset_context_t *c) const
+ bool subset (hb_subset_context_t *c,
+ hb_map_t *klass_map = nullptr /*OUT*/) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
+
hb_sorted_vector_t<HBGlyphID> glyphs;
- hb_vector_t<HBUINT16> klasses;
+ hb_sorted_vector_t<unsigned> orig_klasses;
+ hb_map_t gid_org_klass_map;
hb_codepoint_t start = startGlyph;
hb_codepoint_t end = start + classValue.len;
- for (hb_codepoint_t g = start; g < end; g++)
+ for (const hb_codepoint_t gid : + hb_range (start, end)
+ | hb_filter (glyphset))
{
- if (!glyphset.has (g)) continue;
- unsigned int value = classValue[g - start];
- if (!value) continue;
- glyphs.push(glyph_map[g]);
- klasses.push(value);
+ unsigned klass = classValue[gid - start];
+ if (!klass) continue;
+
+ glyphs.push (glyph_map[gid]);
+ gid_org_klass_map.set (glyph_map[gid], klass);
+ orig_klasses.push (klass);
}
- c->serializer->propagate_error (glyphs, klasses);
- ClassDef_serialize (c->serializer, glyphs, klasses);
+
+ ClassDef_remap_and_serialize (c->serializer, glyphset, gid_org_klass_map,
+ glyphs, orig_klasses, klass_map);
return_trace ((bool) glyphs);
}
@@ -1345,70 +1521,89 @@ struct ClassDefFormat2
return rangeRecord.bsearch (glyph_id).value;
}
+ template<typename Iterator,
+ hb_requires (hb_is_iterator (Iterator))>
bool serialize (hb_serialize_context_t *c,
- hb_array_t<const HBGlyphID> glyphs,
- hb_array_t<const HBUINT16> klasses)
+ Iterator it)
{
TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (*this))) return_trace (false);
- if (unlikely (!glyphs))
+ if (unlikely (!it))
{
rangeRecord.len = 0;
return_trace (true);
}
- unsigned int count = glyphs.len ();
- unsigned int num_ranges = 1;
- for (unsigned int i = 1; i < count; i++)
- if (glyphs[i - 1] + 1 != glyphs[i] ||
- klasses[i - 1] != klasses[i])
- num_ranges++;
- rangeRecord.len = num_ranges;
- if (unlikely (!c->extend (rangeRecord))) return_trace (false);
+ unsigned num_ranges = 1;
+ hb_codepoint_t prev_gid = (*it).first;
+ unsigned prev_klass = (*it).second;
- unsigned int range = 0;
- rangeRecord[range].start = glyphs[0];
- rangeRecord[range].value = klasses[0];
- for (unsigned int i = 1; i < count; i++)
+ RangeRecord range_rec;
+ range_rec.start = prev_gid;
+ range_rec.end = prev_gid;
+ range_rec.value = prev_klass;
+
+ RangeRecord *record = c->copy (range_rec);
+ if (unlikely (!record)) return_trace (false);
+
+ for (const auto gid_klass_pair : + (++it))
{
- if (glyphs[i - 1] + 1 != glyphs[i] ||
- klasses[i - 1] != klasses[i])
+ hb_codepoint_t cur_gid = gid_klass_pair.first;
+ unsigned cur_klass = gid_klass_pair.second;
+
+ if (cur_gid != prev_gid + 1 ||
+ cur_klass != prev_klass)
{
- rangeRecord[range].end = glyphs[i - 1];
- range++;
- rangeRecord[range].start = glyphs[i];
- rangeRecord[range].value = klasses[i];
+ if (unlikely (!record)) break;
+ record->end = prev_gid;
+ num_ranges++;
+
+ range_rec.start = cur_gid;
+ range_rec.end = cur_gid;
+ range_rec.value = cur_klass;
+
+ record = c->copy (range_rec);
}
+
+ prev_klass = cur_klass;
+ prev_gid = cur_gid;
}
- rangeRecord[range].end = glyphs[count - 1];
+
+ if (likely (record)) record->end = prev_gid;
+ rangeRecord.len = num_ranges;
return_trace (true);
}
- bool subset (hb_subset_context_t *c) const
+ bool subset (hb_subset_context_t *c,
+ hb_map_t *klass_map = nullptr /*OUT*/) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
- hb_vector_t<HBGlyphID> glyphs;
- hb_vector_t<HBUINT16> klasses;
- unsigned int count = rangeRecord.len;
- for (unsigned int i = 0; i < count; i++)
+ hb_sorted_vector_t<HBGlyphID> glyphs;
+ hb_sorted_vector_t<unsigned> orig_klasses;
+ hb_map_t gid_org_klass_map;
+
+ unsigned count = rangeRecord.len;
+ for (unsigned i = 0; i < count; i++)
{
- unsigned int value = rangeRecord[i].value;
- if (!value) continue;
+ unsigned klass = rangeRecord[i].value;
+ if (!klass) continue;
hb_codepoint_t start = rangeRecord[i].start;
hb_codepoint_t end = rangeRecord[i].end + 1;
for (hb_codepoint_t g = start; g < end; g++)
{
if (!glyphset.has (g)) continue;
glyphs.push (glyph_map[g]);
- klasses.push (value);
+ gid_org_klass_map.set (glyph_map[g], klass);
+ orig_klasses.push (klass);
}
}
- c->serializer->propagate_error (glyphs, klasses);
- ClassDef_serialize (c->serializer, glyphs, klasses);
+
+ ClassDef_remap_and_serialize (c->serializer, glyphset, gid_org_klass_map,
+ glyphs, orig_klasses, klass_map);
return_trace ((bool) glyphs);
}
@@ -1505,25 +1700,36 @@ struct ClassDef
}
}
- bool serialize (hb_serialize_context_t *c,
- hb_array_t<const HBGlyphID> glyphs,
- hb_array_t<const HBUINT16> klasses)
+ template<typename Iterator,
+ hb_requires (hb_is_iterator (Iterator))>
+ bool serialize (hb_serialize_context_t *c, Iterator it)
{
TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (*this))) return_trace (false);
- unsigned int format = 2;
- if (likely (glyphs))
+ unsigned format = 2;
+ if (likely (it))
{
- hb_codepoint_t glyph_min = +glyphs | hb_reduce (hb_min, 0xFFFFu);
- hb_codepoint_t glyph_max = +glyphs | hb_reduce (hb_max, 0u);
+ hb_codepoint_t glyph_min = (*it).first;
+ hb_codepoint_t glyph_max = + it
+ | hb_map (hb_first)
+ | hb_reduce (hb_max, 0u);
- unsigned int count = glyphs.len ();
- unsigned int num_ranges = 1;
- for (unsigned int i = 1; i < count; i++)
- if (glyphs[i - 1] + 1 != glyphs[i] ||
- klasses[i - 1] != klasses[i])
- num_ranges++;
+ unsigned num_ranges = 1;
+ hb_codepoint_t prev_gid = glyph_min;
+ unsigned prev_klass = (*it).second;
+
+ for (const auto gid_klass_pair : it)
+ {
+ hb_codepoint_t cur_gid = gid_klass_pair.first;
+ unsigned cur_klass = gid_klass_pair.second;
+ if (cur_gid != prev_gid + 1 ||
+ cur_klass != prev_klass)
+ num_ranges++;
+
+ prev_gid = cur_gid;
+ prev_klass = cur_klass;
+ }
if (1 + (glyph_max - glyph_min + 1) < num_ranges * 3)
format = 1;
@@ -1532,18 +1738,19 @@ struct ClassDef
switch (u.format)
{
- case 1: return_trace (u.format1.serialize (c, glyphs, klasses));
- case 2: return_trace (u.format2.serialize (c, glyphs, klasses));
+ case 1: return_trace (u.format1.serialize (c, it));
+ case 2: return_trace (u.format2.serialize (c, it));
default:return_trace (false);
}
}
- bool subset (hb_subset_context_t *c) const
+ bool subset (hb_subset_context_t *c,
+ hb_map_t *klass_map = nullptr /*OUT*/) const
{
TRACE_SUBSET (this);
switch (u.format) {
- case 1: return_trace (u.format1.subset (c));
- case 2: return_trace (u.format2.subset (c));
+ case 1: return_trace (u.format1.subset (c, klass_map));
+ case 2: return_trace (u.format2.subset (c, klass_map));
default:return_trace (false);
}
}
@@ -1610,10 +1817,10 @@ struct ClassDef
DEFINE_SIZE_UNION (2, format);
};
+template<typename Iterator>
static inline void ClassDef_serialize (hb_serialize_context_t *c,
- hb_array_t<const HBGlyphID> glyphs,
- hb_array_t<const HBUINT16> klasses)
-{ c->start_embed<ClassDef> ()->serialize (c, glyphs, klasses); }
+ Iterator it)
+{ c->start_embed<ClassDef> ()->serialize (c, it); }
/*
@@ -1691,6 +1898,21 @@ struct VarRegionList
axesZ.sanitize (c, (unsigned int) axisCount * (unsigned int) regionCount));
}
+ bool serialize (hb_serialize_context_t *c, const VarRegionList *src, const hb_bimap_t &region_map)
+ {
+ TRACE_SERIALIZE (this);
+ VarRegionList *out = c->allocate_min<VarRegionList> ();
+ if (unlikely (!out)) return_trace (false);
+ axisCount = src->axisCount;
+ regionCount = region_map.get_population ();
+ if (unlikely (!c->allocate_size<VarRegionList> (get_size () - min_size))) return_trace (false);
+ for (unsigned int r = 0; r < regionCount; r++)
+ memcpy (&axesZ[axisCount * r], &src->axesZ[axisCount * region_map.backward (r)], VarRegionAxis::static_size * axisCount);
+
+ return_trace (true);
+ }
+
+ unsigned int get_size () const { return min_size + VarRegionAxis::static_size * axisCount * regionCount; }
unsigned int get_region_count () const { return regionCount; }
protected:
@@ -1723,7 +1945,7 @@ struct VarData
unsigned int count = regionIndices.len;
unsigned int scount = shortCount;
- const HBUINT8 *bytes = &StructAfter<HBUINT8> (regionIndices);
+ const HBUINT8 *bytes = get_delta_bytes ();
const HBUINT8 *row = bytes + inner * (scount + count);
float delta = 0.;
@@ -1763,11 +1985,117 @@ struct VarData
return_trace (c->check_struct (this) &&
regionIndices.sanitize (c) &&
shortCount <= regionIndices.len &&
- c->check_range (&StructAfter<HBUINT8> (regionIndices),
+ c->check_range (get_delta_bytes (),
itemCount,
get_row_size ()));
}
+ bool serialize (hb_serialize_context_t *c,
+ const VarData *src,
+ const hb_inc_bimap_t &inner_map,
+ const hb_bimap_t &region_map)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return_trace (false);
+ itemCount = inner_map.get_next_value ();
+
+ /* Optimize short count */
+ unsigned short ri_count = src->regionIndices.len;
+ enum delta_size_t { kZero=0, kByte, kShort };
+ hb_vector_t<delta_size_t> delta_sz;
+ hb_vector_t<unsigned int> ri_map; /* maps old index to new index */
+ delta_sz.resize (ri_count);
+ ri_map.resize (ri_count);
+ unsigned int new_short_count = 0;
+ unsigned int r;
+ for (r = 0; r < ri_count; r++)
+ {
+ delta_sz[r] = kZero;
+ for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
+ {
+ unsigned int old = inner_map.backward (i);
+ int16_t delta = src->get_item_delta (old, r);
+ if (delta < -128 || 127 < delta)
+ {
+ delta_sz[r] = kShort;
+ new_short_count++;
+ break;
+ }
+ else if (delta != 0)
+ delta_sz[r] = kByte;
+ }
+ }
+ unsigned int short_index = 0;
+ unsigned int byte_index = new_short_count;
+ unsigned int new_ri_count = 0;
+ for (r = 0; r < ri_count; r++)
+ if (delta_sz[r])
+ {
+ ri_map[r] = (delta_sz[r] == kShort)? short_index++ : byte_index++;
+ new_ri_count++;
+ }
+
+ shortCount = new_short_count;
+ regionIndices.len = new_ri_count;
+
+ unsigned int size = regionIndices.get_size () - HBUINT16::static_size/*regionIndices.len*/ + (get_row_size () * itemCount);
+ if (unlikely (!c->allocate_size<HBUINT8> (size)))
+ return_trace (false);
+
+ for (r = 0; r < ri_count; r++)
+ if (delta_sz[r]) regionIndices[ri_map[r]] = region_map[src->regionIndices[r]];
+
+ for (unsigned int i = 0; i < itemCount; i++)
+ {
+ unsigned int old = inner_map.backward (i);
+ for (unsigned int r = 0; r < ri_count; r++)
+ if (delta_sz[r]) set_item_delta (i, ri_map[r], src->get_item_delta (old, r));
+ }
+
+ return_trace (true);
+ }
+
+ void collect_region_refs (hb_inc_bimap_t &region_map, const hb_inc_bimap_t &inner_map) const
+ {
+ for (unsigned int r = 0; r < regionIndices.len; r++)
+ {
+ unsigned int region = regionIndices[r];
+ if (region_map.has (region)) continue;
+ for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
+ if (get_item_delta (inner_map.backward (i), r) != 0)
+ {
+ region_map.add (region);
+ break;
+ }
+ }
+ }
+
+ protected:
+ const HBUINT8 *get_delta_bytes () const
+ { return &StructAfter<HBUINT8> (regionIndices); }
+
+ HBUINT8 *get_delta_bytes ()
+ { return &StructAfter<HBUINT8> (regionIndices); }
+
+ int16_t get_item_delta (unsigned int item, unsigned int region) const
+ {
+ if ( item >= itemCount || unlikely (region >= regionIndices.len)) return 0;
+ const HBINT8 *p = (const HBINT8 *)get_delta_bytes () + item * get_row_size ();
+ if (region < shortCount)
+ return ((const HBINT16 *)p)[region];
+ else
+ return (p + HBINT16::static_size * shortCount)[region - shortCount];
+ }
+
+ void set_item_delta (unsigned int item, unsigned int region, int16_t delta)
+ {
+ HBINT8 *p = (HBINT8 *)get_delta_bytes () + item * get_row_size ();
+ if (region < shortCount)
+ ((HBINT16 *)p)[region] = delta;
+ else
+ (p + HBINT16::static_size * shortCount)[region - shortCount] = delta;
+ }
+
protected:
HBUINT16 itemCount;
HBUINT16 shortCount;
@@ -1815,6 +2143,43 @@ struct VariationStore
dataSets.sanitize (c, this));
}
+ bool serialize (hb_serialize_context_t *c,
+ const VariationStore *src,
+ const hb_array_t <hb_inc_bimap_t> &inner_maps)
+ {
+ TRACE_SERIALIZE (this);
+ unsigned int set_count = 0;
+ for (unsigned int i = 0; i < inner_maps.length; i++)
+ if (inner_maps[i].get_population () > 0) set_count++;
+
+ unsigned int size = min_size + HBUINT32::static_size * set_count;
+ if (unlikely (!c->allocate_size<HBUINT32> (size))) return_trace (false);
+ format = 1;
+
+ hb_inc_bimap_t region_map;
+ for (unsigned int i = 0; i < inner_maps.length; i++)
+ (src+src->dataSets[i]).collect_region_refs (region_map, inner_maps[i]);
+ region_map.sort ();
+
+ if (unlikely (!regions.serialize (c, this)
+ .serialize (c, &(src+src->regions), region_map))) return_trace (false);
+
+ /* TODO: The following code could be simplified when
+ * OffsetListOf::subset () can take a custom param to be passed to VarData::serialize ()
+ */
+ dataSets.len = set_count;
+ unsigned int set_index = 0;
+ for (unsigned int i = 0; i < inner_maps.length; i++)
+ {
+ if (inner_maps[i].get_population () == 0) continue;
+ if (unlikely (!dataSets[set_index++].serialize (c, this)
+ .serialize (c, &(src+src->dataSets[i]), inner_maps[i], region_map)))
+ return_trace (false);
+ }
+
+ return_trace (true);
+ }
+
unsigned int get_region_index_count (unsigned int ivs) const
{ return (this+dataSets[ivs]).get_region_index_count (); }
@@ -1833,6 +2198,8 @@ struct VariationStore
&scalars[0], num_scalars);
}
+ unsigned int get_sub_table_count () const { return dataSets.len; }
+
protected:
HBUINT16 format;
LOffsetTo<VarRegionList> regions;
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 73107f490b5..024312d610c 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
@@ -101,10 +101,10 @@ struct ValueFormat : HBUINT16
unsigned int get_len () const { return hb_popcount ((unsigned int) *this); }
unsigned int get_size () const { return get_len () * Value::static_size; }
- bool apply_value (hb_ot_apply_context_t *c,
- const void *base,
- const Value *values,
- hb_glyph_position_t &glyph_pos) const
+ bool apply_value (hb_ot_apply_context_t *c,
+ const void *base,
+ const Value *values,
+ hb_glyph_position_t &glyph_pos) const
{
bool ret = false;
unsigned int format = *this;
@@ -257,7 +257,7 @@ struct AnchorFormat1
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
-
+
AnchorFormat1* copy (hb_serialize_context_t *c) const
{
TRACE_SERIALIZE (this);
@@ -558,7 +558,7 @@ struct SinglePosFormat1
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+ const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
auto it =
@@ -647,7 +647,7 @@ struct SinglePosFormat2
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+ const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
unsigned sub_length = valueFormat.get_len ();
@@ -761,6 +761,18 @@ struct PairValueRecord
{
friend struct PairSet;
+ bool serialize (hb_serialize_context_t *c,
+ unsigned length,
+ const hb_map_t &glyph_map) const
+ {
+ TRACE_SERIALIZE (this);
+ auto *out = c->start_embed (*this);
+ if (unlikely (!c->extend_min (out))) return_trace (false);
+
+ out->secondGlyph = glyph_map[secondGlyph];
+ return_trace (c->copy (values, length));
+ }
+
protected:
HBGlyphID secondGlyph; /* GlyphID of second glyph in the
* pair--first glyph is listed in the
@@ -846,6 +858,37 @@ struct PairSet
return_trace (false);
}
+ bool subset (hb_subset_context_t *c,
+ const ValueFormat valueFormats[2]) const
+ {
+ TRACE_SUBSET (this);
+ auto snap = c->serializer->snapshot ();
+
+ auto *out = c->serializer->start_embed (*this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+ out->len = 0;
+
+ const hb_set_t &glyphset = *c->plan->glyphset ();
+ const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+ unsigned len1 = valueFormats[0].get_len ();
+ unsigned len2 = valueFormats[1].get_len ();
+ unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2);
+
+ const PairValueRecord *record = &firstPairValueRecord;
+ unsigned count = len, num = 0;
+ for (unsigned i = 0; i < count; i++)
+ {
+ if (!glyphset.has (record->secondGlyph)) continue;
+ if (record->serialize (c->serializer, len1 + len2, glyph_map)) num++;
+ record = &StructAtOffset<const PairValueRecord> (record, record_size);
+ }
+
+ out->len = num;
+ if (!num) c->serializer->revert (snap);
+ return_trace (num);
+ }
+
struct sanitize_closure_t
{
const void *base;
@@ -919,8 +962,43 @@ struct PairPosFormat1
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
- // TODO(subset)
- return_trace (false);
+
+ const hb_set_t &glyphset = *c->plan->glyphset ();
+ const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+ auto *out = c->serializer->start_embed (*this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+ out->format = format;
+ out->valueFormat[0] = valueFormat[0];
+ out->valueFormat[1] = valueFormat[1];
+
+ hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+
+ + hb_zip (this+coverage, pairSet)
+ | hb_filter (glyphset, hb_first)
+ | hb_filter ([this, c, out] (const OffsetTo<PairSet>& _)
+ {
+ auto *o = out->pairSet.serialize_append (c->serializer);
+ if (unlikely (!o)) return false;
+ auto snap = c->serializer->snapshot ();
+ bool ret = o->serialize_subset (c, _, this, out, valueFormat);
+ if (!ret)
+ {
+ out->pairSet.pop ();
+ c->serializer->revert (snap);
+ }
+ return ret;
+ },
+ hb_second)
+ | hb_map (hb_first)
+ | hb_map (glyph_map)
+ | hb_sink (new_coverage)
+ ;
+
+ out->coverage.serialize (c->serializer, out)
+ .serialize (c->serializer, new_coverage.iter ());
+
+ return_trace (bool (new_coverage));
}
bool sanitize (hb_sanitize_context_t *c) const
@@ -1011,8 +1089,49 @@ struct PairPosFormat2
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
- // TODO(subset)
- return_trace (false);
+ auto *out = c->serializer->start_embed (*this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+ out->format = format;
+ out->valueFormat1 = valueFormat1;
+ out->valueFormat2 = valueFormat2;
+
+ hb_map_t klass1_map;
+ out->classDef1.serialize_subset (c, classDef1, this, out, &klass1_map);
+ out->class1Count = klass1_map.get_population ();
+
+ hb_map_t klass2_map;
+ out->classDef2.serialize_subset (c, classDef2, this, out, &klass2_map);
+ out->class2Count = klass2_map.get_population ();
+
+ unsigned record_len = valueFormat1.get_len () + valueFormat2.get_len ();
+
+ + hb_range ((unsigned) class1Count)
+ | hb_filter (klass1_map)
+ | hb_apply ([&] (const unsigned class1_idx)
+ {
+ + hb_range ((unsigned) class2Count)
+ | hb_filter (klass2_map)
+ | hb_apply ([&] (const unsigned class2_idx)
+ {
+ unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * record_len;
+ for (unsigned i = 0; i < record_len; i++)
+ c->serializer->copy (values[idx+i]);
+ })
+ ;
+ })
+ ;
+
+ const hb_set_t &glyphset = *c->plan->glyphset ();
+ const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+ auto it =
+ + hb_iter (this+coverage)
+ | hb_filter (glyphset)
+ | hb_map_retains_sorting (glyph_map)
+ ;
+
+ out->coverage.serialize (c->serializer, out).serialize (c->serializer, it);
+ return_trace (out->class1Count && out->class2Count && bool (it));
}
bool sanitize (hb_sanitize_context_t *c) const
@@ -1242,7 +1361,7 @@ struct CursivePosFormat1
hb_requires (hb_is_iterator (Iterator))>
void serialize (hb_serialize_context_t *c,
Iterator it,
- const void *src_base)
+ const void *src_base)
{
if (unlikely (!c->extend_min ((*this)))) return;
this->format = 1;
@@ -1273,7 +1392,7 @@ struct CursivePosFormat1
+ hb_zip (this+coverage, entryExitRecord)
| hb_filter (glyphset, hb_first)
| hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const EntryExitRecord&> p) -> hb_pair_t<hb_codepoint_t, const EntryExitRecord&>
- { return hb_pair (glyph_map[p.first], p.second);})
+ { return hb_pair (glyph_map[p.first], p.second);})
;
bool ret = bool (it);
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 a2722ade93d..fc21cb056e8 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
@@ -452,20 +452,7 @@ struct MultipleSubstFormat1
hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+ hb_zip (this+coverage, sequence)
| hb_filter (glyphset, hb_first)
- | hb_filter ([this, c, out] (const OffsetTo<Sequence>& _)
- {
- auto *o = out->sequence.serialize_append (c->serializer);
- if (unlikely (!o)) return false;
- auto snap = c->serializer->snapshot ();
- bool ret = o->serialize_subset (c, _, this, out);
- if (!ret)
- {
- out->sequence.pop ();
- c->serializer->revert (snap);
- }
- return ret;
- },
- hb_second)
+ | hb_filter (subset_offset_array (c, out->sequence, this, out), hb_second)
| hb_map (hb_first)
| hb_map (glyph_map)
| hb_sink (new_coverage)
@@ -675,20 +662,7 @@ struct AlternateSubstFormat1
hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+ hb_zip (this+coverage, alternateSet)
| hb_filter (glyphset, hb_first)
- | hb_filter ([this, c, out] (const OffsetTo<AlternateSet>& _)
- {
- auto *o = out->alternateSet.serialize_append (c->serializer);
- if (unlikely (!o)) return false;
- auto snap = c->serializer->snapshot ();
- bool ret = o->serialize_subset (c, _, this, out);
- if (!ret)
- {
- out->alternateSet.pop ();
- c->serializer->revert (snap);
- }
- return ret;
- },
- hb_second)
+ | hb_filter (subset_offset_array (c, out->alternateSet, this, out), hb_second)
| hb_map (hb_first)
| hb_map (glyph_map)
| hb_sink (new_coverage)
@@ -948,19 +922,7 @@ struct LigatureSet
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+ hb_iter (ligature)
- | hb_filter ([this, c, out] (const OffsetTo<Ligature>& _)
- {
- auto *o = out->ligature.serialize_append (c->serializer);
- if (unlikely (!o)) return false;
- auto snap = c->serializer->snapshot ();
- bool ret = o->serialize_subset (c, _, this, out);
- if (!ret)
- {
- out->ligature.pop ();
- c->serializer->revert (snap);
- }
- return ret;
- })
+ | hb_filter (subset_offset_array (c, out->ligature, this, out))
| hb_drain
;
return_trace (bool (out->ligature));
@@ -1074,20 +1036,7 @@ struct LigatureSubstFormat1
hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+ hb_zip (this+coverage, ligatureSet)
| hb_filter (glyphset, hb_first)
- | hb_filter ([this, c, out] (const OffsetTo<LigatureSet>& _)
- {
- auto *o = out->ligatureSet.serialize_append (c->serializer);
- if (unlikely (!o)) return false;
- auto snap = c->serializer->snapshot ();
- bool ret = o->serialize_subset (c, _, this, out);
- if (!ret)
- {
- out->ligatureSet.pop ();
- c->serializer->revert (snap);
- }
- return ret;
- },
- hb_second)
+ | hb_filter (subset_offset_array (c, out->ligatureSet, this, out), hb_second)
| hb_map (hb_first)
| hb_map (glyph_map)
| hb_sink (new_coverage)
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh
index c6e6ac9cb40..579d17871b8 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh
@@ -387,7 +387,7 @@ struct hb_ot_apply_context_t :
skip == matcher_t::SKIP_NO))
{
num_items--;
- match_glyph_data++;
+ if (match_glyph_data) match_glyph_data++;
return true;
}
@@ -414,7 +414,7 @@ struct hb_ot_apply_context_t :
skip == matcher_t::SKIP_NO))
{
num_items--;
- match_glyph_data++;
+ if (match_glyph_data) match_glyph_data++;
return true;
}
@@ -712,11 +712,9 @@ static inline bool intersects_array (const hb_set_t *glyphs,
intersects_func_t intersects_func,
const void *intersects_data)
{
- return
- + hb_iter (values, count)
- | hb_map ([&] (const HBUINT16 &_) { return intersects_func (glyphs, _, intersects_data); })
- | hb_any
- ;
+ for (const HBUINT16 &_ : + hb_iter (values, count))
+ if (intersects_func (glyphs, _, intersects_data)) return true;
+ return false;
}
@@ -2002,6 +2000,83 @@ struct ChainRule
lookup.arrayZ, lookup_context));
}
+ template<typename Iterator,
+ hb_requires (hb_is_iterator (Iterator))>
+ void serialize_array (hb_serialize_context_t *c,
+ HBUINT16 len,
+ Iterator it) const
+ {
+ c->copy (len);
+ for (const auto g : it)
+ {
+ HBUINT16 gid;
+ gid = g;
+ c->copy (gid);
+ }
+ }
+
+ ChainRule* copy (hb_serialize_context_t *c,
+ const hb_map_t *backtrack_map,
+ const hb_map_t *input_map = nullptr,
+ const hb_map_t *lookahead_map = nullptr) const
+ {
+ TRACE_SERIALIZE (this);
+ auto *out = c->start_embed (this);
+ if (unlikely (!out)) return_trace (nullptr);
+
+ const hb_map_t *mapping = backtrack_map;
+ serialize_array (c, backtrack.len, + backtrack.iter ()
+ | hb_map (mapping));
+
+ const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack);
+ if (input_map) mapping = input_map;
+ serialize_array (c, input.lenP1, + input.iter ()
+ | hb_map (mapping));
+
+ const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input);
+ if (lookahead_map) mapping = lookahead_map;
+ serialize_array (c, lookahead.len, + lookahead.iter ()
+ | hb_map (mapping));
+
+ const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
+ c->copy (lookup);
+
+ return_trace (out);
+ }
+
+ bool subset (hb_subset_context_t *c,
+ const hb_map_t *backtrack_map = nullptr,
+ const hb_map_t *input_map = nullptr,
+ const hb_map_t *lookahead_map = nullptr) const
+ {
+ TRACE_SUBSET (this);
+
+ const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack);
+ const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input);
+
+ if (!backtrack_map)
+ {
+ const hb_set_t &glyphset = *c->plan->glyphset ();
+ if (!hb_all (backtrack, glyphset) ||
+ !hb_all (input, glyphset) ||
+ !hb_all (lookahead, glyphset))
+ return_trace (false);
+
+ copy (c->serializer, c->plan->glyph_map);
+ }
+ else
+ {
+ if (!hb_all (backtrack, backtrack_map) ||
+ !hb_all (input, input_map) ||
+ !hb_all (lookahead, lookahead_map))
+ return_trace (false);
+
+ copy (c->serializer, backtrack_map, input_map, lookahead_map);
+ }
+
+ return_trace (true);
+ }
+
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -2083,6 +2158,40 @@ struct ChainRuleSet
;
}
+ bool subset (hb_subset_context_t *c,
+ const hb_map_t *backtrack_klass_map = nullptr,
+ const hb_map_t *input_klass_map = nullptr,
+ const hb_map_t *lookahead_klass_map = nullptr) const
+ {
+ TRACE_SUBSET (this);
+
+ auto snap = c->serializer->snapshot ();
+ auto *out = c->serializer->start_embed (*this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+ for (const OffsetTo<ChainRule>& _ : rule)
+ {
+ if (!_) continue;
+ auto *o = out->rule.serialize_append (c->serializer);
+ if (unlikely (!o)) continue;
+
+ auto o_snap = c->serializer->snapshot ();
+ if (!o->serialize_subset (c, _, this, out,
+ backtrack_klass_map,
+ input_klass_map,
+ lookahead_klass_map))
+ {
+ out->rule.pop ();
+ c->serializer->revert (o_snap);
+ }
+ }
+
+ bool ret = bool (out->rule);
+ if (!ret) c->serializer->revert (snap);
+
+ return_trace (ret);
+ }
+
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -2175,8 +2284,25 @@ struct ChainContextFormat1
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
- // TODO(subset)
- return_trace (false);
+ const hb_set_t &glyphset = *c->plan->glyphset ();
+ const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+ auto *out = c->serializer->start_embed (*this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+ out->format = format;
+
+ hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+ + hb_zip (this+coverage, ruleSet)
+ | hb_filter (glyphset, hb_first)
+ | hb_filter (subset_offset_array (c, out->ruleSet, this, out), hb_second)
+ | hb_map (hb_first)
+ | hb_map (glyph_map)
+ | hb_sink (new_coverage)
+ ;
+
+ out->coverage.serialize (c->serializer, out)
+ .serialize (c->serializer, new_coverage.iter ());
+ return_trace (bool (new_coverage));
}
bool sanitize (hb_sanitize_context_t *c) const
@@ -2314,8 +2440,54 @@ struct ChainContextFormat2
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
- // TODO(subset)
- return_trace (false);
+ auto *out = c->serializer->start_embed (*this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+ out->format = format;
+ out->coverage.serialize_subset (c, coverage, this, out);
+
+ hb_map_t backtrack_klass_map;
+ out->backtrackClassDef.serialize_subset (c, backtrackClassDef, this, out, &backtrack_klass_map);
+
+ // subset inputClassDef based on glyphs survived in Coverage subsetting
+ hb_map_t input_klass_map;
+ out->inputClassDef.serialize_subset (c, inputClassDef, this, out, &input_klass_map);
+
+ hb_map_t lookahead_klass_map;
+ out->lookaheadClassDef.serialize_subset (c, lookaheadClassDef, this, out, &lookahead_klass_map);
+
+ hb_vector_t<unsigned> rulesets;
+ bool ret = true;
+ for (const OffsetTo<ChainRuleSet>& _ : + hb_enumerate (ruleSet)
+ | hb_filter (input_klass_map, hb_first)
+ | hb_map (hb_second))
+ {
+ auto *o = out->ruleSet.serialize_append (c->serializer);
+ if (unlikely (!o))
+ {
+ ret = false;
+ break;
+ }
+ if (!o->serialize_subset (c, _, this, out,
+ &backtrack_klass_map,
+ &input_klass_map,
+ &lookahead_klass_map))
+ {
+ rulesets.push (0);
+ }
+ else rulesets.push (1);
+ }
+
+ if (!ret) return_trace (ret);
+
+ //prune empty trailing ruleSets
+ unsigned count = rulesets.length;
+ while (count > 0 && rulesets[count-1] == 0)
+ {
+ out->ruleSet.pop ();
+ count--;
+ }
+
+ return_trace (bool (out->ruleSet));
}
bool sanitize (hb_sanitize_context_t *c) const
@@ -2457,11 +2629,46 @@ struct ChainContextFormat3
lookup.len, lookup.arrayZ, lookup_context));
}
+ template<typename Iterator,
+ hb_requires (hb_is_iterator (Iterator))>
+ bool serialize_coverage_offsets (hb_subset_context_t *c,
+ Iterator it,
+ const void* src_base,
+ const void* dst_base) const
+ {
+ TRACE_SERIALIZE (this);
+ auto *out = c->serializer->start_embed<OffsetArrayOf<Coverage>> ();
+
+ if (unlikely (!c->serializer->allocate_size<HBUINT16> (HBUINT16::static_size))) return_trace (false);
+
+ + it
+ | hb_apply (subset_offset_array (c, *out, src_base, dst_base))
+ ;
+
+ return_trace (out->len);
+ }
+
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
- // TODO(subset)
- return_trace (false);
+
+ auto *out = c->serializer->start_embed (this);
+ if (unlikely (!out)) return_trace (false);
+ if (unlikely (!c->serializer->embed (this->format))) return_trace (false);
+
+ if (!serialize_coverage_offsets (c, backtrack.iter (), this, out))
+ return_trace (false);
+
+ const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
+ if (!serialize_coverage_offsets (c, input.iter (), this, out))
+ return_trace (false);
+
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input);
+ if (!serialize_coverage_offsets (c, lookahead.iter (), this, out))
+ return_trace (false);
+
+ const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
+ return_trace (c->serializer->copy (lookup));
}
bool sanitize (hb_sanitize_context_t *c) const
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc
index d40c67af9c0..e4bb4b63661 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc
@@ -38,7 +38,7 @@
void hb_ot_map_t::collect_lookups (unsigned int table_index, hb_set_t *lookups_out) const
{
for (unsigned int i = 0; i < lookups[table_index].length; i++)
- hb_set_add (lookups_out, lookups[table_index][i].index);
+ lookups_out->add (lookups[table_index][i].index);
}
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh
index 037fcae1e68..f6b150323b6 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh
@@ -134,8 +134,8 @@ struct OS2
OBLIQUE = 1u<<9
};
- bool is_italic () const { return fsSelection & ITALIC; }
- bool is_oblique () const { return fsSelection & OBLIQUE; }
+ bool is_italic () const { return fsSelection & ITALIC; }
+ bool is_oblique () const { return fsSelection & OBLIQUE; }
bool use_typo_metrics () const { return fsSelection & USE_TYPO_METRICS; }
enum width_class_t {
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh
index bb0141d1093..2a7a8ebbc02 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh
@@ -230,8 +230,8 @@ arabic_fallback_plan_init_win1256 (arabic_fallback_plan_t *fallback_plan HB_UNUS
return false;
const Manifest &manifest = reinterpret_cast<const Manifest&> (arabic_win1256_gsub_lookups.manifest);
- static_assert (sizeof (arabic_win1256_gsub_lookups.manifestData) / sizeof (ManifestLookup)
- <= ARABIC_FALLBACK_MAX_LOOKUPS, "");
+ static_assert (sizeof (arabic_win1256_gsub_lookups.manifestData) ==
+ ARABIC_FALLBACK_MAX_LOOKUPS * sizeof (ManifestLookup), "");
/* TODO sanitize the table? */
unsigned j = 0;
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 dad1dba4adf..fc3490d7168 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
@@ -116,8 +116,8 @@ enum myanmar_syllable_type_t {
static void
setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
- hb_buffer_t *buffer,
- hb_font_t *font HB_UNUSED)
+ hb_buffer_t *buffer,
+ hb_font_t *font HB_UNUSED)
{
HB_BUFFER_ALLOCATE_VAR (buffer, myanmar_category);
HB_BUFFER_ALLOCATE_VAR (buffer, myanmar_position);
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc
index 4c5d687c7b4..e3889b3e607 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc
@@ -347,7 +347,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1C00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1C10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
- /* 1C20 */ B, B, B, B, SUB, SUB, VPst, VPre, VPre, VPst, VPst, VPst, VBlw, FAbv, FAbv, FAbv,
+ /* 1C20 */ B, B, B, B, SUB, SUB, VPst, VPre, VPre, VPre, VPst, VPst, VBlw, FAbv, FAbv, FAbv,
/* 1C30 */ FAbv, FAbv, FAbv, FAbv, VMPre, VMPre, FMAbv, CMBlw, O, O, O, O, O, O, O, O,
/* 1C40 */ B, B, B, B, B, B, B, B, B, B, O, O, O, B, B, B,
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh
new file mode 100644
index 00000000000..666b3089521
--- /dev/null
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh
@@ -0,0 +1,734 @@
+/*
+ * Copyright © 2019 Adobe Inc.
+ * Copyright © 2019 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.
+ *
+ * Adobe Author(s): Michiharu Ariza
+ */
+
+#ifndef HB_OT_VAR_GVAR_TABLE_HH
+#define HB_OT_VAR_GVAR_TABLE_HH
+
+#include "hb-open-type.hh"
+#include "hb-ot-glyf-table.hh"
+#include "hb-ot-var-fvar-table.hh"
+
+/*
+ * gvar -- Glyph Variation Table
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/gvar
+ */
+#define HB_OT_TAG_gvar HB_TAG('g','v','a','r')
+
+namespace OT {
+
+struct contour_point_t
+{
+ void init (float x_=0.f, float y_=0.f) { flag = 0; x = x_; y = y_; }
+
+ void translate (const contour_point_t &p) { x += p.x; y += p.y; }
+
+ uint8_t flag;
+ float x, y;
+};
+
+struct contour_point_vector_t : hb_vector_t<contour_point_t>
+{
+ void extend (const hb_array_t<contour_point_t> &a)
+ {
+ unsigned int old_len = length;
+ resize (old_len + a.length);
+ for (unsigned int i = 0; i < a.length; i++)
+ (*this)[old_len + i] = a[i];
+ }
+
+ void transform (const float (&matrix)[4])
+ {
+ for (unsigned int i = 0; i < length; i++)
+ {
+ contour_point_t &p = (*this)[i];
+ float x_ = p.x * matrix[0] + p.y * matrix[2];
+ p.y = p.x * matrix[1] + p.y * matrix[3];
+ p.x = x_;
+ }
+ }
+
+ void translate (const contour_point_t& delta)
+ {
+ for (unsigned int i = 0; i < length; i++)
+ (*this)[i].translate (delta);
+ }
+};
+
+struct range_checker_t
+{
+ range_checker_t (const void *data_, unsigned int length_)
+ : data ((const char *) data_), length (length_) {}
+
+ template <typename T>
+ bool in_range (const T *p, unsigned int size = T::static_size) const
+ {
+ return ((const char *) p) >= data
+ && ((const char *) p + size) <= data + length;
+ }
+
+ protected:
+ const char *data;
+ const unsigned int length;
+};
+
+struct Tuple : UnsizedArrayOf<F2DOT14> {};
+
+struct TuppleIndex : HBUINT16
+{
+ enum Flags {
+ EmbeddedPeakTuple = 0x8000u,
+ IntermediateRegion = 0x4000u,
+ PrivatePointNumbers = 0x2000u,
+ TupleIndexMask = 0x0FFFu
+ };
+
+ DEFINE_SIZE_STATIC (2);
+};
+
+struct TupleVarHeader
+{
+ unsigned int get_size (unsigned int axis_count) const
+ {
+ return min_size +
+ (has_peak () ? get_peak_tuple ().get_size (axis_count) : 0) +
+ (has_intermediate () ? (get_start_tuple (axis_count).get_size (axis_count) +
+ get_end_tuple (axis_count).get_size (axis_count)) : 0);
+ }
+
+ const TupleVarHeader &get_next (unsigned int axis_count) const
+ { return StructAtOffset<TupleVarHeader> (this, get_size (axis_count)); }
+
+ float calculate_scalar (const int *coords, unsigned int coord_count,
+ const hb_array_t<const F2DOT14> shared_tuples) const
+ {
+ const F2DOT14 *peak_tuple;
+
+ if (has_peak ())
+ peak_tuple = &(get_peak_tuple ()[0]);
+ else
+ {
+ unsigned int index = get_index ();
+ if (unlikely (index * coord_count >= shared_tuples.length))
+ return 0.f;
+ peak_tuple = &shared_tuples[coord_count * index];
+ }
+
+ const F2DOT14 *start_tuple = nullptr;
+ const F2DOT14 *end_tuple = nullptr;
+ if (has_intermediate ())
+ {
+ start_tuple = get_start_tuple (coord_count);
+ end_tuple = get_end_tuple (coord_count);
+ }
+
+ float scalar = 1.f;
+ for (unsigned int i = 0; i < coord_count; i++)
+ {
+ int v = coords[i];
+ int peak = peak_tuple[i];
+ if (!peak || v == peak) continue;
+
+ if (has_intermediate ())
+ {
+ int start = start_tuple[i];
+ int end = end_tuple[i];
+ if (unlikely (start > peak || peak > end ||
+ (start < 0 && end > 0 && peak))) continue;
+ if (v < start || v > end) return 0.f;
+ if (v < peak)
+ { if (peak != start) scalar *= (float) (v - start) / (peak - start); }
+ else
+ { if (peak != end) scalar *= (float) (end - v) / (end - peak); }
+ }
+ else if (!v || v < hb_min (0, peak) || v > hb_max (0, peak)) return 0.f;
+ else
+ scalar *= (float) v / peak;
+ }
+ return scalar;
+ }
+
+ unsigned int get_data_size () const { return varDataSize; }
+
+ bool has_peak () const { return (tupleIndex & TuppleIndex::EmbeddedPeakTuple); }
+ bool has_intermediate () const { return (tupleIndex & TuppleIndex::IntermediateRegion); }
+ bool has_private_points () const { return (tupleIndex & TuppleIndex::PrivatePointNumbers); }
+ unsigned int get_index () const { return (tupleIndex & TuppleIndex::TupleIndexMask); }
+
+ protected:
+ const Tuple &get_peak_tuple () const
+ { return StructAfter<Tuple> (tupleIndex); }
+ const Tuple &get_start_tuple (unsigned int axis_count) const
+ { return *(const Tuple *) &get_peak_tuple ()[has_peak () ? axis_count : 0]; }
+ const Tuple &get_end_tuple (unsigned int axis_count) const
+ { return *(const Tuple *) &get_peak_tuple ()[has_peak () ? (axis_count * 2) : axis_count]; }
+
+ HBUINT16 varDataSize;
+ TuppleIndex tupleIndex;
+ /* UnsizedArrayOf<F2DOT14> peakTuple - optional */
+ /* UnsizedArrayOf<F2DOT14> intermediateStartTuple - optional */
+ /* UnsizedArrayOf<F2DOT14> intermediateEndTuple - optional */
+
+ public:
+ DEFINE_SIZE_MIN (4);
+};
+
+struct TupleVarCount : HBUINT16
+{
+ bool has_shared_point_numbers () const { return ((*this) & SharedPointNumbers); }
+ unsigned int get_count () const { return (*this) & CountMask; }
+
+ protected:
+ enum Flags
+ {
+ SharedPointNumbers = 0x8000u,
+ CountMask = 0x0FFFu
+ };
+
+ public:
+ DEFINE_SIZE_STATIC (2);
+};
+
+struct GlyphVarData
+{
+ const TupleVarHeader &get_tuple_var_header (void) const
+ { return StructAfter<TupleVarHeader> (data); }
+
+ struct tuple_iterator_t
+ {
+ void init (const GlyphVarData *var_data_, unsigned int length_, unsigned int axis_count_)
+ {
+ var_data = var_data_;
+ length = length_;
+ index = 0;
+ axis_count = axis_count_;
+ current_tuple = &var_data->get_tuple_var_header ();
+ data_offset = 0;
+ }
+
+ bool get_shared_indices (hb_vector_t<unsigned int> &shared_indices /* OUT */)
+ {
+ if (var_data->has_shared_point_numbers ())
+ {
+ range_checker_t checker (var_data, length);
+ const HBUINT8 *base = &(var_data+var_data->data);
+ const HBUINT8 *p = base;
+ if (!unpack_points (p, shared_indices, checker)) return false;
+ data_offset = p - base;
+ }
+ return true;
+ }
+
+ bool is_valid () const
+ {
+ return (index < var_data->tupleVarCount.get_count ()) &&
+ in_range (current_tuple) &&
+ current_tuple->get_size (axis_count);
+ }
+
+ bool move_to_next ()
+ {
+ data_offset += current_tuple->get_data_size ();
+ current_tuple = &current_tuple->get_next (axis_count);
+ index++;
+ return is_valid ();
+ }
+
+ bool in_range (const void *p, unsigned int l) const
+ { return (const char*) p >= (const char*) var_data && (const char*) p+l <= (const char*) var_data + length; }
+
+ template <typename T> bool in_range (const T *p) const { return in_range (p, sizeof (*p)); }
+
+ const HBUINT8 *get_serialized_data () const
+ { return &(var_data+var_data->data) + data_offset; }
+
+ private:
+ const GlyphVarData *var_data;
+ unsigned int length;
+ unsigned int index;
+ unsigned int axis_count;
+ unsigned int data_offset;
+
+ public:
+ const TupleVarHeader *current_tuple;
+ };
+
+ static bool get_tuple_iterator (const GlyphVarData *var_data,
+ unsigned int length,
+ unsigned int axis_count,
+ hb_vector_t<unsigned int> &shared_indices /* OUT */,
+ tuple_iterator_t *iterator /* OUT */)
+ {
+ iterator->init (var_data, length, axis_count);
+ if (!iterator->get_shared_indices (shared_indices))
+ return false;
+ return iterator->is_valid ();
+ }
+
+ bool has_shared_point_numbers () const { return tupleVarCount.has_shared_point_numbers (); }
+
+ static bool unpack_points (const HBUINT8 *&p /* IN/OUT */,
+ hb_vector_t<unsigned int> &points /* OUT */,
+ const range_checker_t &check)
+ {
+ enum packed_point_flag_t
+ {
+ POINTS_ARE_WORDS = 0x80,
+ POINT_RUN_COUNT_MASK = 0x7F
+ };
+
+ if (unlikely (!check.in_range (p))) return false;
+
+ uint16_t count = *p++;
+ if (count & POINTS_ARE_WORDS)
+ {
+ if (unlikely (!check.in_range (p))) return false;
+ count = ((count & POINT_RUN_COUNT_MASK) << 8) | *p++;
+ }
+ points.resize (count);
+
+ unsigned int n = 0;
+ uint16_t i = 0;
+ while (i < count)
+ {
+ if (unlikely (!check.in_range (p))) return false;
+ uint16_t j;
+ uint8_t control = *p++;
+ uint16_t run_count = (control & POINT_RUN_COUNT_MASK) + 1;
+ if (control & POINTS_ARE_WORDS)
+ {
+ for (j = 0; j < run_count && i < count; j++, i++)
+ {
+ if (unlikely (!check.in_range ((const HBUINT16 *) p)))
+ return false;
+ n += *(const HBUINT16 *)p;
+ points[i] = n;
+ p += HBUINT16::static_size;
+ }
+ }
+ else
+ {
+ for (j = 0; j < run_count && i < count; j++, i++)
+ {
+ if (unlikely (!check.in_range (p))) return false;
+ n += *p++;
+ points[i] = n;
+ }
+ }
+ if (j < run_count) return false;
+ }
+ return true;
+ }
+
+ static bool unpack_deltas (const HBUINT8 *&p /* IN/OUT */,
+ hb_vector_t<int> &deltas /* IN/OUT */,
+ const range_checker_t &check)
+ {
+ enum packed_delta_flag_t
+ {
+ DELTAS_ARE_ZERO = 0x80,
+ DELTAS_ARE_WORDS = 0x40,
+ DELTA_RUN_COUNT_MASK = 0x3F
+ };
+
+ unsigned int i = 0;
+ unsigned int count = deltas.length;
+ while (i < count)
+ {
+ if (unlikely (!check.in_range (p))) return false;
+ uint8_t control = *p++;
+ unsigned int run_count = (control & DELTA_RUN_COUNT_MASK) + 1;
+ unsigned int j;
+ if (control & DELTAS_ARE_ZERO)
+ for (j = 0; j < run_count && i < count; j++, i++)
+ deltas[i] = 0;
+ else if (control & DELTAS_ARE_WORDS)
+ for (j = 0; j < run_count && i < count; j++, i++)
+ {
+ if (unlikely (!check.in_range ((const HBUINT16 *) p)))
+ return false;
+ deltas[i] = *(const HBINT16 *) p;
+ p += HBUINT16::static_size;
+ }
+ else
+ for (j = 0; j < run_count && i < count; j++, i++)
+ {
+ if (unlikely (!check.in_range (p)))
+ return false;
+ deltas[i] = *(const HBINT8 *) p++;
+ }
+ if (j < run_count)
+ return false;
+ }
+ return true;
+ }
+
+ protected:
+ TupleVarCount tupleVarCount;
+ OffsetTo<HBUINT8> data;
+ /* TupleVarHeader tupleVarHeaders[] */
+ public:
+ DEFINE_SIZE_MIN (4);
+};
+
+struct gvar
+{
+ static constexpr hb_tag_t tableTag = HB_OT_TAG_gvar;
+
+ bool sanitize_shallow (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) && (version.major == 1) &&
+ (glyphCount == c->get_num_glyphs ()) &&
+ c->check_array (&(this+sharedTuples), axisCount * sharedTupleCount) &&
+ (is_long_offset () ?
+ c->check_array (get_long_offset_array (), glyphCount+1) :
+ c->check_array (get_short_offset_array (), glyphCount+1)) &&
+ c->check_array (((const HBUINT8*)&(this+dataZ)) + get_offset (0),
+ get_offset (glyphCount) - get_offset (0)));
+ }
+
+ /* GlyphVarData not sanitized here; must be checked while accessing each glyph varation data */
+ bool sanitize (hb_sanitize_context_t *c) const
+ { return sanitize_shallow (c); }
+
+ bool subset (hb_subset_context_t *c) const
+ {
+ TRACE_SUBSET (this);
+
+ gvar *out = c->serializer->allocate_min<gvar> ();
+ if (unlikely (!out)) return_trace (false);
+
+ out->version.major = 1;
+ out->version.minor = 0;
+ out->axisCount = axisCount;
+ out->sharedTupleCount = sharedTupleCount;
+
+ unsigned int num_glyphs = c->plan->num_output_glyphs ();
+ out->glyphCount = num_glyphs;
+
+ unsigned int subset_data_size = 0;
+ for (hb_codepoint_t gid = 0; gid < num_glyphs; gid++)
+ {
+ hb_codepoint_t old_gid;
+ if (!c->plan->old_gid_for_new_gid (gid, &old_gid)) continue;
+ subset_data_size += get_glyph_var_data_length (old_gid);
+ }
+
+ bool long_offset = subset_data_size & ~0xFFFFu;
+ out->flags = long_offset ? 1 : 0;
+
+ HBUINT8 *subset_offsets = c->serializer->allocate_size<HBUINT8> ((long_offset ? 4 : 2) * (num_glyphs + 1));
+ if (!subset_offsets) return_trace (false);
+
+ /* shared tuples */
+ if (!sharedTupleCount || !sharedTuples)
+ out->sharedTuples = 0;
+ else
+ {
+ unsigned int shared_tuple_size = F2DOT14::static_size * axisCount * sharedTupleCount;
+ F2DOT14 *tuples = c->serializer->allocate_size<F2DOT14> (shared_tuple_size);
+ if (!tuples) return_trace (false);
+ out->sharedTuples = (char *) tuples - (char *) out;
+ memcpy (tuples, &(this+sharedTuples), shared_tuple_size);
+ }
+
+ char *subset_data = c->serializer->allocate_size<char> (subset_data_size);
+ if (!subset_data) return_trace (false);
+ out->dataZ = subset_data - (char *)out;
+
+ unsigned int glyph_offset = 0;
+ for (hb_codepoint_t gid = 0; gid < num_glyphs; gid++)
+ {
+ hb_codepoint_t old_gid;
+ unsigned int length = c->plan->old_gid_for_new_gid (gid, &old_gid) ? get_glyph_var_data_length (old_gid) : 0;
+
+ if (long_offset)
+ ((HBUINT32 *) subset_offsets)[gid] = glyph_offset;
+ else
+ ((HBUINT16 *) subset_offsets)[gid] = glyph_offset / 2;
+
+ if (length > 0) memcpy (subset_data, get_glyph_var_data (old_gid), length);
+ subset_data += length;
+ glyph_offset += length;
+ }
+ if (long_offset)
+ ((HBUINT32 *) subset_offsets)[num_glyphs] = glyph_offset;
+ else
+ ((HBUINT16 *) subset_offsets)[num_glyphs] = glyph_offset / 2;
+
+ return_trace (true);
+ }
+
+ protected:
+ const GlyphVarData *get_glyph_var_data (hb_codepoint_t glyph) const
+ {
+ unsigned int start_offset = get_offset (glyph);
+ unsigned int end_offset = get_offset (glyph+1);
+
+ if ((start_offset == end_offset) ||
+ unlikely ((start_offset > get_offset (glyphCount)) ||
+ (start_offset + GlyphVarData::min_size > end_offset)))
+ return &Null (GlyphVarData);
+ return &(((unsigned char *) this + start_offset) + dataZ);
+ }
+
+ bool is_long_offset () const { return (flags & 1) != 0; }
+
+ unsigned int get_offset (unsigned int i) const
+ {
+ if (is_long_offset ())
+ return get_long_offset_array ()[i];
+ else
+ return get_short_offset_array ()[i] * 2;
+ }
+
+ unsigned int get_glyph_var_data_length (unsigned int glyph) const
+ {
+ unsigned int end_offset = get_offset (glyph + 1);
+ unsigned int start_offset = get_offset (glyph);
+ if (unlikely (start_offset > end_offset || end_offset > get_offset (glyphCount)))
+ return 0;
+ return end_offset - start_offset;
+ }
+
+ const HBUINT32 * get_long_offset_array () const { return (const HBUINT32 *) &offsetZ; }
+ const HBUINT16 *get_short_offset_array () const { return (const HBUINT16 *) &offsetZ; }
+
+ public:
+ struct accelerator_t
+ {
+ void init (hb_face_t *face)
+ {
+ gvar_table = hb_sanitize_context_t ().reference_table<gvar> (face);
+ hb_blob_ptr_t<fvar> fvar_table = hb_sanitize_context_t ().reference_table<fvar> (face);
+ unsigned int axis_count = fvar_table->get_axis_count ();
+ fvar_table.destroy ();
+
+ if (unlikely ((gvar_table->glyphCount != face->get_num_glyphs ()) ||
+ (gvar_table->axisCount != axis_count)))
+ fini ();
+
+ unsigned int num_shared_coord = gvar_table->sharedTupleCount * gvar_table->axisCount;
+ shared_tuples.resize (num_shared_coord);
+ for (unsigned int i = 0; i < num_shared_coord; i++)
+ shared_tuples[i] = (&(gvar_table + gvar_table->sharedTuples))[i];
+ }
+
+ void fini ()
+ {
+ gvar_table.destroy ();
+ shared_tuples.fini ();
+ }
+
+ private:
+ struct x_getter { static float get (const contour_point_t &p) { return p.x; } };
+ struct y_getter { static float get (const contour_point_t &p) { return p.y; } };
+
+ template <typename T>
+ static float infer_delta (const hb_array_t<contour_point_t> points,
+ const hb_array_t<contour_point_t> deltas,
+ unsigned int target, unsigned int prev, unsigned int next)
+ {
+ float target_val = T::get (points[target]);
+ float prev_val = T::get (points[prev]);
+ float next_val = T::get (points[next]);
+ float prev_delta = T::get (deltas[prev]);
+ float next_delta = T::get (deltas[next]);
+
+ if (prev_val == next_val)
+ return (prev_delta == next_delta) ? prev_delta : 0.f;
+ else if (target_val <= hb_min (prev_val, next_val))
+ return (prev_val < next_val) ? prev_delta : next_delta;
+ else if (target_val >= hb_max (prev_val, next_val))
+ return (prev_val > next_val) ? prev_delta : next_delta;
+
+ /* linear interpolation */
+ float r = (target_val - prev_val) / (next_val - prev_val);
+ return (1.f - r) * prev_delta + r * next_delta;
+ }
+
+ static unsigned int next_index (unsigned int i, unsigned int start, unsigned int end)
+ { return (i >= end) ? start : (i + 1); }
+
+ public:
+ bool apply_deltas_to_points (hb_codepoint_t glyph,
+ const int *coords, unsigned int coord_count,
+ const hb_array_t<contour_point_t> points,
+ const hb_array_t<unsigned int> end_points) const
+ {
+ if (unlikely (coord_count != gvar_table->axisCount)) return false;
+
+ const GlyphVarData *var_data = gvar_table->get_glyph_var_data (glyph);
+ if (var_data == &Null (GlyphVarData)) return true;
+ hb_vector_t<unsigned int> shared_indices;
+ GlyphVarData::tuple_iterator_t iterator;
+ if (!GlyphVarData::get_tuple_iterator (var_data,
+ gvar_table->get_glyph_var_data_length (glyph),
+ gvar_table->axisCount,
+ shared_indices,
+ &iterator))
+ return false;
+
+ /* Save original points for inferred delta calculation */
+ contour_point_vector_t orig_points;
+ orig_points.resize (points.length);
+ for (unsigned int i = 0; i < orig_points.length; i++)
+ orig_points[i] = points[i];
+
+ contour_point_vector_t deltas; /* flag is used to indicate referenced point */
+ deltas.resize (points.length);
+
+ do
+ {
+ float scalar = iterator.current_tuple->calculate_scalar (coords, coord_count, shared_tuples.as_array ());
+ if (scalar == 0.f) continue;
+ const HBUINT8 *p = iterator.get_serialized_data ();
+ unsigned int length = iterator.current_tuple->get_data_size ();
+ if (unlikely (!iterator.in_range (p, length)))
+ return false;
+
+ range_checker_t checker (p, length);
+ hb_vector_t<unsigned int> private_indices;
+ if (iterator.current_tuple->has_private_points () &&
+ !GlyphVarData::unpack_points (p, private_indices, checker))
+ return false;
+ const hb_array_t<unsigned int> &indices = private_indices.length ? private_indices : shared_indices;
+
+ bool apply_to_all = (indices.length == 0);
+ unsigned int num_deltas = apply_to_all ? points.length : indices.length;
+ hb_vector_t<int> x_deltas;
+ x_deltas.resize (num_deltas);
+ if (!GlyphVarData::unpack_deltas (p, x_deltas, checker))
+ return false;
+ hb_vector_t<int> y_deltas;
+ y_deltas.resize (num_deltas);
+ if (!GlyphVarData::unpack_deltas (p, y_deltas, checker))
+ return false;
+
+ for (unsigned int i = 0; i < deltas.length; i++)
+ deltas[i].init ();
+ for (unsigned int i = 0; i < num_deltas; i++)
+ {
+ unsigned int pt_index = apply_to_all ? i : indices[i];
+ deltas[pt_index].flag = 1; /* this point is referenced, i.e., explicit deltas specified */
+ deltas[pt_index].x += x_deltas[i] * scalar;
+ deltas[pt_index].y += y_deltas[i] * scalar;
+ }
+
+ /* infer deltas for unreferenced points */
+ unsigned int start_point = 0;
+ for (unsigned int c = 0; c < end_points.length; c++)
+ {
+ unsigned int end_point = end_points[c];
+ unsigned int i, j;
+
+ /* Check the number of unreferenced points in a contour. If no unref points or no ref points, nothing to do. */
+ unsigned int unref_count = 0;
+ for (i = start_point; i <= end_point; i++)
+ if (!deltas[i].flag) unref_count++;
+ if (unref_count == 0 || unref_count > end_point - start_point)
+ goto no_more_gaps;
+
+ j = start_point;
+ for (;;)
+ {
+ /* Locate the next gap of unreferenced points between two referenced points prev and next.
+ * Note that a gap may wrap around at left (start_point) and/or at right (end_point).
+ */
+ unsigned int prev, next;
+ for (;;)
+ {
+ i = j;
+ j = next_index (i, start_point, end_point);
+ if (deltas[i].flag && !deltas[j].flag) break;
+ }
+ prev = j = i;
+ for (;;)
+ {
+ i = j;
+ j = next_index (i, start_point, end_point);
+ if (!deltas[i].flag && deltas[j].flag) break;
+ }
+ next = j;
+ /* Infer deltas for all unref points in the gap between prev and next */
+ i = prev;
+ for (;;)
+ {
+ i = next_index (i, start_point, end_point);
+ if (i == next) break;
+ deltas[i].x = infer_delta<x_getter> (orig_points.as_array (), deltas.as_array (), i, prev, next);
+ deltas[i].y = infer_delta<y_getter> (orig_points.as_array (), deltas.as_array (), i, prev, next);
+ if (--unref_count == 0) goto no_more_gaps;
+ }
+ }
+no_more_gaps:
+ start_point = end_point + 1;
+ }
+
+ /* apply specified / inferred deltas to points */
+ for (unsigned int i = 0; i < points.length; i++)
+ {
+ points[i].x += (float) roundf (deltas[i].x);
+ points[i].y += (float) roundf (deltas[i].y);
+ }
+ } while (iterator.move_to_next ());
+
+ return true;
+ }
+
+ unsigned int get_axis_count () const { return gvar_table->axisCount; }
+
+ protected:
+ const GlyphVarData *get_glyph_var_data (hb_codepoint_t glyph) const
+ { return gvar_table->get_glyph_var_data (glyph); }
+
+ private:
+ hb_blob_ptr_t<gvar> gvar_table;
+ hb_vector_t<F2DOT14> shared_tuples;
+ };
+
+ protected:
+ FixedVersion<>version; /* Version of gvar table. Set to 0x00010000u. */
+ HBUINT16 axisCount;
+ HBUINT16 sharedTupleCount;
+ LOffsetTo<F2DOT14>
+ sharedTuples; /* LOffsetTo<UnsizedArrayOf<Tupple>> */
+ HBUINT16 glyphCount;
+ HBUINT16 flags;
+ LOffsetTo<GlyphVarData>
+ dataZ; /* Array of GlyphVarData */
+ UnsizedArrayOf<HBUINT8>
+ offsetZ; /* Array of 16-bit or 32-bit (glyphCount+1) offsets */
+ public:
+ DEFINE_SIZE_MIN (20);
+};
+
+struct gvar_accelerator_t : gvar::accelerator_t {};
+
+} /* namespace OT */
+
+#endif /* HB_OT_VAR_GVAR_TABLE_HH */
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh
index a8d9fe3c875..223430fb829 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh
@@ -114,14 +114,21 @@ struct HVARVVAR
rsbMap.sanitize (c, this));
}
- float get_advance_var (hb_codepoint_t glyph,
- const int *coords, unsigned int coord_count) const
+ float get_advance_var (hb_font_t *font, hb_codepoint_t glyph) const
{
unsigned int varidx = (this+advMap).map (glyph);
+ return (this+varStore).get_delta (varidx, font->coords, font->num_coords);
+ }
+
+ float get_side_bearing_var (hb_codepoint_t glyph,
+ const int *coords, unsigned int coord_count) const
+ {
+ if (!has_side_bearing_deltas ()) return 0.f;
+ unsigned int varidx = (this+lsbMap).map (glyph);
return (this+varStore).get_delta (varidx, coords, coord_count);
}
- bool has_sidebearing_deltas () const { return lsbMap && rsbMap; }
+ bool has_side_bearing_deltas () const { return lsbMap && rsbMap; }
protected:
FixedVersion<>version; /* Version of the metrics variation table
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc
index deff77bedcd..cf4e1525a25 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc
@@ -154,7 +154,9 @@ hb_shape_full (hb_font_t *font,
*
* Shapes @buffer using @font turning its Unicode characters content to
* positioned glyphs. If @features is not %NULL, it will be used to control the
- * features applied during shaping.
+ * features applied during shaping. If two @features have the same tag but
+ * overlapping ranges the value of the feature with the higher index takes
+ * precedence.
*
* Since: 0.9.2
**/
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.cc
index b71ac57cc08..c9a880ad500 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.cc
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.cc
@@ -68,8 +68,7 @@ hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan,
{
/* use hb_set to determine the subset of font dicts */
hb_set_t *set = hb_set_create ();
- if (set == &Null (hb_set_t))
- return false;
+ if (unlikely (set == &Null (hb_set_t))) return false;
hb_codepoint_t prev_fd = CFF_UNDEF_CODE;
for (hb_codepoint_t i = 0; i < subset_num_glyphs; i++)
{
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh
index 6c36e458f53..3c66119603f 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh
@@ -548,7 +548,7 @@ struct subr_remap_t : hb_inc_bimap_t
/* create a remapping of subroutine numbers from old to new.
* no optimization based on usage counts. fonttools doesn't appear doing that either.
*/
-
+
hb_codepoint_t old_num = HB_SET_VALUE_INVALID;
while (hb_set_next (closure, &old_num))
add (old_num);
@@ -916,7 +916,7 @@ struct subr_subsetter_t
hb_set_t *closure,
const subr_subset_param_t &param)
{
- hb_set_add (closure, subr_num);
+ closure->add (subr_num);
collect_subr_refs_in_str (subrs[subr_num], param);
}
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff1.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff1.cc
index 21bd97fbb80..e9e075749e7 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff1.cc
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff1.cc
@@ -389,7 +389,7 @@ struct cff1_cs_opset_subr_subset_t : cff1_cs_opset_t<cff1_cs_opset_subr_subset_t
byte_str_ref_t str_ref = env.str_ref;
env.call_subr (subrs, type);
param.current_parsed_str->add_call_op (op, str_ref, env.context.subr_num);
- hb_set_add (closure, env.context.subr_num);
+ closure->add (env.context.subr_num);
param.set_current_str (env, true);
}
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff2.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff2.cc
index 9bdd0ee7d6e..7edc3f51535 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff2.cc
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff2.cc
@@ -219,7 +219,7 @@ struct cff2_cs_opset_subr_subset_t : cff2_cs_opset_t<cff2_cs_opset_subr_subset_t
byte_str_ref_t str_ref = env.str_ref;
env.call_subr (subrs, type);
param.current_parsed_str->add_call_op (op, str_ref, env.context.subr_num);
- hb_set_add (closure, env.context.subr_num);
+ closure->add (env.context.subr_num);
param.set_current_str (env, true);
}
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc
index 65591136834..e537772c093 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc
@@ -34,38 +34,17 @@
#include "hb-ot-var-fvar-table.hh"
#include "hb-ot-stat-table.hh"
-static inline void
-_add_gid_and_children (const OT::glyf::accelerator_t &glyf,
- hb_codepoint_t gid,
- hb_set_t *gids_to_retain)
-{
- if (gids_to_retain->has (gid))
- // Already visited this gid, ignore.
- return;
-
- hb_set_add (gids_to_retain, gid);
-
- OT::glyf::CompositeGlyphHeader::Iterator composite;
- if (glyf.get_composite (gid, &composite))
- {
- do
- {
- _add_gid_and_children (glyf, (hb_codepoint_t) composite.current->glyphIndex, gids_to_retain);
- } while (composite.move_to_next());
- }
-}
-
#ifndef HB_NO_SUBSET_CFF
static inline void
_add_cff_seac_components (const OT::cff1::accelerator_t &cff,
- hb_codepoint_t gid,
- hb_set_t *gids_to_retain)
+ hb_codepoint_t gid,
+ hb_set_t *gids_to_retain)
{
hb_codepoint_t base_gid, accent_gid;
if (cff.get_seac_components (gid, &base_gid, &accent_gid))
{
- hb_set_add (gids_to_retain, base_gid);
- hb_set_add (gids_to_retain, accent_gid);
+ gids_to_retain->add (base_gid);
+ gids_to_retain->add (accent_gid);
}
}
#endif
@@ -151,7 +130,7 @@ _populate_gids_to_retain (hb_subset_plan_t* plan,
hb_codepoint_t gid = HB_SET_VALUE_INVALID;
while (plan->_glyphset_gsub->next (&gid))
{
- _add_gid_and_children (glyf, gid, plan->_glyphset);
+ glyf.add_gid_and_children (gid, plan->_glyphset);
#ifndef HB_NO_SUBSET_CFF
if (cff.is_valid ())
_add_cff_seac_components (cff, gid, plan->_glyphset);
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc
index 9a8184063df..08a4054cd0c 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc
@@ -270,9 +270,9 @@ hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
**/
hb_bool_t
hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
- hb_user_data_key_t *key,
- void * data,
- hb_destroy_func_t destroy,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
hb_bool_t replace)
{
return hb_object_set_user_data (ufuncs, key, data, destroy, replace);
@@ -291,7 +291,7 @@ hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
**/
void *
hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
- hb_user_data_key_t *key)
+ hb_user_data_key_t *key)
{
return hb_object_get_user_data (ufuncs, key);
}
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.h
index df0b91f0190..61b1b0ba1f7 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.h
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.h
@@ -200,15 +200,15 @@ hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs);
HB_EXTERN hb_bool_t
hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
- hb_user_data_key_t *key,
- void * data,
- hb_destroy_func_t destroy,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
hb_bool_t replace);
HB_EXTERN void *
hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
- hb_user_data_key_t *key);
+ hb_user_data_key_t *key);
HB_EXTERN void
@@ -260,7 +260,7 @@ typedef hb_bool_t (*hb_unicode_decompose_func_t) (hb_unicode_funcs_t *ufuncs,
* @user_data:
* @destroy:
*
- *
+ *
*
* Since: 0.9.2
**/
@@ -276,7 +276,7 @@ hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs,
* @user_data:
* @destroy:
*
- *
+ *
*
* Since: 0.9.2
**/
@@ -292,7 +292,7 @@ hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs,
* @user_data:
* @destroy:
*
- *
+ *
*
* Since: 0.9.2
**/
@@ -308,7 +308,7 @@ hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs,
* @user_data:
* @destroy:
*
- *
+ *
*
* Since: 0.9.2
**/
@@ -324,7 +324,7 @@ hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs,
* @user_data:
* @destroy:
*
- *
+ *
*
* Since: 0.9.2
**/
@@ -340,7 +340,7 @@ hb_unicode_funcs_set_compose_func (hb_unicode_funcs_t *ufuncs,
* @user_data:
* @destroy:
*
- *
+ *
*
* Since: 0.9.2
**/
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh
index 288a5416dec..7b150fba054 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh
@@ -302,8 +302,8 @@ struct hb_sorted_vector_t : hb_vector_t<Type>
{ return as_array ().bsearch (x, not_found); }
template <typename T>
bool bfind (const T &x, unsigned int *i = nullptr,
- hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
- unsigned int to_store = (unsigned int) -1) const
+ hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
+ unsigned int to_store = (unsigned int) -1) const
{ return as_array ().bfind (x, i, not_found, to_store); }
};
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-warning.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-warning.cc
deleted file mode 100644
index 60c7445b789..00000000000
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-warning.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright © 2012 Google, Inc.
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Behdad Esfahbod
- */
-
-#include "hb.hh"
-
-#ifdef HB_ATOMIC_INT_NIL
-#error "Could not find any system to define atomic_int macros, library WILL NOT be thread-safe"
-#error "Check hb-atomic.hh for possible resolutions."
-#endif
-
-#ifdef HB_MUTEX_IMPL_NIL
-#error "Could not find any system to define mutex macros, library WILL NOT be thread-safe"
-#error "Check hb-mutex.hh for possible resolutions."
-#endif
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc
index 0aa4a5b204b..983cb557db7 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc
@@ -45,7 +45,8 @@ using namespace OT;
int
main (int argc, char **argv)
{
- if (argc != 2) {
+ if (argc != 2)
+ {
fprintf (stderr, "usage: %s font-file.ttf\n", argv[0]);
exit (1);
}
@@ -65,7 +66,8 @@ main (int argc, char **argv)
const OpenTypeFontFile& ot = *sanitized;
- switch (ot.get_tag ()) {
+ switch (ot.get_tag ())
+ {
case OpenTypeFontFile::TrueTypeTag:
printf ("OpenType font with TrueType outlines\n");
break;
@@ -91,20 +93,23 @@ main (int argc, char **argv)
int num_fonts = ot.get_face_count ();
printf ("%d font(s) found in file\n", num_fonts);
- for (int n_font = 0; n_font < num_fonts; n_font++) {
+ for (int n_font = 0; n_font < num_fonts; n_font++)
+ {
const OpenTypeFontFace &font = ot.get_face (n_font);
printf ("Font %d of %d:\n", n_font, num_fonts);
int num_tables = font.get_table_count ();
printf (" %d table(s) found in font\n", num_tables);
- for (int n_table = 0; n_table < num_tables; n_table++) {
+ for (int n_table = 0; n_table < num_tables; n_table++)
+ {
const OpenTypeTable &table = font.get_table (n_table);
printf (" Table %2d of %2d: %.4s (0x%08x+0x%08x)\n", n_table, num_tables,
(const char *) table.tag,
(unsigned int) table.offset,
(unsigned int) table.length);
- switch (table.tag) {
+ switch (table.tag)
+ {
case HB_OT_TAG_GSUB:
case HB_OT_TAG_GPOS:
@@ -114,10 +119,11 @@ main (int argc, char **argv)
int num_scripts = g.get_script_count ();
printf (" %d script(s) found in table\n", num_scripts);
- for (int n_script = 0; n_script < num_scripts; n_script++) {
+ for (int n_script = 0; n_script < num_scripts; n_script++)
+ {
const Script &script = g.get_script (n_script);
printf (" Script %2d of %2d: %.4s\n", n_script, num_scripts,
- (const char *)g.get_script_tag(n_script));
+ (const char *)g.get_script_tag(n_script));
if (!script.has_default_lang_sys())
printf (" No default language system\n");
@@ -140,34 +146,37 @@ main (int argc, char **argv)
int num_features = langsys.get_feature_count ();
printf (" %d feature(s) found in language system\n", num_features);
- for (int n_feature = 0; n_feature < num_features; n_feature++) {
+ for (int n_feature = 0; n_feature < num_features; n_feature++)
+ {
printf (" Feature index %2d of %2d: %d\n", n_feature, num_features,
- langsys.get_feature_index (n_feature));
+ langsys.get_feature_index (n_feature));
}
}
}
int num_features = g.get_feature_count ();
printf (" %d feature(s) found in table\n", num_features);
- for (int n_feature = 0; n_feature < num_features; n_feature++) {
+ for (int n_feature = 0; n_feature < num_features; n_feature++)
+ {
const Feature &feature = g.get_feature (n_feature);
int num_lookups = feature.get_lookup_count ();
printf (" Feature %2d of %2d: %c%c%c%c\n", n_feature, num_features,
- HB_UNTAG(g.get_feature_tag(n_feature)));
+ HB_UNTAG(g.get_feature_tag(n_feature)));
printf (" %d lookup(s) found in feature\n", num_lookups);
for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) {
printf (" Lookup index %2d of %2d: %d\n", n_lookup, num_lookups,
- feature.get_lookup_index (n_lookup));
+ feature.get_lookup_index (n_lookup));
}
}
int num_lookups = g.get_lookup_count ();
printf (" %d lookup(s) found in table\n", num_lookups);
- for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) {
+ for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++)
+ {
const Lookup &lookup = g.get_lookup (n_lookup);
printf (" Lookup %2d of %2d: type %d, props 0x%04X\n", n_lookup, num_lookups,
- lookup.get_type(), lookup.get_props());
+ lookup.get_type(), lookup.get_props());
}
}
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/test-iter.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/test-iter.cc
index b5a4c8695aa..9c83171889f 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/test-iter.cc
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/test-iter.cc
@@ -234,7 +234,7 @@ main (int argc, char **argv)
{
hb_set_t *set = hb_set_create ();
for (unsigned int i = 0; i < temp1; ++i)
- hb_set_add (set, i);
+ hb_set_add (set, i);
temp1++;
return set;
})
diff --git a/Build/source/libs/harfbuzz/version.ac b/Build/source/libs/harfbuzz/version.ac
index d261233f584..65a8e5045c5 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], [2.6.2])
+m4_define([harfbuzz_version], [2.6.3])