Imported Upstream version 1.8.1 upstream/1.8.1
authorYoungbok Shin <youngb.shin@samsung.com>
Tue, 26 Jun 2018 02:15:52 +0000 (11:15 +0900)
committerYoungbok Shin <youngb.shin@samsung.com>
Tue, 26 Jun 2018 02:15:52 +0000 (11:15 +0900)
279 files changed:
CMakeLists.txt
ChangeLog
Makefile.am
Makefile.in
NEWS
README
README.python.md [moved from README.python with 83% similarity]
README.wine.md [new file with mode: 0644]
RELEASING.md
TODO
aclocal.m4
config.h.in
configure
configure.ac
docs/Makefile.in
docs/harfbuzz-sections.txt
docs/html/api-index-full.html
docs/html/harfbuzz-Buffers.html
docs/html/harfbuzz-hb-blob.html
docs/html/harfbuzz-hb-common.html
docs/html/harfbuzz-hb-face.html
docs/html/harfbuzz-hb-ot-layout.html
docs/html/harfbuzz-hb-set.html
docs/html/harfbuzz-hb-version.html
docs/html/harfbuzz.devhelp2
docs/html/pt02.html
docs/version.xml
m4/ax_check_link_flag.m4 [new file with mode: 0644]
src/Makefile.am
src/Makefile.in
src/Makefile.sources
src/check-symbols.sh
src/dump-emoji.cc [new file with mode: 0644]
src/dump-fon.cc [new file with mode: 0644]
src/gen-arabic-table.py
src/gen-def.py
src/gen-indic-table.py
src/gen-use-table.py
src/hb-aat-fmtx-table.hh [new file with mode: 0644]
src/hb-aat-gcid-table.hh [new file with mode: 0644]
src/hb-aat-layout-ankr-table.hh
src/hb-aat-layout-bsln-table.hh [new file with mode: 0644]
src/hb-aat-layout-common-private.hh
src/hb-aat-layout-feat-table.hh [new file with mode: 0644]
src/hb-aat-layout-kerx-table.hh
src/hb-aat-layout-morx-table.hh
src/hb-aat-layout-trak-table.hh
src/hb-aat-layout.cc
src/hb-aat-ltag-table.hh [new file with mode: 0644]
src/hb-atomic-private.hh
src/hb-blob-private.hh [new file with mode: 0644]
src/hb-blob.cc
src/hb-blob.h
src/hb-buffer-deserialize-json.hh
src/hb-buffer-deserialize-json.rl
src/hb-buffer-deserialize-text.hh
src/hb-buffer-deserialize-text.rl
src/hb-buffer-private.hh
src/hb-buffer.cc
src/hb-common.cc
src/hb-common.h
src/hb-coretext.cc
src/hb-directwrite.cc
src/hb-directwrite.h
src/hb-dsalgs.hh
src/hb-face.cc
src/hb-face.h
src/hb-font-private.hh
src/hb-font.cc
src/hb-ft.cc
src/hb-glib.cc
src/hb-graphite2.cc
src/hb-graphite2.h
src/hb-icu.cc
src/hb-map-private.hh [new file with mode: 0644]
src/hb-map.cc [new file with mode: 0644]
src/hb-map.h [new file with mode: 0644]
src/hb-mutex-private.hh
src/hb-object-private.hh
src/hb-open-file-private.hh
src/hb-open-type-private.hh
src/hb-ot-cmap-table.hh
src/hb-ot-color-cbdt-table.hh
src/hb-ot-color-colr-table.hh
src/hb-ot-color-cpal-table.hh
src/hb-ot-color-sbix-table.hh [new file with mode: 0644]
src/hb-ot-color-svg-table.hh [new file with mode: 0644]
src/hb-ot-color.cc
src/hb-ot-font.cc
src/hb-ot-glyf-table.hh
src/hb-ot-hdmx-table.hh
src/hb-ot-head-table.hh
src/hb-ot-hhea-table.hh
src/hb-ot-hmtx-table.hh
src/hb-ot-kern-table.hh
src/hb-ot-layout-base-table.hh
src/hb-ot-layout-common-private.hh
src/hb-ot-layout-gdef-table.hh
src/hb-ot-layout-gpos-table.hh
src/hb-ot-layout-gsub-table.hh
src/hb-ot-layout-gsubgpos-private.hh
src/hb-ot-layout-jstf-table.hh
src/hb-ot-layout-private.hh
src/hb-ot-layout.cc
src/hb-ot-layout.h
src/hb-ot-map-private.hh
src/hb-ot-map.cc
src/hb-ot-math-table.hh
src/hb-ot-math.cc
src/hb-ot-maxp-table.hh
src/hb-ot-name-table.hh
src/hb-ot-os2-table.hh
src/hb-ot-os2-unicode-ranges.hh
src/hb-ot-post-table.hh
src/hb-ot-shape-complex-arabic-table.hh
src/hb-ot-shape-complex-arabic.cc
src/hb-ot-shape-complex-hangul.cc
src/hb-ot-shape-complex-indic-machine.hh
src/hb-ot-shape-complex-indic-machine.rl
src/hb-ot-shape-complex-indic-private.hh
src/hb-ot-shape-complex-indic-table.cc
src/hb-ot-shape-complex-indic.cc
src/hb-ot-shape-complex-khmer-machine.hh
src/hb-ot-shape-complex-khmer-machine.rl
src/hb-ot-shape-complex-khmer.cc
src/hb-ot-shape-complex-myanmar-private.hh
src/hb-ot-shape-complex-myanmar.cc
src/hb-ot-shape-complex-private.hh
src/hb-ot-shape-complex-thai.cc
src/hb-ot-shape-complex-use-machine.hh
src/hb-ot-shape-complex-use-machine.rl
src/hb-ot-shape-complex-use-private.hh
src/hb-ot-shape-complex-use-table.cc
src/hb-ot-shape-complex-use.cc
src/hb-ot-shape-fallback.cc
src/hb-ot-shape-normalize.cc
src/hb-ot-shape-private.hh
src/hb-ot-shape.cc
src/hb-ot-tag.cc
src/hb-ot-var-avar-table.hh
src/hb-ot-var-fvar-table.hh
src/hb-ot-var-hvar-table.hh
src/hb-ot-var-mvar-table.hh
src/hb-ot-var.cc
src/hb-private.hh
src/hb-set-private.hh
src/hb-set.cc
src/hb-set.h
src/hb-shape.cc
src/hb-shaper.cc
src/hb-static.cc [new file with mode: 0644]
src/hb-string-array.hh
src/hb-subset-glyf.cc
src/hb-subset-input.cc
src/hb-subset-plan.cc
src/hb-subset-plan.hh
src/hb-subset-private.hh
src/hb-subset.cc
src/hb-subset.h
src/hb-ucdn.cc
src/hb-ucdn/Makefile.in
src/hb-ucdn/ucdn.h
src/hb-ucdn/ucdn_db.h
src/hb-unicode-private.hh
src/hb-unicode.cc
src/hb-uniscribe.cc
src/hb-version.h
src/hb.h
src/main.cc
src/test-buffer-serialize.cc
src/test-size-params.cc
src/test-would-substitute.cc
src/test.cc
test/Makefile.in
test/api/CMakeLists.txt
test/api/Makefile.am
test/api/Makefile.in
test/api/fonts/Mplus1p-Regular.660E,6975,73E0,5EA6,8F38,6E05.ttf [new file with mode: 0644]
test/api/fonts/Mplus1p-Regular.660E.ttf [new file with mode: 0644]
test/api/fonts/Roboto-Regular.D7,D8,D9,DA,DE.ttf [new file with mode: 0644]
test/api/fonts/Roboto-Regular.abc.format12.ttf [new file with mode: 0644]
test/api/fonts/Roboto-Regular.abc.format4.ttf [new file with mode: 0644]
test/api/fonts/Roboto-Regular.gsub.fi.ttf [new file with mode: 0644]
test/api/fonts/Roboto-Regular.gsub.fil.ttf [new file with mode: 0644]
test/api/fonts/Roboto-Regular.nogsub.fi.ttf [new file with mode: 0644]
test/api/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5521982557782016 [new file with mode: 0644]
test/api/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5609911946838016 [new file with mode: 0644]
test/api/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-6651660668502016 [new file with mode: 0644]
test/api/fonts/crash-4b60576767ee4d9fe1cc10959d89baf73d4e8249 [new file with mode: 0644]
test/api/fonts/crash-b577db318b30f2851828a4c9ef97cb30678b1b54 [new file with mode: 0644]
test/api/fonts/crash-ccc61c92d589f895174cdef6ff2e3b20e9999a1a [new file with mode: 0644]
test/api/fonts/crash-e4e0bb1458a91b692eba492c907ae1f94e635480 [new file with mode: 0644]
test/api/fonts/oom-6ef8c96d3710262511bcc730dce9c00e722cb653 [new file with mode: 0644]
test/api/fonts/oom-ccc61c92d589f895174cdef6ff2e3b20e9999a1a [new file with mode: 0644]
test/api/hb-subset-test.h
test/api/hb-test.h
test/api/test-buffer.c
test/api/test-common.c
test/api/test-ot-tag.c
test/api/test-set.c
test/api/test-shape.c
test/api/test-subset-cmap.c
test/api/test-subset-codepoints.c [new file with mode: 0644]
test/api/test-subset-glyf.c
test/api/test-subset-hdmx.c
test/api/test-subset-hmtx.c
test/api/test-subset-os2.c
test/api/test-subset-post.c [new file with mode: 0644]
test/api/test-subset-vmtx.c [new file with mode: 0644]
test/api/test-subset.c [new file with mode: 0644]
test/fuzzing/CMakeLists.txt
test/fuzzing/Makefile.am
test/fuzzing/Makefile.in
test/fuzzing/hb-shape-fuzzer.cc [moved from test/fuzzing/hb-fuzzer.cc with 100% similarity]
test/fuzzing/hb-subset-fuzzer.cc [new file with mode: 0644]
test/fuzzing/hb-subset-get-codepoints-fuzzer.cc [new file with mode: 0644]
test/fuzzing/run-fuzzer-tests.py [deleted file]
test/fuzzing/run-shape-fuzzer-tests.py [new file with mode: 0755]
test/fuzzing/run-subset-fuzzer-tests.py [new file with mode: 0755]
test/shaping/CMakeLists.txt
test/shaping/Makefile.in
test/shaping/data/Makefile.in
test/shaping/data/in-house/Makefile.in
test/shaping/data/in-house/Makefile.sources
test/shaping/data/in-house/fonts/5af5361ed4d1e8305780b100e1730cb09132f8d1.ttf [new file with mode: 0644]
test/shaping/data/in-house/fonts/73e84dac2fc6a2d1bc9250d1414353661088937d.ttf [new file with mode: 0644]
test/shaping/data/in-house/fonts/932ad5132c2761297c74e9976fe25b08e5ffa10b.ttf [new file with mode: 0644]
test/shaping/data/in-house/tests/indic-decompose.tests [new file with mode: 0644]
test/shaping/data/in-house/tests/none-directional.tests [new file with mode: 0644]
test/shaping/data/in-house/tests/sinhala.tests [new file with mode: 0644]
test/shaping/data/text-rendering-tests/Makefile.in
test/shaping/data/text-rendering-tests/Makefile.sources
test/shaping/data/text-rendering-tests/extract-tests.py
test/shaping/data/text-rendering-tests/fonts/TestMORXTwentyeight.ttf [new file with mode: 0644]
test/shaping/data/text-rendering-tests/fonts/TestMORXTwentyseven.ttf [new file with mode: 0644]
test/shaping/data/text-rendering-tests/fonts/TestShapeKndaV3.ttf [new file with mode: 0644]
test/shaping/hb_test_tools.py
test/shaping/record-test.sh
test/shaping/run-tests.py
test/subset/CMakeLists.txt
test/subset/Makefile.in
test/subset/data/Makefile.am
test/subset/data/Makefile.in
test/subset/data/Makefile.sources
test/subset/data/expected/basics/Roboto-Regular.abc.default.61,62,63.ttf
test/subset/data/expected/basics/Roboto-Regular.abc.default.61,63.ttf
test/subset/data/expected/basics/Roboto-Regular.abc.default.61.ttf
test/subset/data/expected/basics/Roboto-Regular.abc.default.62.ttf
test/subset/data/expected/basics/Roboto-Regular.abc.default.63.ttf
test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61,62,63.ttf
test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61,63.ttf
test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61.ttf
test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.62.ttf
test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.63.ttf
test/subset/data/expected/full-font/Roboto-Regular.default.1FC,21,41,20,62,63.ttf
test/subset/data/expected/full-font/Roboto-Regular.default.61,62,63.ttf
test/subset/data/expected/full-font/Roboto-Regular.default.D7,D8,D9,DA,DE.ttf [new file with mode: 0644]
test/subset/data/expected/full-font/Roboto-Regular.drop-hints.1FC,21,41,20,62,63.ttf
test/subset/data/expected/full-font/Roboto-Regular.drop-hints.61,62,63.ttf
test/subset/data/expected/full-font/Roboto-Regular.drop-hints.D7,D8,D9,DA,DE.ttf [new file with mode: 0644]
test/subset/data/expected/japanese/Mplus1p-Regular.default.3042,3044,3046,3048,304A,304B.ttf [new file with mode: 0644]
test/subset/data/expected/japanese/Mplus1p-Regular.default.3042,3044,3046,73E0,5EA6,8F38.ttf [new file with mode: 0644]
test/subset/data/expected/japanese/Mplus1p-Regular.default.61,63,65,6B.ttf [new file with mode: 0644]
test/subset/data/expected/japanese/Mplus1p-Regular.default.660E,6975,73E0,5EA6,8F38,6E05.ttf [new file with mode: 0644]
test/subset/data/expected/japanese/Mplus1p-Regular.default.660E.ttf [new file with mode: 0644]
test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.3042,3044,3046,3048,304A,304B.ttf [new file with mode: 0644]
test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.3042,3044,3046,73E0,5EA6,8F38.ttf [new file with mode: 0644]
test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.61,63,65,6B.ttf [new file with mode: 0644]
test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.ttf [new file with mode: 0644]
test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.660E.ttf [new file with mode: 0644]
test/subset/data/fonts/Mplus1p-Regular.ttf [new file with mode: 0644]
test/subset/data/tests/full-font.tests
test/subset/data/tests/japanese.tests [new file with mode: 0644]
test/subset/run-tests.py
util/Makefile.in
util/options.cc
util/options.hh
util/view-cairo.cc
util/view-cairo.hh

index defd5d6..9ed7e56 100644 (file)
@@ -90,6 +90,8 @@ include_directories(AFTER
 add_definitions(-DHAVE_OT)
 add_definitions(-DHAVE_FALLBACK)
 
+# We need PYTHON_EXECUTABLE to be set for running the tests...
+include (FindPythonInterp)
 
 ## Functions and headers
 include (CheckFunctionExists)
@@ -103,7 +105,10 @@ macro (check_funcs) # Similar to AC_CHECK_FUNCS of autotools
     endif ()
   endforeach ()
 endmacro ()
-check_funcs(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l)
+if (UNIX)
+  list(APPEND CMAKE_REQUIRED_LIBRARIES m)
+endif ()
+check_funcs(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l round)
 check_include_file(unistd.h HAVE_UNISTD_H)
 if (${HAVE_UNISTD_H})
   add_definitions(-DHAVE_UNISTD_H)
@@ -116,20 +121,16 @@ check_include_file(xlocale.h HAVE_XLOCALE_H)
 if (${HAVE_XLOCALE_H})
   add_definitions(-DHAVE_XLOCALE_H)
 endif ()
+check_include_file(stdbool.h HAVE_STDBOOL_H)
+if (${HAVE_STDBOOL_H})
+  add_definitions(-DHAVE_STDBOOL_H)
+endif ()
 
 
 if (MSVC)
   add_definitions(-wd4244 -wd4267 -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS)
 endif ()
 
-if (BUILD_SHARED_LIBS)
-  if (WIN32 AND NOT MINGW)
-    add_definitions("-DHB_EXTERN=__declspec(dllexport) extern")
-  else ()
-    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden")
-  endif ()
-endif ()
-
 
 ## Detect if we are running inside a distribution or regular repository folder
 # if (EXISTS "${PROJECT_SOURCE_DIR}/ChangeLog")
@@ -385,7 +386,6 @@ if (WIN32 AND HB_HAVE_DIRECTWRITE)
 endif ()
 
 if (HB_HAVE_GOBJECT)
-  include (FindPythonInterp)
   include (FindPerl)
 
   # Use the hints from glib-2.0.pc to find glib-mkenums
@@ -531,9 +531,17 @@ add_library(harfbuzz-subset ${subset_project_sources} ${subset_project_headers})
 add_dependencies(harfbuzz-subset harfbuzz)
 target_link_libraries(harfbuzz-subset harfbuzz ${THIRD_PARTY_LIBS})
 
+if (BUILD_SHARED_LIBS)
+  set_target_properties(harfbuzz harfbuzz-subset PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE)
+endif ()
+
 if (UNIX OR MINGW)
   # Make symbols link locally
-  link_libraries(-Bsymbolic-functions)
+  include (CheckCXXCompilerFlag)
+  check_cxx_compiler_flag(-Bsymbolic-functions CXX_SUPPORTS_FLAG_BSYMB_FUNCS)
+  if (CXX_SUPPORTS_FLAG_BSYMB_FUNCS)
+    link_libraries(-Bsymbolic-functions)
+  endif ()
 
   if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
     # Make sure we don't link to libstdc++
@@ -559,6 +567,14 @@ if (HB_HAVE_GOBJECT)
   include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/src)
   add_dependencies(harfbuzz-gobject harfbuzz)
   target_link_libraries(harfbuzz-gobject harfbuzz ${GOBJECT_LIBRARIES} ${THIRD_PARTY_LIBS})
+
+  if (BUILD_SHARED_LIBS)
+    set_target_properties(harfbuzz-gobject PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE)
+  endif ()
+endif ()
+
+if (BUILD_SHARED_LIBS AND WIN32 AND NOT MINGW)
+  add_definitions("-DHB_EXTERN=__declspec(dllexport) extern")
 endif ()
 
 # On Windows, g-ir-scanner requires a DLL build in order for it to work
@@ -638,6 +654,11 @@ if (HB_HAVE_INTROSPECTION)
     endif ()
   endforeach ()
 
+  file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/src/hb_gir_list)
+  foreach (s ${introspected_sources})
+    file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/src/hb_gir_list "${s}\n")
+  endforeach ()
+
   # Finally, build the introspection files...
   add_custom_command(
     TARGET harfbuzz-gobject
@@ -667,9 +688,9 @@ if (HB_HAVE_INTROSPECTION)
       --library=harfbuzz
       -L${hb_libpath}
       ${extra_libs}
-      ${introspected_sources}
+      --filelist ${CMAKE_CURRENT_BINARY_DIR}/src/hb_gir_list
       -o ${hb_libpath}/HarfBuzz-0.0.gir
-    DEPENDS harfbuzz-gobject harfbuzz
+    DEPENDS harfbuzz-gobject harfbuzz ${CMAKE_CURRENT_BINARY_DIR}/src/hb_gir_list
   )
 
   add_custom_command(
@@ -749,7 +770,7 @@ if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
     install(TARGETS hb-view
       RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
     )
-    install(TARGETS hb-view
+    install(TARGETS hb-subset
       RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
     )
 
index 02300c3..7331471 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
+commit f3e58ab8a957cdf36bddef793c473664744885a7
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 12 19:32:04 2018 -0400
+
+    [docs] Enlist misc new symbols
+
+ RELEASING.md               |  3 ++-
+ docs/harfbuzz-sections.txt | 24 +++++++++++++++++++++++-
+ 2 files changed, 25 insertions(+), 2 deletions(-)
+
+commit f6893ef82c51a35dd075973b2041b1b19f81faff
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 12 19:20:20 2018 -0400
+
+    Move hb-version.h generation to Makefile
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/864
+
+    Unfortunately 1.7.7 and 1.8.0 went out with the wrong hb-version.h
+    contents.
+
+ configure.ac     |  1 -
+ src/Makefile.am  | 21 ++++++++++++++++-----
+ src/hb-version.h |  6 +++---
+ 3 files changed, 19 insertions(+), 9 deletions(-)
+
+commit cc0b04f48f261c1deb8f4142e7ae0222fbec67fb
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 12 18:24:54 2018 -0400
+
+    [subset] Remove HB_SUBSET_BUILTIN
+
+    Just include hb-static.cc in libharfbuzz-subset.so source list as
+    well.  Those building it built-in will include hb-static.cc once
+    already.  No need for any gymnastics.
+
+ src/Makefile.sources | 1 +
+ src/hb-subset.cc     | 5 -----
+ 2 files changed, 1 insertion(+), 5 deletions(-)
+
+commit ba0ea56efab9caa942d59bf51c78e490969cab87
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 11 23:24:41 2018 -0400
+
+    [substitute-closure] Rename function for clarity
+
+ src/hb-ot-layout-gsub-table.hh       | 4 ++--
+ src/hb-ot-layout-gsubgpos-private.hh | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+commit 7b5ce416383101cb9d72a775a32d0088984e6817
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 11 23:23:40 2018 -0400
+
+    Whitespace
+
+ src/hb-ot-layout-gsub-table.hh | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit c4d0d11c55f018026fc9c1db75fe7a4f8a38f81f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 11 22:11:45 2018 -0400
+
+    [vector] Always 0-fill new items
+
+ src/hb-private.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit a7e1b4a3b2d7b853ca244156571dd83321739bb1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 11 22:05:08 2018 -0400
+
+    Fix compiler warning re reordering of initializations
+
+ src/hb-ot-layout-gsubgpos-private.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit f56cd9df10824fbbef52172470d07ff673d460cc
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 11 22:02:38 2018 -0400
+
+    Style
+
+ src/hb-ot-layout.cc | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit a95cde15af4aa34e76c4394dfdf17e7d25164d5b
+Author: Jonathan Kew <jfkthame@gmail.com>
+Date:   Mon Jun 11 18:09:35 2018 -0700
+
+    [hb-set] Additional testcase for hb-set-intersect.
+
+ test/api/test-set.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 82484b05ca7a51dec6f3f9e9b0d7967823d7657f
+Author: Jonathan Kew <jfkthame@gmail.com>
+Date:   Mon Jun 11 20:55:14 2018 -0700
+
+    [hb-set] Don't shrink vectors until after processing their contents.
+
+    Fixes #1054.
+
+ src/hb-set-private.hh | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+commit eb585033cae33ca069bbcdaa21e4074678b6a6e9
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Jun 11 03:47:43 2018 +0430
+
+    Fetch the updated dwrite_1.h header from a better place
+
+    Following to
+    https://ci.appveyor.com/project/harfbuzz/harfbuzz/build/1.0.1693/job/mfkjdhcdykjuqdfc
+
+ appveyor.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b8e406f0c7c381d46e2d2bbe35a6107d560f2122
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Jun 10 17:22:38 2018 -0400
+
+    More fixes for SunStudio 12.6 build
+
+    Followup to https://github.com/harfbuzz/harfbuzz/pull/1053
+
+ src/hb-ft.cc     | 8 ++++----
+ src/hb-subset.cc | 2 +-
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 498e4373dc2eb98fa9b18a0824c7912ed84a4c80
+Author: prrace <philip.race@oracle.com>
+Date:   Sat Jun 9 16:04:28 2018 -0700
+
+    Fix SunStudio 12.6 build (#1053)
+
+ src/hb-face.cc    | 2 +-
+ src/hb-private.hh | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 46f7e7760f4c9b1b2886a27eff3c0fabdab45dbe
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu Jun 7 15:55:45 2018 -0700
+
+    [subset] Use REPLACEME instead of version.
+
+ src/hb-subset-input.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit fc246ec985890f8256f6e03cdf74c86b9b51ff2a
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu Jun 7 15:54:19 2018 -0700
+
+    [subset] Move variable declaration out of loop.
+
+ test/api/test-subset-glyf.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 197cb18b22ce11f32f5f2c68c13f7068fb5cc338
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu Jun 7 15:32:52 2018 -0700
+
+    [subset] Add test cases for gsub closure in subsetting.
+
+ test/api/fonts/Roboto-Regular.gsub.fi.ttf   | Bin 0 -> 2652 bytes
+ test/api/fonts/Roboto-Regular.gsub.fil.ttf  | Bin 0 -> 3228 bytes
+ test/api/fonts/Roboto-Regular.nogsub.fi.ttf | Bin 0 -> 1856 bytes
+ test/api/test-subset-glyf.c                 |  52
+ ++++++++++++++++++++++++++++
+ 4 files changed, 52 insertions(+)
+
+commit 37eab27be3b88079614f66e484c700bb2d40af10
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu Jun 7 14:39:03 2018 -0700
+
+    [subset] Add fuzzing of gsub closure to hb-subset-fuzzer.
+
+ test/fuzzing/hb-subset-fuzzer.cc | 27 ++++++++++++++++++++-------
+ 1 file changed, 20 insertions(+), 7 deletions(-)
+
+commit feb23892a36a7c855306db6d21521d5e8362bdf7
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu Jun 7 14:32:34 2018 -0700
+
+    [subset] Use gsub closure if ot layout is not being dropped.
+
+ src/hb-ot-layout.cc   | 10 ++++++++--
+ src/hb-subset-plan.cc | 20 ++++++++++++++++++--
+ 2 files changed, 26 insertions(+), 4 deletions(-)
+
+commit a5673da9be70f2ba0ff79aab4bd9a4480cb0223e
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu Jun 7 14:23:03 2018 -0700
+
+    [subset] Add drop_ot_layout setting to subset input.
+
+ src/hb-subset-input.cc   | 17 +++++++++++++++++
+ src/hb-subset-plan.cc    |  1 +
+ src/hb-subset-plan.hh    |  1 +
+ src/hb-subset-private.hh |  1 +
+ src/hb-subset.cc         |  3 ++-
+ src/hb-subset.h          |  3 +++
+ 6 files changed, 25 insertions(+), 1 deletion(-)
+
+commit 57badadb769d0bcdbee00afce3af4972bc5c6bf1
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed Jun 6 16:02:51 2018 -0700
+
+    [subset] add a new closure call to hb-ot-layout that can compute
+    the closure over multiple lookups.
+
+ src/hb-ot-layout.cc | 26 ++++++++++++++++++++++++++
+ src/hb-ot-layout.h  |  6 ++++++
+ src/hb-ot-shape.cc  | 10 +---------
+ 3 files changed, 33 insertions(+), 9 deletions(-)
+
+commit 11f1f4131b722f0e0338bee222a78110806f5a3d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 6 16:46:50 2018 -0700
+
+    [set] Add is_subset
+
+    New API:
+    +hb_set_is_subset()
+
+ src/hb-set-private.hh       | 13 +++++++++++++
+ src/hb-set.cc               | 22 ++++++++++++++++++++--
+ src/hb-set.h                |  4 ++++
+ test/api/test-set.c         |  4 ++++
+ test/api/test-subset-glyf.c | 11 +++++------
+ 5 files changed, 46 insertions(+), 8 deletions(-)
+
+commit 45186b9b8cbffa7b5c8509624fb431a0f79f5130
+Author: Garret Rieger <grieger@google.com>
+Date:   Tue Jun 5 17:14:42 2018 -0700
+
+    [subset] Add memoization of GSUB lookup closures.
+
+ src/hb-ot-layout-gsub-table.hh       | 15 +++++++++++++--
+ src/hb-ot-layout-gsubgpos-private.hh | 20 ++++++++++++++++++++
+ src/hb-ot-layout.cc                  |  6 ++++--
+ 3 files changed, 37 insertions(+), 4 deletions(-)
+
+commit 78d92e0f27e8b688efac014526ef5c4f1f53a58f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 6 15:24:43 2018 -0700
+
+    Minorish
+
+ src/hb-private.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 676b19f0d1d21629b654e69f220bf53965735940
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 6 15:23:35 2018 -0700
+
+    Compiler gymnastics
+
+    Part of https://github.com/harfbuzz/harfbuzz/issues/630
+
+ src/hb-private.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 0a5952e8ddb3ec955496d582ef5a559a27684a0c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 6 14:55:30 2018 -0700
+
+    Move prime_for back into map
+
+    This was causing problem on systems without visibility when map
+    was used
+    from both libharfbuzz and libharfbuzz-subset. Sigh.
+
+    https://ci.appveyor.com/project/harfbuzz/harfbuzz/build/1.0.1669/job/dey47nmff0770vp3
+
+ src/hb-map-private.hh | 53
+ ++++++++++++++++++++++++++++++++++++++++++++++++++-
+ src/hb-private.hh     |  3 ---
+ src/hb-static.cc      | 51
+ -------------------------------------------------
+ 3 files changed, 52 insertions(+), 55 deletions(-)
+
+commit a2a1484ef93d5b5c3748b15219eca669d866b0a9
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Wed Jun 6 12:57:28 2018 -0400
+
+    Convert Consonant_Initial_Postfixed to CONS_FINAL
+
+    Consonant_Initial_Postfixed was split off of
+    Consonant_Succeeding_Repha,
+    so it should correspond to the same USE class, CONS_FINAL.
+
+ src/gen-use-table.py                 | 5 +++--
+ src/hb-ot-shape-complex-use-table.cc | 2 +-
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+commit 37986aa9b7ac44b1c4c50ebba9902d06cc8a45e0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 5 18:04:40 2018 -0700
+
+    1.8.0
+
+ NEWS         | 5 +++++
+ configure.ac | 2 +-
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+commit 9d3cd13c30d8df41a2f7ff6c4208a1b2d75ddd64
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 5 17:59:31 2018 -0700
+
+    [ucdn] Update to Unicode 11
+
+    https://github.com/grigorig/ucdn/issues/19
+
+ src/hb-ucdn.cc        |    7 +
+ src/hb-ucdn/ucdn_db.h | 2754
+ ++++++++++++++++++++++++++-----------------------
+ 2 files changed, 1479 insertions(+), 1282 deletions(-)
+
+commit 060e6b4a13a4224de885214d374b079610224123
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 5 17:31:46 2018 -0700
+
+    Update to Unicode 11.0.0
+
+    UCDN is not updated yet.
+
+ src/gen-use-table.py                    | 13 +++--
+ src/hb-common.cc                        |  5 ++
+ src/hb-common.h                         | 11 ++++
+ src/hb-ot-shape-complex-arabic-table.hh | 43 ++++++++++++---
+ src/hb-ot-shape-complex-indic-table.cc  | 77 ++++++++++++++-------------
+ src/hb-ot-shape-complex-private.hh      |  9 ++++
+ src/hb-ot-shape-complex-use-machine.rl  |  2 +-
+ src/hb-ot-shape-complex-use-table.cc    | 94
+ +++++++++++++++++++++------------
+ 8 files changed, 170 insertions(+), 84 deletions(-)
+
+commit 105a3b5e2d2ff228cdc1fbe8618f6c8fdfdabe9e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 5 15:31:04 2018 -0700
+
+    Minor
+
+ src/Makefile.am | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 60c516789bab499c5a423f80071638955b7b13fd
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 5 15:20:23 2018 -0700
+
+    [RELEASING] Update
+
+ RELEASING.md | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit df01f3e560d21900e234c4a6616bcf9c98f5f567
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 5 15:17:39 2018 -0700
+
+    1.7.7
+
+ NEWS           | 37 +++++++++++++++++++++++++++++++++++++
+ RELEASING.md   |  5 +++--
+ configure.ac   |  2 +-
+ src/hb-blob.cc |  2 +-
+ src/hb-face.cc |  2 +-
+ src/hb-map.cc  | 28 ++++++++++++++--------------
+ src/hb-map.h   |  2 +-
+ 7 files changed, 58 insertions(+), 20 deletions(-)
+
+commit ba3b6d6c6512b58a3d0e5277fbbe4e69b085467d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 4 16:47:45 2018 -0700
+
+    [khmer] Fix Coeng vs Halant confusion
+
+    Test suite results are unchanged (34).
+
+ src/hb-ot-shape-complex-khmer.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 8220ef8a54bcc94f122d50804c0a5e829de81be1
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Jun 5 22:50:53 2018 +0430
+
+    Fix hb_face_count build issue
+
+    I should've rebased #1002 before the merge, my bad
+
+ src/hb-face.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 32da0c6bc4770568346f6c05fd6b374be2bbd2b2
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Jun 5 18:56:26 2018 +0430
+
+    Add hb_face_count, a new API (#1002)
+
+    Simply, it returns the number of faces on a font blob.
+
+    To be used on hb-sanitizer tool but other clients also
+    can benefit from it.
+
+ TODO                       |  2 -
+ docs/harfbuzz-sections.txt |  1 +
+ src/hb-face.cc             | 95
+ ++++++++++++++++++++++++++++------------------
+ src/hb-face.h              |  4 ++
+ 4 files changed, 64 insertions(+), 38 deletions(-)
+
+commit 4a115fe7fe71e381decb7c894208540663419f75
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 4 15:40:43 2018 -0700
+
+    [sinhala] Move reph to after post-consonants
+
+    Apparently this changed between Win 7 and Win 10.
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/967
+
+    To be continued in https://github.com/harfbuzz/harfbuzz/issues/1044
+
+ src/hb-ot-shape-complex-indic.cc                         |   2 +-
+ test/shaping/data/in-house/Makefile.sources              |   1 +
+ .../fonts/5af5361ed4d1e8305780b100e1730cb09132f8d1.ttf   | Bin 0 ->
+ 3152 bytes
+ test/shaping/data/in-house/tests/sinhala.tests           |   1 +
+ 4 files changed, 3 insertions(+), 1 deletion(-)
+
+commit 3e494caae3dc096339a46d5a3fdeb5a718de6911
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 4 15:38:05 2018 -0700
+
+    [test] Fix record-test to use gids not glyph-names
+
+    as those might not match what FontTools think of the glyphs if font
+    does NOT have glyph names.
+
+ test/shaping/record-test.sh | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+commit 58400a2ad8b18aeb1da40d6c327135cd62312316
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Jun 2 20:30:09 2018 -0700
+
+    Remove DISALLOW_* from vector, set, and map
+
+    Some of the build bots, still fail on this.  I suppose mine pass
+    because
+    I enable C++11...
+
+    Anyway, remove these again.
+
+ src/hb-map-private.hh | 3 ---
+ src/hb-private.hh     | 6 ------
+ src/hb-set-private.hh | 3 ---
+ src/hb-subset-plan.hh | 3 ++-
+ 4 files changed, 2 insertions(+), 13 deletions(-)
+
+commit f9abbf83b6404bc9eb0c0983f562c9dbba1ef57c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Jun 2 15:30:59 2018 -0700
+
+    Fix fallout from 975bdd5ef562e37655067b703b2b9ca7481f4985
+
+    Ouch!
+
+ src/hb-ot-map-private.hh   | 40 ++++++++++++++++++++++------------------
+ src/hb-ot-map.cc           | 11 +++++++++++
+ src/hb-ot-post-table.hh    |  3 ++-
+ src/hb-ot-shape-private.hh | 10 ++++++++--
+ src/hb-ot-shape.cc         |  2 ++
+ src/hb-subset.cc           |  2 ++
+ 6 files changed, 47 insertions(+), 21 deletions(-)
+
+commit f7515769fd024faca888a47c58f87fb868b0e760
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jun 1 17:48:37 2018 -0700
+
+    [vector] Use Crap pool in push() as well
+
+ src/hb-coretext.cc      | 20 +++-----------------
+ src/hb-ot-cmap-table.hh |  3 ++-
+ src/hb-ot-layout.cc     |  3 +--
+ src/hb-ot-map.cc        | 17 ++++-------------
+ src/hb-ot-post-table.hh |  6 +-----
+ src/hb-private.hh       | 11 ++++-------
+ src/hb-subset-plan.cc   |  2 --
+ src/hb-subset.cc        |  2 --
+ src/hb-uniscribe.cc     | 28 ++++++++--------------------
+ 9 files changed, 23 insertions(+), 69 deletions(-)
+
+commit 975bdd5ef562e37655067b703b2b9ca7481f4985
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jun 1 17:37:13 2018 -0700
+
+    [vector] Keep success status
+
+ src/hb-private.hh | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+commit 1ab3c3ed1bbc404086aefffaef4b8261bb77caa7
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jun 1 17:34:24 2018 -0700
+
+    [vector] Whitespace
+
+ src/hb-private.hh | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+commit fb07d1a3ce896f8ebf8b5d5fef51dee91b6ead11
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jun 1 17:32:07 2018 -0700
+
+    Another attempt at making every compiler happy...
+
+    Sigh.
+
+ src/hb-private.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 4f76f956bb3a95b307322cdad4f8d3b97851678e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jun 1 17:28:47 2018 -0700
+
+    [map] Move prime_for to hb-static
+
+ src/hb-map-private.hh | 53
+ +--------------------------------------------------
+ src/hb-private.hh     |  2 ++
+ src/hb-static.cc      | 51
+ +++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 54 insertions(+), 52 deletions(-)
+
+commit 33d6f46bbbb4fdee110f1cb024a37ed2e46e5e22
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jun 1 17:25:35 2018 -0700
+
+    [set] Shrink page-map size again
+
+ src/hb-set-private.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 4ca211bce192b01644c82f721251604df935b603
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jun 1 17:18:57 2018 -0700
+
+    Fix hb_vector_size_t
+
+ src/hb-private.hh     | 4 ++--
+ src/hb-set-private.hh | 3 ++-
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+commit a070dfd333f411bf720120eb332f7da93077054f
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu May 31 16:47:39 2018 -0700
+
+    [subset] Have the subset fuzzer pull the text string to subset to
+    from the end of the fuzzer provided data.
+
+ test/fuzzing/hb-subset-fuzzer.cc | 54
+ +++++++++++++++++++++++++---------------
+ 1 file changed, 34 insertions(+), 20 deletions(-)
+
+commit bb6f4adac70a161505953414aa85ba78cd993c65
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jun 1 16:30:38 2018 -0700
+
+    Add Codacy badge
+
+ README | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit a7dd90f519fb7ab046e92ea3b7101c21d5040bbc
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jun 1 16:07:55 2018 -0700
+
+    Revert "Remove HB_DISALLOW_COPY_AND_ASSIGN"
+
+    This reverts commit ff92de766bf775bfdd3a01bda94de699180ff86a.
+
+    Revert that and remove ASSERT_POD. Let's see which bots are
+    unhappy with this configuration...
+
+ src/hb-map-private.hh      | 3 +--
+ src/hb-ot-shape-private.hh | 2 +-
+ src/hb-private.hh          | 6 +++++-
+ src/hb-set-private.hh      | 3 +--
+ 4 files changed, 8 insertions(+), 6 deletions(-)
+
+commit 7b50bf52f274f75f0b41008e0eab150124ae928a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 31 20:20:17 2018 -0700
+
+    Use NullPool for _hb_set_nil and _hb_map_nil
+
+ src/hb-map.cc     | 12 +-----------
+ src/hb-private.hh |  2 +-
+ src/hb-set.cc     |  8 +-------
+ 3 files changed, 3 insertions(+), 19 deletions(-)
+
+commit f040ca40ab3ebd4fdb85747477e0e656ab8b073e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 31 20:15:21 2018 -0700
+
+    [set] Minor
+
+ src/hb-set.cc | 2 --
+ 1 file changed, 2 deletions(-)
+
+commit 7185b273b3d92ee0ba0a589eb94387f25ea40b82
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 31 20:03:00 2018 -0700
+
+    Rename in_error to !successful
+
+    Towards possibly using Null pool for some nil objects.
+
+ src/hb-buffer-deserialize-json.hh    | 758
+ +++++++++++++++++------------------
+ src/hb-buffer-deserialize-json.rl    |   2 +-
+ src/hb-buffer-deserialize-text.hh    | 510 +++++++++++------------
+ src/hb-buffer-deserialize-text.rl    |   2 +-
+ src/hb-buffer-private.hh             |   2 +-
+ src/hb-buffer.cc                     |  24 +-
+ src/hb-map-private.hh                |  10 +-
+ src/hb-map.cc                        |   4 +-
+ src/hb-ot-layout-gsubgpos-private.hh |   4 +-
+ src/hb-ot-layout.cc                  |   2 +-
+ src/hb-ot-shape-complex-hangul.cc    |   8 +-
+ src/hb-ot-shape-complex-indic.cc     |   4 +-
+ src/hb-ot-shape-complex-khmer.cc     |   4 +-
+ src/hb-ot-shape-complex-myanmar.cc   |   2 +-
+ src/hb-ot-shape-complex-thai.cc      |   4 +-
+ src/hb-ot-shape-complex-use.cc       |   4 +-
+ src/hb-ot-shape-normalize.cc         |  12 +-
+ src/hb-ot-shape.cc                   |   2 +-
+ src/hb-set-private.hh                |  28 +-
+ src/hb-set.cc                        |   4 +-
+ 20 files changed, 696 insertions(+), 694 deletions(-)
+
+commit 353f4d2efc6c0ce32f5bee08bbdf5a268d720a6a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 31 19:52:16 2018 -0700
+
+    Fix a whitespace inconsistency
+
+    Null() and Crap() are only places that there's no space before '('...
+
+ src/dump-fon.cc   | 12 ++++++------
+ src/hb-private.hh |  2 +-
+ src/main.cc       |  2 +-
+ 3 files changed, 8 insertions(+), 8 deletions(-)
+
+commit e36cd1dfd36ed336f63883098dc870c56a5fc10d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 31 19:31:39 2018 -0700
+
+    Remove trivial HB_ATOMIC_INT_INIT()
+
+ src/hb-atomic-private.hh | 9 +--------
+ src/hb-object-private.hh | 2 +-
+ 2 files changed, 2 insertions(+), 9 deletions(-)
+
+commit 550a70f8011c4c1cfd27d739469e79cb98bcdd6e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 31 19:28:04 2018 -0700
+
+    Use 0 as inert object reference value instead of -1
+
+    Towards using Null object for nil objects.
+
+ src/hb-object-private.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit dcd1b07eeaf2c28f0d20b9812749810d069041e3
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 31 17:58:40 2018 -0700
+
+    Add const OffsetTo<> dereference
+
+    Unused, but now that we have CrapPool, implement it.
+
+ src/hb-open-type-private.hh | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 2baa357ac7fe2ae91029dff26a01b8ba1cc0b365
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu May 31 12:27:31 2018 +0430
+
+    Fix symbol export issue of prime_mod on Alpine bot
+
+    Apparently our gcc-6.4.0 on Alpine Linux distribution doesn't like
+    defining static const
+    inside a method, lets put that on outside the classes.
+
+ src/hb-map-private.hh | 89
+ ++++++++++++++++++++++++++-------------------------
+ 1 file changed, 45 insertions(+), 44 deletions(-)
+
+commit 54800f8322e8ab106d801fc332b7e813c58138ac
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 30 16:26:50 2018 -0700
+
+    [map] Mark prime_for HB_INTERNAL
+
+    Trying to see if it fixes gcc-4.2 bots.
+
+ src/hb-map-private.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit d600e844aa4736b52fe71c1b2a9fa785be5cfecc
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 30 16:25:46 2018 -0700
+
+    Add CrapOrNull
+
+ src/hb-private.hh | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+commit 251cc977e93a75cfdc34671760ef4241daebf60f
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed May 30 12:23:51 2018 -0700
+
+    [subset] Switch to using hb_map_t inside of hb_subset_plan_t.
+
+ src/hb-ot-cmap-table.hh |  20 +++---
+ src/hb-ot-glyf-table.hh |  12 ++--
+ src/hb-ot-hdmx-table.hh |  10 +--
+ src/hb-ot-hmtx-table.hh |   6 +-
+ src/hb-ot-maxp-table.hh |   4 +-
+ src/hb-ot-os2-table.hh  |  35 +++--------
+ src/hb-ot-post-table.hh |   2 +-
+ src/hb-subset-glyf.cc   |   9 ++-
+ src/hb-subset-plan.cc   | 159
+ ++++++++++++++++--------------------------------
+ src/hb-subset-plan.hh   |  68 +++++++++++++--------
+ src/hb-subset.cc        |   2 +-
+ 11 files changed, 139 insertions(+), 188 deletions(-)
+
+commit b3d45de6cff4501e6171ec9d9069af7de29584d4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 30 14:02:49 2018 -0700
+
+    [map] Fix size calculation
+
+    Don't know why I thought I should subtract one there...
+
+ src/hb-map-private.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ff92de766bf775bfdd3a01bda94de699180ff86a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 29 18:48:45 2018 -0700
+
+    Remove HB_DISALLOW_COPY_AND_ASSIGN
+
+    llvm-gcc-4.2 bot had this problem:
+    hb-private.hh:812: error: initializer specified for non-virtual method
+    'void hb_vector_t<Type, StaticSize>::operator=(const hb_vector_t<Type,
+    StaticSize>&) [with Type = hb_user_data_array_t::hb_user_data_item_t,
+    unsigned int StaticSize = 1u]'
+
+    Removing the delete didn't work with a constructor. So, remove
+    constructor.
+    Just disallow assignment.  Still better than nothing.
+
+ src/hb-map-private.hh      | 2 +-
+ src/hb-ot-shape-private.hh | 2 +-
+ src/hb-private.hh          | 6 +-----
+ src/hb-set-private.hh      | 2 +-
+ 4 files changed, 4 insertions(+), 8 deletions(-)
+
+commit a2444346220757e7743c972cbd24f925e72b419d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 29 18:32:57 2018 -0700
+
+    [map] Fix resize
+
+ src/hb-map-private.hh | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+commit efbab6ba3f7434fca41be1b38e4a5281695f231c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 29 18:21:55 2018 -0700
+
+    Disable use of thread_local
+
+    Clang build was failing with:
+
+    /usr/bin/ld: .libs/libharfbuzz_la-hb-blob.o: relocation R_X86_64_PC32
+    against undefined hidden symbol `_ZTH12_hb_CrapPool' can not be used
+    when making a shared object
+
+    Instead of fighting it, just disable use of it.
+
+ src/hb-private.hh | 4 ++--
+ src/hb-static.cc  | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+commit 8c2c5d450817d4cb6f782d286da6ac6d9e5a5e95
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 29 18:15:52 2018 -0700
+
+    [map] Not going to implement is_equal which is complicated
+
+ src/hb-map.h | 7 -------
+ 1 file changed, 7 deletions(-)
+
+commit ccd01c65559122499b38a44e4449cd5a828d0b05
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 29 18:13:13 2018 -0700
+
+    [map] Move prime_mod to header to avoid linkage issues in subset.so
+
+ src/hb-map-private.hh | 53
+ +++++++++++++++++++++++++++++++++++++++++++++++++--
+ src/hb-map.cc         | 52
+ --------------------------------------------------
+ 2 files changed, 51 insertions(+), 54 deletions(-)
+
+commit 6baebc5d559e15c7903a81f21be08b45537e7903
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 29 17:58:46 2018 -0700
+
+    [map] Fix copyright year
+
+ src/hb-map-private.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b0158129d2b161665f8872deeb540ac73349c2de
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 29 17:52:37 2018 -0700
+
+    [map] Minor
+
+ src/hb-map-private.hh | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 4099c66f70e1acf89013215ab3add42b11e31fea
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 29 17:52:07 2018 -0700
+
+    [map] Don't return INVALID from get() just because in_error
+
+ src/hb-map-private.hh | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 25783907737b561f7b8648b8e92dba601a439828
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 29 17:34:35 2018 -0700
+
+    [map] Fix bool use in C API
+
+ src/hb-map.cc | 2 +-
+ src/hb-map.h  | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit a9fa39dca56d3a96dddcdbeb1c55a3d55a6537da
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 29 17:31:01 2018 -0700
+
+    [map] More minor
+
+ src/hb-map-private.hh | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+commit f76c4a7708773eca7a2b8c7ff47f8b5ade5ca0d9
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 29 17:27:25 2018 -0700
+
+    [map] Make initial resize actually work
+
+ src/hb-map-private.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 661e9ae4a55c198eb9fdb2c104979dd55a0fa1f1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 29 17:09:17 2018 -0700
+
+    [map] Add clear(), is_empty(), and get_population()
+
+ src/hb-map-private.hh | 22 ++++++++++++++++++----
+ src/hb-map.cc         | 43 +++++++++++++++++++++++++++++++++++++++++++
+ src/hb-map.h          | 17 +++++++++--------
+ 3 files changed, 70 insertions(+), 12 deletions(-)
+
+commit b6959c33e23b464ddbe5fe98fafc80bbb669189c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 29 17:02:22 2018 -0700
+
+    [map] Minor
+
+ src/hb-map-private.hh | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+commit 686476a8ae0039f277eb55ab7bd69386d43a8dc7
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 29 17:00:02 2018 -0700
+
+    [map] Track population and occupancy separately
+
+ src/hb-map-private.hh | 30 +++++++++++++++++++++---------
+ src/hb-map.cc         |  1 +
+ 2 files changed, 22 insertions(+), 9 deletions(-)
+
+commit 8a978790cb4dc66816c2cd7b617829f3e9d6e88e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 29 16:45:20 2018 -0700
+
+    [map] Minor
+
+ src/hb-map.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6f12ce47c0ed8c2c4bb251cd6e685459af104db8
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 29 16:45:06 2018 -0700
+
+    Revert "[map] Return bool from set()"
+
+    This reverts commit face7cf55d4895ffca314c8448c0a749a26cc182.
+
+ src/hb-map-private.hh | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+commit fc51c45079feb7d77d25204c4c17a0733f1eca56
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 29 16:44:55 2018 -0700
+
+    Revert "[map] Make hb_map_set() return bool"
+
+    This reverts commit 7bf1980146cfc081b06264ac367b23ae9397adf1.
+
+ src/hb-map.cc | 4 ++--
+ src/hb-map.h  | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+commit 7bf1980146cfc081b06264ac367b23ae9397adf1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 29 16:42:44 2018 -0700
+
+    [map] Make hb_map_set() return bool
+
+ src/hb-map.cc | 4 ++--
+ src/hb-map.h  | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+commit face7cf55d4895ffca314c8448c0a749a26cc182
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 29 16:39:03 2018 -0700
+
+    [map] Return bool from set()
+
+ src/hb-map-private.hh | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+commit e94be200bd7976a26ea2d6df5050d9dab4de0f08
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 29 16:37:44 2018 -0700
+
+    [map] Implement operator[] for get()ting
+
+ src/hb-map-private.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 743fdd9c618c949d7f45324386bd0bb37435db46
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 29 16:28:48 2018 -0700
+
+    [map] First try at implementing an integer-to-integer hashmap
+
+    Fully untested.
+
+ src/Makefile.sources  |   3 +
+ src/hb-map-private.hh | 180 ++++++++++++++++++++++++++++++++
+ src/hb-map.cc         | 279
+ ++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-map.h          | 110 ++++++++++++++++++++
+ src/hb.h              |   1 +
+ 5 files changed, 573 insertions(+)
+
+commit 65c82179c9b3aafd90987485a49c09dbbb473c90
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat May 26 23:50:10 2018 +0430
+
+    [blob] Use MAP_NORESERVE if available (#1039)
+
+    MAP_NORESERVE is not available on macOS for example so set the flag
+    to zero if not defined on the headers.
+
+ src/hb-blob.cc | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+commit 1ce40d900a9c451d8d5814a9b30759d1e66f99c8
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 25 16:34:08 2018 -0700
+
+    [set] Remove stale comment
+
+ src/hb-set.h | 2 --
+ 1 file changed, 2 deletions(-)
+
+commit 6c2227640bc14754c9472fead5cd04ff25f91b52
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 25 16:21:27 2018 -0700
+
+    Add HB_DISALLOW_COPY_AND_ASSIGN
+
+ src/hb-ot-map-private.hh   |  1 -
+ src/hb-ot-shape-private.hh |  4 +---
+ src/hb-ot-shape.cc         |  2 --
+ src/hb-private.hh          | 10 ++++++++++
+ src/hb-set-private.hh      |  3 +++
+ 5 files changed, 14 insertions(+), 6 deletions(-)
+
+commit fd3d0042319c33c923a60d435779bf7ed5a9a6f5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 24 15:58:26 2018 -0700
+
+    Move pool definitions to hb-static.cc
+
+ src/Makefile.sources |  1 +
+ src/dump-emoji.cc    |  8 +-------
+ src/dump-fon.cc      |  6 +-----
+ src/hb-ot-layout.cc  |  6 ------
+ src/hb-static.cc     | 32 ++++++++++++++++++++++++++++++++
+ src/hb-subset.cc     |  5 ++---
+ src/main.cc          |  6 +-----
+ 7 files changed, 38 insertions(+), 26 deletions(-)
+
+commit 7f7b1370d37b9187f688dea5e6fee5ea7c2b7290
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 24 14:09:04 2018 -0700
+
+    Fix Uniscribe build
+
+    If a pointer type was passed to Null(), reinterpret_cast<> was
+    complaining about qualifiers being removed. Turns out I need the
+    const on
+    the other side of "Type" to fix that.  Also remove unused const from
+    NullPool type.
+
+ src/dump-emoji.cc   | 2 +-
+ src/dump-fon.cc     | 2 +-
+ src/hb-ot-layout.cc | 2 +-
+ src/hb-private.hh   | 6 +++---
+ src/hb-subset.cc    | 2 +-
+ src/main.cc         | 2 +-
+ 6 files changed, 8 insertions(+), 8 deletions(-)
+
+commit 31c4236d9643063e518289b28c3e17cedd8401e0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 24 13:38:46 2018 -0700
+
+    Underflow protection in hb_vector_t
+
+ src/hb-private.hh | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+commit f83e992c8b27111ab802fd7e5678592a0c717518
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 24 11:46:57 2018 -0700
+
+    Mark CrapPool thread_local
+
+    Not sure if I like to keep it. For now, aim for correctness.
+
+ src/dump-emoji.cc   |  2 +-
+ src/dump-fon.cc     |  2 +-
+ src/hb-ot-layout.cc |  2 +-
+ src/hb-private.hh   | 14 +++++++++++++-
+ src/hb-subset.cc    |  2 +-
+ src/main.cc         |  2 +-
+ 6 files changed, 18 insertions(+), 6 deletions(-)
+
+commit 5d80129891107c7f629c6950b5d257f2a867eee0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 24 11:33:15 2018 -0700
+
+    Add CrapPool
+
+    Common Regoin for Access Protection.  Like the NullPool, but writable.
+
+ src/dump-emoji.cc           |  1 +
+ src/dump-fon.cc             |  1 +
+ src/hb-open-type-private.hh | 11 +++++++++++
+ src/hb-ot-layout.cc         |  1 +
+ src/hb-private.hh           | 39 +++++++++++++++++++++++++++++++++++----
+ src/hb-subset.cc            |  1 +
+ src/main.cc                 |  1 +
+ 7 files changed, 51 insertions(+), 4 deletions(-)
+
+commit 673b764de050957b2d3b9972d9e55b3a2e5615f4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 23 20:12:23 2018 -0700
+
+    Move code around
+
+ src/hb-private.hh | 91
+ ++++++++++++++++++++++++++++++-------------------------
+ 1 file changed, 49 insertions(+), 42 deletions(-)
+
+commit 65aeabd62275b37c6bb6715f3341e45625f4ba6e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 23 16:15:28 2018 -0700
+
+    Add hb_vector_t::push(const Type &v)
+
+    Makes for cleaner code.
+
+ src/hb-coretext.cc      |  3 +--
+ src/hb-ot-post-table.hh |  3 +--
+ src/hb-private.hh       | 18 +++++++++++-------
+ src/hb-subset-plan.cc   | 12 +++++-------
+ src/hb-uniscribe.cc     |  8 ++------
+ 5 files changed, 20 insertions(+), 24 deletions(-)
+
+commit 38ae0add7001c4db506d3a2c18b9960a2cae7b5d
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed May 23 13:37:57 2018 +0430
+
+    [ci] Revive the SunCC bot
+
+    * Adds libnsl to the bot as it is now needed apparently
+    * Disables hb-icu, apparently the newer ICU itself is not compatible
+    with SunCC
+
+ .circleci/config.yml | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 6c818c5516913f2c8192d58bd2724b1d3bb60d24
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 22 22:00:05 2018 -0700
+
+    Actually enable vectorized operations
+
+    Fixup for previous commit. Was accidentally turned off.
+
+ src/hb-private.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f56a250b04f50f12c78d81d1a068187be3d95a8c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 22 21:36:07 2018 -0700
+
+    Another try at smart vectorization
+
+    Make clang happy. Also, don't use anonymous union.
+
+ src/hb-private.hh | 36 +++++++++++++++++++++++++-----------
+ 1 file changed, 25 insertions(+), 11 deletions(-)
+
+commit b995b501ef5cf113534c5aead6c85baea6cc423c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 22 21:06:22 2018 -0700
+
+    Try enabling vectorization smartly
+
+    We'll see if this sticks to the bots.
+
+ src/hb-private.hh     | 25 +++++++++++++++++--------
+ src/hb-set-private.hh |  7 -------
+ 2 files changed, 17 insertions(+), 15 deletions(-)
+
+commit dd22c29f951ceec98516d7cb378bf2aa7e21d89a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 22 20:57:19 2018 -0700
+
+    [set] Always check population before checking for equality
+
+ src/hb-set-private.hh | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit 2eb9bbd986f6930f1b2594b8971ac677e9647c93
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 22 18:28:13 2018 -0700
+
+    [test/text-rendering-tests] Update from upstream
+
+ test/shaping/data/text-rendering-tests/DISABLED         |   2 ++
+ test/shaping/data/text-rendering-tests/Makefile.sources |   2 ++
+ .../text-rendering-tests/fonts/TestMORXTwentyeight.ttf  | Bin 0 ->
+ 2660 bytes
+ .../text-rendering-tests/fonts/TestMORXTwentyseven.ttf  | Bin 0 ->
+ 2432 bytes
+ .../data/text-rendering-tests/fonts/TestShapeKndaV3.ttf | Bin 0 ->
+ 89400 bytes
+ .../data/text-rendering-tests/tests/MORX-27.tests       |   3 +++
+ .../data/text-rendering-tests/tests/MORX-28.tests       |   5 +++++
+ 7 files changed, 12 insertions(+)
+
+commit 8eb53b853dcc4b0cc8e240cff6bfc5acb92182b0
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri May 11 22:44:44 2018 +0430
+
+    Minor, make CreateFile compatible with the disabled writable flag
+
+    "writable" is not in use and probably we can go in the reverse
+    direction
+    and remove the flags that are useful for enabled writable, this
+    is just
+    for the sake of completeness however.
+
+ src/hb-blob.cc | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit 33eb1bd23b100a8e65a0e66621760368b5aecdaf
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri May 11 14:36:41 2018 +0430
+
+    Remove unnecessary headers and definitions of hb-blob (#1028)
+
+    It removes io.h and other polyfills which we no longer need as 7e76d74
+
+ src/hb-blob.cc | 22 ++++------------------
+ 1 file changed, 4 insertions(+), 18 deletions(-)
+
+commit 7e76d746e2555d5bba7f65d3958aa97a7f179d7b
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri May 11 13:40:33 2018 +0430
+
+    Make hb_blob_create_from_file more portable (#1027)
+
+    This makes it compatible with ARMCC which I had access in
+    a collaboration with @imgtec, thanks!
+
+    Basically hb_blob_create_from_file features three code paths,
+    mmap, Win32 and fallback.
+
+    We had fallback implementation even before this but it was relied
+    to "open" which is not available on some environments. This change
+    improved the situtation by using only fopen and friends for
+    fallback path.
+
+    Interestingly we could use "open" on Windows but in fact it was
+    emulated by MSVCRT so I've completely split that from Unix path
+    now that we have a distinct path for fallback path also.
+
+ src/hb-blob.cc | 64
+ +++++++++++++++++++++++++++++++++++++++-------------------
+ 1 file changed, 43 insertions(+), 21 deletions(-)
+
+commit e99d75ea9c4fe1f64d7f8408093741a682ed5243
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 9 15:28:30 2018 -0700
+
+    Fix warning
+
+ src/hb-ot-cmap-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 191c4edc5423017d9123d291462fbfa87a805218
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 9 15:27:17 2018 -0700
+
+    Reinstante DEFINE_NULL_DATA
+
+    Seems like I messed up; buffer overrun got reported.
+
+ src/hb-open-type-private.hh        |  2 ++
+ src/hb-ot-layout-common-private.hh | 13 +++----------
+ src/hb-private.hh                  | 13 +++++++++++++
+ 3 files changed, 18 insertions(+), 10 deletions(-)
+
+commit 93bdf9b2dfe18af0f1aa93b890f0be260f31d90e
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed May 9 23:24:17 2018 +0430
+
+    Use arrayZ on hb-coretext and hb-uniscribe and fix macOS/Win bots
+    (#1024)
+
+    Following to 63f57f4
+
+ src/hb-coretext.cc  |  2 +-
+ src/hb-uniscribe.cc | 12 ++++++------
+ 2 files changed, 7 insertions(+), 7 deletions(-)
+
+commit 63f57f4dab3d3179838d5d1cd03d116837a7e5c2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 8 16:56:11 2018 -0700
+
+    Mark more unsized array's as arrayZ
+
+ src/hb-aat-layout-common-private.hh  | 14 ++++----
+ src/hb-aat-layout-kerx-table.hh      |  2 +-
+ src/hb-aat-layout-morx-table.hh      |  6 ++--
+ src/hb-open-file-private.hh          |  6 ++--
+ src/hb-open-type-private.hh          | 40 +++++++++++-----------
+ src/hb-ot-cmap-table.hh              |  2 +-
+ src/hb-ot-color-cbdt-table.hh        | 10 +++---
+ src/hb-ot-layout-common-private.hh   | 12 +++----
+ src/hb-ot-layout-gsub-table.hh       | 16 ++++-----
+ src/hb-ot-layout-gsubgpos-private.hh | 64
+ ++++++++++++++++++------------------
+ src/hb-ot-post-table.hh              |  4 +--
+ src/hb-ot-var-avar-table.hh          | 26 +++++++--------
+ src/hb-private.hh                    | 54 +++++++++++++++---------------
+ src/hb-set-private.hh                |  4 +--
+ src/hb-subset.cc                     |  2 +-
+ 15 files changed, 131 insertions(+), 131 deletions(-)
+
+commit 091c17df5ac5f7ddc9b776481da845f4eda67570
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 8 16:42:45 2018 -0700
+
+    Use UnsizedArrayOf<> in one place where [VAR] was used
+
+    Trying to see how many can converted meaningfully.
+
+ src/hb-ot-layout-common-private.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 0644d92ef32b09e32d473c758d2a968f2d125628
+Merge: 2a2e28e7 3be050f0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 8 15:21:09 2018 -0700
+
+    Merge pull request #1018 from googlefonts/cmap4
+
+    [subset] Add cmap format 4 subsetting.
+
+commit 2a2e28e701319b4053a5c95f06c68f859e4ce99b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 8 03:00:21 2018 -0700
+
+    Don't keep instance in hb_table_lazy_loader_t
+
+ src/hb-open-type-private.hh | 15 ++++++---------
+ 1 file changed, 6 insertions(+), 9 deletions(-)
+
+commit 57bac8f6995fabbb98eb9824d822f370f9449488
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 8 02:55:20 2018 -0700
+
+    Rename
+
+ src/hb-open-type-private.hh | 6 +++---
+ src/hb-ot-layout-private.hh | 8 ++++----
+ 2 files changed, 7 insertions(+), 7 deletions(-)
+
+commit 2a46a020fd2fa2fe99886ab06188db5f0fa37ad1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 8 02:53:03 2018 -0700
+
+    Minor
+
+ src/hb-open-type-private.hh | 4 ++--
+ src/hb-ot-kern-table.hh     | 2 +-
+ src/hb-ot-layout.cc         | 6 +++---
+ src/hb-ot-post-table.hh     | 2 +-
+ 4 files changed, 7 insertions(+), 7 deletions(-)
+
+commit eba1c16a604d1be774f22541bf3e417f27a27c68
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 8 02:47:42 2018 -0700
+
+    Always lock blob in sanitize. Remove blob->lock_as() in favor of
+    blob->lock()
+
+ src/dump-emoji.cc             | 4 ++--
+ src/dump-fon.cc               | 2 +-
+ src/hb-aat-layout.cc          | 4 ++--
+ src/hb-blob-private.hh        | 6 ------
+ src/hb-face.cc                | 8 ++++----
+ src/hb-open-type-private.hh   | 8 ++++++--
+ src/hb-ot-cmap-table.hh       | 2 +-
+ src/hb-ot-color-cbdt-table.hh | 4 ++--
+ src/hb-ot-color-sbix-table.hh | 2 +-
+ src/hb-ot-color-svg-table.hh  | 2 +-
+ src/hb-ot-glyf-table.hh       | 6 +++---
+ src/hb-ot-hmtx-table.hh       | 8 ++++----
+ src/hb-ot-kern-table.hh       | 2 +-
+ src/hb-ot-layout.cc           | 6 +++---
+ src/hb-ot-post-table.hh       | 2 +-
+ src/hb-subset.cc              | 2 +-
+ src/main.cc                   | 2 +-
+ 17 files changed, 34 insertions(+), 36 deletions(-)
+
+commit b4fa50501414b7471e840f2ee6b9dfe87080b078
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 8 02:45:08 2018 -0700
+
+    Move Sanitizer::lock_instance<>() to blob->lock_as<>().
+
+ src/dump-emoji.cc             |  4 ++--
+ src/dump-fon.cc               |  3 +--
+ src/hb-aat-layout.cc          |  4 ++--
+ src/hb-blob-private.hh        | 17 +++++++++++++++++
+ src/hb-face.cc                |  9 +++++----
+ src/hb-open-type-private.hh   |  9 ++-------
+ src/hb-ot-cmap-table.hh       |  2 +-
+ src/hb-ot-color-cbdt-table.hh |  4 ++--
+ src/hb-ot-color-sbix-table.hh |  2 +-
+ src/hb-ot-color-svg-table.hh  |  2 +-
+ src/hb-ot-glyf-table.hh       |  6 +++---
+ src/hb-ot-hmtx-table.hh       |  8 ++++----
+ src/hb-ot-kern-table.hh       |  2 +-
+ src/hb-ot-layout.cc           |  6 +++---
+ src/hb-ot-post-table.hh       |  2 +-
+ src/hb-subset.cc              |  2 +-
+ src/main.cc                   |  2 +-
+ 17 files changed, 48 insertions(+), 36 deletions(-)
+
+commit abc12f7b8157c3981216d82ead60627db31a6c14
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 8 02:23:36 2018 -0700
+
+    Move null pool to hb-private
+
+ src/dump-emoji.cc                  |  6 ++---
+ src/dump-fon.cc                    | 14 +++++------
+ src/hb-aat-layout.cc               |  8 +++----
+ src/hb-open-type-private.hh        | 48
+ +++-----------------------------------
+ src/hb-ot-cmap-table.hh            |  4 ++--
+ src/hb-ot-color.cc                 |  4 ++--
+ src/hb-ot-layout-common-private.hh | 13 ++++++++---
+ src/hb-ot-layout.cc                | 22 ++++++++---------
+ src/hb-ot-math.cc                  |  4 ++--
+ src/hb-ot-var.cc                   |  6 ++---
+ src/hb-private.hh                  | 29 +++++++++++++++++++++++
+ src/hb-subset.cc                   |  4 ++--
+ src/main.cc                        |  2 +-
+ 13 files changed, 79 insertions(+), 85 deletions(-)
+
+commit 08e280fd84384f73d395918646ee044a5bbfee45
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 8 01:57:27 2018 -0700
+
+    Rename hb_string_t to hb_bytes_t
+
+ src/hb-ot-post-table.hh | 16 ++++++++--------
+ src/hb-private.hh       | 12 ++++++------
+ src/hb-string-array.hh  |  6 +++---
+ 3 files changed, 17 insertions(+), 17 deletions(-)
+
+commit bd021a67203aa5b07c31c02d63e6154da0c05d31
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 8 01:50:30 2018 -0700
+
+    Minor
+
+ src/hb-private.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 16e4ccf7b417f021948643012cbe7641ba02c039
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 8 01:47:05 2018 -0700
+
+    Allocate user-data-array on the heap
+
+    This saves each object allocation 72 bytes.  Now object overhead
+    is just
+    16 bytes (on x86) instead of 88 bytes. Neat.
+
+ src/hb-object-private.hh | 36 ++++++++++++++++++++++++++++--------
+ 1 file changed, 28 insertions(+), 8 deletions(-)
+
+commit 61920b21ca0c632ba58aef95c7f65f409cc0fbd2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 8 01:28:19 2018 -0700
+
+    Oops
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1023
+
+ src/hb-blob-private.hh | 77
+ ++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 77 insertions(+)
+
+commit f673cfbd64d0c9d97123500a7b851b9cfc09deb3
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 7 13:58:32 2018 -0700
+
+    Support scripts that are written both LTR and RTL
+
+    Right now only Old Italic is marked as such.
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1000
+
+ src/hb-buffer.cc                                         |   4 ++++
+ src/hb-common.cc                                         |   6 ++++++
+ src/hb-ot-shape.cc                                       |   7 +++++--
+ test/api/test-common.c                                   |   1 +
+ test/shaping/data/in-house/Makefile.sources              |   1 +
+ .../fonts/73e84dac2fc6a2d1bc9250d1414353661088937d.ttf   | Bin 0 ->
+ 1136 bytes
+ test/shaping/data/in-house/tests/none-directional.tests  |   3 +++
+ 7 files changed, 20 insertions(+), 2 deletions(-)
+
+commit 90869e6962caf0e55a480b5d7e777cc521596e8b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 7 14:04:01 2018 -0700
+
+    [ot] Apply langsys's required feature even if no other feature exists
+
+ src/hb-ot-map.cc | 3 ---
+ 1 file changed, 3 deletions(-)
+
+commit 90baf721978236f2e06dff89ad1cb0cace0753ea
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 3 22:14:54 2018 -0400
+
+    Move some blob functions to methods
+
+ src/hb-blob.cc | 80
+ +++++++++++++++++++++++++---------------------------------
+ 1 file changed, 34 insertions(+), 46 deletions(-)
+
+commit 5c64d61475f15d7f8de8993a52639735b2bcf750
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 3 21:10:57 2018 -0400
+
+    Add hb-blob-private.hh
+
+    Towards making blob more memory-allocation-friendly
+
+ src/Makefile.sources |  1 +
+ src/hb-blob.cc       | 21 +++++----------------
+ 2 files changed, 6 insertions(+), 16 deletions(-)
+
+commit 203dc44ebc141af0ba8c54edec2dc0405664997a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 3 21:03:27 2018 -0400
+
+    [ot-layout] Remove unused members
+
+    We should hang those off somewhere else. For now, the unused ones
+    can go.
+
+ src/hb-aat-layout-common-private.hh |  2 +-
+ src/hb-aat-layout.cc                |  6 ++++++
+ src/hb-ot-layout-private.hh         |  6 ------
+ src/hb-ot-layout.cc                 | 29 ++++++++---------------------
+ 4 files changed, 15 insertions(+), 28 deletions(-)
+
+commit ac92ed7d6875374451246a2391859fb763329adb
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue May 8 01:05:15 2018 +0430
+
+    Set inline hidden flag only on shared library building
+
+    To avoid need of CMP0063 which is not available on older CMake
+    versions
+
+ CMakeLists.txt | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit 3be050f07572d8556726b188668d727e3e7ba643
+Author: Garret Rieger <grieger@google.com>
+Date:   Fri May 4 11:23:32 2018 -0700
+
+    [subset] entrySelectorZ -> entrySelector.
+
+ src/hb-ot-cmap-table.hh | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+commit 7c22f98da789f831e1afb9078085b2e33d864d25
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu May 3 13:14:28 2018 -0700
+
+    [subset] add missing template parameter.
+
+ src/hb-ot-cmap-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 95eb0f3bafb7ab0e2451e3e2f8afc5008e18e88e
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu May 3 13:00:19 2018 -0700
+
+    [subset] Switch to a non-log using implementation of caculating
+    searchRangeZ, entrySelectorZ, and rangeShiftZ in cmap4.
+
+ src/hb-ot-cmap-table.hh | 12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+commit b0d7971be0fa3c9393b04038b8d0a76398b0d8d7
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu May 3 11:22:51 2018 -0700
+
+    [subset] Updated expected files for japanese subset integration
+    tests to include cmap4.
+
+ ...gular.default.3042,3044,3046,3048,304A,304B.ttf | Bin 3032 ->
+ 3112 bytes
+ ...gular.default.3042,3044,3046,73E0,5EA6,8F38.ttf | Bin 3268 ->
+ 3356 bytes
+ .../Mplus1p-Regular.default.61,63,65,6B.ttf        | Bin 2584 ->
+ 2656 bytes
+ ...gular.default.660E,6975,73E0,5EA6,8F38,6E05.ttf | Bin 3564 ->
+ 3652 bytes
+ .../japanese/Mplus1p-Regular.default.660E.ttf      | Bin 2348 ->
+ 2396 bytes
+ ...ar.drop-hints.3042,3044,3046,3048,304A,304B.ttf | Bin 2304 ->
+ 2384 bytes
+ ...ar.drop-hints.3042,3044,3046,73E0,5EA6,8F38.ttf | Bin 2540 ->
+ 2628 bytes
+ .../Mplus1p-Regular.drop-hints.61,63,65,6B.ttf     | Bin 1856 ->
+ 1928 bytes
+ ...ar.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.ttf | Bin 2836 ->
+ 2924 bytes
+ .../japanese/Mplus1p-Regular.drop-hints.660E.ttf   | Bin 1620 ->
+ 1668 bytes
+ test/subset/data/fonts/Mplus1p-Regular.ttf         | Bin 1758820 ->
+ 1757292 bytes
+ 11 files changed, 0 insertions(+), 0 deletions(-)
+
+commit 79479273170275447042aa50912acee74bbacdf6
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu May 3 11:18:02 2018 -0700
+
+    [subset] Update expected files for subset integration tests to
+    include cmap4.
+
+ .../basics/Roboto-Regular.abc.default.61,62,63.ttf    | Bin 2120 ->
+ 2168 bytes
+ .../basics/Roboto-Regular.abc.default.61,63.ttf       | Bin 1932 ->
+ 1988 bytes
+ .../expected/basics/Roboto-Regular.abc.default.61.ttf | Bin 1744 ->
+ 1792 bytes
+ .../expected/basics/Roboto-Regular.abc.default.62.ttf | Bin 1692 ->
+ 1740 bytes
+ .../expected/basics/Roboto-Regular.abc.default.63.ttf | Bin 1668 ->
+ 1716 bytes
+ .../basics/Roboto-Regular.abc.drop-hints.61,62,63.ttf | Bin 876 ->
+ 924 bytes
+ .../basics/Roboto-Regular.abc.drop-hints.61,63.ttf    | Bin 792 ->
+ 848 bytes
+ .../basics/Roboto-Regular.abc.drop-hints.61.ttf       | Bin 684 ->
+ 732 bytes
+ .../basics/Roboto-Regular.abc.drop-hints.62.ttf       | Bin 652 ->
+ 700 bytes
+ .../basics/Roboto-Regular.abc.drop-hints.63.ttf       | Bin 656 ->
+ 704 bytes
+ .../Roboto-Regular.default.1FC,21,41,20,62,63.ttf     | Bin 3700 ->
+ 3772 bytes
+ .../full-font/Roboto-Regular.default.61,62,63.ttf     | Bin 3320 ->
+ 3368 bytes
+ .../Roboto-Regular.default.D7,D8,D9,DA,DE.ttf         | Bin 3668 ->
+ 3732 bytes
+ .../Roboto-Regular.drop-hints.1FC,21,41,20,62,63.ttf  | Bin 2152 ->
+ 2224 bytes
+ .../full-font/Roboto-Regular.drop-hints.61,62,63.ttf  | Bin 1968 ->
+ 2016 bytes
+ .../Roboto-Regular.drop-hints.D7,D8,D9,DA,DE.ttf      | Bin 2188 ->
+ 2252 bytes
+ 16 files changed, 0 insertions(+), 0 deletions(-)
+
+commit a8e7f9b958dcb4e00226f78d0ff83f031bc1323d
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu May 3 10:59:00 2018 -0700
+
+    [subset] Get cmap tests passing again.
+
+ test/api/fonts/Roboto-Regular.D7,D8,D9,DA,DE.ttf | Bin 2972 -> 2816 bytes
+ test/api/test-subset-cmap.c                      |   2 +-
+ 2 files changed, 1 insertion(+), 1 deletion(-)
+
+commit c817992f495cba21bf468014f22afe349fbc799f
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu May 3 10:53:20 2018 -0700
+
+    [subset] Write out a format 4, plat 0 encoding record to match
+    fontTools.
+
+ src/hb-ot-cmap-table.hh     | 24 +++++++++++++++---------
+ test/api/test-subset-cmap.c |  2 +-
+ 2 files changed, 16 insertions(+), 10 deletions(-)
+
+commit 9ef55a4c1354028f4d5e81300cdaf8ce5e03b8e9
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed May 2 18:50:56 2018 -0700
+
+    [subset] A few bug fixes for cmap format 4 subsetting.
+
+ src/hb-ot-cmap-table.hh | 57
+ ++++++++++++++++++++++++++++---------------------
+ 1 file changed, 33 insertions(+), 24 deletions(-)
+
+commit 81ea75f5c860ef682184bd2c9d0ff8b48251e3ce
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed May 2 17:46:30 2018 -0700
+
+    [subset] Complete implementation of cmap4 subsetting.
+
+ src/hb-ot-cmap-table.hh | 31 ++++++++++++++++++++++++++++---
+ 1 file changed, 28 insertions(+), 3 deletions(-)
+
+commit 4195a52b041af749046b716dcac7d6560ae37611
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed May 2 17:11:18 2018 -0700
+
+    [subset] WIP implementation of serialize for cmap format 4.
+
+ src/hb-ot-cmap-table.hh | 39 ++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 38 insertions(+), 1 deletion(-)
+
+commit cfa592d31ce2fd1ec2765a69ab31bf80161479dd
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed May 2 16:37:38 2018 -0700
+
+    [subset] Add an implement for cmap format 4 create_sub_table_plan.
+
+ src/hb-ot-cmap-table.hh | 43 ++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 42 insertions(+), 1 deletion(-)
+
+commit 295d67ea7d0ddac5666bd6aa4b647dd9cbf8e8f7
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed May 2 16:12:04 2018 -0700
+
+    [subset] WIP cmap format 4 subsetting.
+
+ src/hb-ot-cmap-table.hh | 104
+ ++++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 88 insertions(+), 16 deletions(-)
+
+commit 0053d13283458996372f04bd501001d450523605
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed May 2 15:42:43 2018 -0700
+
+    [subset] Refactor cmap subsetting to make it possible to add support
+    for more sub tables.
+
+ src/hb-ot-cmap-table.hh | 161
+ ++++++++++++++++++++++++++++++------------------
+ 1 file changed, 102 insertions(+), 59 deletions(-)
+
+commit 03b27548123756dfd9988a8fc74bc78733fb2c44
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed May 2 15:42:08 2018 -0700
+
+    [subset] Add const to the hb_subset_plan_t input to a couple functions
+    in hb-subset-plan.
+
+ src/hb-subset-plan.cc |  4 ++--
+ src/hb-subset-plan.hh | 18 +++++++++---------
+ 2 files changed, 11 insertions(+), 11 deletions(-)
+
+commit 5b93f6916958e6096044372c1195501ea9f37436
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 2 14:59:14 2018 -0400
+
+    Rename some X-terminated members to Z-terminated
+
+    X-terminated means don't access this, it's not located correctly.
+    Z-terminated means this is a C array with no bound checking.
+
+ src/hb-aat-layout-morx-table.hh |  4 ++--
+ src/hb-open-type-private.hh     | 16 ++++++++--------
+ src/hb-ot-cmap-table.hh         | 28 ++++++++++++++--------------
+ src/hb-ot-glyf-table.hh         | 14 +++++++-------
+ src/hb-ot-var-avar-table.hh     |  6 +++---
+ 5 files changed, 34 insertions(+), 34 deletions(-)
+
+commit f1f6bc0a6f28a6611a247f37b8a83e6f782d7227
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 2 12:56:21 2018 -0400
+
+    [set] Fix init/fini of set on the stack to call object init/fini
+
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1017
+
+ src/hb-set-private.hh | 14 ++++++++++++--
+ src/hb-set.cc         |  4 ++--
+ 2 files changed, 14 insertions(+), 4 deletions(-)
+
+commit 37b95612d4ae8a9d75a1a5a5165bc073c709cf30
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 1 19:09:00 2018 -0400
+
+    Remove hb_auto_array_t
+
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1017
+
+ src/hb-coretext.cc      |  8 ++++----
+ src/hb-ot-cmap-table.hh |  2 +-
+ src/hb-ot-layout.cc     |  2 +-
+ src/hb-subset-plan.cc   |  2 +-
+ src/hb-uniscribe.cc     | 12 ++++++------
+ 5 files changed, 13 insertions(+), 13 deletions(-)
+
+commit 5c3112aec8b77d0fe39164f0f700e2a1aa810022
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 1 19:07:04 2018 -0400
+
+    s/hb_prealloced_array_t/hb_vector_t/g
+
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1017
+
+ src/hb-ot-cmap-table.hh  |  6 +++---
+ src/hb-ot-hmtx-table.hh  |  2 +-
+ src/hb-ot-map-private.hh | 10 +++++-----
+ src/hb-ot-os2-table.hh   |  4 ++--
+ src/hb-ot-post-table.hh  |  2 +-
+ src/hb-private.hh        |  6 +++---
+ src/hb-set-private.hh    |  4 ++--
+ src/hb-subset-glyf.cc    | 12 ++++++------
+ src/hb-subset-plan.cc    |  8 ++++----
+ src/hb-subset-plan.hh    |  6 +++---
+ src/hb-subset.cc         |  2 +-
+ 11 files changed, 31 insertions(+), 31 deletions(-)
+
+commit 4a01eb1234a72e6a91ed66d3ed60b5db378fe340
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 1 19:05:58 2018 -0400
+
+    Add hb_auto_t
+
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1017
+
+ src/hb-private.hh | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+commit a60ba7964ea196a3a02c48e813f2d9505d0cded2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 1 19:01:25 2018 -0400
+
+    s/finish/fini
+
+    For consistency.
+
+ src/hb-common.cc            |  8 ++++----
+ src/hb-mutex-private.hh     |  2 +-
+ src/hb-object-private.hh    | 10 +++++-----
+ src/hb-ot-layout-private.hh |  4 ++--
+ src/hb-ot-map-private.hh    | 14 +++++++-------
+ src/hb-ot-post-table.hh     |  2 +-
+ src/hb-ot-shape-private.hh  |  4 ++--
+ src/hb-ot-shape.cc          |  2 +-
+ src/hb-private.hh           | 16 ++++++++--------
+ src/hb-set-private.hh       |  6 +++---
+ src/hb-set.cc               |  2 +-
+ src/hb-subset-glyf.cc       |  6 +++---
+ src/hb-subset-plan.cc       |  6 +++---
+ src/hb-subset.cc            |  2 +-
+ 14 files changed, 42 insertions(+), 42 deletions(-)
+
+commit 17618ee2ecd02cb100ca911bd1907d108e9df475
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 1 18:39:25 2018 -0400
+
+    Add hb_object_fini()
+
+ src/hb-object-private.hh | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+commit bd5f918e2f86241d3e2cb706bf558de21c198860
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 1 18:27:41 2018 -0400
+
+    [set] Cache population
+
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1017
+
+ src/hb-set-private.hh | 24 +++++++++++++++++++++++-
+ src/hb-set.cc         |  1 +
+ 2 files changed, 24 insertions(+), 1 deletion(-)
+
+commit 93b03119da8674a3eddb7879857e9f17fa16fd2a
+Author: violet-sippial <38817272+violet-sippial@users.noreply.github.com>
+Date:   Sat Apr 28 20:29:13 2018 +0200
+
+    [subset] Do not compare ttx progress output in the tests
+
+    Suppress progress messages of ttx. This avoids comparing this output
+    to the reference file which lets the test fail.
+
+ test/subset/run-tests.py | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit a57f5a1a185c333ae21a4ac1577387312895e107
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Apr 28 13:58:55 2018 +0430
+
+    [dwrite] Minor, enable the original code assertions
+
+ src/hb-directwrite.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 9925030f19851957381b78c197e6f50c77fde756
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Apr 13 12:43:29 2018 +0430
+
+    Don't decompose Bengali Rra and Rha
+
+    Fixes #779 and follow up to b01d9b3d90e892341ee4463f2eda4600850b97d8
+
+ src/hb-ot-shape-complex-indic.cc                        |   3 +++
+ test/shaping/data/in-house/Makefile.sources             |   1 +
+ .../fonts/932ad5132c2761297c74e9976fe25b08e5ffa10b.ttf  | Bin 0 ->
+ 22980 bytes
+ test/shaping/data/in-house/tests/indic-decompose.tests  |   1 +
+ 4 files changed, 5 insertions(+)
+
+commit 5ad87a93fefcb94ee5f28de8d75903b2550c8d94
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Apr 25 16:44:04 2018 +0430
+
+    Minor, improve file reading failing condition comment
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=659212 for more context
+
+ src/hb-blob.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 2eaba80cbd3afb32363da93ebf6e60b11509d3f8
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Apr 24 09:04:15 2018 +0430
+
+    Minor, re-add unused mark to some of ragel defined state machines
+    (#1005)
+
+ src/hb-ot-shape-complex-indic-machine.hh   | 2 +-
+ src/hb-ot-shape-complex-indic-machine.rl   | 2 +-
+ src/hb-ot-shape-complex-khmer-machine.hh   | 2 +-
+ src/hb-ot-shape-complex-khmer-machine.rl   | 2 +-
+ src/hb-ot-shape-complex-myanmar-machine.hh | 2 +-
+ src/hb-ot-shape-complex-myanmar-machine.rl | 2 +-
+ src/hb-ot-shape-complex-use-machine.hh     | 2 +-
+ src/hb-ot-shape-complex-use-machine.rl     | 2 +-
+ 8 files changed, 8 insertions(+), 8 deletions(-)
+
+commit 48f0204cfea616a788d75c5065ad4999c7685513
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Apr 24 08:11:13 2018 +0430
+
+    Minor, re-add unused mark for two TRACE_ macros
+
+    To revive Travis CI bot
+
+ src/hb-debug.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 816b8169a90e0454b82a83719fc9ec1c83934d6f
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Apr 23 19:36:53 2018 +0430
+
+    Resolve some of clang's double-promotion warnings
+
+ src/hb-aat-layout-trak-table.hh    | 6 +++---
+ src/hb-open-type-private.hh        | 8 ++++----
+ src/hb-ot-layout-common-private.hh | 2 +-
+ 3 files changed, 8 insertions(+), 8 deletions(-)
+
+commit 24b8b9b227f53b4f67a713c994cec04a5f774634
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Apr 23 19:03:57 2018 +0430
+
+    Resolve clang's used-but-marked-unused warnings
+
+ src/hb-debug.hh                            | 4 ++--
+ src/hb-font.cc                             | 4 ++--
+ src/hb-ft.cc                               | 8 ++++----
+ src/hb-open-type-private.hh                | 2 +-
+ src/hb-ot-font.cc                          | 6 +++---
+ src/hb-ot-shape-complex-indic-machine.hh   | 2 +-
+ src/hb-ot-shape-complex-indic-machine.rl   | 2 +-
+ src/hb-ot-shape-complex-khmer-machine.hh   | 2 +-
+ src/hb-ot-shape-complex-khmer-machine.rl   | 2 +-
+ src/hb-ot-shape-complex-myanmar-machine.hh | 2 +-
+ src/hb-ot-shape-complex-myanmar-machine.rl | 2 +-
+ src/hb-ot-shape-complex-use-machine.hh     | 2 +-
+ src/hb-ot-shape-complex-use-machine.rl     | 2 +-
+ src/hb-set.cc                              | 2 +-
+ src/hb-unicode.cc                          | 2 +-
+ 15 files changed, 22 insertions(+), 22 deletions(-)
+
+commit eaf649450a29115ca0b2aac2921cc40c17aa55ac
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Apr 23 18:39:40 2018 +0430
+
+    Resolve clang's conditional-uninitialize warnings
+
+ src/hb-ot-layout-gpos-table.hh | 2 +-
+ src/hb-ot-shape-normalize.cc   | 4 ++--
+ util/view-cairo.cc             | 2 +-
+ 3 files changed, 4 insertions(+), 4 deletions(-)
+
+commit 8b0d642e6610dd44f98a986580451eb562276897
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Apr 23 18:37:35 2018 +0430
+
+    Resolve some of clang's zero-as-null-pointer-constant warnings
+
+ src/hb-coretext.cc              | 4 ++--
+ src/hb-dsalgs.hh                | 2 +-
+ src/hb-ot-os2-unicode-ranges.hh | 2 +-
+ 3 files changed, 4 insertions(+), 4 deletions(-)
+
+commit 8100380d9e6fdd52eb7054f3300046028dcde8f9
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Apr 22 10:58:37 2018 +0430
+
+    Minor, fix calloc call order
+
+ src/hb-blob.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 2a4cdfad20fa8f0d2894383c2f10a6983f88b34b
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Apr 20 21:12:58 2018 +0430
+
+    [aat/kerx] Minor (#1003)
+
+ src/hb-aat-layout-kerx-table.hh | 46
+ +++++++++++++++++++++--------------------
+ 1 file changed, 24 insertions(+), 22 deletions(-)
+
+commit ce17340b23d96f543cd88e400e631bdb5656331c
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Apr 20 10:29:06 2018 +0430
+
+    Add hb_blob_create_from_file, a new API (#926)
+
+ TODO                         |   2 -
+ docs/harfbuzz-sections.txt   |   1 +
+ src/dump-emoji.cc            |  33 +----------
+ src/dump-fon.cc              |  11 +---
+ src/hb-blob.cc               | 131
+ ++++++++++++++++++++++++++++++++++++++++---
+ src/hb-blob.h                |   2 +
+ src/main.cc                  |  26 +--------
+ src/test-buffer-serialize.cc |  42 +-------------
+ src/test-size-params.cc      |  42 +-------------
+ src/test-would-substitute.cc |  42 +-------------
+ src/test.cc                  |  42 +-------------
+ test/api/hb-subset-test.h    |  54 +-----------------
+ test/api/hb-test.h           |  33 -----------
+ util/options.cc              |  88 +++++++----------------------
+ util/options.hh              |   6 --
+ util/view-cairo.hh           |   3 +-
+ 16 files changed, 159 insertions(+), 399 deletions(-)
+
+commit 4fa1c6705a1bc5299adb5a848ceaf6ac8f33c0ba
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu Apr 19 15:30:35 2018 -0700
+
+    [subset] Check instruction offsets in glyph to ensure they are
+    in bounds.
+
+ src/hb-ot-glyf-table.hh                            |  18 ++++++++++--
+ .../oom-ccc61c92d589f895174cdef6ff2e3b20e9999a1a   | Bin 0 -> 63302 bytes
+ test/api/test-subset-glyf.c                        |  31
+ +++++++++++++++++++++
+ 3 files changed, 47 insertions(+), 2 deletions(-)
+
+commit 3c97614598ecd0bbccb2c90a8e0e99f010952b76
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu Apr 19 13:39:57 2018 -0700
+
+    [subset] In subset fuzzer run through drop hints and keep hints
+    pathways.
+
+ test/fuzzing/hb-subset-fuzzer.cc | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+commit 6fdeeb2ae3059ac1bc5ff99fd1655b4e94576151
+Author: Khaled Hosny <khaledhosny@eglug.org>
+Date:   Thu Apr 19 23:41:37 2018 +0300
+
+    [util] Check all specified shapers are known (#993)
+
+    A bit brute force and requires all shapers to be known, not just one.
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/956
+
+ util/options.cc | 22 ++++++++++++++++++++--
+ 1 file changed, 20 insertions(+), 2 deletions(-)
+
+commit 535fb23c0211c733d59f72c3431643d89dc16d16
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed Apr 18 17:37:39 2018 -0700
+
+    [subset] Add integration tests for cmap breakge.
+
+ .../full-font/Roboto-Regular.default.D7,D8,D9,DA,DE.ttf  | Bin 0 ->
+ 3668 bytes
+ .../Roboto-Regular.drop-hints.D7,D8,D9,DA,DE.ttf         | Bin 0 ->
+ 2188 bytes
+ test/subset/data/tests/full-font.tests                   |   1 +
+ 3 files changed, 1 insertion(+)
+
+commit e29c8e33f3debf721e18306b896df7a3233386ac
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed Apr 18 17:32:43 2018 -0700
+
+    [subset] Add a test for previous cmap breakage.
+
+ test/api/fonts/Roboto-Regular.D7,D8,D9,DA,DE.ttf | Bin 0 -> 2972 bytes
+ test/api/test-subset-cmap.c                      |  23
+ +++++++++++++++++++++++
+ 2 files changed, 23 insertions(+)
+
+commit 5e318e09ba590eef7b7ec047d7857f7f1eb7d787
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed Apr 18 17:13:37 2018 -0700
+
+    [subset] Fix broken cmap creation.
+    It was ignoring the restriction that gids must be consecutive to be
+    placed into a single group.
+
+ src/hb-ot-cmap-table.hh | 23 ++++++++++++++++-------
+ 1 file changed, 16 insertions(+), 7 deletions(-)
+
+commit a47070cd40cee51fe792cb838ff9f21e0ea482c6
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Apr 18 12:09:37 2018 +0430
+
+    Minor, annotate the added tables with likely/unlikely (#997)
+
+ src/hb-aat-fmtx-table.hh        |  2 +-
+ src/hb-aat-gcid-table.hh        |  2 +-
+ src/hb-aat-layout-ankr-table.hh |  7 ++++---
+ src/hb-aat-layout-bsln-table.hh |  9 +++++----
+ src/hb-aat-layout-feat-table.hh | 10 +++++-----
+ src/hb-aat-layout-kerx-table.hh | 12 ++++++------
+ src/hb-aat-layout-trak-table.hh | 21 +++++++++++++--------
+ src/hb-aat-ltag-table.hh        |  2 +-
+ src/hb-ot-color-colr-table.hh   | 10 +++++-----
+ src/hb-ot-color-cpal-table.hh   | 18 ++++++++++--------
+ src/hb-ot-color-sbix-table.hh   |  2 +-
+ src/hb-ot-color-svg-table.hh    |  6 +++---
+ 12 files changed, 55 insertions(+), 46 deletions(-)
+
+commit 1a309dcd72f9f54672a7341788a9b2241c922793
+Author: Garret Rieger <grieger@google.com>
+Date:   Tue Apr 17 18:11:32 2018 -0700
+
+    [subset] Remove printf's from fuzzing targets.
+
+ test/fuzzing/hb-subset-fuzzer.cc                | 1 -
+ test/fuzzing/hb-subset-get-codepoints-fuzzer.cc | 1 -
+ 2 files changed, 2 deletions(-)
+
+commit c55aa147c33eb733ab552d404a88749cb6ff6d73
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Apr 18 00:01:20 2018 +0430
+
+    Do sanitization before the use on 'main' mini-program (#994)
+
+ src/main.cc | 22 ++++++++++++++++++----
+ 1 file changed, 18 insertions(+), 4 deletions(-)
+
+commit c02b40e58f35ecd10c4945d2fa2b7074137c2c04
+Author: Garret Rieger <grieger@google.com>
+Date:   Tue Apr 17 08:21:22 2018 -0600
+
+    [subset] add a fuzzer target for subset_get_all_codepoints
+    method. (#987)
+
+ test/fuzzing/CMakeLists.txt                     |  7 ++++++-
+ test/fuzzing/Makefile.am                        | 16 ++++++++++++++++
+ test/fuzzing/hb-subset-get-codepoints-fuzzer.cc | 24
+ ++++++++++++++++++++++++
+ test/fuzzing/run-subset-fuzzer-tests.py         | 19 ++++++++++++++++++-
+ 4 files changed, 64 insertions(+), 2 deletions(-)
+
+commit 924803166e074c569ecfa7e598686f334777770f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 17 15:32:02 2018 +0200
+
+    [colr] Check layer record access
+
+ src/hb-ot-color-colr-table.hh | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+commit 5dadbb0fa096574b6bccd75cced203baf615fedf
+Author: Garret Rieger <grieger@google.com>
+Date:   Tue Apr 17 07:00:23 2018 -0600
+
+    [subset] Add implementation of cmap format 12 codepoint
+    listing. (#988)
+
+ src/hb-ot-cmap-table.hh                        |  21 +++++++++++-
+ test/api/fonts/Roboto-Regular.abc.format12.ttf | Bin 0 -> 2412 bytes
+ test/api/test-subset-codepoints.c              |  44
+ +++++++++++++++++++++++++
+ 3 files changed, 64 insertions(+), 1 deletion(-)
+
+commit 6771e79bcc2166b5c03ca615d271c8508d692416
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Apr 17 09:36:52 2018 +0430
+
+    Add pre-opentype font pages detection code (#986)
+
+    As Khaled's finding on #981 this is the way Uniscribe detects those
+    fonts. This is its detection part.
+
+ src/hb-ot-os2-table.hh | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+commit 277e328986d5887fa93c72dc8b12d842d41db87f
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Apr 17 09:13:35 2018 +0430
+
+    Make some of implicit header uses explicit (#989)
+
+    Splitted from #950 and #986 IIRC Chromium had a policy about this
+    encouraging it,
+    not sure about automated way to detect and add them but for now lets
+    have the needed
+    ones of them.
+
+ src/hb-aat-layout-morx-table.hh | 1 +
+ src/hb-aat-layout-trak-table.hh | 1 +
+ src/hb-ot-hdmx-table.hh         | 1 +
+ src/hb-ot-hmtx-table.hh         | 1 +
+ src/hb-ot-os2-table.hh          | 1 +
+ src/hb-ot-post-table.hh         | 1 +
+ 6 files changed, 6 insertions(+)
+
+commit f5811bad04be9dac8a4fca8e16904d6270e47777
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Apr 17 09:13:03 2018 +0430
+
+    Add round to F2DOT14 inner store setter (#990)
+
+    It uses floor implicitly without it but explicit use of round will
+    be more correct.
+
+ src/hb-open-type-private.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 39754fb65981fa8d11615e1dced852285ad09e4e
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Apr 16 15:09:27 2018 -0700
+
+    [subset] Don't assume the last segment in cmap 4 can be skipped,
+    actually check it.
+
+ src/hb-ot-cmap-table.hh | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+commit 21a181af2bf1582991c55de5f9281494733c5d12
+Author: Garret Rieger <grieger@google.com>
+Date:   Tue Apr 10 15:40:24 2018 -0700
+
+    [subset] sketch out support for a call that lists all codepoints
+    present in a font. Implement support for it in format 4 cmap sub
+    table.
+
+ src/hb-ot-cmap-table.hh                       |  37 ++++++++++++++--
+ src/hb-subset.cc                              |  14 ++++++
+ src/hb-subset.h                               |   5 ++-
+ test/api/Makefile.am                          |   2 +
+ test/api/fonts/Roboto-Regular.abc.format4.ttf | Bin 0 -> 2424 bytes
+ test/api/test-subset-codepoints.c             |  59
+ ++++++++++++++++++++++++++
+ 6 files changed, 113 insertions(+), 4 deletions(-)
+
+commit aef96e246cb695c4c83b8b6daed06a0d14fe1d32
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Apr 16 18:30:25 2018 +0430
+
+    Further improvements on dump-fon (#985)
+
+ src/dump-fon.cc | 153
+ +++++++++++++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 123 insertions(+), 30 deletions(-)
+
+commit 67dfb1937b703b3f1dc45251f4f884abf35c8576
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Apr 16 14:25:45 2018 +0430
+
+    Add dump-fon, a prototype on how to work with .fon/.fnt files (#981)
+
+ src/Makefile.am |   4 +
+ src/dump-fon.cc | 475
+ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 479 insertions(+)
+
+commit ce99dd04de830c8426af14c11dbee45f8bcc9e60
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Apr 15 22:08:50 2018 +0430
+
+    Implement to_float and set_float of F2DOT14 (#984)
+
+ src/hb-open-type-private.hh | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+commit 435b1878e710b67e21872572ad9fd5ed1369e97f
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Apr 15 21:18:48 2018 +0430
+
+    Rename UINT24 to HBUINT24 for consistency (#983)
+
+ src/hb-open-type-private.hh        | 2 +-
+ src/hb-ot-cmap-table.hh            | 6 +++---
+ src/hb-ot-layout-common-private.hh | 2 +-
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 3737c652a5e0b6d73b6090dc6c3863008c9dc8fd
+Merge: 632713ba 8f4c1230
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Apr 13 23:19:19 2018 +0430
+
+    Merge pull request #979 from ebraminio/msvc05
+
+    Reinstate support for Visual Studio 2005
+
+commit 8f4c12308a8d9e61922fb352e913acae46b28a88
+Author: Tor Andersson <tor.andersson@artifex.com>
+Date:   Fri Apr 13 23:01:54 2018 +0430
+
+    Reinstate support for Visual Studio 2005
+
+ src/hb-common.h    | 10 ++++++++++
+ src/hb-private.hh  |  6 +++---
+ src/hb-ucdn/ucdn.h | 10 ++++++++++
+ 3 files changed, 23 insertions(+), 3 deletions(-)
+
+commit 632713babbc349920f71f73cc304c9a18078fd6b
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Apr 12 14:17:03 2018 +0430
+
+    Always enable atexit on Android (#971)
+
+    Obviously one can use a newer NDK for building an updated HarfBuzz
+    instead that now pretty old version however I am concerned if that
+    version checking is working with clang that is used with the newer
+    NDK versions.
+
+ src/hb-private.hh | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+commit f24b0b9728f87d7599867a4ba6ec7d30da43b869
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Apr 12 13:40:45 2018 +0430
+
+    Update the links and revive the dead ones
+
+ src/hb-common.cc                           |  4 ++--
+ src/hb-common.h                            |  6 +++---
+ src/hb-coretext.cc                         |  6 +++---
+ src/hb-ft.cc                               |  2 +-
+ src/hb-ot-cmap-table.hh                    | 12 ++++++------
+ src/hb-ot-layout-common-private.hh         |  8 ++++----
+ src/hb-ot-layout-private.hh                |  2 +-
+ src/hb-ot-layout.h                         |  2 +-
+ src/hb-ot-shape-complex-arabic.cc          |  4 ++--
+ src/hb-ot-shape-complex-indic-private.hh   |  2 +-
+ src/hb-ot-shape-complex-indic.cc           |  4 ++--
+ src/hb-ot-shape-complex-khmer.cc           |  2 +-
+ src/hb-ot-shape-complex-myanmar-private.hh |  2 +-
+ src/hb-ot-shape-complex-myanmar.cc         |  2 +-
+ src/hb-ot-shape-complex-thai.cc            |  2 +-
+ src/hb-ot-shape-complex-use-private.hh     |  2 +-
+ src/hb-ot-shape-complex-use.cc             |  2 +-
+ src/hb-ot-shape-fallback.cc                |  2 +-
+ src/hb-ot-tag.cc                           |  9 ++++-----
+ src/hb-private.hh                          |  4 ++--
+ src/hb-string-array.hh                     |  2 +-
+ src/hb-unicode-private.hh                  | 18 +++++++++---------
+ test/api/test-buffer.c                     |  2 +-
+ test/api/test-ot-tag.c                     |  6 +++---
+ test/api/test-shape.c                      |  2 +-
+ 25 files changed, 54 insertions(+), 55 deletions(-)
+
+commit a02c3ee70f4ca9de1fd55f1d8d535f6bd0d32606
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Apr 12 13:38:19 2018 +0430
+
+    Add or update tables specifications links
+
+ src/hb-aat-fmtx-table.hh        |  9 ++++-----
+ src/hb-aat-gcid-table.hh        |  8 ++++----
+ src/hb-aat-layout-ankr-table.hh |  8 ++++----
+ src/hb-aat-layout-bsln-table.hh | 10 +++++-----
+ src/hb-aat-layout-feat-table.hh | 10 +++++-----
+ src/hb-aat-layout-kerx-table.hh |  4 ++++
+ src/hb-aat-layout-morx-table.hh |  4 ++++
+ src/hb-aat-layout-trak-table.hh |  4 ++++
+ src/hb-aat-ltag-table.hh        | 10 +++++-----
+ src/hb-ot-color-cbdt-table.hh   | 24 ++++++++++++------------
+ src/hb-ot-color-colr-table.hh   |  6 +++---
+ src/hb-ot-color-cpal-table.hh   |  6 +++---
+ src/hb-ot-color-sbix-table.hh   | 11 ++++++-----
+ src/hb-ot-color-svg-table.hh    |  3 ++-
+ src/hb-ot-glyf-table.hh         |  4 ++--
+ src/hb-ot-hdmx-table.hh         | 11 ++++++-----
+ src/hb-ot-head-table.hh         | 10 +++++-----
+ src/hb-ot-hhea-table.hh         | 15 ++++++++-------
+ src/hb-ot-hmtx-table.hh         | 14 +++++++-------
+ src/hb-ot-kern-table.hh         | 10 ++++++----
+ src/hb-ot-layout-base-table.hh  |  3 ++-
+ src/hb-ot-layout-gdef-table.hh  |  3 ++-
+ src/hb-ot-layout-gpos-table.hh  |  3 ++-
+ src/hb-ot-layout-gsub-table.hh  |  3 ++-
+ src/hb-ot-layout-jstf-table.hh  |  3 ++-
+ src/hb-ot-math-table.hh         |  3 ++-
+ src/hb-ot-maxp-table.hh         |  3 ++-
+ src/hb-ot-name-table.hh         |  4 ++--
+ src/hb-ot-os2-table.hh          |  3 +--
+ src/hb-ot-post-table.hh         |  8 ++++----
+ src/hb-ot-var-avar-table.hh     | 14 ++++++++------
+ src/hb-ot-var-fvar-table.hh     | 15 ++++++++-------
+ src/hb-ot-var-hvar-table.hh     |  7 ++++---
+ src/hb-ot-var-mvar-table.hh     |  4 ++--
+ 34 files changed, 142 insertions(+), 115 deletions(-)
+
+commit b799fc80777c1424e469a835f782b4e0f41c0043
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Apr 11 18:36:09 2018 +0430
+
+    minor, use LOffsetTo and LArrayOf whenever possible (#966)
+
+ src/hb-aat-layout-morx-table.hh | 10 ++++++----
+ src/hb-aat-ltag-table.hh        |  2 +-
+ src/hb-open-file-private.hh     |  2 +-
+ src/hb-ot-cmap-table.hh         |  4 ++--
+ 4 files changed, 10 insertions(+), 8 deletions(-)
+
+commit cb3fa70cd4c33e9f1c736f778cb3b606d15c0936
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Apr 11 18:00:13 2018 +0430
+
+    [dwrite] Cosmetic change (#963)
+
+ src/hb-directwrite.cc | 39 +++++++++++++++++++--------------------
+ src/hb-directwrite.h  |  5 +++--
+ 2 files changed, 22 insertions(+), 22 deletions(-)
+
+commit 09d5e5468858f4403ce91aca46749397b23825d9
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Apr 11 17:41:48 2018 +0430
+
+    [graphite] Use tabs instead 8 spaces (#965)
+
+ src/hb-graphite2.cc | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit 211da5efdcaff203eafda2a5081cd81e3d6cc35b
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Apr 11 17:41:24 2018 +0430
+
+    [aat] Cosmetic changes (#964)
+
+ src/hb-aat-gcid-table.hh            |  4 ++--
+ src/hb-aat-layout-ankr-table.hh     | 11 ++++++-----
+ src/hb-aat-layout-common-private.hh |  6 +++---
+ src/hb-aat-layout-kerx-table.hh     | 29 +++++++++++++++--------------
+ src/hb-aat-layout-morx-table.hh     |  6 +++---
+ src/hb-aat-layout-trak-table.hh     | 10 +++++-----
+ src/hb-aat-ltag-table.hh            |  8 ++++----
+ 7 files changed, 38 insertions(+), 36 deletions(-)
+
+commit f8bb582bcc2af6cae531d8255da002f0c514f1a9
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Apr 11 17:13:20 2018 +0430
+
+    [ot-color] Cosmetic changes (#962)
+
+ src/hb-open-type-private.hh   |  1 -
+ src/hb-ot-color-cbdt-table.hh | 10 +++++-----
+ src/hb-ot-color-cpal-table.hh |  4 ++--
+ src/hb-ot-color-sbix-table.hh | 41
+ ++++++++++++++++++++---------------------
+ src/hb-ot-color-svg-table.hh  | 37 +++++++++++++++++++------------------
+ 5 files changed, 46 insertions(+), 47 deletions(-)
+
+commit 1e1e9086c09185a7bd6f65d1e391418642229616
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Apr 10 03:26:01 2018 +0430
+
+    minor
+
+ src/dump-emoji.cc | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit a62554af89b8324c73c623e64f87ec822c757515
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Apr 10 00:53:50 2018 +0430
+
+    [colr/cpal] Improvements and add a sample renderer (#927)
+
+ src/Makefile.am               |  13 ++-
+ src/dump-emoji.cc             | 181
+ +++++++++++++++++++++++++++++++++++++++---
+ src/hb-ot-color-colr-table.hh |  43 +++++++++-
+ src/hb-ot-color-cpal-table.hh |  70 +++++++++-------
+ 4 files changed, 259 insertions(+), 48 deletions(-)
+
+commit f25731a3606ff0972505eeb934477480019ffcd3
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Apr 10 00:51:57 2018 +0430
+
+    [ci] Don't fail on brew warnings
+
+    Not the best fix but it works and we don't care about brew warnings,
+    so
+
+ .travis.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 58e569e5f7143a12cadcd6c42434558f9981e00e
+Author: Ryan Schmidt <ryandesign@macports.org>
+Date:   Thu Apr 5 17:03:36 2018 -0500
+
+    Fix build with CoreText on OS X 10.7 and earlier (#952)
+
+ src/hb-coretext.cc | 30 ++++++++++++++++++++++++++++--
+ 1 file changed, 28 insertions(+), 2 deletions(-)
+
+commit d3984b45b5d110f34febbb9e1d8a9c2203080a1b
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Apr 1 12:16:42 2018 +0430
+
+    [aat] Further improvements on feat (#948)
+
+ src/Makefile.sources                               |  2 +-
+ ...t-feat-table.hh => hb-aat-layout-feat-table.hh} | 48
+ +++++++++++-----------
+ src/hb-aat-layout.cc                               |  2 +-
+ 3 files changed, 25 insertions(+), 27 deletions(-)
+
+commit 93dad9ade7078d28086b2e5c3b5e8dafa67617d2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 31 17:06:17 2018 +0200
+
+    [hangul] Fix comment
+
+ src/hb-ot-shape-complex-hangul.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 44bf4320922d340d1357c4d42d093fa466c3610f
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Mar 31 16:51:36 2018 +0430
+
+    [aat] Implement feat table parsing (#947)
+
+ src/Makefile.sources     |   3 +-
+ src/hb-aat-feat-table.hh | 122
+ +++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-aat-layout.cc     |   1 +
+ 3 files changed, 125 insertions(+), 1 deletion(-)
+
+commit 08b8eb678a6cb74c118a32e75b880599e3ac4a7c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 31 12:15:50 2018 +0200
+
+    Another try at fixing linker issue
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/880
+
+ configure.ac    | 11 +++++++++--
+ src/Makefile.am |  6 ------
+ 2 files changed, 9 insertions(+), 8 deletions(-)
+
+commit eff36cd8f06ee992218ed3f198f6a4ea19d7089c
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Mar 30 22:25:35 2018 +0430
+
+    Minor build related changes
+
+ .editorconfig  | 3 +++
+ CMakeLists.txt | 6 +++---
+ configure.ac   | 2 +-
+ 3 files changed, 7 insertions(+), 4 deletions(-)
+
+commit 9d68f73d5cf3f3df6bc5516ada987d9019d3fe3d
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Mar 30 21:57:10 2018 +0430
+
+    [aat] Implement gcid table parsing (#944)
+
+ src/Makefile.sources     |  1 +
+ src/hb-aat-gcid-table.hh | 73
+ ++++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-aat-layout.cc     |  1 +
+ 3 files changed, 75 insertions(+)
+
+commit 0e230a83ae8a2c5fbe40dc0e74e5e7ead106e45e
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Mar 30 19:36:00 2018 +0430
+
+    [aat] Implement bsln table parsing (#943)
+
+ src/Makefile.sources            |   1 +
+ src/hb-aat-layout-bsln-table.hh | 156
+ ++++++++++++++++++++++++++++++++++++++++
+ src/hb-aat-layout.cc            |   3 +-
+ 3 files changed, 159 insertions(+), 1 deletion(-)
+
+commit 70d36543aa929320ff82a9ce589786e58adb1836
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Mar 30 05:00:28 2018 +0430
+
+    Make atexit callbacks threadsafe (#930)
+
+ src/hb-common.cc    | 60
+ +++++++++++++++++++++++++++++------------------------
+ src/hb-ft.cc        | 44 ++++++++++++++++++++++++---------------
+ src/hb-glib.cc      |  7 ++++++-
+ src/hb-icu.cc       |  7 ++++++-
+ src/hb-ot-font.cc   |  7 ++++++-
+ src/hb-shape.cc     |  7 ++++++-
+ src/hb-shaper.cc    |  9 ++++++--
+ src/hb-ucdn.cc      |  7 ++++++-
+ src/hb-uniscribe.cc |  8 +++++++
+ 9 files changed, 105 insertions(+), 51 deletions(-)
+
+commit d3a432a7b272917edb83f8fe8468120beb37206b
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Mar 30 04:58:47 2018 +0430
+
+    [graphite] Make get_table threadsafe (#931)
+
+ src/hb-graphite2.cc | 10 ++++++----
+ src/hb-graphite2.h  |  4 ++--
+ 2 files changed, 8 insertions(+), 6 deletions(-)
+
+commit 80395f14e8873f30d2c9a49e42fc9febf5c87e45
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Mar 29 22:00:41 2018 +0430
+
+    Make gen-* scripts LC_ALL=C compatible (#942)
+
+ src/gen-arabic-table.py | 5 ++---
+ src/gen-indic-table.py  | 4 ++--
+ src/gen-use-table.py    | 4 ++--
+ 3 files changed, 6 insertions(+), 7 deletions(-)
+
+commit 26e0cbd834e7a8bab331b395257e9c21dde4c2b1
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Mar 29 21:22:47 2018 +0430
+
+    Actual py3 compatibility making on gen-* scripts (#941)
+
+ src/gen-arabic-table.py       |  6 ++----
+ src/gen-indic-table.py        | 13 +++++--------
+ src/gen-use-table.py          | 12 +++++++++---
+ test/shaping/hb_test_tools.py |  4 ++--
+ 4 files changed, 18 insertions(+), 17 deletions(-)
+
+commit cab2c2c08c67e7d1606c03700df3e4e9c0dc59fd
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Mar 29 12:48:47 2018 +0430
+
+    Make more gen-* scripts py3 compatible (#940)
+
+ src/Makefile.am                                    |   2 +-
+ src/gen-arabic-table.py                            | 163
+ +++++++++++----------
+ src/gen-def.py                                     |   2 +-
+ src/gen-indic-table.py                             | 120 +++++++--------
+ src/gen-unicode-ranges.py                          |   8 +-
+ src/gen-use-table.py                               |   3 +-
+ src/hb-ot-shape-complex-indic-table.cc             |   2 -
+ src/sample.py                                      |   5 +-
+ test/fuzzing/run-shape-fuzzer-tests.py             |   3 +-
+ test/fuzzing/run-subset-fuzzer-tests.py            |   3 +-
+ .../data/text-rendering-tests/extract-tests.py     |   3 +-
+ test/shaping/hb_test_tools.py                      |   3 +-
+ test/shaping/run-tests.py                          |   3 +-
+ test/subset/run-tests.py                           |   2 +-
+ 14 files changed, 166 insertions(+), 156 deletions(-)
+
+commit 5f7f0bfa1ecef6406cb9670b4eb057ea12c28730
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Mar 29 04:22:53 2018 +0430
+
+    Add README.wine.md and touch some other docs (#939)
+
+ Makefile.am                       |  3 ++-
+ README.python => README.python.md | 12 +++++++++---
+ README.wine.md                    | 40
+ +++++++++++++++++++++++++++++++++++++++
+ RELEASING.md                      | 25 +++++++++++++-----------
+ 4 files changed, 65 insertions(+), 15 deletions(-)
+
+commit 5aa2c6e194bc75637d3f4862a096c0e7100072e2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Mar 28 15:33:51 2018 -0700
+
+    [atexit] Make hb_languate_item_t *langs freeing threadsafe
+
+    Part of https://github.com/harfbuzz/harfbuzz/issues/923
+
+ src/hb-common.cc | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+commit 8c9451107d46c87ed0e50e718977f0c286972f3b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Mar 28 14:06:58 2018 -0700
+
+    Fix one UBSan warning
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/935
+
+ src/hb-font-private.hh | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+commit 48baf7e389faf8a57649ddc572da2ec8ec8829bb
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Mar 28 13:38:51 2018 -0700
+
+    [uniscribe] Fixup for previous commit
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/934
+
+ src/hb-uniscribe.cc | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit b17e1a40885245df690a14c7528939b3881e1fe4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Mar 28 10:44:52 2018 -0700
+
+    [uniscribe] Fix assertion fail in checksum calc
+
+    Program:
+    Z:\Users\ebrahim\Desktop\harfbuzz\winbuild\util\.libs\hb-shape.exe
+    File: ../../src/hb-open-type-private.hh, Line 769
+
+    Expression: 0 == (Length & 3)
+
+    abnormal program termination
+
+ src/hb-uniscribe.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit a48dd6ef235d569d4b6f6f213ba93a54e142458d
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Mar 28 19:08:19 2018 +0430
+
+    Make gen-use-table.py py3 compatible (#932)
+
+ src/gen-use-table.py | 105
+ ++++++++++++++++++++++++++-------------------------
+ 1 file changed, 53 insertions(+), 52 deletions(-)
+
+commit 1c3372786c503f3f9108971dfa8956e4cb95f65d
+Author: Garret Rieger <grieger@google.com>
+Date:   Tue Mar 27 10:42:19 2018 -0700
+
+    [subset] fix infinite loop bug in looping through tables for
+    subsetting.
+
+ src/hb-subset.cc                                   |   2 +-
+ ...ase-minimized-hb-subset-fuzzer-5521982557782016 | Bin 0 -> 1228 bytes
+ test/api/test-subset.c                             |  23
+ +++++++++++++++++++++
+ 3 files changed, 24 insertions(+), 1 deletion(-)
+
+commit 8fd55422c3fa2279991d93875d912fca4ee89cf5
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Mar 27 16:57:09 2018 +0430
+
+    Implement an internal emojis dumper tool (#909)
+
+    Later to be expanded to a more general tool but for now it only
+    supports CBDT, SVG and CBDT.
+
+ CMakeLists.txt                |   2 +-
+ src/Makefile.am               |   4 ++
+ src/dump-emoji.cc             | 141
+ ++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-color-cbdt-table.hh |  71 +++++++++++++++++++++
+ src/hb-ot-color-sbix-table.hh |  79 ++++++++++++++---------
+ src/hb-ot-color-svg-table.hh  |  56 ++++++++++++-----
+ 6 files changed, 307 insertions(+), 46 deletions(-)
+
+commit 430f82817d048ac917f1956e07d9089b9fd7e695
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Mar 27 13:59:56 2018 +0430
+
+    [ci] Fix coverage build fail (#925)
+
+ src/Makefile.am | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+commit 07851aae9d28fed751663c543799f2b59369f892
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Mar 26 20:56:56 2018 -0600
+
+    [subset] Couple of fixes for fuzzer discovered issues. (#924)
+
+    * [subset] sanitize individual DeviceRecord's as part of hdmx
+    sanitization.
+
+    * [subset] Fix out of bounds read with non-two byte align glyphs.
+
+    * [subset] Just use size_device_record >= DeviceRecord::min_size.
+
+    * [subset] Add TODO.
+
+    * [subset] Re-order checks in hdmx sanitize.
+
+ src/hb-ot-hdmx-table.hh                            |   1 +
+ src/hb-subset-glyf.cc                              |   6 +++---
+ src/hb-subset.cc                                   |   6 +++++-
+ ...ase-minimized-hb-subset-fuzzer-5609911946838016 | Bin 0 -> 313 bytes
+ ...ase-minimized-hb-subset-fuzzer-6651660668502016 | Bin 0 -> 15229 bytes
+ test/api/test-subset-hdmx.c                        |  23
+ +++++++++++++++++++++
+ 6 files changed, 32 insertions(+), 4 deletions(-)
+
+commit 6f46883f5b74b206a3b77246891ab2ac57a27c4e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Mar 26 19:55:22 2018 -0700
+
+    [hdmx] Minor
+
+ src/hb-ot-hdmx-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit c589681926e50834bdc614479efced7382dfbf61
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Mar 26 19:55:16 2018 -0700
+
+    Minor
+
+ src/check-symbols.sh | 2 --
+ 1 file changed, 2 deletions(-)
+
+commit 19ec366fb12afe5fce23239bbeb61e67d732a169
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Mar 26 15:09:54 2018 -0700
+
+    Fix previous commit
+
+    Automake has this stupid behavior where if your Makefile.am has
+    syntactic error, it can get to a state that make succeeds but just
+    ignores broken Makefile.am.  Ouch.
+
+ src/Makefile.am | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 44b6c77c64d367eb3c9227cf1c0fbaff4ab294b2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Mar 26 14:26:45 2018 -0700
+
+    Try fixing linking again
+
+    Before 1.7.5, we were setting -fno-exceptions etc on CXXFLAGS. In
+    1.7.6
+    we set it as CPPFLAGS. Try fixing. Also, I'm fairly sure it's safe to
+    set these unconditionally.
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/880 (or so I hope)
+
+ src/Makefile.am      | 19 +++++++------------
+ test/api/Makefile.am |  2 +-
+ 2 files changed, 8 insertions(+), 13 deletions(-)
+
+commit e4d1cbfb4fbc17d7dbe08133d1e5e181e1c9bbc5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Mar 26 14:09:29 2018 -0700
+
+    Add HB_SUBSET_BUILTIN
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/865
+
+ src/hb-subset.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit c14b24fcd0052fc6100c32deea6ee1dcb0c98f85
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Mar 26 10:44:54 2018 -0700
+
+    Add HB_NO_ATEXIT
+
+ src/hb-private.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit aa53cb50ba3eea5c23458207faf879bd162d6599
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Mar 26 13:28:26 2018 +0430
+
+    [aat] Unprefix not essentially layout tables (#921)
+
+ src/Makefile.sources                                      | 4 ++--
+ src/{hb-aat-layout-fmtx-table.hh => hb-aat-fmtx-table.hh} | 7 ++++---
+ src/hb-aat-layout.cc                                      | 4 ++--
+ src/{hb-aat-layout-ltag-table.hh => hb-aat-ltag-table.hh} | 7 ++++---
+ 4 files changed, 12 insertions(+), 10 deletions(-)
+
+commit 8269791900cc765234915b29c974b34ed1f35519
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Sun Mar 25 20:50:41 2018 -0400
+
+    Allow trailing non-numeric chars in --unicodes
+
+ util/options.cc | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit a289aaff477dfbda25b90ba5ffb1296518d68d21
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Mar 26 01:14:07 2018 -0700
+
+    [aat/ltag] Whitespace
+
+ src/hb-aat-layout-ltag-table.hh | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+commit 158f2810b2868c7398dc80cbb089b88a566ce99e
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Mar 26 12:04:30 2018 +0430
+
+    [aat/ltag] Implement the table parsing (#911)
+
+ src/Makefile.sources            |  2 ++
+ src/hb-aat-layout-fmtx-table.hh |  6 ++--
+ src/hb-aat-layout-kerx-table.hh |  4 +--
+ src/hb-aat-layout-ltag-table.hh | 80
+ +++++++++++++++++++++++++++++++++++++++++
+ src/hb-aat-layout-morx-table.hh |  4 +--
+ src/hb-aat-layout-trak-table.hh |  4 +--
+ src/hb-aat-layout.cc            |  3 +-
+ 7 files changed, 93 insertions(+), 10 deletions(-)
+
+commit 9eee38a55cdcbfd34b530dcc8defff84057a9eb2
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Mar 25 23:56:02 2018 +0430
+
+    [aat/fmtx] Implement the table parsing (#910)
+
+ src/hb-aat-layout-fmtx-table.hh | 67
+ +++++++++++++++++++++++++++++++++++++++++
+ src/hb-aat-layout-trak-table.hh |  4 +--
+ src/hb-aat-layout.cc            |  1 +
+ 3 files changed, 70 insertions(+), 2 deletions(-)
+
+commit 1d3f4f835175c658c63e96be12052b80d27cf6fa
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Mar 25 18:45:50 2018 +0430
+
+    [ci] Add a build only apple-gcc-4.2 i686 bot
+
+ .circleci/config.yml | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+commit fe18c471a4aee1f6eba62383b64f0a8969cbc6ea
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Mar 25 18:19:23 2018 +0430
+
+    [dwrite] minor
+
+ src/dev-run.sh        |   5 ++-
+ src/hb-directwrite.cc | 118
+ ++++++++++++++++++++------------------------------
+ 2 files changed, 50 insertions(+), 73 deletions(-)
+
+commit ebccd019749e24e6c045518ee1ffbfc947744204
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 24 17:51:55 2018 -0700
+
+    More ULL fixes
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/901
+
+ src/hb-private.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 7ec3ba21f0dc43f9f8ea1fc4344d3ea4524841b1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 24 14:12:12 2018 -0700
+
+    Define uint64_t constants with ULL suffix
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/901
+
+ src/hb-private.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 19256bef9d264f96187261929992b96e61fa43fd
+Author: Chun-wei Fan <fanchunwei@src.gnome.org>
+Date:   Mon Mar 12 13:33:03 2018 +0800
+
+    hb-private.hh: Add fallback implementation for round()
+
+    For pre-C99 compilers that do not support round(), we need to have a
+    simplistic implementation for it, when it is not detected during build
+    configuration, either via CMake or autotools, by using floor() and
+    ceil(), which are provided in the pre-C99 compilers.
+
+    Please see discussion at commit 86a0ac2 for more details for re-adding
+    this patch.
+
+ src/hb-private.hh | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+commit 95f0458f44e9a7ec250f1bc7d9f060745dbabcf3
+Author: Nikolaus Waxweiler <madigens@gmail.com>
+Date:   Fri Mar 23 19:38:11 2018 +0000
+
+    Policy 0063 must be enabled to have hidden inline visibility... (#900)
+
+    ...on static builds.
+
+ CMakeLists.txt | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 2a236063392c4f7c4d718be36d2dec2b8804b560
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Mar 23 18:37:01 2018 +0430
+
+    Fix llvm-gcc-4.2 compile issue and add a macOS bot to test it (#899)
+
+ .circleci/config.yml        | 16 ++++++++++++++++
+ src/hb-open-file-private.hh | 12 +++++++-----
+ src/hb-ot-glyf-table.hh     | 40 ++++++++++++++++++++++------------------
+ src/hb-ot-kern-table.hh     |  2 +-
+ 4 files changed, 46 insertions(+), 24 deletions(-)
+
+commit 7919033ce8f6fd32b2dd980ad0aa59c7149a4827
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Mar 22 16:04:38 2018 +0430
+
+    [dwrite] Replace rest of 'malloc/free's with 'new/delete' (#897)
+
+ src/hb-directwrite.cc | 251
+ +++++++++++++++++++++++++-------------------------
+ 1 file changed, 127 insertions(+), 124 deletions(-)
+
+commit 3f55e0e74680c246819233a7250df612821698d7
+Author: Garret Rieger <grieger@google.com>
+Date:   Tue Mar 20 17:36:52 2018 -0700
+
+    [subset] Check for the Null table and not nullptr to detect failure
+    to find a table in glyf accelerator.
+
+ src/hb-ot-glyf-table.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 45def99eae81e470be3c38d2962aafaaa85500b9
+Author: Garret Rieger <grieger@google.com>
+Date:   Tue Mar 20 17:28:47 2018 -0700
+
+    [subset] Fix to debug message.
+
+ src/hb-subset-glyf.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 139661404006b8be039436a81cb6b1a73ec44042
+Author: Garret Rieger <grieger@google.com>
+Date:   Tue Mar 20 16:55:42 2018 -0700
+
+    [subset] don't use pointers returned from push after array has
+    resized in hb-subset-glyf.cc
+
+ src/hb-subset-glyf.cc                                   |   9 +++++++--
+ .../crash-b577db318b30f2851828a4c9ef97cb30678b1b54      | Bin 0 ->
+ 22473 bytes
+ 2 files changed, 7 insertions(+), 2 deletions(-)
+
+commit 3531efdb4c641ef543ea0686fef9289307d52096
+Author: Garret Rieger <grieger@google.com>
+Date:   Tue Mar 20 16:31:21 2018 -0700
+
+    [subset] Fixed out of bounds read when subsetting hdmx.
+
+ src/hb-ot-hdmx-table.hh                            |  30
+ ++++++++++++++++-----
+ .../crash-ccc61c92d589f895174cdef6ff2e3b20e9999a1a | Bin 0 -> 63302 bytes
+ test/api/test-subset-hdmx.c                        |  23 ++++++++++++++++
+ 3 files changed, 47 insertions(+), 6 deletions(-)
+
+commit e597436b994c0a553e85e4c2dbd74aa037e69b60
+Author: Garret Rieger <grieger@google.com>
+Date:   Tue Mar 20 13:00:49 2018 -0700
+
+    [subset] Disable glyf accelerator_t methods if it didn't successfully
+    init.
+
+ src/hb-ot-glyf-table.hh                            |   7 ++++++-
+ .../crash-4b60576767ee4d9fe1cc10959d89baf73d4e8249 | Bin 0 -> 3140 bytes
+ test/api/test-subset.c                             |  23
+ +++++++++++++++++++++
+ 3 files changed, 29 insertions(+), 1 deletion(-)
+
+commit 7251181b56af564e2a9444f002f8ac03f98c7ee3
+Author: Garret Rieger <grieger@google.com>
+Date:   Tue Mar 20 11:21:06 2018 -0700
+
+    [subset] Fix infinite loop in there are more then 32 tables.
+
+ src/hb-subset.cc                                   |   1 +
+ test/api/Makefile.am                               |   1 +
+ .../oom-6ef8c96d3710262511bcc730dce9c00e722cb653   | Bin 0 -> 24233 bytes
+ test/api/test-subset.c                             |  62
+ +++++++++++++++++++++
+ 4 files changed, 64 insertions(+)
+
+commit 1a94804d35d533d39849d21a177039c4cbfade98
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Mar 19 18:39:22 2018 -0700
+
+    [subset] Add a fix for segfault in hmtx/vmtx subsetting code.
+
+ src/hb-ot-hmtx-table.hh     | 13 +++++++++++--
+ test/api/test-subset-hmtx.c |  3 ++-
+ 2 files changed, 13 insertions(+), 3 deletions(-)
+
+commit 31281d6a17a03a124456a4cab54e31b248b41267
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Mar 19 17:47:57 2018 -0700
+
+    [subset] Add a test demonstrating a seg fault while subsetting hmtx.
+
+ .../crash-e4e0bb1458a91b692eba492c907ae1f94e635480 | Bin 0 -> 63302 bytes
+ test/api/test-subset-hmtx.c                        |  22
+ +++++++++++++++++++++
+ 2 files changed, 22 insertions(+)
+
+commit b5c7d6cffc2098dafa06822b28a5fd4f6218b60c
+Author: Garret Rieger <grieger@google.com>
+Date:   Fri Mar 16 10:20:21 2018 -0700
+
+    [subset] Restore subset to hb-subset-fuzzer.
+
+ test/fuzzing/Makefile.am         | 2 +-
+ test/fuzzing/hb-subset-fuzzer.cc | 2 --
+ 2 files changed, 1 insertion(+), 3 deletions(-)
+
+commit 957e7756634a4fdf1654041e20e883cf964ecac9
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Mar 19 12:19:42 2018 +0330
+
+    [dwrite] Use new again and enable the build on msys2 bots (#890)
+
+ appveyor.yml          |  7 ++++---
+ src/hb-directwrite.cc | 19 ++++++++-----------
+ 2 files changed, 12 insertions(+), 14 deletions(-)
+
+commit 8d1b4082ae01b8fd87b2e83c89f670c1c7cfa0b1
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Mar 17 01:05:03 2018 +0330
+
+    Appropriate fix for msys2 bot fail on gen-def.py (#894)
+
+ src/Makefile.am | 2 +-
+ src/gen-def.py  | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 7b4333b090a3adf04519ec853456cafff07dedf0
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Mar 16 22:45:09 2018 +0330
+
+    Do feature test before adding -Bsymbolic-functions, autotools part
+    (#892)
+
+ configure.ac             |  2 +-
+ m4/ax_check_link_flag.m4 | 74
+ ++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 75 insertions(+), 1 deletion(-)
+
+commit d68f00e4d8b061f56d3bd46d5ed1bc51406a4f1a
+Author: Joel Winarske <joel.winarske@gmail.com>
+Date:   Fri Mar 16 12:14:27 2018 -0700
+
+    Do feature test before adding -Bsymbolic-functions, cmake part (#889)
+
+ CMakeLists.txt | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+commit 42d3271cc39050c9df5f8c7345322ae90592158e
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Mar 16 22:39:58 2018 +0330
+
+    [cmake] Don't hide symbols by default (#891)
+
+    But keep use of cmake idiomatic way of making inlines hidden
+
+ CMakeLists.txt | 17 ++---------------
+ 1 file changed, 2 insertions(+), 15 deletions(-)
+
+commit 584693e0cb3585a910b18d7916d7e554ecdf619a
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu Mar 15 18:27:01 2018 -0700
+
+    [subset] Test not linking libharfbuzz-subset-fuzzing into
+    hb-subset-fuzzer.
+
+ test/fuzzing/Makefile.am                | 2 +-
+ test/fuzzing/hb-subset-fuzzer.cc        | 2 ++
+ test/fuzzing/run-subset-fuzzer-tests.py | 2 +-
+ 3 files changed, 4 insertions(+), 2 deletions(-)
+
+commit 3f9361fe7a68896d2a5a44709ec08fe510144215
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu Mar 15 18:06:15 2018 -0700
+
+    [subset] Test hb-shape-fuzzer in run-subset-fuzzer-tests.
+
+ test/fuzzing/run-subset-fuzzer-tests.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ce368e0d05147e70d8ad90383d748644b07f1d6f
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu Mar 15 18:04:54 2018 -0700
+
+    [subset] make libharfbuzz-subset-fuzzing.la depend on lib target.
+
+ test/fuzzing/Makefile.am | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 85a57029cdad634f56aa3ccc768e72bcb03888e3
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu Mar 15 16:31:38 2018 -0700
+
+    [subset] %d -> %zu
+
+ test/fuzzing/hb-subset-fuzzer.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 318eea585329807477aab4eec173b561a08a46ca
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu Mar 15 16:14:01 2018 -0700
+
+    [subset] Add some more logging to hb-subset-fuzzer.
+
+ test/fuzzing/hb-subset-fuzzer.cc | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 64bab8b3d009ed4327c2db9fa3425682de225810
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu Mar 15 16:12:00 2018 -0700
+
+    [subset] Fix run-shape-fuzzer-tests.py. It was generating incorrect
+    paths for input fonts.
+
+ test/fuzzing/run-shape-fuzzer-tests.py | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 6f9a584371ba4a9a63be3fa89f46474047a43ceb
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu Mar 15 15:41:08 2018 -0700
+
+    [subset] Add more verbose output for subset fuzzer test.
+
+ test/fuzzing/run-shape-fuzzer-tests.py  | 2 +-
+ test/fuzzing/run-subset-fuzzer-tests.py | 8 ++++++--
+ 2 files changed, 7 insertions(+), 3 deletions(-)
+
+commit 0ce0f8781213f8f01b9ebc8cfa31434784899952
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu Mar 15 13:04:31 2018 -0700
+
+    [subset] Rename hb-fuzzer -> hb-shape-fuzzer.
+
+ test/fuzzing/CMakeLists.txt                              | 16
+ ++++++++--------
+ test/fuzzing/Makefile.am                                 | 16
+ ++++++++--------
+ test/fuzzing/{hb-fuzzer.cc => hb-shape-fuzzer.cc}        |  0
+ .../{run-fuzzer-tests.py => run-shape-fuzzer-tests.py}   | 12
+ ++++++------
+ 4 files changed, 22 insertions(+), 22 deletions(-)
+
+commit 1e9bd6d5ff0af0189b6398c5e13cff11ee70762b
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed Mar 14 19:58:15 2018 -0700
+
+    [subset] Add rub-subset-fuzzer-tests.py to dist files.
+
+ test/fuzzing/Makefile.am | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 474afaafd908a9c8174e05d693ac214ef2cc2597
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed Mar 14 19:15:33 2018 -0700
+
+    [subset] Add a test runner for hb-subset-fuzzer and cmake build
+    config.
+
+ test/fuzzing/CMakeLists.txt             |  9 +++++++++
+ test/fuzzing/Makefile.am                |  3 ++-
+ test/fuzzing/run-subset-fuzzer-tests.py | 31
+ +++++++++++++++++++++++++++++++
+ 3 files changed, 42 insertions(+), 1 deletion(-)
+
+commit aa9612d35f59f7f269fba4797c8da491844c56ec
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Mar 12 18:04:34 2018 -0700
+
+    [subset] Fix fuzzing build for hb-subset-fuzzer.
+
+ src/Makefile.am          | 19 +++----------------
+ test/fuzzing/Makefile.am |  1 +
+ 2 files changed, 4 insertions(+), 16 deletions(-)
+
+commit b674fc1f9fa36857214ddaba3d32877f03ffec8c
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Mar 12 16:33:47 2018 -0700
+
+    [subset] Add missing destroy of subsetting result in subset fuzzer.
+
+ test/fuzzing/hb-subset-fuzzer.cc | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 1beb08862e9bd668599f0385d7ba59272fc24912
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Mar 12 16:08:16 2018 -0700
+
+    [subset] First pass at setting up a fuzzing program for hb-subset.
+
+ src/Makefile.am                  | 24 +++++++++++++++++++++++-
+ test/fuzzing/Makefile.am         | 15 +++++++++++++++
+ test/fuzzing/hb-subset-fuzzer.cc | 37
+ +++++++++++++++++++++++++++++++++++++
+ 3 files changed, 75 insertions(+), 1 deletion(-)
+
+commit 127096e4748d6381339342fc2750dd540e815fa5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Mar 15 13:23:27 2018 -0700
+
+    [util] Remove line buffering
+
+    Something weird seems to be going on. Just kill it.
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/888
+
+ configure.ac    |  2 +-
+ util/options.cc | 12 ------------
+ 2 files changed, 1 insertion(+), 13 deletions(-)
+
+commit e6e2ee2b923f8ab7c0694d4557375ba316e15dff
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Mar 15 09:05:22 2018 -0700
+
+    Remove extra stdbool includes
+
+    They are handled in our common header.
+
+ test/api/test-subset-post.c | 2 --
+ test/api/test-subset-vmtx.c | 2 --
+ 2 files changed, 4 deletions(-)
+
+commit a0dccb6188d7a9174643c7239041cb1a5300b957
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Mar 14 16:31:53 2018 +0100
+
+    Add NameID
+
+ src/hb-aat-layout-trak-table.hh    |  8 ++++----
+ src/hb-open-type-private.hh        |  3 +++
+ src/hb-ot-layout-common-private.hh | 10 +++++-----
+ src/hb-ot-var-fvar-table.hh        |  6 +++---
+ 4 files changed, 15 insertions(+), 12 deletions(-)
+
+commit 56946d21c0696ed6a098434537979396171c9bfb
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Mar 14 16:26:33 2018 +0100
+
+    [color/COLR] Simplify
+
+ src/hb-ot-color-colr-table.hh | 48
+ +++----------------------------------------
+ 1 file changed, 3 insertions(+), 45 deletions(-)
+
+commit 6418ae4e8a3f4681cb4e7d54c589562930bc0678
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Mar 14 16:18:42 2018 +0100
+
+    [color/COLR] Clean up
+
+ src/hb-aat-layout-common-private.hh | 84
+ -------------------------------------
+ src/hb-open-type-private.hh         | 84
+ +++++++++++++++++++++++++++++++++++++
+ src/hb-ot-color-colr-table.hh       | 30 ++++++-------
+ 3 files changed, 99 insertions(+), 99 deletions(-)
+
+commit 150c53ee969876c2831b6165cb71655e7ce2dbdb
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Mar 14 16:08:12 2018 +0100
+
+    [color/COLR] Fix bad sanitize
+
+    Bad bad bad bad code. Don't do that. If compiler's not happy,
+    understand why.
+
+ src/hb-ot-color-colr-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 399c800b93879186da2b7c892c7aa21468f062f2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Mar 14 16:03:01 2018 +0100
+
+    [color/COLR] Clean up
+
+ src/hb-ot-color-colr-table.hh | 32 +++++++++++++++++---------------
+ 1 file changed, 17 insertions(+), 15 deletions(-)
+
+commit 9e337341d54c4ee12eec58e025a6831bb976d61f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Mar 14 15:52:53 2018 +0100
+
+    [color/cbdt] Clean up
+
+ src/hb-ot-color-cbdt-table.hh | 112
+ ++++++++++++++++++++----------------------
+ 1 file changed, 54 insertions(+), 58 deletions(-)
+
+commit 86a0ac284fc4c2ce96354bfdf32878b6db5c77bd
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Mar 14 15:51:33 2018 +0100
+
+    Revert "hb-private.hh: Add fallback implementation for round()"
+
+    This reverts commit b9dcbb1f8312d8606b230f75594d40b7d4087004.
+
+    This is gross. Should be only done if a specific macro is defined. Not
+    the other way
+    around. This fails my build as autotools companions where not
+    added anyway.
+
+ src/hb-private.hh | 13 -------------
+ 1 file changed, 13 deletions(-)
+
+commit 791d80a1d42ce0bd7c5f0a3d3d10c562a6161a82
+Merge: d4907e83 22de9bf5
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Mar 15 11:40:52 2018 +0330
+
+    Merge pull request #886 from madig/only-export-visible-symbols
+
+    CMake: hide symbols by default on non-MSVC, define export attribute
+
+commit 22de9bf56d80dbf6a13a06beafd21711bdab78af
+Author: Nikolaus Waxweiler <nikolaus.waxweiler@daltonmaag.com>
+Date:   Wed Mar 14 10:29:24 2018 +0000
+
+    Enable implicit symbol hiding for all libraries, static and shared
+
+    This covers all built libraries now and both static and shared builds.
+
+ CMakeLists.txt | 35 +++++++++++++++++++++++------------
+ 1 file changed, 23 insertions(+), 12 deletions(-)
+
+commit d4907e83ef8e0d03acb701957cc1ee9acacb0a19
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Mar 14 11:04:28 2018 +0330
+
+    [dwrite] GCC/mingw/msys2 compatibility (#884)
+
+ src/hb-directwrite.cc | 37 +++++++++++++++++++++----------------
+ 1 file changed, 21 insertions(+), 16 deletions(-)
+
+commit 93f8f89dedd2f8cf5eb40165a20d009de24c5eda
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Mar 14 09:56:31 2018 +0330
+
+    [ci] Trying to fix gen-def issue on appveyor (#885)
+
+ src/gen-def.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ce975dce7ae8950b6e7b9a2d0c00ead9d45f73ff
+Author: Nikolaus Waxweiler <madigens@gmail.com>
+Date:   Wed Mar 14 00:50:32 2018 +0000
+
+    CMake: hide symbols by default on non-MSVC, define export attribute
+
+    This change makes sure that non-MSVC builds using CMake properly hide
+    non-exported functions.
+
+ CMakeLists.txt | 20 ++++++++++++--------
+ 1 file changed, 12 insertions(+), 8 deletions(-)
+
+commit a12dd6f75d85cf29ed78182ac97a12ebbcf77375
+Merge: 28f25f32 7c43adab
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Mar 14 02:54:07 2018 +0330
+
+    Merge pull request #877 from fanc999/master.msvc
+
+    Fix CMake builds on Windows, MSVC in particular
+
+commit 7c43adab6deb9302a24cc857c4aaa9b6b62215d2
+Author: Chun-wei Fan <fanchunwei@src.gnome.org>
+Date:   Mon Mar 12 16:43:53 2018 +0800
+
+    CMake: Fix utility program installation
+
+    Put in the utility program that was missed in installation by
+    replacing
+    the one that was duplicated.
+
+ CMakeLists.txt | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit e9b8002a6024d7a9b6de204897345ae77bb50881
+Author: Chun-wei Fan <fanchunwei@src.gnome.org>
+Date:   Mon Mar 12 16:23:57 2018 +0800
+
+    CMake: Fix introspection on Windows
+
+    The list of source files to pass to g-ir-scanner is becoming too
+    long for Windows, as Windows imposes a 8192-character limit for
+    command
+    lines, so we need to first transform that list into a listings
+    file, and
+    then use the --filelist option for g-ir-scanner to build the
+    introspection files.
+
+ CMakeLists.txt | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+commit 831d4a2dab1f229811c3a90b791f2a19c88fc1b5
+Author: Chun-wei Fan <fanchunwei@src.gnome.org>
+Date:   Mon Mar 12 13:48:55 2018 +0800
+
+    test/api: Fix building subset tests
+
+    Include stdbool.h in hb-setset-test.h instead of in the individual
+    sources, if it is found; otherwise use a simplistic fallback for it if
+    it is not found.
+
+    Also declare variables at the top of the block, to build on pre-C99
+    compiliers.
+
+ test/api/hb-subset-test.h   | 17 +++++++++++++++--
+ test/api/test-subset-cmap.c |  8 ++++----
+ test/api/test-subset-glyf.c | 23 ++++++++++++++---------
+ test/api/test-subset-hdmx.c |  8 ++++----
+ test/api/test-subset-hmtx.c | 17 ++++++++++-------
+ test/api/test-subset-os2.c  |  4 ++--
+ 6 files changed, 49 insertions(+), 28 deletions(-)
+
+commit eda6a5ea807ba8a4e7fa20ad0273b394ed72d106
+Author: Chun-wei Fan <fanchunwei@src.gnome.org>
+Date:   Mon Mar 12 13:38:01 2018 +0800
+
+    CMake: Fix running tests on Windows
+
+    For the API tests, output the test programs at $(TOP_BUILDDIR) so that
+    the freshly-built DLLs will be available for the test programs.  For
+    those that are run through the Python wrapper scripts, use
+    ${PYTHON_EXECUTABLE} instead of plain 'python' in case the Python
+    interpreter is not in the PATH.
+
+ test/api/CMakeLists.txt     | 7 ++++++-
+ test/fuzzing/CMakeLists.txt | 2 +-
+ test/shaping/CMakeLists.txt | 4 ++--
+ test/subset/CMakeLists.txt  | 2 +-
+ 4 files changed, 10 insertions(+), 5 deletions(-)
+
+commit b9dcbb1f8312d8606b230f75594d40b7d4087004
+Author: Chun-wei Fan <fanchunwei@src.gnome.org>
+Date:   Mon Mar 12 13:33:03 2018 +0800
+
+    hb-private.hh: Add fallback implementation for round()
+
+    Add a simplistic round() implementation for our purposes, used
+    when the
+    compiler does not support round() directly.
+
+ src/hb-private.hh | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+commit 89dbabff65a39dfb0d9ad036516d5b96c37739de
+Author: Chun-wei Fan <fanchunwei@src.gnome.org>
+Date:   Mon Mar 12 13:27:38 2018 +0800
+
+    configure.ac/CMake: Check for round() and stdbool.h
+
+    Not all the compilers that HarfBuzz is buildable on supports round()
+    and
+    has the header stdbool.h, so we check for them and define HAVE_ROUND
+    and
+    HAVE_STDBOOL_H repsectively in our CFLAGS so that we include them only
+    when they are found, or use fallback implementations when necessary.
+
+    Also include FindPythonInterp earlier as we need PYTHON_EXECUTABLE
+    to be
+    set for running the tests.
+
+ CMakeLists.txt | 12 ++++++++++--
+ configure.ac   |  9 ++++++++-
+ 2 files changed, 18 insertions(+), 3 deletions(-)
+
+commit 28f25f32fc63c3e1ae0d04b6eb5ea6b729fb2228
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Mar 12 14:00:11 2018 +0330
+
+    [ot-color/SVG] Minor (#878)
+
+ src/hb-ot-color-svg-table.hh | 24 ++++++++++++++++--------
+ 1 file changed, 16 insertions(+), 8 deletions(-)
+
+commit fb0f3e3767b488651f13978c1fd8651aefdd6b83
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Mar 11 20:38:40 2018 +0100
+
+    [sbix] Clean up
+
+ src/hb-ot-color-sbix-table.hh | 70
+ +++++++++++++++++++++++--------------------
+ 1 file changed, 37 insertions(+), 33 deletions(-)
+
+commit 218fa7166e9626f2036d08882854a86d753e4192
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Mar 10 11:13:52 2018 +0330
+
+    [ot-color] SVG table implementation (#874)
+
+ src/Makefile.sources         |   3 +-
+ src/hb-ot-color-svg-table.hh | 111
+ +++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-layout.cc          |   1 +
+ 3 files changed, 114 insertions(+), 1 deletion(-)
+
+commit 4c63c82383cba11f2c44c00cbc953863346e627c
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Mar 10 11:07:56 2018 +0330
+
+    [ot-color] sbix table implementation (#870)
+
+ src/Makefile.sources          |   1 +
+ src/hb-ot-color-sbix-table.hh | 128
+ ++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-layout.cc           |   1 +
+ 3 files changed, 130 insertions(+)
+
+commit 62b3d8fb7034c53e0804689d58e2eb7330e04430
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Mar 10 00:44:36 2018 +0330
+
+    [dev-run] minor
+
+ src/dev-run.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 743ef317619a57ebf5a75935db0eecccade5d5b7
+Merge: 9206762b 39b2f69f
+Author: Garret Rieger <grieger@google.com>
+Date:   Fri Mar 9 12:06:52 2018 -0700
+
+    Merge pull request #872 from googlefonts/drop-tables
+
+    [subset] Drop the same tables by default as fontTools does.
+
+commit 9206762bbd4033e97d6d35ef1cce1b7940fbc935
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Mar 9 15:43:03 2018 +0330
+
+    Make subset test runner compatible with py3
+
+    Fixes #873
+
+ test/subset/run-tests.py | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit dbadb871d1ca62eff10768564fc0a17b9aaa4d63
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Mar 9 15:25:59 2018 +0330
+
+    [ci] Enable subset tests on ArchLinux to test
+
+    This makes ArchLinux bots fail, a starting point to #873
+
+ .circleci/config.yml | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+commit 39b2f69fab3b8aec1296dcda111d358559d39f0b
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu Mar 8 16:30:36 2018 -0800
+
+    [subset] Drop the same tables by default as fontTools does.
+
+ src/hb-subset.cc | 49 ++++++++++++++++++++++++++++++++++---------------
+ 1 file changed, 34 insertions(+), 15 deletions(-)
+
+commit dbe552770fa7cec91bba750e0e81aaeae96b3caf
+Merge: 2ebf4c69 8548fa15
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu Mar 8 15:50:25 2018 -0700
+
+    Merge pull request #871 from googlefonts/mplus
+
+    [subset] Add a Japanese font to the subset integration tests.
+
+commit 8548fa152241d6c5b020146f97aac15934ba0065
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed Mar 7 12:37:03 2018 -0800
+
+    [subset] Drop cmap 12, platform 0 tables from Mplus1p expected files.
+
+ ...-Regular.default.3042,3044,3046,3048,304A,304B.ttf | Bin 3040 ->
+ 3032 bytes
+ ...-Regular.default.3042,3044,3046,73E0,5EA6,8F38.ttf | Bin 3276 ->
+ 3268 bytes
+ .../japanese/Mplus1p-Regular.default.61,63,65,6B.ttf  | Bin 2592 ->
+ 2584 bytes
+ ...-Regular.default.660E,6975,73E0,5EA6,8F38,6E05.ttf | Bin 3572 ->
+ 3564 bytes
+ .../japanese/Mplus1p-Regular.default.660E.ttf         | Bin 2356 ->
+ 2348 bytes
+ ...gular.drop-hints.3042,3044,3046,3048,304A,304B.ttf | Bin 2312 ->
+ 2304 bytes
+ ...gular.drop-hints.3042,3044,3046,73E0,5EA6,8F38.ttf | Bin 2548 ->
+ 2540 bytes
+ .../Mplus1p-Regular.drop-hints.61,63,65,6B.ttf        | Bin 1864 ->
+ 1856 bytes
+ ...gular.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.ttf | Bin 2844 ->
+ 2836 bytes
+ .../japanese/Mplus1p-Regular.drop-hints.660E.ttf      | Bin 1628 ->
+ 1620 bytes
+ 10 files changed, 0 insertions(+), 0 deletions(-)
+
+commit 9b00b9a10d5fdfd2d9deb1b0e847695797b7e09b
+Author: Garret Rieger <grieger@google.com>
+Date:   Tue Mar 6 17:47:40 2018 -0800
+
+    [subset] Fix deadlock waiting for process output in subset test
+    runner.
+
+ test/subset/run-tests.py | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit bfec28a7db0631f42dd420a8c04638624e4602af
+Author: Garret Rieger <grieger@google.com>
+Date:   Tue Mar 6 15:43:08 2018 -0800
+
+    [subset] add some extra logging to subset run-tests.py.
+
+ test/subset/run-tests.py | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit c7d814eaa8e9af6c447124ceeaa896eb5e17abd7
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu Mar 1 18:20:00 2018 -0800
+
+    [subset] Add japanese font file to subset integration tests.
+
+ test/subset/data/Makefile.am                          |   1 +
+ test/subset/data/Makefile.sources                     |   1 +
+ ...-Regular.default.3042,3044,3046,3048,304A,304B.ttf | Bin 0 ->
+ 3040 bytes
+ ...-Regular.default.3042,3044,3046,73E0,5EA6,8F38.ttf | Bin 0 ->
+ 3276 bytes
+ .../japanese/Mplus1p-Regular.default.61,63,65,6B.ttf  | Bin 0 ->
+ 2592 bytes
+ ...-Regular.default.660E,6975,73E0,5EA6,8F38,6E05.ttf | Bin 0 ->
+ 3572 bytes
+ .../japanese/Mplus1p-Regular.default.660E.ttf         | Bin 0 ->
+ 2356 bytes
+ ...gular.drop-hints.3042,3044,3046,3048,304A,304B.ttf | Bin 0 ->
+ 2312 bytes
+ ...gular.drop-hints.3042,3044,3046,73E0,5EA6,8F38.ttf | Bin 0 ->
+ 2548 bytes
+ .../Mplus1p-Regular.drop-hints.61,63,65,6B.ttf        | Bin 0 ->
+ 1864 bytes
+ ...gular.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.ttf | Bin 0 ->
+ 2844 bytes
+ .../japanese/Mplus1p-Regular.drop-hints.660E.ttf      | Bin 0 ->
+ 1628 bytes
+ test/subset/data/fonts/Mplus1p-Regular.ttf            | Bin 0 ->
+ 1758820 bytes
+ test/subset/data/tests/japanese.tests                 |  16
+ ++++++++++++++++
+ 14 files changed, 18 insertions(+)
+
+commit 2ebf4c69b18452caa0c871aebec9785e80348166
+Merge: 1ab51480 869ccac5
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu Mar 8 14:41:59 2018 -0700
+
+    Merge pull request #868 from googlefonts/post
+
+    [subset] Drop glyph names from post when subsetting.
+
+commit 869ccac5ab69060f2db2893014b5538539fd4f45
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu Mar 8 11:06:49 2018 -0800
+
+    [subset] use create_sub_blob instead of manually copying the post
+    table.
+
+ src/hb-ot-post-table.hh | 20 +++++++-------------
+ 1 file changed, 7 insertions(+), 13 deletions(-)
+
+commit ec47cd95ba6c550314a1cbcc46fafd7946e52ece
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed Mar 7 10:33:02 2018 -0800
+
+    [subset] Unit test to check that post subsetting drops glyph names.
+
+ test/api/Makefile.am                               |   2 +
+ ...lus1p-Regular.660E,6975,73E0,5EA6,8F38,6E05.ttf | Bin 3572 ->
+ 3724 bytes
+ test/api/test-subset-post.c                        |  61
+ +++++++++++++++++++++
+ 3 files changed, 63 insertions(+)
+
+commit dd107699938740e261948e4b525fa0ad501beb03
+Author: Garret Rieger <grieger@google.com>
+Date:   Tue Mar 6 18:33:39 2018 -0800
+
+    [subset] drop all glyph names from the post table.
+
+ src/hb-ot-post-table.hh | 28 ++++++++++++++++++++++++++++
+ src/hb-subset.cc        |  4 ++++
+ 2 files changed, 32 insertions(+)
+
+commit 1ab514805ced190efdabc2103e4800d40b248300
+Merge: 70ad69f2 362f2824
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed Mar 7 12:36:00 2018 -0700
+
+    Merge pull request #867 from googlefonts/vmtx
+
+    [subset] Add vmtx subsetting.
+
+commit 362f28240683fde395ff52f4fc1216fbc7131452
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed Mar 7 11:08:55 2018 -0800
+
+    [subset] fix author.
+
+ test/api/test-subset-vmtx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 89465cb1c7b8ab61c0ef4887f51572ba91039f3e
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed Mar 7 10:29:15 2018 -0800
+
+    [subset] s/hmetrics/vmetrics.
+
+ test/api/test-subset-vmtx.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 91867cda6ae5ae063482b28b0a52ebc30718cb40
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed Mar 7 10:17:06 2018 -0800
+
+    [subset] cleanup.
+
+ src/hb-subset.cc            | 2 +-
+ test/api/test-subset-vmtx.c | 3 +--
+ 2 files changed, 2 insertions(+), 3 deletions(-)
+
+commit d9263f0230693d108249be0904bc5a3280560cb3
+Author: Garret Rieger <grieger@google.com>
+Date:   Tue Mar 6 15:40:35 2018 -0800
+
+    [subset] add unit tests for vmtx subsetting.
+
+ test/api/Makefile.am                               |   2 +
+ ...lus1p-Regular.660E,6975,73E0,5EA6,8F38,6E05.ttf | Bin 0 -> 3572 bytes
+ test/api/fonts/Mplus1p-Regular.660E.ttf            | Bin 0 -> 2356 bytes
+ test/api/test-subset-vmtx.c                        | 100
+ +++++++++++++++++++++
+ 4 files changed, 102 insertions(+)
+
+commit 0e8f9430c83c076993a0c7a320713bb484051343
+Author: Garret Rieger <grieger@google.com>
+Date:   Tue Mar 6 13:08:20 2018 -0800
+
+    [subset] Skip subsetting vhea.
+
+ src/hb-subset.cc | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 64cf53d6197a0e6c56aef744ceff2f8a0ff85654
+Author: Garret Rieger <grieger@google.com>
+Date:   Fri Mar 2 17:33:49 2018 -0800
+
+    [subset] Subset vmtx if present.
+
+ src/hb-ot-hmtx-table.hh | 2 +-
+ src/hb-subset.cc        | 3 +++
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+commit 70ad69f2449d754fcc5270ff3ca3848a77f4c7af
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Mar 7 16:11:44 2018 +0100
+
+    [test] Fix build with older glib
+
+ test/api/hb-subset-test.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ff2f81432bb0484a019a678058595e10217df51d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Mar 7 16:05:14 2018 +0100
+
+    1.7.6
+
+ NEWS             | 15 +++++++++++++++
+ configure.ac     |  2 +-
+ src/hb-version.h |  4 ++--
+ 3 files changed, 18 insertions(+), 3 deletions(-)
+
 commit ac2ece3e153167224c85cc384e2826ea9711a8b5
 Author: Behdad Esfahbod <behdad@behdad.org>
 Date:   Wed Mar 7 15:52:42 2018 +0100
index fde5256..eb46cea 100644 (file)
@@ -9,7 +9,8 @@ SUBDIRS = src util test docs
 EXTRA_DIST = \
        autogen.sh \
        harfbuzz.doap \
-       README.python \
+       README.python.md \
+       README.wine.md \
        BUILD.md \
        RELEASING.md \
        CMakeLists.txt \
index 420fb67..7ea6386 100644 (file)
@@ -91,7 +91,8 @@ build_triplet = @build@
 host_triplet = @host@
 subdir = .
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
+       $(top_srcdir)/m4/ax_code_coverage.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
@@ -401,7 +402,8 @@ SUBDIRS = src util test docs
 EXTRA_DIST = \
        autogen.sh \
        harfbuzz.doap \
-       README.python \
+       README.python.md \
+       README.wine.md \
        BUILD.md \
        RELEASING.md \
        CMakeLists.txt \
diff --git a/NEWS b/NEWS
index fe09ab1..12010bd 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,53 @@
+Overview of changes leading to 1.8.1
+Tuesday, June 12, 2018
+====================================
+- Fix hb-version.h file generation; last two releases went out with wrong ones.
+- Add correctness bug in hb_set_t operations, introduced in 1.7.7.
+- Remove HB_SUBSET_BUILTIN build option.  Not necessary.
+
+Overview of changes leading to 1.8.0
+Tuesday, June 5, 2018
+====================================
+- Update to Unicode 11.0.0.
+
+
+Overview of changes leading to 1.7.7
+Tuesday, June 5, 2018
+====================================
+- Lots of internal changes, but not yet exposed externally.
+- All HarfBuzz objects are significantly smaller in size now.
+- Sinhala: Position repha on top of post-consonant, not base.
+  This better matches Windows 10 behavior, which was changed
+  from previous Windows versions.
+- New build options:
+  o New cpp macro HB_NO_ATEXIT
+  o New cpp macro HB_SUBSET_BUILTIN
+- Significant libharfbuzz-subset changes. API subject to change.
+- New API in libharfbuzz:
+
++hb_blob_create_from_file()
++hb_face_count()
+
+A hashmap implementation:
++hb-map.h
++HB_MAP_VALUE_INVALID
++hb_map_t
++hb_map_create()
++hb_map_get_empty()
++hb_map_reference()
++hb_map_destroy()
++hb_map_set_user_data()
++hb_map_get_user_data()
++hb_map_allocation_successful()
++hb_map_clear()
++hb_map_is_empty()
++hb_map_get_population()
++hb_map_set()
++hb_map_get()
++hb_map_del()
++hb_map_has()
+
+
 Overview of changes leading to 1.7.6
 Wednesday, March 7, 2018
 ====================================
diff --git a/README b/README
index 6e21322..55775c8 100644 (file)
--- a/README
+++ b/README
@@ -2,6 +2,7 @@
 [![Build status](https://ci.appveyor.com/api/projects/status/0t0flrxpstj9lb9w?svg=true)](https://ci.appveyor.com/project/harfbuzz/harfbuzz)
 [![CircleCI](https://circleci.com/gh/harfbuzz/harfbuzz.svg?style=svg)](https://circleci.com/gh/harfbuzz/harfbuzz)
 [![Coverity](https://img.shields.io/coverity/scan/5450.svg)](https://scan.coverity.com/projects/behdad-harfbuzz)
+[![Codacy Badge](https://api.codacy.com/project/badge/Grade/f17f1708783c447488bc8dd317150eaa)](https://app.codacy.com/app/behdad/harfbuzz)
 [![Coverage Status](https://img.shields.io/coveralls/harfbuzz/harfbuzz.svg)](https://coveralls.io/r/harfbuzz/harfbuzz)
 [ABI Tracker](http://abi-laboratory.pro/tracker/timeline/harfbuzz/)
 
similarity index 83%
rename from README.python
rename to README.python.md
index cd31264..4c0ba9b 100644 (file)
@@ -2,11 +2,15 @@ To enable HarfBuzz bindings for Python among other languages, make sure
 you have latest version of gobject-introspection available.  On Ubuntu,
 you can install that this way:
 
-  sudo apt-get install libgirepository1.0-dev
+```bash
+sudo apt-get install libgirepository1.0-dev
+```
 
 And then run autogen.sh (if building from git), and then:
 
-  ./configure --with-gobject --enable-introspection
+```bash
+./configure --with-gobject --enable-introspection
+```
 
 Make sure that gobject-introspection is enabled then in the final report.
 
@@ -21,7 +25,9 @@ $prefix/lib/girepository-* directory.
 Make sure you have pygobject installed.  Then check that the following
 import works in your Python interpretter:
 
-  from gi.repository import HarfBuzz
+```python
+from gi.repository import HarfBuzz
+```
 
 If it does, you are ready to call HarfBuzz from Python!  Congratulations.
 See src/sample.py.
diff --git a/README.wine.md b/README.wine.md
new file mode 100644 (file)
index 0000000..851d2bf
--- /dev/null
@@ -0,0 +1,40 @@
+For the development of HarfBuzz, the Microsoft shaping technology, Uniscribe,
+as a widely used and tested shaper is used as more-or-less OpenType reference
+implemenetation and that specially is important where OpenType specification
+is or wasn't that clear. For having access to Uniscribe on Linux/macOS these
+steps are recommended:
+
+1. Install Wine from your favorite package manager.
+
+2. And `mingw-w64` compiler.
+   With `brew` on macOS, you can have it like `brew install mingw-w64`
+
+3. Download and put [this](https://drive.google.com/open?id=0B3_fQkxDZZXXbWltRGd5bjVrUDQ)
+   on your `~/.local/i686-w64-mingw32`.
+
+4. Replace all the instances of `/home/behdad/.local/i586-mingw32msvc`
+   and `/home/behdad/.local/i686-w64-mingw32` with `<$HOME>/.local/i686-w64-mingw32`
+   on that folder. (`<$HOME>` replace it with `/home/XXX` or `/Users/XXX` on macOS)
+
+   Probably you shouldn't replace the ones are inside binaries.
+
+5. `NOCONFIGURE=1 ./autogen.sh && mkdir winbuild && cd winbuild`
+
+6. `../mingw32.sh --with-uniscribe && cd ..`
+
+7. `make -Cwinbuild`
+
+Now you can use hb-shape using `wine winbuild/util/hb-shape.exe` but if you like to
+to use the original Uniscribe,
+
+8. Bring a 32bit version of `usp10.dll` for youself from `C:\Windows\SysWOW64\usp10.dll` of your
+   Windows installation (asuming you have a 64-bit installation, otherwise `C:\Windows\System32\usp10.dll`)
+   that it is not a DirectWrite proxy ([for more info](https://en.wikipedia.org/wiki/Uniscribe)).
+   Rule of thumb, your `usp10.dll` should have a size more than 500kb, otherwise
+   it is designed to work with DirectWrite which Wine can't work with its original one.
+
+   Put the dll on the folder you are going to run the next command,
+
+9. `WINEDLLOVERRIDES="usp10=n" wine winbuild/util/hb-shape.exe fontname.ttf -u 0061,0062,0063 --shaper=uniscribe`
+
+(`0061,0062,0063` means `abc`, use test/shaping/hb-unicode-decode to generate ones you need)
index dedcca8..0aef610 100644 (file)
@@ -7,7 +7,8 @@ HarfBuzz release walk-through checklist:
 
      Document them in NEWS.  All API and API semantic changes should be clearly
      marked as API additions, API changes, or API deletions.  Document
-     deprecations.
+     deprecations.  Ensure all new API / deprecations are in listed correctly in
+     docs/harfbuzz-sections.txt
 
      If there's a backward-incompatible API change (including deletions for API
      used anywhere), that's a release blocker.  Do NOT release.
@@ -15,33 +16,39 @@ HarfBuzz release walk-through checklist:
 2. Based on severity of changes, decide whether it's a minor or micro release
    number bump,
 
-3. Make sure you have correct date and new version at the top of NEWS file,
+3. Search for REPLACEME on the repository and replace it with the chosen version
+   for the release.
 
-4. Bump version in configure.ac line 3,
+4. Make sure you have correct date and new version at the top of NEWS file,
 
-5. Do "make distcheck", if it passes, you get a tarball.
+5. Bump version in configure.ac line 3,
+
+6. Do "make distcheck", if it passes, you get a tarball.
    Otherwise, fix things and commit them separately before making release,
 
-6. "make release-files".  Enter your GPG password.  This creates a sha256 hash
+7. "make release-files".  Enter your GPG password.  This creates a sha256 hash
    and signs it.
 
-7. Now that you have release files built, commit NEWS and configure.ac changes.
-   The commit message is simply the release number.  Eg. "1.4.7"
+8. Now that you have release files built, commit NEWS and configure.ac changes,
+   as well as any REPLACEME changes you made.  The commit message is simply the
+   release number.  Eg. "1.4.7"
 
-8. Tag the release and sign it: Eg. "git tag -s 1.4.7 -m 1.4.7".  Enter your
+9. Tag the release and sign it: Eg. "git tag -s 1.4.7 -m 1.4.7".  Enter your
    GPG password again.
 
-9. Build win32 bundle.
+10. Build win32 bundle.
 
    a. Put contents of [this](https://drive.google.com/open?id=0B3_fQkxDZZXXbWltRGd5bjVrUDQ) on your `~/.local/i686-w64-mingw32`,
 
-   b. Run `../mingw32.sh --with-uniscribe` script (available below) to configure harfbuzz with mingw in a subdirector (eg. winbuild/),
+   b. Run `../mingw32.sh --with-uniscribe` script to configure harfbuzz with mingw
+   in a subdirector (eg. winbuild/),
 
    c. make
 
-   d. Back in the parent directory, run `./UPDATE.sh` (available below) to build win32 bundle.
+   d. Back in the parent directory, run `./UPDATE.sh`(available below) to build win32
+      bundle.
 
-10. Copy all artefacts to users.freedesktop.org and move them into
+11. Copy all artefacts to users.freedesktop.org and move them into
     `/srv/www.freedesktop.org/www/software/harfbuzz/release` There should be four
     files.  Eg.:
  ```
@@ -51,15 +58,15 @@ HarfBuzz release walk-through checklist:
 -rw-r--r--  1 behdad eng 2895619 Jul 18 11:34 harfbuzz-1.4.7-win32.zip
 ```
 
-11. While doing that, quickly double-check the size of the .tar.bz2 and .zip
+12. While doing that, quickly double-check the size of the .tar.bz2 and .zip
     files against their previous releases to make sure nothing bad happened.
     They should be in the ballpark, perhaps slightly larger.  Sometimes they
     do shrink, that's not by itself a stopper.
 
-12. Push the commit and tag out: "git push --follow-tags".  Make sure it's
+13. Push the commit and tag out: "git push --follow-tags".  Make sure it's
     pushed both to freedesktop repo and github.
 
-13. Go to GitHub release page [here](https://github.com/harfbuzz/harfbuzz/releases),
+14. Go to GitHub release page [here](https://github.com/harfbuzz/harfbuzz/releases),
     edit the tag, upload artefacts and NEWS entry and save.
 
 
diff --git a/TODO b/TODO
index 53ffbe9..6dac0be 100644 (file)
--- a/TODO
+++ b/TODO
@@ -17,8 +17,6 @@ API additions
 
 - Language to/from script.
 
-- blob_from_file?
-
 - Add hb-cairo glue
 
 - Add sanitize API (and a cached version, that saves result on blob user-data)
@@ -29,8 +27,6 @@ API additions
 
 - Add query / enumeration API for aalt-like features?
 
-- SFNT api? get_num_faces?
-
 - Add segmentation API
 
 - Add hb-fribidi glue?
index 31c76e3..178d1c5 100644 (file)
@@ -1307,6 +1307,7 @@ AC_SUBST([am__tar])
 AC_SUBST([am__untar])
 ]) # _AM_PROG_TAR
 
+m4_include([m4/ax_check_link_flag.m4])
 m4_include([m4/ax_code_coverage.m4])
 m4_include([m4/ax_pthread.m4])
 m4_include([m4/gtk-doc.m4])
index 1515f81..c52ceb9 100644 (file)
 /* Have Core Text backend */
 #undef HAVE_CORETEXT
 
+/* Define to 1 if you have the declaration of `round', and to 0 if you don't.
+   */
+#undef HAVE_DECL_ROUND
+
 /* Have DirectWrite library */
 #undef HAVE_DIRECTWRITE
 
 /* Have PTHREAD_PRIO_INHERIT. */
 #undef HAVE_PTHREAD_PRIO_INHERIT
 
+/* Define to 1 if you have the `round' function. */
+#undef HAVE_ROUND
+
 /* Define to 1 if you have the <sched.h> header file. */
 #undef HAVE_SCHED_H
 
 /* Have sched_yield */
 #undef HAVE_SCHED_YIELD
 
-/* Define to 1 if you have the `setlinebuf' function. */
-#undef HAVE_SETLINEBUF
-
 /* Have Solaris __machine_*_barrier and atomic_* operations */
 #undef HAVE_SOLARIS_ATOMIC_OPS
 
+/* Define to 1 if you have the <stdbool.h> header file. */
+#undef HAVE_STDBOOL_H
+
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
index 21e02f7..bd784a3 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for HarfBuzz 1.7.6.
+# Generated by GNU Autoconf 2.69 for HarfBuzz 1.8.1.
 #
 # Report bugs to <https://github.com/harfbuzz/harfbuzz/issues/new>.
 #
@@ -590,8 +590,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='HarfBuzz'
 PACKAGE_TARNAME='harfbuzz'
-PACKAGE_VERSION='1.7.6'
-PACKAGE_STRING='HarfBuzz 1.7.6'
+PACKAGE_VERSION='1.8.1'
+PACKAGE_STRING='HarfBuzz 1.8.1'
 PACKAGE_BUGREPORT='https://github.com/harfbuzz/harfbuzz/issues/new'
 PACKAGE_URL='http://harfbuzz.org/'
 
@@ -1493,7 +1493,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 1.7.6 to adapt to many kinds of systems.
+\`configure' configures HarfBuzz 1.8.1 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1564,7 +1564,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of HarfBuzz 1.7.6:";;
+     short | recursive ) echo "Configuration of HarfBuzz 1.8.1:";;
    esac
   cat <<\_ACEOF
 
@@ -1743,7 +1743,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-HarfBuzz configure 1.7.6
+HarfBuzz configure 1.8.1
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2230,6 +2230,52 @@ fi
 
 } # ac_fn_cxx_try_link
 
+# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
+# ---------------------------------------------
+# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
+# accordingly.
+ac_fn_c_check_decl ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  as_decl_name=`echo $2|sed 's/ *(.*//'`
+  as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
+$as_echo_n "checking whether $as_decl_name is declared... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+#ifndef $as_decl_name
+#ifdef __cplusplus
+  (void) $as_decl_use;
+#else
+  (void) $as_decl_name;
+#endif
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_decl
+
 # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
 # --------------------------------------------
 # Tries to find the compile-time value of EXPR in a program that includes
@@ -2561,7 +2607,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 $as_me 1.7.6, which was
+It was created by HarfBuzz $as_me 1.8.1, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -3430,7 +3476,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='harfbuzz'
- VERSION='1.7.6'
+ VERSION='1.8.1'
 
 
 # Some tools Automake needs.
@@ -18416,9 +18462,9 @@ GIT=${GIT-"${am_missing_run}git"}
 
 
 HB_VERSION_MAJOR=1
-HB_VERSION_MINOR=7
-HB_VERSION_MICRO=6
-HB_VERSION=1.7.6
+HB_VERSION_MINOR=8
+HB_VERSION_MICRO=1
+HB_VERSION=1.8.1
 
 
 
@@ -18429,7 +18475,7 @@ HB_VERSION=1.7.6
 
 
 
-HB_LIBTOOL_VERSION_INFO=10706:0:10706
+HB_LIBTOOL_VERSION_INFO=10800:1:10800
 
 
 
@@ -18827,8 +18873,8 @@ fi
        fi
 
 
-# Functions, and headers
-for ac_func in atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l setlinebuf
+# Functions and headers
+for ac_func in atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -18840,7 +18886,36 @@ _ACEOF
 fi
 done
 
-for ac_header in unistd.h sys/mman.h xlocale.h
+
+save_libs="$LIBS"
+LIBS="$LIBS -lm"
+for ac_func in round
+do :
+  ac_fn_c_check_func "$LINENO" "round" "ac_cv_func_round"
+if test "x$ac_cv_func_round" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_ROUND 1
+_ACEOF
+
+else
+  ac_fn_c_check_decl "$LINENO" "round" "ac_cv_have_decl_round" "#include <math.h>
+"
+if test "x$ac_cv_have_decl_round" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_ROUND $ac_have_decl
+_ACEOF
+
+fi
+done
+
+LIBS="$save_libs"
+
+for ac_header in unistd.h sys/mman.h xlocale.h stdbool.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -18894,7 +18969,50 @@ _ACEOF
 if test "x$GCC" = "xyes"; then
 
        # Make symbols link locally
-       LDFLAGS="$LDFLAGS -Bsymbolic-functions"
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts -Bsymbolic-functions" >&5
+$as_echo_n "checking whether the linker accepts -Bsymbolic-functions... " >&6; }
+if ${ax_cv_check_ldflags___Bsymbolic_functions+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  -Bsymbolic-functions"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ax_cv_check_ldflags___Bsymbolic_functions=yes
+else
+  ax_cv_check_ldflags___Bsymbolic_functions=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  LDFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_ldflags___Bsymbolic_functions" >&5
+$as_echo "$ax_cv_check_ldflags___Bsymbolic_functions" >&6; }
+if test "x$ax_cv_check_ldflags___Bsymbolic_functions" = xyes; then :
+  LDFLAGS="$LDFLAGS -Bsymbolic-functions"
+else
+  :
+fi
+
+
+       # Make it possible to not link to libstdc++
+       # No threadsafe statics in C++ as we do it ourselves.
+       # We don't use these features, so it's safe to disable them
+       # even in the cases where we DO link to libstdc++.
+       # Put -fno-rtti before $CXXFLAGS such that users can re-enable it
+       # by overriding CXXFLAGS.
+       CXXFLAGS="-fno-rtti $CXXFLAGS -fno-exceptions -fno-threadsafe-statics"
 
        # Assorted warnings
        CXXFLAGS="$CXXFLAGS -Wcast-align"
@@ -21052,7 +21170,7 @@ fi
 fi
 
 
-ac_config_files="$ac_config_files Makefile src/Makefile src/hb-version.h src/harfbuzz-config.cmake src/hb-ucdn/Makefile util/Makefile test/Makefile test/api/Makefile test/fuzzing/Makefile test/shaping/Makefile test/shaping/data/Makefile test/shaping/data/in-house/Makefile test/shaping/data/text-rendering-tests/Makefile test/subset/Makefile test/subset/data/Makefile docs/Makefile docs/version.xml"
+ac_config_files="$ac_config_files Makefile src/Makefile src/harfbuzz-config.cmake src/hb-ucdn/Makefile util/Makefile test/Makefile test/api/Makefile test/fuzzing/Makefile test/shaping/Makefile test/shaping/data/Makefile test/shaping/data/in-house/Makefile test/shaping/data/text-rendering-tests/Makefile test/subset/Makefile test/subset/data/Makefile docs/Makefile docs/version.xml"
 
 
 cat >confcache <<\_ACEOF
@@ -21705,7 +21823,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 $as_me 1.7.6, which was
+This file was extended by HarfBuzz $as_me 1.8.1, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -21772,7 +21890,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 config.status 1.7.6
+HarfBuzz config.status 1.8.1
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -22287,7 +22405,6 @@ do
     "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
     "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
     "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
-    "src/hb-version.h") CONFIG_FILES="$CONFIG_FILES src/hb-version.h" ;;
     "src/harfbuzz-config.cmake") CONFIG_FILES="$CONFIG_FILES src/harfbuzz-config.cmake" ;;
     "src/hb-ucdn/Makefile") CONFIG_FILES="$CONFIG_FILES src/hb-ucdn/Makefile" ;;
     "util/Makefile") CONFIG_FILES="$CONFIG_FILES util/Makefile" ;;
@@ -23759,8 +23876,8 @@ Additional shapers (the more the merrier):
 
 Platform shapers (not normally needed):
        CoreText:               ${have_coretext}
-       Uniscribe:              ${have_uniscribe}
        DirectWrite:            ${have_directwrite}
+       Uniscribe:              ${have_uniscribe}
 
 Other features:
        Documentation:          ${enable_gtk_doc}
@@ -23788,8 +23905,8 @@ Additional shapers (the more the merrier):
 
 Platform shapers (not normally needed):
        CoreText:               ${have_coretext}
-       Uniscribe:              ${have_uniscribe}
        DirectWrite:            ${have_directwrite}
+       Uniscribe:              ${have_uniscribe}
 
 Other features:
        Documentation:          ${enable_gtk_doc}
index 1fb8a10..13cd1ce 100644 (file)
@@ -1,6 +1,6 @@
 AC_PREREQ([2.64])
 AC_INIT([HarfBuzz],
-        [1.7.6],
+        [1.8.1],
         [https://github.com/harfbuzz/harfbuzz/issues/new],
         [harfbuzz],
         [http://harfbuzz.org/])
@@ -77,9 +77,15 @@ GTK_DOC_CHECK([1.15],[--flavour no-tmpl])
        AM_CONDITIONAL([ENABLE_GTK_DOC], false)
 ])
 
-# Functions, and headers
-AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l setlinebuf)
-AC_CHECK_HEADERS(unistd.h sys/mman.h xlocale.h)
+# Functions and headers
+AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l)
+
+save_libs="$LIBS"
+LIBS="$LIBS -lm"
+AC_CHECK_FUNCS([round], ,[AC_CHECK_DECLS([round], , ,[#include <math.h>])])
+LIBS="$save_libs"
+
+AC_CHECK_HEADERS(unistd.h sys/mman.h xlocale.h stdbool.h)
 
 # Compiler flags
 AC_CANONICAL_HOST
@@ -87,7 +93,15 @@ AC_CHECK_ALIGNOF([struct{char;}])
 if test "x$GCC" = "xyes"; then
 
        # Make symbols link locally
-       LDFLAGS="$LDFLAGS -Bsymbolic-functions"
+       AX_CHECK_LINK_FLAG([[-Bsymbolic-functions]], [LDFLAGS="$LDFLAGS -Bsymbolic-functions"])
+
+       # Make it possible to not link to libstdc++
+       # No threadsafe statics in C++ as we do it ourselves.
+       # We don't use these features, so it's safe to disable them
+       # even in the cases where we DO link to libstdc++.
+       # Put -fno-rtti before $CXXFLAGS such that users can re-enable it
+       # by overriding CXXFLAGS.
+       CXXFLAGS="-fno-rtti $CXXFLAGS -fno-exceptions -fno-threadsafe-statics"
 
        # Assorted warnings
        CXXFLAGS="$CXXFLAGS -Wcast-align"
@@ -492,7 +506,6 @@ dnl ===========================================================================
 AC_CONFIG_FILES([
 Makefile
 src/Makefile
-src/hb-version.h
 src/harfbuzz-config.cmake
 src/hb-ucdn/Makefile
 util/Makefile
@@ -532,8 +545,8 @@ Additional shapers (the more the merrier):
 
 Platform shapers (not normally needed):
        CoreText:               ${have_coretext}
-       Uniscribe:              ${have_uniscribe}
        DirectWrite:            ${have_directwrite}
+       Uniscribe:              ${have_uniscribe}
 
 Other features:
        Documentation:          ${enable_gtk_doc}
index 2039ee1..100c353 100644 (file)
@@ -99,7 +99,8 @@ host_triplet = @host@
 @HAVE_GOBJECT_TRUE@am__append_2 = $(top_builddir)/src/libharfbuzz-gobject.la
 subdir = docs
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
+       $(top_srcdir)/m4/ax_code_coverage.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
index 91faa0b..5715d77 100644 (file)
@@ -8,6 +8,7 @@ HB_EXTERN
 <SECTION>
 <FILE>hb-blob</FILE>
 hb_blob_create
+hb_blob_create_from_file
 hb_blob_create_sub_blob
 hb_blob_copy_writable_or_fail
 hb_blob_destroy
@@ -168,6 +169,7 @@ hb_coretext_font_get_ct_font
 
 <SECTION>
 <FILE>hb-face</FILE>
+hb_face_count
 hb_face_create
 hb_face_create_for_tables
 hb_face_destroy
@@ -399,6 +401,26 @@ hb_icu_script_to_script
 </SECTION>
 
 <SECTION>
+<FILE>hb-map</FILE>
+HB_MAP_VALUE_INVALID
+hb_map_allocation_successful
+hb_map_clear
+hb_map_create
+hb_map_del
+hb_map_destroy
+hb_map_get
+hb_map_get_empty
+hb_map_get_population
+hb_map_get_user_data
+hb_map_has
+hb_map_is_empty
+hb_map_reference
+hb_map_set
+hb_map_set_user_data
+hb_map_t
+</SECTION>
+
+<SECTION>
 <FILE>hb-ot</FILE>
 <SUBSECTION Private>
 HB_OT_H_IN
@@ -443,6 +465,7 @@ hb_ot_layout_language_get_feature_tags
 hb_ot_layout_language_get_required_feature
 hb_ot_layout_lookup_collect_glyphs
 hb_ot_layout_lookup_substitute_closure
+hb_ot_layout_lookups_substitute_closure
 hb_ot_layout_lookup_would_substitute
 hb_ot_layout_script_find_language
 hb_ot_layout_script_get_language_tags
@@ -527,9 +550,10 @@ hb_set_has
 hb_set_intersect
 hb_set_is_empty
 hb_set_is_equal
+hb_set_is_subset
 hb_set_next
-hb_set_previous
 hb_set_next_range
+hb_set_previous
 hb_set_previous_range
 hb_set_reference
 hb_set_set
index 311bad1..591bfe4 100644 (file)
 </dt>
 <dd></dd>
 <dt>
+<a class="link" href="harfbuzz-hb-blob.html#hb-blob-create-from-file" title="hb_blob_create_from_file ()">hb_blob_create_from_file</a>, function in <a class="link" href="harfbuzz-hb-blob.html" title="hb-blob">hb-blob</a>
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="harfbuzz-hb-blob.html#hb-blob-create-sub-blob" title="hb_blob_create_sub_blob ()">hb_blob_create_sub_blob</a>, function in <a class="link" href="harfbuzz-hb-blob.html" title="hb-blob">hb-blob</a>
 </dt>
 <dd></dd>
 <dd></dd>
 <a name="idxF"></a><h3 class="title">F</h3>
 <dt>
+<a class="link" href="harfbuzz-hb-face.html#hb-face-count" title="hb_face_count ()">hb_face_count</a>, function in <a class="link" href="harfbuzz-hb-face.html" title="hb-face">hb-face</a>
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="harfbuzz-hb-face.html#hb-face-create" title="hb_face_create ()">hb_face_create</a>, function in <a class="link" href="harfbuzz-hb-face.html" title="hb-face">hb-face</a>
 </dt>
 <dd></dd>
 <dd></dd>
 <a name="idxM"></a><h3 class="title">M</h3>
 <dt>
+hb_map_allocation_successful, function in hb-map
+</dt>
+<dd></dd>
+<dt>
+hb_map_clear, function in hb-map
+</dt>
+<dd></dd>
+<dt>
+hb_map_create, function in hb-map
+</dt>
+<dd></dd>
+<dt>
+hb_map_del, function in hb-map
+</dt>
+<dd></dd>
+<dt>
+hb_map_destroy, function in hb-map
+</dt>
+<dd></dd>
+<dt>
+hb_map_get, function in hb-map
+</dt>
+<dd></dd>
+<dt>
+hb_map_get_empty, function in hb-map
+</dt>
+<dd></dd>
+<dt>
+hb_map_get_population, function in hb-map
+</dt>
+<dd></dd>
+<dt>
+hb_map_get_user_data, function in hb-map
+</dt>
+<dd></dd>
+<dt>
+hb_map_has, function in hb-map
+</dt>
+<dd></dd>
+<dt>
+hb_map_is_empty, function in hb-map
+</dt>
+<dd></dd>
+<dt>
+hb_map_reference, function in hb-map
+</dt>
+<dd></dd>
+<dt>
+hb_map_set, function in hb-map
+</dt>
+<dd></dd>
+<dt>
+hb_map_set_user_data, function in hb-map
+</dt>
+<dd></dd>
+<dt>
+hb_map_t, typedef in hb-map
+</dt>
+<dd></dd>
+<dt>
+HB_MAP_VALUE_INVALID, macro in hb-map
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="harfbuzz-hb-common.html#hb-mask-t" title="hb_mask_t">hb_mask_t</a>, typedef in <a class="link" href="harfbuzz-hb-common.html" title="hb-common">hb-common</a>
 </dt>
 <dd></dd>
 </dt>
 <dd></dd>
 <dt>
+<a class="link" href="harfbuzz-hb-ot-layout.html#hb-ot-layout-lookups-substitute-closure" title="hb_ot_layout_lookups_substitute_closure ()">hb_ot_layout_lookups_substitute_closure</a>, function in <a class="link" href="harfbuzz-hb-ot-layout.html" title="hb-ot-layout">hb-ot-layout</a>
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="harfbuzz-hb-ot-layout.html#hb-ot-layout-lookup-collect-glyphs" title="hb_ot_layout_lookup_collect_glyphs ()">hb_ot_layout_lookup_collect_glyphs</a>, function in <a class="link" href="harfbuzz-hb-ot-layout.html" title="hb-ot-layout">hb-ot-layout</a>
 </dt>
 <dd></dd>
@@ -1699,6 +1775,10 @@ HB_OT_VAR_NO_AXIS_INDEX, macro in hb-ot-var
 </dt>
 <dd></dd>
 <dt>
+<a class="link" href="harfbuzz-hb-set.html#hb-set-is-subset" title="hb_set_is_subset ()">hb_set_is_subset</a>, function in <a class="link" href="harfbuzz-hb-set.html" title="hb-set">hb-set</a>
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="harfbuzz-hb-set.html#hb-set-next" title="hb_set_next ()">hb_set_next</a>, function in <a class="link" href="harfbuzz-hb-set.html" title="hb-set">hb-set</a>
 </dt>
 <dd></dd>
index 387fa36..af4e7a3 100644 (file)
@@ -1678,11 +1678,13 @@ contents.  If buffer is not empty, it must have content type
 <a class="link" href="harfbuzz-Buffers.html#HB-BUFFER-CONTENT-TYPE-UNICODE:CAPS"><code class="literal">HB_BUFFER_CONTENT_TYPE_UNICODE</code></a>.</p>
 <p>If buffer script is not set (ie. is <a class="link" href="harfbuzz-hb-common.html#HB-SCRIPT-INVALID:CAPS"><code class="literal">HB_SCRIPT_INVALID</code></a>), it
 will be set to the Unicode script of the first character in
-the buffer that has a script other than <a href="harfbuzz-hb-common.html#HB-SCRIPT-COMMON:CAPS"><code class="literal">HB_SCRIPT_COMMON</code></a>,
-<a href="harfbuzz-hb-common.html#HB-SCRIPT-INHERITED:CAPS"><code class="literal">HB_SCRIPT_INHERITED</code></a>, and <a href="harfbuzz-hb-common.html#HB-SCRIPT-UNKNOWN:CAPS"><code class="literal">HB_SCRIPT_UNKNOWN</code></a>.</p>
+the buffer that has a script other than <code class="literal">HB_SCRIPT_COMMON</code>,
+<code class="literal">HB_SCRIPT_INHERITED</code>, and <code class="literal">HB_SCRIPT_UNKNOWN</code>.</p>
 <p>Next, if buffer direction is not set (ie. is <a class="link" href="harfbuzz-hb-common.html#HB-DIRECTION-INVALID:CAPS"><code class="literal">HB_DIRECTION_INVALID</code></a>),
 it will be set to the natural horizontal direction of the
-buffer script as returned by <a class="link" href="harfbuzz-hb-common.html#hb-script-get-horizontal-direction" title="hb_script_get_horizontal_direction ()"><code class="function">hb_script_get_horizontal_direction()</code></a>.</p>
+buffer script as returned by <a class="link" href="harfbuzz-hb-common.html#hb-script-get-horizontal-direction" title="hb_script_get_horizontal_direction ()"><code class="function">hb_script_get_horizontal_direction()</code></a>.
+If <a class="link" href="harfbuzz-hb-common.html#hb-script-get-horizontal-direction" title="hb_script_get_horizontal_direction ()"><code class="function">hb_script_get_horizontal_direction()</code></a> returns <a class="link" href="harfbuzz-hb-common.html#HB-DIRECTION-INVALID:CAPS"><code class="literal">HB_DIRECTION_INVALID</code></a>,
+then <a class="link" href="harfbuzz-hb-common.html#HB-DIRECTION-LTR:CAPS"><code class="literal">HB_DIRECTION_LTR</code></a> is used.</p>
 <p>Finally, if buffer language is not set (ie. is <a class="link" href="harfbuzz-hb-common.html#HB-LANGUAGE-INVALID:CAPS" title="HB_LANGUAGE_INVALID"><code class="literal">HB_LANGUAGE_INVALID</code></a>),
 it will be set to the process's default language as returned by
 <a class="link" href="harfbuzz-hb-common.html#hb-language-get-default" title="hb_language_get_default ()"><code class="function">hb_language_get_default()</code></a>.  This may change in the future by
index 75a4901..b3d9a76 100644 (file)
 <a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
 </td>
 <td class="function_name">
+<a class="link" href="harfbuzz-hb-blob.html#hb-blob-create-from-file" title="hb_blob_create_from_file ()">hb_blob_create_from_file</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
+</td>
+<td class="function_name">
 <a class="link" href="harfbuzz-hb-blob.html#hb-blob-create-sub-blob" title="hb_blob_create_sub_blob ()">hb_blob_create_sub_blob</a> <span class="c_punctuation">()</span>
 </td>
 </tr>
@@ -242,6 +250,32 @@ zero.  Destroy with <a class="link" href="harfbuzz-hb-blob.html#hb-blob-destroy"
 </div>
 <hr>
 <div class="refsect2">
+<a name="hb-blob-create-from-file"></a><h3>hb_blob_create_from_file ()</h3>
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
+hb_blob_create_from_file (<em class="parameter"><code>const <span class="type">char</span> *file_name</code></em>);</pre>
+<div class="refsect3">
+<a name="hb-blob-create-from-file.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>file_name</p></td>
+<td class="parameter_description"><p>font filename.</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="hb-blob-create-from-file.returns"></a><h4>Returns</h4>
+<p> A hb_blob_t pointer with the content of the file</p>
+</div>
+<p class="since">Since: 1.7.7</p>
+</div>
+<hr>
+<div class="refsect2">
 <a name="hb-blob-create-sub-blob"></a><h3>hb_blob_create_sub_blob ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
 hb_blob_create_sub_blob (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="type">hb_blob_t</span></a> *parent</code></em>,
index 091fc62..7db2c8b 100644 (file)
@@ -700,6 +700,11 @@ hb_language_get_default (<em class="parameter"><code><span class="type">void</sp
 <td> </td>
 </tr>
 <tr>
+<td class="enum_member_name"><p><a name="HB-SCRIPT-DOGRA:CAPS"></a>HB_SCRIPT_DOGRA</p></td>
+<td> </td>
+<td> </td>
+</tr>
+<tr>
 <td class="enum_member_name"><p><a name="HB-SCRIPT-INVALID:CAPS"></a>HB_SCRIPT_INVALID</p></td>
 <td> </td>
 <td> </td>
index d4f59cd..7192ddc 100644 (file)
 </colgroup>
 <tbody>
 <tr>
+<td class="function_type">unsigned <span class="returnvalue">int</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-face.html#hb-face-count" title="hb_face_count ()">hb_face_count</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
 <td class="function_type">
 <a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="returnvalue">hb_face_t</span></a> *
 </td>
 <div class="refsect1">
 <a name="harfbuzz-hb-face.functions_details"></a><h2>Functions</h2>
 <div class="refsect2">
+<a name="hb-face-count"></a><h3>hb_face_count ()</h3>
+<pre class="programlisting">unsigned <span class="returnvalue">int</span>
+hb_face_count (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="type">hb_blob_t</span></a> *blob</code></em>);</pre>
+</div>
+<hr>
+<div class="refsect2">
 <a name="hb-face-create"></a><h3>hb_face_create ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="returnvalue">hb_face_t</span></a> *
 hb_face_create (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="type">hb_blob_t</span></a> *blob</code></em>,
index c9c833a..4bab397 100644 (file)
 </tr>
 <tr>
 <td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-ot-layout.html#hb-ot-layout-lookups-substitute-closure" title="hb_ot_layout_lookups_substitute_closure ()">hb_ot_layout_lookups_substitute_closure</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
 <a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
 </td>
 <td class="function_name">
@@ -512,6 +520,18 @@ hb_ot_layout_lookup_substitute_closure
 </div>
 <hr>
 <div class="refsect2">
+<a name="hb-ot-layout-lookups-substitute-closure"></a><h3>hb_ot_layout_lookups_substitute_closure ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+hb_ot_layout_lookups_substitute_closure
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
+                                <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *lookups</code></em>,
+                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *glyphs</code></em>);</pre>
+<p>Compute the transitive closure of glyphs needed for all of the
+provided lookups.</p>
+<p class="since">Since: 1.8.1</p>
+</div>
+<hr>
+<div class="refsect2">
 <a name="hb-ot-layout-lookup-would-substitute"></a><h3>hb_ot_layout_lookup_would_substitute ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
 hb_ot_layout_lookup_would_substitute (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
index 7f9db9e..d05e57d 100644 (file)
 <a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
 </td>
 <td class="function_name">
-<a class="link" href="harfbuzz-hb-set.html#hb-set-next" title="hb_set_next ()">hb_set_next</a> <span class="c_punctuation">()</span>
+<a class="link" href="harfbuzz-hb-set.html#hb-set-is-subset" title="hb_set_is_subset ()">hb_set_is_subset</a> <span class="c_punctuation">()</span>
 </td>
 </tr>
 <tr>
 <a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
 </td>
 <td class="function_name">
-<a class="link" href="harfbuzz-hb-set.html#hb-set-previous" title="hb_set_previous ()">hb_set_previous</a> <span class="c_punctuation">()</span>
+<a class="link" href="harfbuzz-hb-set.html#hb-set-next" title="hb_set_next ()">hb_set_next</a> <span class="c_punctuation">()</span>
 </td>
 </tr>
 <tr>
 <a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
 </td>
 <td class="function_name">
+<a class="link" href="harfbuzz-hb-set.html#hb-set-previous" title="hb_set_previous ()">hb_set_previous</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
+</td>
+<td class="function_name">
 <a class="link" href="harfbuzz-hb-set.html#hb-set-previous-range" title="hb_set_previous_range ()">hb_set_previous_range</a> <span class="c_punctuation">()</span>
 </td>
 </tr>
@@ -665,28 +673,34 @@ hb_set_is_equal (<em class="parameter"><code>const <a class="link" href="harfbuz
 <col class="parameters_description">
 <col width="200px" class="parameters_annotations">
 </colgroup>
-<tbody><tr>
+<tbody>
+<tr>
 <td class="parameter_name"><p>set</p></td>
 <td class="parameter_description"><p>a set.</p></td>
 <td class="parameter_annotations"> </td>
-</tr></tbody>
+</tr>
+<tr>
+<td class="parameter_name"><p>other</p></td>
+<td class="parameter_description"><p>other set.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
 </table></div>
 </div>
+<div class="refsect3">
+<a name="hb-set-is-equal.returns"></a><h4>Returns</h4>
+<p> <code class="literal">TRUE</code> if the two sets are equal, <code class="literal">FALSE</code> otherwise.</p>
+</div>
 <p class="since">Since: <a class="link" href="api-index-0-9-7.html#api-index-0.9.7">0.9.7</a></p>
 </div>
 <hr>
 <div class="refsect2">
-<a name="hb-set-next"></a><h3>hb_set_next ()</h3>
+<a name="hb-set-is-subset"></a><h3>hb_set_is_subset ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_set_next (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>,
-             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *codepoint</code></em>);</pre>
-<p>Gets the next number in <em class="parameter"><code>set</code></em>
- that is greater than current value of <em class="parameter"><code>codepoint</code></em>
-.</p>
-<p>Set <em class="parameter"><code>codepoint</code></em>
- to <a class="link" href="harfbuzz-hb-set.html#HB-SET-VALUE-INVALID:CAPS" title="HB_SET_VALUE_INVALID"><code class="literal">HB_SET_VALUE_INVALID</code></a> to get started.</p>
+hb_set_is_subset (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>,
+                  <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *larger_set</code></em>);</pre>
 <div class="refsect3">
-<a name="hb-set-next.parameters"></a><h4>Parameters</h4>
+<a name="hb-set-is-subset.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
 <colgroup>
 <col width="150px" class="parameters_name">
@@ -700,32 +714,34 @@ hb_set_next (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
-<td class="parameter_name"><p>codepoint</p></td>
-<td class="parameter_description"><p></p></td>
-<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for input and for returning results. Default is transfer full."><span class="acronym">inout</span></acronym>]</span></td>
+<td class="parameter_name"><p>larger_set</p></td>
+<td class="parameter_description"><p>other set.</p></td>
+<td class="parameter_annotations"> </td>
 </tr>
 </tbody>
 </table></div>
 </div>
 <div class="refsect3">
-<a name="hb-set-next.returns"></a><h4>Returns</h4>
-<p> whether there was a next value.</p>
+<a name="hb-set-is-subset.returns"></a><h4>Returns</h4>
+<p> <code class="literal">TRUE</code> if the <em class="parameter"><code>set</code></em>
+is a subset of (or equal to) <em class="parameter"><code>larger_set</code></em>
+, <code class="literal">FALSE</code> otherwise.</p>
 </div>
-<p class="since">Since: <a class="link" href="api-index-0-9-2.html#api-index-0.9.2">0.9.2</a></p>
+<p class="since">Since: 1.8.1</p>
 </div>
 <hr>
 <div class="refsect2">
-<a name="hb-set-previous"></a><h3>hb_set_previous ()</h3>
+<a name="hb-set-next"></a><h3>hb_set_next ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_set_previous (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>,
-                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *codepoint</code></em>);</pre>
-<p>Gets the previous number in <em class="parameter"><code>set</code></em>
- that is slower than current value of <em class="parameter"><code>codepoint</code></em>
+hb_set_next (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>,
+             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *codepoint</code></em>);</pre>
+<p>Gets the next number in <em class="parameter"><code>set</code></em>
+ that is greater than current value of <em class="parameter"><code>codepoint</code></em>
 .</p>
 <p>Set <em class="parameter"><code>codepoint</code></em>
  to <a class="link" href="harfbuzz-hb-set.html#HB-SET-VALUE-INVALID:CAPS" title="HB_SET_VALUE_INVALID"><code class="literal">HB_SET_VALUE_INVALID</code></a> to get started.</p>
 <div class="refsect3">
-<a name="hb-set-previous.parameters"></a><h4>Parameters</h4>
+<a name="hb-set-next.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
 <colgroup>
 <col width="150px" class="parameters_name">
@@ -747,10 +763,10 @@ hb_set_previous (<em class="parameter"><code>const <a class="link" href="harfbuz
 </table></div>
 </div>
 <div class="refsect3">
-<a name="hb-set-previous.returns"></a><h4>Returns</h4>
-<p> whether there was a previous value.</p>
+<a name="hb-set-next.returns"></a><h4>Returns</h4>
+<p> whether there was a next value.</p>
 </div>
-<p class="since">Since: 1.8.0</p>
+<p class="since">Since: <a class="link" href="api-index-0-9-2.html#api-index-0.9.2">0.9.2</a></p>
 </div>
 <hr>
 <div class="refsect2">
@@ -800,6 +816,45 @@ are greater than current value of <em class="parameter"><code>last</code></em>
 </div>
 <hr>
 <div class="refsect2">
+<a name="hb-set-previous"></a><h3>hb_set_previous ()</h3>
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
+hb_set_previous (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>,
+                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *codepoint</code></em>);</pre>
+<p>Gets the previous number in <em class="parameter"><code>set</code></em>
+ that is slower than current value of <em class="parameter"><code>codepoint</code></em>
+.</p>
+<p>Set <em class="parameter"><code>codepoint</code></em>
+ to <a class="link" href="harfbuzz-hb-set.html#HB-SET-VALUE-INVALID:CAPS" title="HB_SET_VALUE_INVALID"><code class="literal">HB_SET_VALUE_INVALID</code></a> to get started.</p>
+<div class="refsect3">
+<a name="hb-set-previous.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>set</p></td>
+<td class="parameter_description"><p>a set.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>codepoint</p></td>
+<td class="parameter_description"><p>. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for input and for returning results. Default is transfer full."><span class="acronym">inout</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="hb-set-previous.returns"></a><h4>Returns</h4>
+<p> whether there was a previous value.</p>
+</div>
+<p class="since">Since: 1.8.0</p>
+</div>
+<hr>
+<div class="refsect2">
 <a name="hb-set-previous-range"></a><h3>hb_set_previous_range ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
 hb_set_previous_range (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>,
index 3b06755..3180c50 100644 (file)
@@ -170,22 +170,26 @@ hb_version_string (<em class="parameter"><code><span class="type">void</span></c
 <a name="harfbuzz-hb-version.other_details"></a><h2>Types and Values</h2>
 <div class="refsect2">
 <a name="HB-VERSION-MAJOR:CAPS"></a><h3>HB_VERSION_MAJOR</h3>
-<pre class="programlisting">#define             HB_VERSION_MAJOR</pre>
+<pre class="programlisting">#define HB_VERSION_MAJOR 1
+</pre>
 </div>
 <hr>
 <div class="refsect2">
 <a name="HB-VERSION-MICRO:CAPS"></a><h3>HB_VERSION_MICRO</h3>
-<pre class="programlisting">#define             HB_VERSION_MICRO</pre>
+<pre class="programlisting">#define HB_VERSION_MICRO 1
+</pre>
 </div>
 <hr>
 <div class="refsect2">
 <a name="HB-VERSION-MINOR:CAPS"></a><h3>HB_VERSION_MINOR</h3>
-<pre class="programlisting">#define             HB_VERSION_MINOR</pre>
+<pre class="programlisting">#define HB_VERSION_MINOR 8
+</pre>
 </div>
 <hr>
 <div class="refsect2">
 <a name="HB-VERSION-STRING:CAPS"></a><h3>HB_VERSION_STRING</h3>
-<pre class="programlisting">#define             HB_VERSION_STRING</pre>
+<pre class="programlisting">#define HB_VERSION_STRING "1.8.1"
+</pre>
 </div>
 </div>
 </div>
index dff4321..c4ed6ff 100644 (file)
     <keyword type="enum" name="enum hb_buffer_serialize_flags_t" link="harfbuzz-Buffers.html#hb-buffer-serialize-flags-t" since="0.9.20"/>
     <keyword type="enum" name="enum hb_buffer_diff_flags_t" link="harfbuzz-Buffers.html#hb-buffer-diff-flags-t"/>
     <keyword type="function" name="hb_blob_create ()" link="harfbuzz-hb-blob.html#hb-blob-create" since="0.9.2"/>
+    <keyword type="function" name="hb_blob_create_from_file ()" link="harfbuzz-hb-blob.html#hb-blob-create-from-file" since="1.7.7"/>
     <keyword type="function" name="hb_blob_create_sub_blob ()" link="harfbuzz-hb-blob.html#hb-blob-create-sub-blob" since="0.9.2"/>
     <keyword type="function" name="hb_blob_copy_writable_or_fail ()" link="harfbuzz-hb-blob.html#hb-blob-copy-writable-or-fail" since="1.8.0"/>
     <keyword type="function" name="hb_blob_destroy ()" link="harfbuzz-hb-blob.html#hb-blob-destroy" since="0.9.2"/>
     <keyword type="function" name="hb_blob_set_user_data ()" link="harfbuzz-hb-blob.html#hb-blob-set-user-data" since="0.9.2"/>
     <keyword type="typedef" name="hb_blob_t" link="harfbuzz-hb-blob.html#hb-blob-t"/>
     <keyword type="enum" name="enum hb_memory_mode_t" link="harfbuzz-hb-blob.html#hb-memory-mode-t"/>
+    <keyword type="function" name="hb_face_count ()" link="harfbuzz-hb-face.html#hb-face-count"/>
     <keyword type="function" name="hb_face_create ()" link="harfbuzz-hb-face.html#hb-face-create" since="0.9.2"/>
     <keyword type="function" name="hb_face_create_for_tables ()" link="harfbuzz-hb-face.html#hb-face-create-for-tables" since="0.9.2"/>
     <keyword type="function" name="hb_face_destroy ()" link="harfbuzz-hb-face.html#hb-face-destroy" since="0.9.2"/>
     <keyword type="function" name="hb_set_intersect ()" link="harfbuzz-hb-set.html#hb-set-intersect" since="0.9.2"/>
     <keyword type="function" name="hb_set_is_empty ()" link="harfbuzz-hb-set.html#hb-set-is-empty" since="0.9.7"/>
     <keyword type="function" name="hb_set_is_equal ()" link="harfbuzz-hb-set.html#hb-set-is-equal" since="0.9.7"/>
+    <keyword type="function" name="hb_set_is_subset ()" link="harfbuzz-hb-set.html#hb-set-is-subset" since="1.8.1"/>
     <keyword type="function" name="hb_set_next ()" link="harfbuzz-hb-set.html#hb-set-next" since="0.9.2"/>
-    <keyword type="function" name="hb_set_previous ()" link="harfbuzz-hb-set.html#hb-set-previous" since="1.8.0"/>
     <keyword type="function" name="hb_set_next_range ()" link="harfbuzz-hb-set.html#hb-set-next-range" since="0.9.7"/>
+    <keyword type="function" name="hb_set_previous ()" link="harfbuzz-hb-set.html#hb-set-previous" since="1.8.0"/>
     <keyword type="function" name="hb_set_previous_range ()" link="harfbuzz-hb-set.html#hb-set-previous-range" since="1.8.0"/>
     <keyword type="function" name="hb_set_reference ()" link="harfbuzz-hb-set.html#hb-set-reference" since="0.9.2"/>
     <keyword type="function" name="hb_set_set ()" link="harfbuzz-hb-set.html#hb-set-set" since="0.9.2"/>
     <keyword type="function" name="hb_ot_layout_language_get_required_feature ()" link="harfbuzz-hb-ot-layout.html#hb-ot-layout-language-get-required-feature" since="0.9.30"/>
     <keyword type="function" name="hb_ot_layout_lookup_collect_glyphs ()" link="harfbuzz-hb-ot-layout.html#hb-ot-layout-lookup-collect-glyphs" since="0.9.7"/>
     <keyword type="function" name="hb_ot_layout_lookup_substitute_closure ()" link="harfbuzz-hb-ot-layout.html#hb-ot-layout-lookup-substitute-closure" since="0.9.7"/>
+    <keyword type="function" name="hb_ot_layout_lookups_substitute_closure ()" link="harfbuzz-hb-ot-layout.html#hb-ot-layout-lookups-substitute-closure" since="1.8.1"/>
     <keyword type="function" name="hb_ot_layout_lookup_would_substitute ()" link="harfbuzz-hb-ot-layout.html#hb-ot-layout-lookup-would-substitute" since="0.9.7"/>
     <keyword type="function" name="hb_ot_layout_script_find_language ()" link="harfbuzz-hb-ot-layout.html#hb-ot-layout-script-find-language"/>
     <keyword type="function" name="hb_ot_layout_script_get_language_tags ()" link="harfbuzz-hb-ot-layout.html#hb-ot-layout-script-get-language-tags"/>
     <keyword type="constant" name="HB_SCRIPT_BASSA_VAH" link="harfbuzz-hb-common.html#HB-SCRIPT-BASSA-VAH:CAPS"/>
     <keyword type="constant" name="HB_SCRIPT_ADLAM" link="harfbuzz-hb-common.html#HB-SCRIPT-ADLAM:CAPS"/>
     <keyword type="constant" name="HB_SCRIPT_MASARAM_GONDI" link="harfbuzz-hb-common.html#HB-SCRIPT-MASARAM-GONDI:CAPS"/>
+    <keyword type="constant" name="HB_SCRIPT_DOGRA" link="harfbuzz-hb-common.html#HB-SCRIPT-DOGRA:CAPS"/>
     <keyword type="constant" name="HB_SCRIPT_INVALID" link="harfbuzz-hb-common.html#HB-SCRIPT-INVALID:CAPS"/>
     <keyword type="constant" name="_HB_SCRIPT_MAX_VALUE" link="harfbuzz-hb-common.html#HB-SCRIPT-MAX-VALUE:CAPS"/>
     <keyword type="constant" name="_HB_SCRIPT_MAX_VALUE_SIGNED" link="harfbuzz-hb-common.html#HB-SCRIPT-MAX-VALUE-SIGNED:CAPS"/>
index 9bdd8a7..ac7201f 100644 (file)
@@ -24,7 +24,7 @@
 <div><h1 class="title">
 <a name="id-1.3"></a>Part II. Reference manual</h1></div>
 <div><p class="releaseinfo">
-        This document is for HarfBuzz 1.7.6
+        This document is for HarfBuzz 1.8.1
 .
         
       </p></div>
index de28578..a8fdfda 100644 (file)
@@ -1 +1 @@
-1.7.6
+1.8.1
diff --git a/m4/ax_check_link_flag.m4 b/m4/ax_check_link_flag.m4
new file mode 100644 (file)
index 0000000..819409a
--- /dev/null
@@ -0,0 +1,74 @@
+# ===========================================================================
+#    https://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
+#
+# DESCRIPTION
+#
+#   Check whether the given FLAG works with the linker or gives an error.
+#   (Warnings, however, are ignored)
+#
+#   ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+#   success/failure.
+#
+#   If EXTRA-FLAGS is defined, it is added to the linker's default flags
+#   when the check is done.  The check is thus made with the flags: "LDFLAGS
+#   EXTRA-FLAGS FLAG".  This can for example be used to force the linker to
+#   issue an error when a bad flag is given.
+#
+#   INPUT gives an alternative input source to AC_LINK_IFELSE.
+#
+#   NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+#   macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+#   Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <https://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 5
+
+AC_DEFUN([AX_CHECK_LINK_FLAG],
+[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
+AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl
+AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS $4 $1"
+  AC_LINK_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
+    [AS_VAR_SET(CACHEVAR,[yes])],
+    [AS_VAR_SET(CACHEVAR,[no])])
+  LDFLAGS=$ax_check_save_flags])
+AS_VAR_IF(CACHEVAR,yes,
+  [m4_default([$2], :)],
+  [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_LINK_FLAGS
index afa104b..9d5662e 100644 (file)
@@ -12,12 +12,9 @@ DISTCHECK_CONFIGURE_FLAGS = --enable-introspection
 TESTS =
 check_PROGRAMS =
 
-# The following warning options are useful for debugging: -Wpadded
-#AM_CXXFLAGS =
-
 # Convenience targets:
 lib: $(BUILT_SOURCES) libharfbuzz.la libharfbuzz-subset.la
-fuzzing: $(BUILT_SOURCES) libharfbuzz-fuzzing.la
+fuzzing: $(BUILT_SOURCES) libharfbuzz-fuzzing.la libharfbuzz-subset-fuzzing.la
 
 lib_LTLIBRARIES = libharfbuzz.la
 
@@ -31,15 +28,6 @@ HBSOURCES =  $(HB_BASE_sources)
 HBSOURCES += $(HB_BASE_RAGEL_GENERATED_sources)
 HBHEADERS = $(HB_BASE_headers)
 
-if WITH_LIBSTDCXX
-HBNOLIBCXXCFLAGS =
-else
-# Make sure we don't link to libstdc++
-# No threadsafe statics in C++ as we do it ourselves
-HBCFLAGS += -fno-exceptions
-HBNOLIBCXXFLAGS = -fno-threadsafe-statics -fno-rtti
-endif
-
 if HAVE_OT
 HBSOURCES += $(HB_OT_sources)
 HBSOURCES += $(HB_OT_RAGEL_GENERATED_sources)
@@ -117,6 +105,17 @@ endif
 DIST_SUBDIRS += hb-ucdn
 
 
+BUILT_SOURCES += \
+       hb-version.h
+
+$(srcdir)/hb-version.h: hb-version.h.in $(top_srcdir)/configure.ac
+       $(AM_V_GEN) $(SED) \
+               -e 's/[@]HB_VERSION_MAJOR@/$(HB_VERSION_MAJOR)/' \
+               -e 's/[@]HB_VERSION_MINOR@/$(HB_VERSION_MINOR)/' \
+               -e 's/[@]HB_VERSION_MICRO@/$(HB_VERSION_MICRO)/' \
+               -e 's/[@]HB_VERSION@/$(HB_VERSION)/' \
+               "$<" > "$@" || ($(RM) "$@"; false)
+
 # Put the library together
 
 HBLIBS += $(HBNONPCLIBS)
@@ -147,10 +146,10 @@ endif
 @CODE_COVERAGE_RULES@
 
 base_link_flags = $(AM_LDFLAGS) -lm -version-info $(HB_LIBTOOL_VERSION_INFO) -no-undefined
-libharfbuzz_la_LINK = $(chosen_linker) $(libharfbuzz_la_LDFLAGS) $(CODE_COVERAGE_LDFLAGS)
+libharfbuzz_la_LINK = $(chosen_linker) $(libharfbuzz_la_LDFLAGS)
 libharfbuzz_la_SOURCES = $(HBSOURCES) $(HBHEADERS)
-libharfbuzz_la_CPPFLAGS = $(HBCFLAGS) $(HBNOLIBCXXFLAGS) $(CODE_COVERAGE_CFLAGS)
-libharfbuzz_la_LDFLAGS = $(base_link_flags) $(export_symbols)
+libharfbuzz_la_CPPFLAGS = $(HBCFLAGS) $(CODE_COVERAGE_CFLAGS)
+libharfbuzz_la_LDFLAGS = $(base_link_flags) $(export_symbols) $(CODE_COVERAGE_LDFLAGS)
 libharfbuzz_la_LIBADD = $(HBLIBS)
 EXTRA_libharfbuzz_la_DEPENDENCIES = $(harfbuzz_def_dependency)
 pkginclude_HEADERS = $(HBHEADERS)
@@ -159,12 +158,12 @@ pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = harfbuzz.pc
 cmakedir = $(libdir)/cmake/harfbuzz
 cmake_DATA = harfbuzz-config.cmake
-EXTRA_DIST += harfbuzz.pc.in harfbuzz-config.cmake.in
+EXTRA_DIST += hb-version.h.in harfbuzz.pc.in harfbuzz-config.cmake.in
 
 lib_LTLIBRARIES += libharfbuzz-subset.la
 libharfbuzz_subset_la_SOURCES = $(HB_SUBSET_sources)
-libharfbuzz_subset_la_CPPFLAGS = $(HBCFLAGS)
-libharfbuzz_subset_la_LDFLAGS = $(base_link_flags) $(export_symbols_subset)
+libharfbuzz_subset_la_CPPFLAGS = $(HBCFLAGS) $(CODE_COVERAGE_CFLAGS)
+libharfbuzz_subset_la_LDFLAGS = $(base_link_flags) $(export_symbols_subset) $(CODE_COVERAGE_LDFLAGS)
 libharfbuzz_subset_la_LIBADD = libharfbuzz.la
 EXTRA_libharfbuzz_subset_la_DEPENDENCIES = $(harfbuzz_subset_def_dependency)
 pkginclude_HEADERS += $(HB_SUBSET_headers)
@@ -184,7 +183,8 @@ FUZZING_CPPFLAGS = \
        -DHB_BUFFER_MAX_OPS_MIN=64 \
        -DHB_BUFFER_MAX_OPS_DEFAULT=1024 \
        $(NULL)
-EXTRA_LTLIBRARIES = libharfbuzz-fuzzing.la
+EXTRA_LTLIBRARIES = libharfbuzz-fuzzing.la libharfbuzz-subset-fuzzing.la
+
 libharfbuzz_fuzzing_la_LINK = $(chosen_linker) $(libharfbuzz_fuzzing_la_LDFLAGS)
 libharfbuzz_fuzzing_la_SOURCES = $(libharfbuzz_la_SOURCES)
 libharfbuzz_fuzzing_la_CPPFLAGS = $(HBCFLAGS) $(FUZZING_CPPFLAGS)
@@ -193,6 +193,14 @@ libharfbuzz_fuzzing_la_LIBADD = $(libharfbuzz_la_LIBADD)
 EXTRA_libharfbuzz_fuzzing_la_DEPENDENCIES = $(EXTRA_libharfbuzz_la_DEPENDENCIES)
 CLEANFILES += libharfbuzz-fuzzing.la
 
+libharfbuzz_subset_fuzzing_la_LINK = $(chosen_linker) $(libharfbuzz_subset_fuzzing_la_LDFLAGS)
+libharfbuzz_subset_fuzzing_la_SOURCES = $(libharfbuzz_subset_la_SOURCES)
+libharfbuzz_subset_fuzzing_la_CPPFLAGS = $(HBCFLAGS) $(FUZZING_CPPFLAGS)
+libharfbuzz_subset_fuzzing_la_LDFLAGS = $(AM_LDFLAGS)
+libharfbuzz_subset_fuzzing_la_LIBADD = $(libharfbuzz_subset_la_LIBADD)
+EXTRA_libharfbuzz_subset_fuzzing_la_DEPENDENCIES = $(EXTRA_libharfbuzz_subset_la_DEPENDENCIES)
+CLEANFILES += libharfbuzz-subset-fuzzing.la
+
 if HAVE_ICU
 if HAVE_ICU_BUILTIN
 HBCFLAGS += $(ICU_CFLAGS)
@@ -202,8 +210,8 @@ HBHEADERS += $(HB_ICU_headers)
 else
 lib_LTLIBRARIES += libharfbuzz-icu.la
 libharfbuzz_icu_la_SOURCES = $(HB_ICU_sources)
-libharfbuzz_icu_la_CPPFLAGS = $(HBCFLAGS) $(ICU_CFLAGS)
-libharfbuzz_icu_la_LDFLAGS = $(base_link_flags) $(export_symbols_icu)
+libharfbuzz_icu_la_CPPFLAGS = $(HBCFLAGS) $(ICU_CFLAGS) $(CODE_COVERAGE_CFLAGS)
+libharfbuzz_icu_la_LDFLAGS = $(base_link_flags) $(export_symbols_icu) $(CODE_COVERAGE_LDFLAGS)
 libharfbuzz_icu_la_LIBADD = $(ICU_LIBS) libharfbuzz.la
 EXTRA_libharfbuzz_icu_la_DEPENDENCIES = $(harfbuzz_icu_def_dependency)
 pkginclude_HEADERS += $(HB_ICU_headers)
@@ -217,8 +225,8 @@ lib_LTLIBRARIES += libharfbuzz-gobject.la
 libharfbuzz_gobject_la_LINK = $(chosen_linker) $(libharfbuzz_gobject_la_LDFLAGS)
 libharfbuzz_gobject_la_SOURCES = $(HB_GOBJECT_DIST_sources)
 nodist_libharfbuzz_gobject_la_SOURCES = $(HB_GOBJECT_NODIST_sources)
-libharfbuzz_gobject_la_CPPFLAGS = $(HBCFLAGS) $(HBNOLIBCXXFLAGS) $(GOBJECT_CFLAGS)
-libharfbuzz_gobject_la_LDFLAGS = $(base_link_flags)
+libharfbuzz_gobject_la_CPPFLAGS = $(HBCFLAGS) $(GOBJECT_CFLAGS) $(CODE_COVERAGE_CFLAGS)
+libharfbuzz_gobject_la_LDFLAGS = $(base_link_flags) $(CODE_COVERAGE_LDFLAGS)
 libharfbuzz_gobject_la_LIBADD = $(GOBJECT_LIBS) libharfbuzz.la
 EXTRA_libharfbuzz_gobject_la_DEPENDENCIES = $(harfbuzz_gobject_def_dependency)
 pkginclude_HEADERS += $(HB_GOBJECT_DIST_headers)
@@ -234,7 +242,7 @@ DISTCLEANFILES += \
        $(HB_GOBJECT_ENUM_headers) \
        $(NULL)
 hb-gobject-enums.%: hb-gobject-enums.%.tmpl $(HBHEADERS)
-       $(AM_V_GEN) $(GLIB_MKENUMS) \
+       $(AM_V_GEN) PYTHONIOENCODING=UTF-8 $(GLIB_MKENUMS) \
                --identifier-prefix hb_ --symbol-prefix hb_gobject \
                --template $^ | \
        sed 's/_t_get_type/_get_type/g; s/_T (/ (/g' > "$@" \
@@ -269,13 +277,13 @@ endif
 check: $(DEF_FILES) # For check-symbols.sh
 CLEANFILES += $(DEF_FILES)
 harfbuzz.def: $(HBHEADERS) $(HBNODISTHEADERS)
-       $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py $@
+       $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py "$@"
 harfbuzz-subset.def: $(HB_SUBSET_headers)
-       $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py $@
+       $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py "$@"
 harfbuzz-icu.def: $(HB_ICU_headers)
-       $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py $@
+       $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py "$@"
 harfbuzz-gobject.def: $(HB_GOBJECT_headers)
-       $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py $@
+       $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py "$@"
 
 
 GENERATORS = \
@@ -289,16 +297,16 @@ EXTRA_DIST += $(GENERATORS)
 unicode-tables: arabic-table indic-table use-table
 
 arabic-table: gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt
-       $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-arabic-table.hh \
-       || ($(RM) hb-ot-shape-complex-arabic-table.hh; false)
+       $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-arabic-table.hh \
+       || ($(RM) $(srcdir)/hb-ot-shape-complex-arabic-table.hh; false)
 
-indic-table: gen-indic-table.py IndicSyllabicCategory-7.0.0.txt IndicMatraCategory-7.0.0.txt Blocks.txt
-       $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-indic-table.cc \
-       || ($(RM) hb-ot-shape-complex-indic-table.cc; false)
+indic-table: gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt
+       $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-indic-table.cc \
+       || ($(RM) $(srcdir)/hb-ot-shape-complex-indic-table.cc; false)
 
 use-table: gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt
-       $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-use-table.cc \
-       || ($(RM) hb-ot-shape-complex-use-table.cc; false)
+       $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-use-table.cc \
+       || ($(RM) $(srcdir)/hb-ot-shape-complex-use-table.cc; false)
 
 built-sources: $(BUILT_SOURCES)
 
@@ -365,11 +373,15 @@ dist_check_SCRIPTS += \
 endif
 
 check_PROGRAMS += \
+       dump-fon \
        dump-indic-data \
        dump-khmer-data \
        dump-myanmar-data \
        dump-use-data \
        $(NULL)
+dump_fon_SOURCES = dump-fon.cc
+dump_fon_CPPFLAGS = $(HBCFLAGS)
+dump_fon_LDADD = libharfbuzz.la $(HBLIBS)
 dump_indic_data_SOURCES = dump-indic-data.cc hb-ot-shape-complex-indic-table.cc
 dump_indic_data_CPPFLAGS = $(HBCFLAGS)
 dump_indic_data_LDADD = libharfbuzz.la $(HBLIBS)
@@ -383,6 +395,15 @@ dump_use_data_SOURCES = dump-use-data.cc hb-ot-shape-complex-use-table.cc
 dump_use_data_CPPFLAGS = $(HBCFLAGS)
 dump_use_data_LDADD = libharfbuzz.la $(HBLIBS)
 
+if HAVE_FREETYPE
+if HAVE_CAIRO_FT
+check_PROGRAMS += dump-emoji
+dump_emoji_SOURCES = dump-emoji.cc
+dump_emoji_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS) $(CAIRO_FT_CFLAGS)
+dump_emoji_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS) $(CAIRO_LIBS) $(CAIRO_FT_LIBS)
+endif # HAVE_CAIRO_FT
+endif # HAVE_FREETYPE
+
 check_PROGRAMS += test-ot-tag test-unicode-ranges
 TESTS += test-ot-tag test-unicode-ranges
 
index f2f5c6b..e3715e8 100644 (file)
@@ -95,91 +95,90 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
-TESTS = $(am__EXEEXT_3) test-ot-tag$(EXEEXT) \
+TESTS = $(am__EXEEXT_4) test-ot-tag$(EXEEXT) \
        test-unicode-ranges$(EXEEXT)
-check_PROGRAMS = dump-indic-data$(EXEEXT) dump-khmer-data$(EXEEXT) \
-       dump-myanmar-data$(EXEEXT) dump-use-data$(EXEEXT) \
-       $(am__EXEEXT_1) test-ot-tag$(EXEEXT) \
-       test-unicode-ranges$(EXEEXT)
-# Make sure we don't link to libstdc++
-# No threadsafe statics in C++ as we do it ourselves
-@WITH_LIBSTDCXX_FALSE@am__append_1 = -fno-exceptions
-@HAVE_OT_TRUE@am__append_2 = $(HB_OT_sources) \
+check_PROGRAMS = dump-fon$(EXEEXT) dump-indic-data$(EXEEXT) \
+       dump-khmer-data$(EXEEXT) dump-myanmar-data$(EXEEXT) \
+       dump-use-data$(EXEEXT) $(am__EXEEXT_1) $(am__EXEEXT_2) \
+       test-ot-tag$(EXEEXT) test-unicode-ranges$(EXEEXT)
+@HAVE_OT_TRUE@am__append_1 = $(HB_OT_sources) \
 @HAVE_OT_TRUE@ $(HB_OT_RAGEL_GENERATED_sources)
-@HAVE_OT_TRUE@am__append_3 = $(HB_OT_headers)
-@HAVE_FALLBACK_TRUE@am__append_4 = $(HB_FALLBACK_sources)
-@HAVE_PTHREAD_TRUE@am__append_5 = $(PTHREAD_CFLAGS)
-@HAVE_PTHREAD_TRUE@am__append_6 = $(PTHREAD_LIBS)
-@HAVE_GLIB_TRUE@am__append_7 = $(GLIB_CFLAGS)
-@HAVE_GLIB_TRUE@am__append_8 = $(GLIB_LIBS)
-@HAVE_GLIB_TRUE@am__append_9 = $(GLIB_DEPS)
-@HAVE_GLIB_TRUE@am__append_10 = $(HB_GLIB_sources)
-@HAVE_GLIB_TRUE@am__append_11 = $(HB_GLIB_headers)
-@HAVE_FREETYPE_TRUE@am__append_12 = $(FREETYPE_CFLAGS)
-@HAVE_FREETYPE_TRUE@am__append_13 = $(FREETYPE_LIBS)
+@HAVE_OT_TRUE@am__append_2 = $(HB_OT_headers)
+@HAVE_FALLBACK_TRUE@am__append_3 = $(HB_FALLBACK_sources)
+@HAVE_PTHREAD_TRUE@am__append_4 = $(PTHREAD_CFLAGS)
+@HAVE_PTHREAD_TRUE@am__append_5 = $(PTHREAD_LIBS)
+@HAVE_GLIB_TRUE@am__append_6 = $(GLIB_CFLAGS)
+@HAVE_GLIB_TRUE@am__append_7 = $(GLIB_LIBS)
+@HAVE_GLIB_TRUE@am__append_8 = $(GLIB_DEPS)
+@HAVE_GLIB_TRUE@am__append_9 = $(HB_GLIB_sources)
+@HAVE_GLIB_TRUE@am__append_10 = $(HB_GLIB_headers)
+@HAVE_FREETYPE_TRUE@am__append_11 = $(FREETYPE_CFLAGS)
+@HAVE_FREETYPE_TRUE@am__append_12 = $(FREETYPE_LIBS)
 # XXX
 # The following creates a recursive dependency on FreeType if FreeType is
 # built with HarfBuzz support enabled.  Newer pkg-config handles that just
 # fine but pkg-config 0.26 as shipped in Ubuntu 14.04 crashes.  Remove
 # in a year or two, or otherwise work around it...
 #HBDEPS   += $(FREETYPE_DEPS)
-@HAVE_FREETYPE_TRUE@am__append_14 = $(HB_FT_sources)
-@HAVE_FREETYPE_TRUE@am__append_15 = $(HB_FT_headers)
-@HAVE_GRAPHITE2_TRUE@am__append_16 = $(GRAPHITE2_CFLAGS)
-@HAVE_GRAPHITE2_TRUE@am__append_17 = $(GRAPHITE2_LIBS)
-@HAVE_GRAPHITE2_TRUE@am__append_18 = $(GRAPHITE2_DEPS)
-@HAVE_GRAPHITE2_TRUE@am__append_19 = $(HB_GRAPHITE2_sources)
-@HAVE_GRAPHITE2_TRUE@am__append_20 = $(HB_GRAPHITE2_headers)
-@HAVE_UNISCRIBE_TRUE@am__append_21 = $(UNISCRIBE_CFLAGS)
-@HAVE_UNISCRIBE_TRUE@am__append_22 = $(UNISCRIBE_LIBS)
-@HAVE_UNISCRIBE_TRUE@am__append_23 = $(HB_UNISCRIBE_sources)
-@HAVE_UNISCRIBE_TRUE@am__append_24 = $(HB_UNISCRIBE_headers)
-@HAVE_DIRECTWRITE_TRUE@am__append_25 = $(DIRECTWRITE_CXXFLAGS)
-@HAVE_DIRECTWRITE_TRUE@am__append_26 = $(DIRECTWRITE_LIBS)
-@HAVE_DIRECTWRITE_TRUE@am__append_27 = $(HB_DIRECTWRITE_sources)
-@HAVE_DIRECTWRITE_TRUE@am__append_28 = $(HB_DIRECTWRITE_headers)
-@HAVE_CORETEXT_TRUE@am__append_29 = $(CORETEXT_CFLAGS)
-@HAVE_CORETEXT_TRUE@am__append_30 = $(CORETEXT_LIBS)
-@HAVE_CORETEXT_TRUE@am__append_31 = $(HB_CORETEXT_sources)
-@HAVE_CORETEXT_TRUE@am__append_32 = $(HB_CORETEXT_headers)
-@HAVE_UCDN_TRUE@am__append_33 = hb-ucdn
-@HAVE_UCDN_TRUE@am__append_34 = -I$(srcdir)/hb-ucdn
-@HAVE_UCDN_TRUE@am__append_35 = hb-ucdn/libhb-ucdn.la
-@HAVE_UCDN_TRUE@am__append_36 = $(HB_UCDN_sources)
-@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__append_37 = $(ICU_CFLAGS)
-@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__append_38 = $(ICU_LIBS)
-@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__append_39 = $(HB_ICU_sources)
-@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__append_40 = $(HB_ICU_headers)
-@HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@am__append_41 = libharfbuzz-icu.la
-@HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@am__append_42 = $(HB_ICU_headers)
-@HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@am__append_43 = harfbuzz-icu.pc
-@HAVE_GOBJECT_TRUE@am__append_44 = libharfbuzz-gobject.la
-@HAVE_GOBJECT_TRUE@am__append_45 = $(HB_GOBJECT_DIST_headers)
-@HAVE_GOBJECT_TRUE@am__append_46 = $(HB_GOBJECT_NODIST_headers)
-@HAVE_GOBJECT_TRUE@am__append_47 = harfbuzz-gobject.pc
-@HAVE_GOBJECT_TRUE@am__append_48 = \
+@HAVE_FREETYPE_TRUE@am__append_13 = $(HB_FT_sources)
+@HAVE_FREETYPE_TRUE@am__append_14 = $(HB_FT_headers)
+@HAVE_GRAPHITE2_TRUE@am__append_15 = $(GRAPHITE2_CFLAGS)
+@HAVE_GRAPHITE2_TRUE@am__append_16 = $(GRAPHITE2_LIBS)
+@HAVE_GRAPHITE2_TRUE@am__append_17 = $(GRAPHITE2_DEPS)
+@HAVE_GRAPHITE2_TRUE@am__append_18 = $(HB_GRAPHITE2_sources)
+@HAVE_GRAPHITE2_TRUE@am__append_19 = $(HB_GRAPHITE2_headers)
+@HAVE_UNISCRIBE_TRUE@am__append_20 = $(UNISCRIBE_CFLAGS)
+@HAVE_UNISCRIBE_TRUE@am__append_21 = $(UNISCRIBE_LIBS)
+@HAVE_UNISCRIBE_TRUE@am__append_22 = $(HB_UNISCRIBE_sources)
+@HAVE_UNISCRIBE_TRUE@am__append_23 = $(HB_UNISCRIBE_headers)
+@HAVE_DIRECTWRITE_TRUE@am__append_24 = $(DIRECTWRITE_CXXFLAGS)
+@HAVE_DIRECTWRITE_TRUE@am__append_25 = $(DIRECTWRITE_LIBS)
+@HAVE_DIRECTWRITE_TRUE@am__append_26 = $(HB_DIRECTWRITE_sources)
+@HAVE_DIRECTWRITE_TRUE@am__append_27 = $(HB_DIRECTWRITE_headers)
+@HAVE_CORETEXT_TRUE@am__append_28 = $(CORETEXT_CFLAGS)
+@HAVE_CORETEXT_TRUE@am__append_29 = $(CORETEXT_LIBS)
+@HAVE_CORETEXT_TRUE@am__append_30 = $(HB_CORETEXT_sources)
+@HAVE_CORETEXT_TRUE@am__append_31 = $(HB_CORETEXT_headers)
+@HAVE_UCDN_TRUE@am__append_32 = hb-ucdn
+@HAVE_UCDN_TRUE@am__append_33 = -I$(srcdir)/hb-ucdn
+@HAVE_UCDN_TRUE@am__append_34 = hb-ucdn/libhb-ucdn.la
+@HAVE_UCDN_TRUE@am__append_35 = $(HB_UCDN_sources)
+@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__append_36 = $(ICU_CFLAGS)
+@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__append_37 = $(ICU_LIBS)
+@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__append_38 = $(HB_ICU_sources)
+@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__append_39 = $(HB_ICU_headers)
+@HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@am__append_40 = libharfbuzz-icu.la
+@HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@am__append_41 = $(HB_ICU_headers)
+@HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@am__append_42 = harfbuzz-icu.pc
+@HAVE_GOBJECT_TRUE@am__append_43 = libharfbuzz-gobject.la
+@HAVE_GOBJECT_TRUE@am__append_44 = $(HB_GOBJECT_DIST_headers)
+@HAVE_GOBJECT_TRUE@am__append_45 = $(HB_GOBJECT_NODIST_headers)
+@HAVE_GOBJECT_TRUE@am__append_46 = harfbuzz-gobject.pc
+@HAVE_GOBJECT_TRUE@am__append_47 = \
 @HAVE_GOBJECT_TRUE@    $(HB_GOBJECT_ENUM_sources) \
 @HAVE_GOBJECT_TRUE@    $(HB_GOBJECT_ENUM_headers) \
 @HAVE_GOBJECT_TRUE@    $(NULL)
 
-@HAVE_GOBJECT_TRUE@am__append_49 = \
+@HAVE_GOBJECT_TRUE@am__append_48 = \
 @HAVE_GOBJECT_TRUE@    $(HB_GOBJECT_ENUM_sources) \
 @HAVE_GOBJECT_TRUE@    $(HB_GOBJECT_ENUM_headers) \
 @HAVE_GOBJECT_TRUE@    $(NULL)
 
-@HAVE_GOBJECT_TRUE@am__append_50 = harfbuzz-gobject.def
+@HAVE_GOBJECT_TRUE@am__append_49 = harfbuzz-gobject.def
 noinst_PROGRAMS = main$(EXEEXT) test$(EXEEXT) \
        test-buffer-serialize$(EXEEXT) test-size-params$(EXEEXT) \
        test-would-substitute$(EXEEXT) $(am__EXEEXT_1)
 bin_PROGRAMS =
-@WITH_LIBSTDCXX_FALSE@am__append_51 = \
+@WITH_LIBSTDCXX_FALSE@am__append_50 = \
 @WITH_LIBSTDCXX_FALSE@ check-libstdc++.sh \
 @WITH_LIBSTDCXX_FALSE@ $(NULL)
 
+@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@am__append_51 = dump-emoji
 @HAVE_INTROSPECTION_TRUE@am__append_52 = $(gir_DATA) $(typelib_DATA)
 subdir = src
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
+       $(top_srcdir)/m4/ax_code_coverage.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
@@ -191,7 +190,7 @@ DIST_COMMON = $(srcdir)/Makefile.am $(am__dist_check_SCRIPTS_DIST) \
        $(am__pkginclude_HEADERS_DIST) $(am__DIST_COMMON)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES = hb-version.h harfbuzz-config.cmake
+CONFIG_CLEAN_FILES = harfbuzz-config.cmake
 CONFIG_CLEAN_VPATH_FILES =
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
 am__vpath_adj = case $$p in \
@@ -238,38 +237,41 @@ am__DEPENDENCIES_9 = $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_6) \
 @HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__DEPENDENCIES_10 =  \
 @HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@ $(am__DEPENDENCIES_1)
 am__DEPENDENCIES_11 = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3) \
-       $(am__DEPENDENCIES_4) $(am__append_35) $(am__DEPENDENCIES_9) \
+       $(am__DEPENDENCIES_4) $(am__append_34) $(am__DEPENDENCIES_9) \
        $(am__DEPENDENCIES_10)
 am__DEPENDENCIES_12 = $(am__DEPENDENCIES_11)
 libharfbuzz_fuzzing_la_DEPENDENCIES = $(am__DEPENDENCIES_12)
 am__libharfbuzz_fuzzing_la_SOURCES_DIST = hb-atomic-private.hh \
-       hb-blob.cc hb-buffer-private.hh hb-buffer-serialize.cc \
-       hb-buffer.cc hb-common.cc hb-debug.hh hb-dsalgs.hh \
-       hb-face-private.hh hb-face.cc hb-font-private.hh hb-font.cc \
-       hb-mutex-private.hh hb-object-private.hh \
-       hb-open-file-private.hh hb-open-type-private.hh \
-       hb-ot-color-cbdt-table.hh hb-ot-cmap-table.hh \
-       hb-ot-glyf-table.hh hb-ot-hdmx-table.hh hb-ot-head-table.hh \
-       hb-ot-hhea-table.hh hb-ot-hmtx-table.hh hb-ot-kern-table.hh \
-       hb-ot-maxp-table.hh hb-ot-name-table.hh hb-ot-os2-table.hh \
-       hb-ot-os2-unicode-ranges.hh hb-ot-post-macroman.hh \
-       hb-ot-post-table.hh hb-ot-tag.cc hb-private.hh \
-       hb-set-digest-private.hh hb-set-private.hh hb-set.cc \
-       hb-shape.cc hb-shape-plan-private.hh hb-shape-plan.cc \
-       hb-shaper-list.hh hb-shaper-impl-private.hh \
-       hb-shaper-private.hh hb-shaper.cc hb-string-array.hh \
-       hb-unicode-private.hh hb-unicode.cc hb-utf-private.hh \
-       hb-warning.cc hb-buffer-deserialize-json.hh \
+       hb-blob-private.hh hb-blob.cc hb-buffer-private.hh \
+       hb-buffer-serialize.cc hb-buffer.cc hb-common.cc hb-debug.hh \
+       hb-dsalgs.hh hb-face-private.hh hb-face.cc hb-font-private.hh \
+       hb-font.cc hb-map-private.hh hb-map.cc hb-mutex-private.hh \
+       hb-object-private.hh hb-open-file-private.hh \
+       hb-open-type-private.hh hb-ot-color-cbdt-table.hh \
+       hb-ot-cmap-table.hh hb-ot-glyf-table.hh hb-ot-hdmx-table.hh \
+       hb-ot-head-table.hh hb-ot-hhea-table.hh hb-ot-hmtx-table.hh \
+       hb-ot-kern-table.hh hb-ot-maxp-table.hh hb-ot-name-table.hh \
+       hb-ot-os2-table.hh hb-ot-os2-unicode-ranges.hh \
+       hb-ot-post-macroman.hh hb-ot-post-table.hh hb-ot-tag.cc \
+       hb-private.hh hb-set-digest-private.hh hb-set-private.hh \
+       hb-set.cc hb-shape.cc hb-shape-plan-private.hh \
+       hb-shape-plan.cc hb-shaper-list.hh hb-shaper-impl-private.hh \
+       hb-shaper-private.hh hb-shaper.cc hb-static.cc \
+       hb-string-array.hh hb-unicode-private.hh hb-unicode.cc \
+       hb-utf-private.hh hb-warning.cc hb-buffer-deserialize-json.hh \
        hb-buffer-deserialize-text.hh hb-aat-layout.cc \
        hb-aat-layout-common-private.hh hb-aat-layout-ankr-table.hh \
+       hb-aat-layout-bsln-table.hh hb-aat-layout-feat-table.hh \
        hb-aat-layout-kerx-table.hh hb-aat-layout-morx-table.hh \
        hb-aat-layout-trak-table.hh hb-aat-layout-private.hh \
+       hb-aat-fmtx-table.hh hb-aat-gcid-table.hh hb-aat-ltag-table.hh \
        hb-ot-font.cc hb-ot-layout.cc hb-ot-layout-base-table.hh \
        hb-ot-layout-common-private.hh hb-ot-layout-gdef-table.hh \
        hb-ot-layout-gpos-table.hh hb-ot-layout-gsubgpos-private.hh \
        hb-ot-layout-gsub-table.hh hb-ot-layout-jstf-table.hh \
        hb-ot-layout-private.hh hb-ot-color.cc \
        hb-ot-color-colr-table.hh hb-ot-color-cpal-table.hh \
+       hb-ot-color-sbix-table.hh hb-ot-color-svg-table.hh \
        hb-ot-map.cc hb-ot-map-private.hh hb-ot-math.cc \
        hb-ot-math-table.hh hb-ot-shape.cc \
        hb-ot-shape-complex-arabic.cc \
@@ -300,11 +302,11 @@ am__libharfbuzz_fuzzing_la_SOURCES_DIST = hb-atomic-private.hh \
        hb-glib.cc hb-ft.cc hb-graphite2.cc hb-uniscribe.cc \
        hb-directwrite.cc hb-coretext.cc hb-ucdn.cc hb-icu.cc hb.h \
        hb-blob.h hb-buffer.h hb-common.h hb-deprecated.h hb-face.h \
-       hb-font.h hb-set.h hb-shape.h hb-shape-plan.h hb-unicode.h \
-       hb-version.h hb-ot.h hb-ot-font.h hb-ot-layout.h hb-ot-math.h \
-       hb-ot-shape.h hb-ot-tag.h hb-ot-var.h hb-glib.h hb-ft.h \
-       hb-graphite2.h hb-uniscribe.h hb-directwrite.h hb-coretext.h \
-       hb-icu.h
+       hb-font.h hb-map.h hb-set.h hb-shape.h hb-shape-plan.h \
+       hb-unicode.h hb-version.h hb-ot.h hb-ot-font.h hb-ot-layout.h \
+       hb-ot-math.h hb-ot-shape.h hb-ot-tag.h hb-ot-var.h hb-glib.h \
+       hb-ft.h hb-graphite2.h hb-uniscribe.h hb-directwrite.h \
+       hb-coretext.h hb-icu.h
 am__objects_1 =
 am__objects_2 = libharfbuzz_fuzzing_la-hb-blob.lo \
        libharfbuzz_fuzzing_la-hb-buffer-serialize.lo \
@@ -312,11 +314,13 @@ am__objects_2 = libharfbuzz_fuzzing_la-hb-blob.lo \
        libharfbuzz_fuzzing_la-hb-common.lo \
        libharfbuzz_fuzzing_la-hb-face.lo \
        libharfbuzz_fuzzing_la-hb-font.lo \
+       libharfbuzz_fuzzing_la-hb-map.lo \
        libharfbuzz_fuzzing_la-hb-ot-tag.lo \
        libharfbuzz_fuzzing_la-hb-set.lo \
        libharfbuzz_fuzzing_la-hb-shape.lo \
        libharfbuzz_fuzzing_la-hb-shape-plan.lo \
        libharfbuzz_fuzzing_la-hb-shaper.lo \
+       libharfbuzz_fuzzing_la-hb-static.lo \
        libharfbuzz_fuzzing_la-hb-unicode.lo \
        libharfbuzz_fuzzing_la-hb-warning.lo $(am__objects_1)
 am__objects_3 = $(am__objects_1)
@@ -413,22 +417,36 @@ libharfbuzz_icu_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
        $(LDFLAGS) -o $@
 @HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@am_libharfbuzz_icu_la_rpath =  \
 @HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@        -rpath $(libdir)
+libharfbuzz_subset_fuzzing_la_DEPENDENCIES =  \
+       $(libharfbuzz_subset_la_LIBADD)
+am__objects_39 = libharfbuzz_subset_fuzzing_la-hb-static.lo \
+       libharfbuzz_subset_fuzzing_la-hb-subset.lo \
+       libharfbuzz_subset_fuzzing_la-hb-subset-glyf.lo \
+       libharfbuzz_subset_fuzzing_la-hb-subset-input.lo \
+       libharfbuzz_subset_fuzzing_la-hb-subset-plan.lo \
+       $(am__objects_1)
+am__objects_40 = $(am__objects_39)
+am_libharfbuzz_subset_fuzzing_la_OBJECTS = $(am__objects_40)
+libharfbuzz_subset_fuzzing_la_OBJECTS =  \
+       $(am_libharfbuzz_subset_fuzzing_la_OBJECTS)
 libharfbuzz_subset_la_DEPENDENCIES = libharfbuzz.la
-am__objects_39 = libharfbuzz_subset_la-hb-subset.lo \
+am__objects_41 = libharfbuzz_subset_la-hb-static.lo \
+       libharfbuzz_subset_la-hb-subset.lo \
        libharfbuzz_subset_la-hb-subset-glyf.lo \
        libharfbuzz_subset_la-hb-subset-input.lo \
        libharfbuzz_subset_la-hb-subset-plan.lo $(am__objects_1)
-am_libharfbuzz_subset_la_OBJECTS = $(am__objects_39)
+am_libharfbuzz_subset_la_OBJECTS = $(am__objects_41)
 libharfbuzz_subset_la_OBJECTS = $(am_libharfbuzz_subset_la_OBJECTS)
 libharfbuzz_subset_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
        $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
        $(AM_CXXFLAGS) $(CXXFLAGS) $(libharfbuzz_subset_la_LDFLAGS) \
        $(LDFLAGS) -o $@
 libharfbuzz_la_DEPENDENCIES = $(am__DEPENDENCIES_11)
-am__libharfbuzz_la_SOURCES_DIST = hb-atomic-private.hh hb-blob.cc \
-       hb-buffer-private.hh hb-buffer-serialize.cc hb-buffer.cc \
-       hb-common.cc hb-debug.hh hb-dsalgs.hh hb-face-private.hh \
-       hb-face.cc hb-font-private.hh hb-font.cc hb-mutex-private.hh \
+am__libharfbuzz_la_SOURCES_DIST = hb-atomic-private.hh \
+       hb-blob-private.hh hb-blob.cc hb-buffer-private.hh \
+       hb-buffer-serialize.cc hb-buffer.cc hb-common.cc hb-debug.hh \
+       hb-dsalgs.hh hb-face-private.hh hb-face.cc hb-font-private.hh \
+       hb-font.cc hb-map-private.hh hb-map.cc hb-mutex-private.hh \
        hb-object-private.hh hb-open-file-private.hh \
        hb-open-type-private.hh hb-ot-color-cbdt-table.hh \
        hb-ot-cmap-table.hh hb-ot-glyf-table.hh hb-ot-hdmx-table.hh \
@@ -439,19 +457,22 @@ am__libharfbuzz_la_SOURCES_DIST = hb-atomic-private.hh hb-blob.cc \
        hb-private.hh hb-set-digest-private.hh hb-set-private.hh \
        hb-set.cc hb-shape.cc hb-shape-plan-private.hh \
        hb-shape-plan.cc hb-shaper-list.hh hb-shaper-impl-private.hh \
-       hb-shaper-private.hh hb-shaper.cc hb-string-array.hh \
-       hb-unicode-private.hh hb-unicode.cc hb-utf-private.hh \
-       hb-warning.cc hb-buffer-deserialize-json.hh \
+       hb-shaper-private.hh hb-shaper.cc hb-static.cc \
+       hb-string-array.hh hb-unicode-private.hh hb-unicode.cc \
+       hb-utf-private.hh hb-warning.cc hb-buffer-deserialize-json.hh \
        hb-buffer-deserialize-text.hh hb-aat-layout.cc \
        hb-aat-layout-common-private.hh hb-aat-layout-ankr-table.hh \
+       hb-aat-layout-bsln-table.hh hb-aat-layout-feat-table.hh \
        hb-aat-layout-kerx-table.hh hb-aat-layout-morx-table.hh \
        hb-aat-layout-trak-table.hh hb-aat-layout-private.hh \
+       hb-aat-fmtx-table.hh hb-aat-gcid-table.hh hb-aat-ltag-table.hh \
        hb-ot-font.cc hb-ot-layout.cc hb-ot-layout-base-table.hh \
        hb-ot-layout-common-private.hh hb-ot-layout-gdef-table.hh \
        hb-ot-layout-gpos-table.hh hb-ot-layout-gsubgpos-private.hh \
        hb-ot-layout-gsub-table.hh hb-ot-layout-jstf-table.hh \
        hb-ot-layout-private.hh hb-ot-color.cc \
        hb-ot-color-colr-table.hh hb-ot-color-cpal-table.hh \
+       hb-ot-color-sbix-table.hh hb-ot-color-svg-table.hh \
        hb-ot-map.cc hb-ot-map-private.hh hb-ot-math.cc \
        hb-ot-math-table.hh hb-ot-shape.cc \
        hb-ot-shape-complex-arabic.cc \
@@ -482,20 +503,21 @@ am__libharfbuzz_la_SOURCES_DIST = hb-atomic-private.hh hb-blob.cc \
        hb-glib.cc hb-ft.cc hb-graphite2.cc hb-uniscribe.cc \
        hb-directwrite.cc hb-coretext.cc hb-ucdn.cc hb-icu.cc hb.h \
        hb-blob.h hb-buffer.h hb-common.h hb-deprecated.h hb-face.h \
-       hb-font.h hb-set.h hb-shape.h hb-shape-plan.h hb-unicode.h \
-       hb-version.h hb-ot.h hb-ot-font.h hb-ot-layout.h hb-ot-math.h \
-       hb-ot-shape.h hb-ot-tag.h hb-ot-var.h hb-glib.h hb-ft.h \
-       hb-graphite2.h hb-uniscribe.h hb-directwrite.h hb-coretext.h \
-       hb-icu.h
-am__objects_40 = libharfbuzz_la-hb-blob.lo \
+       hb-font.h hb-map.h hb-set.h hb-shape.h hb-shape-plan.h \
+       hb-unicode.h hb-version.h hb-ot.h hb-ot-font.h hb-ot-layout.h \
+       hb-ot-math.h hb-ot-shape.h hb-ot-tag.h hb-ot-var.h hb-glib.h \
+       hb-ft.h hb-graphite2.h hb-uniscribe.h hb-directwrite.h \
+       hb-coretext.h hb-icu.h
+am__objects_42 = libharfbuzz_la-hb-blob.lo \
        libharfbuzz_la-hb-buffer-serialize.lo \
        libharfbuzz_la-hb-buffer.lo libharfbuzz_la-hb-common.lo \
        libharfbuzz_la-hb-face.lo libharfbuzz_la-hb-font.lo \
-       libharfbuzz_la-hb-ot-tag.lo libharfbuzz_la-hb-set.lo \
-       libharfbuzz_la-hb-shape.lo libharfbuzz_la-hb-shape-plan.lo \
-       libharfbuzz_la-hb-shaper.lo libharfbuzz_la-hb-unicode.lo \
+       libharfbuzz_la-hb-map.lo libharfbuzz_la-hb-ot-tag.lo \
+       libharfbuzz_la-hb-set.lo libharfbuzz_la-hb-shape.lo \
+       libharfbuzz_la-hb-shape-plan.lo libharfbuzz_la-hb-shaper.lo \
+       libharfbuzz_la-hb-static.lo libharfbuzz_la-hb-unicode.lo \
        libharfbuzz_la-hb-warning.lo $(am__objects_1)
-am__objects_41 = libharfbuzz_la-hb-aat-layout.lo \
+am__objects_43 = libharfbuzz_la-hb-aat-layout.lo \
        libharfbuzz_la-hb-ot-font.lo libharfbuzz_la-hb-ot-layout.lo \
        libharfbuzz_la-hb-ot-color.lo libharfbuzz_la-hb-ot-map.lo \
        libharfbuzz_la-hb-ot-math.lo libharfbuzz_la-hb-ot-shape.lo \
@@ -514,34 +536,48 @@ am__objects_41 = libharfbuzz_la-hb-aat-layout.lo \
        libharfbuzz_la-hb-ot-shape-normalize.lo \
        libharfbuzz_la-hb-ot-shape-fallback.lo \
        libharfbuzz_la-hb-ot-var.lo $(am__objects_1)
-@HAVE_OT_TRUE@am__objects_42 = $(am__objects_41) $(am__objects_3)
-am__objects_43 = libharfbuzz_la-hb-fallback-shape.lo $(am__objects_1)
-@HAVE_FALLBACK_TRUE@am__objects_44 = $(am__objects_43)
-am__objects_45 = libharfbuzz_la-hb-glib.lo
-@HAVE_GLIB_TRUE@am__objects_46 = $(am__objects_45)
-am__objects_47 = libharfbuzz_la-hb-ft.lo
-@HAVE_FREETYPE_TRUE@am__objects_48 = $(am__objects_47)
-am__objects_49 = libharfbuzz_la-hb-graphite2.lo
-@HAVE_GRAPHITE2_TRUE@am__objects_50 = $(am__objects_49)
-am__objects_51 = libharfbuzz_la-hb-uniscribe.lo
-@HAVE_UNISCRIBE_TRUE@am__objects_52 = $(am__objects_51)
-am__objects_53 = libharfbuzz_la-hb-directwrite.lo
-@HAVE_DIRECTWRITE_TRUE@am__objects_54 = $(am__objects_53)
-am__objects_55 = libharfbuzz_la-hb-coretext.lo
-@HAVE_CORETEXT_TRUE@am__objects_56 = $(am__objects_55)
-am__objects_57 = libharfbuzz_la-hb-ucdn.lo
-@HAVE_UCDN_TRUE@am__objects_58 = $(am__objects_57)
-am__objects_59 = libharfbuzz_la-hb-icu.lo
-@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__objects_60 =  \
-@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@ $(am__objects_59)
-am__objects_61 = $(am__objects_40) $(am__objects_3) $(am__objects_42) \
-       $(am__objects_44) $(am__objects_46) $(am__objects_48) \
-       $(am__objects_50) $(am__objects_52) $(am__objects_54) \
-       $(am__objects_56) $(am__objects_58) $(am__objects_60)
-am_libharfbuzz_la_OBJECTS = $(am__objects_61) $(am__objects_33)
+@HAVE_OT_TRUE@am__objects_44 = $(am__objects_43) $(am__objects_3)
+am__objects_45 = libharfbuzz_la-hb-fallback-shape.lo $(am__objects_1)
+@HAVE_FALLBACK_TRUE@am__objects_46 = $(am__objects_45)
+am__objects_47 = libharfbuzz_la-hb-glib.lo
+@HAVE_GLIB_TRUE@am__objects_48 = $(am__objects_47)
+am__objects_49 = libharfbuzz_la-hb-ft.lo
+@HAVE_FREETYPE_TRUE@am__objects_50 = $(am__objects_49)
+am__objects_51 = libharfbuzz_la-hb-graphite2.lo
+@HAVE_GRAPHITE2_TRUE@am__objects_52 = $(am__objects_51)
+am__objects_53 = libharfbuzz_la-hb-uniscribe.lo
+@HAVE_UNISCRIBE_TRUE@am__objects_54 = $(am__objects_53)
+am__objects_55 = libharfbuzz_la-hb-directwrite.lo
+@HAVE_DIRECTWRITE_TRUE@am__objects_56 = $(am__objects_55)
+am__objects_57 = libharfbuzz_la-hb-coretext.lo
+@HAVE_CORETEXT_TRUE@am__objects_58 = $(am__objects_57)
+am__objects_59 = libharfbuzz_la-hb-ucdn.lo
+@HAVE_UCDN_TRUE@am__objects_60 = $(am__objects_59)
+am__objects_61 = libharfbuzz_la-hb-icu.lo
+@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__objects_62 =  \
+@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@ $(am__objects_61)
+am__objects_63 = $(am__objects_42) $(am__objects_3) $(am__objects_44) \
+       $(am__objects_46) $(am__objects_48) $(am__objects_50) \
+       $(am__objects_52) $(am__objects_54) $(am__objects_56) \
+       $(am__objects_58) $(am__objects_60) $(am__objects_62)
+am_libharfbuzz_la_OBJECTS = $(am__objects_63) $(am__objects_33)
 libharfbuzz_la_OBJECTS = $(am_libharfbuzz_la_OBJECTS)
 am__EXEEXT_1 =
+@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@am__EXEEXT_2 =  \
+@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@       dump-emoji$(EXEEXT)
 PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
+am__dump_emoji_SOURCES_DIST = dump-emoji.cc
+@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@am_dump_emoji_OBJECTS = dump_emoji-dump-emoji.$(OBJEXT)
+dump_emoji_OBJECTS = $(am_dump_emoji_OBJECTS)
+@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@dump_emoji_DEPENDENCIES =  \
+@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@       libharfbuzz.la \
+@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@       $(am__DEPENDENCIES_11) \
+@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@       $(am__DEPENDENCIES_1) \
+@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@       $(am__DEPENDENCIES_1) \
+@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@       $(am__DEPENDENCIES_1)
+am_dump_fon_OBJECTS = dump_fon-dump-fon.$(OBJEXT)
+dump_fon_OBJECTS = $(am_dump_fon_OBJECTS)
+dump_fon_DEPENDENCIES = libharfbuzz.la $(am__DEPENDENCIES_11)
 am_dump_indic_data_OBJECTS =  \
        dump_indic_data-dump-indic-data.$(OBJEXT) \
        dump_indic_data-hb-ot-shape-complex-indic-table.$(OBJEXT)
@@ -647,20 +683,26 @@ am__v_CCLD_1 =
 SOURCES = $(libharfbuzz_fuzzing_la_SOURCES) \
        $(libharfbuzz_gobject_la_SOURCES) \
        $(nodist_libharfbuzz_gobject_la_SOURCES) \
-       $(libharfbuzz_icu_la_SOURCES) $(libharfbuzz_subset_la_SOURCES) \
-       $(libharfbuzz_la_SOURCES) $(dump_indic_data_SOURCES) \
-       $(dump_khmer_data_SOURCES) $(dump_myanmar_data_SOURCES) \
-       $(dump_use_data_SOURCES) $(main_SOURCES) $(test_SOURCES) \
+       $(libharfbuzz_icu_la_SOURCES) \
+       $(libharfbuzz_subset_fuzzing_la_SOURCES) \
+       $(libharfbuzz_subset_la_SOURCES) $(libharfbuzz_la_SOURCES) \
+       $(dump_emoji_SOURCES) $(dump_fon_SOURCES) \
+       $(dump_indic_data_SOURCES) $(dump_khmer_data_SOURCES) \
+       $(dump_myanmar_data_SOURCES) $(dump_use_data_SOURCES) \
+       $(main_SOURCES) $(test_SOURCES) \
        $(test_buffer_serialize_SOURCES) $(test_ot_tag_SOURCES) \
        $(test_size_params_SOURCES) $(test_unicode_ranges_SOURCES) \
        $(test_would_substitute_SOURCES)
 DIST_SOURCES = $(am__libharfbuzz_fuzzing_la_SOURCES_DIST) \
        $(am__libharfbuzz_gobject_la_SOURCES_DIST) \
        $(am__libharfbuzz_icu_la_SOURCES_DIST) \
+       $(libharfbuzz_subset_fuzzing_la_SOURCES) \
        $(libharfbuzz_subset_la_SOURCES) \
-       $(am__libharfbuzz_la_SOURCES_DIST) $(dump_indic_data_SOURCES) \
-       $(dump_khmer_data_SOURCES) $(dump_myanmar_data_SOURCES) \
-       $(dump_use_data_SOURCES) $(main_SOURCES) $(test_SOURCES) \
+       $(am__libharfbuzz_la_SOURCES_DIST) \
+       $(am__dump_emoji_SOURCES_DIST) $(dump_fon_SOURCES) \
+       $(dump_indic_data_SOURCES) $(dump_khmer_data_SOURCES) \
+       $(dump_myanmar_data_SOURCES) $(dump_use_data_SOURCES) \
+       $(main_SOURCES) $(test_SOURCES) \
        $(test_buffer_serialize_SOURCES) $(test_ot_tag_SOURCES) \
        $(test_size_params_SOURCES) $(test_unicode_ranges_SOURCES) \
        $(test_would_substitute_SOURCES)
@@ -679,13 +721,13 @@ am__can_run_installinfo = \
   esac
 DATA = $(cmake_DATA) $(gir_DATA) $(pkgconfig_DATA) $(typelib_DATA)
 am__pkginclude_HEADERS_DIST = hb.h hb-blob.h hb-buffer.h hb-common.h \
-       hb-deprecated.h hb-face.h hb-font.h hb-set.h hb-shape.h \
-       hb-shape-plan.h hb-unicode.h hb-version.h hb-ot.h hb-ot-font.h \
-       hb-ot-layout.h hb-ot-math.h hb-ot-shape.h hb-ot-tag.h \
-       hb-ot-var.h hb-glib.h hb-ft.h hb-graphite2.h hb-uniscribe.h \
-       hb-directwrite.h hb-coretext.h hb-icu.h hb-subset.h \
-       hb-subset-glyf.hh hb-subset-plan.hh hb-subset-private.hh \
-       hb-gobject.h hb-gobject-structs.h
+       hb-deprecated.h hb-face.h hb-font.h hb-map.h hb-set.h \
+       hb-shape.h hb-shape-plan.h hb-unicode.h hb-version.h hb-ot.h \
+       hb-ot-font.h hb-ot-layout.h hb-ot-math.h hb-ot-shape.h \
+       hb-ot-tag.h hb-ot-var.h hb-glib.h hb-ft.h hb-graphite2.h \
+       hb-uniscribe.h hb-directwrite.h hb-coretext.h hb-icu.h \
+       hb-subset.h hb-subset-glyf.hh hb-subset-plan.hh \
+       hb-subset-private.hh hb-gobject.h hb-gobject-structs.h
 HEADERS = $(nodist_pkginclude_HEADERS) $(pkginclude_HEADERS)
 RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive        \
   distclean-recursive maintainer-clean-recursive
@@ -870,11 +912,11 @@ am__set_TESTS_bases = \
   bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
   bases=`echo $$bases`
 RECHECK_LOGS = $(TEST_LOGS)
-@WITH_LIBSTDCXX_FALSE@am__EXEEXT_2 = check-libstdc++.sh \
+@WITH_LIBSTDCXX_FALSE@am__EXEEXT_3 = check-libstdc++.sh \
 @WITH_LIBSTDCXX_FALSE@ $(am__EXEEXT_1)
-am__EXEEXT_3 = check-c-linkage-decls.sh check-externs.sh \
+am__EXEEXT_4 = check-c-linkage-decls.sh check-externs.sh \
        check-header-guards.sh check-includes.sh check-static-inits.sh \
-       check-symbols.sh $(am__EXEEXT_1) $(am__EXEEXT_2)
+       check-symbols.sh $(am__EXEEXT_1) $(am__EXEEXT_3)
 TEST_SUITE_LOG = test-suite.log
 TEST_EXTENSIONS = @EXEEXT@ .test
 LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
@@ -896,8 +938,8 @@ TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
 TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
        $(TEST_LOG_FLAGS)
 am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.sources \
-       $(srcdir)/harfbuzz-config.cmake.in $(srcdir)/hb-version.h.in \
-       $(top_srcdir)/depcomp $(top_srcdir)/test-driver
+       $(srcdir)/harfbuzz-config.cmake.in $(top_srcdir)/depcomp \
+       $(top_srcdir)/test-driver
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 am__relativize = \
   dir0=`pwd`; \
@@ -1110,23 +1152,24 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 NULL = 
-SUBDIRS = $(am__append_33)
+SUBDIRS = $(am__append_32)
 DIST_SUBDIRS = hb-ucdn
-BUILT_SOURCES = $(am__append_48) $(RAGEL_GENERATED)
-EXTRA_DIST = harfbuzz.pc.in harfbuzz-config.cmake.in \
+BUILT_SOURCES = hb-version.h $(am__append_47) $(RAGEL_GENERATED)
+EXTRA_DIST = hb-version.h.in harfbuzz.pc.in harfbuzz-config.cmake.in \
        harfbuzz-subset.pc.in harfbuzz-icu.pc.in \
        harfbuzz-gobject.pc.in hb-gobject-enums.cc.tmpl \
        hb-gobject-enums.h.tmpl $(NULL) $(GENERATORS) \
        $(HB_BASE_RAGEL_sources) $(HB_OT_RAGEL_sources) $(NULL)
-CLEANFILES = libharfbuzz-fuzzing.la $(pkgconfig_DATA) $(DEF_FILES) \
-       $(am__append_52)
-DISTCLEANFILES = $(am__append_49)
+CLEANFILES = libharfbuzz-fuzzing.la libharfbuzz-subset-fuzzing.la \
+       $(pkgconfig_DATA) $(DEF_FILES) $(am__append_52)
+DISTCLEANFILES = $(am__append_48)
 MAINTAINERCLEANFILES = 
 DISTCHECK_CONFIGURE_FLAGS = --enable-introspection
 lib_LTLIBRARIES = libharfbuzz.la libharfbuzz-subset.la \
-       $(am__append_41) $(am__append_44)
+       $(am__append_40) $(am__append_43)
 HB_BASE_sources = \
        hb-atomic-private.hh \
+       hb-blob-private.hh \
        hb-blob.cc \
        hb-buffer-private.hh \
        hb-buffer-serialize.cc \
@@ -1138,6 +1181,8 @@ HB_BASE_sources = \
        hb-face.cc \
        hb-font-private.hh \
        hb-font.cc \
+       hb-map-private.hh \
+       hb-map.cc \
        hb-mutex-private.hh \
        hb-object-private.hh \
        hb-open-file-private.hh \
@@ -1168,6 +1213,7 @@ HB_BASE_sources = \
        hb-shaper-impl-private.hh \
        hb-shaper-private.hh \
        hb-shaper.cc \
+       hb-static.cc \
        hb-string-array.hh \
        hb-unicode-private.hh \
        hb-unicode.cc \
@@ -1193,6 +1239,7 @@ HB_BASE_headers = \
        hb-deprecated.h \
        hb-face.h \
        hb-font.h \
+       hb-map.h \
        hb-set.h \
        hb-shape.h \
        hb-shape-plan.h \
@@ -1208,10 +1255,15 @@ HB_OT_sources = \
        hb-aat-layout.cc \
        hb-aat-layout-common-private.hh \
        hb-aat-layout-ankr-table.hh \
+       hb-aat-layout-bsln-table.hh \
+       hb-aat-layout-feat-table.hh \
        hb-aat-layout-kerx-table.hh \
        hb-aat-layout-morx-table.hh \
        hb-aat-layout-trak-table.hh \
        hb-aat-layout-private.hh \
+       hb-aat-fmtx-table.hh \
+       hb-aat-gcid-table.hh \
+       hb-aat-ltag-table.hh \
        hb-ot-font.cc \
        hb-ot-layout.cc \
        hb-ot-layout-base-table.hh \
@@ -1225,6 +1277,8 @@ HB_OT_sources = \
        hb-ot-color.cc \
        hb-ot-color-colr-table.hh \
        hb-ot-color-cpal-table.hh \
+       hb-ot-color-sbix-table.hh \
+       hb-ot-color-svg-table.hh \
        hb-ot-map.cc \
        hb-ot-map-private.hh \
        hb-ot-math.cc \
@@ -1313,6 +1367,7 @@ HB_ICU_headers = hb-icu.h
 
 # Sources for libharfbuzz-subset
 HB_SUBSET_sources = \
+       hb-static.cc \
        hb-subset.cc \
        hb-subset-glyf.cc \
        hb-subset-input.cc \
@@ -1334,27 +1389,24 @@ HB_GOBJECT_NODIST_sources = $(HB_GOBJECT_ENUM_sources)
 HB_GOBJECT_NODIST_headers = $(HB_GOBJECT_ENUM_headers)
 HB_GOBJECT_sources = $(HB_GOBJECT_DIST_sources) $(HB_GOBJECT_NODIST_sources)
 HB_GOBJECT_headers = $(HB_GOBJECT_DIST_headers) $(HB_GOBJECT_NODIST_headers)
-HBCFLAGS = $(am__append_1) $(am__append_5) $(am__append_7) \
-       $(am__append_12) $(am__append_16) $(am__append_21) \
-       $(am__append_25) $(am__append_29) $(am__append_34) \
-       $(am__append_37)
+HBCFLAGS = $(am__append_4) $(am__append_6) $(am__append_11) \
+       $(am__append_15) $(am__append_20) $(am__append_24) \
+       $(am__append_28) $(am__append_33) $(am__append_36)
 
 # Put the library together
-HBLIBS = $(am__append_8) $(am__append_13) $(am__append_17) \
-       $(am__append_35) $(HBNONPCLIBS) $(am__append_38)
-HBNONPCLIBS = $(am__append_6) $(am__append_22) $(am__append_26) \
-       $(am__append_30)
-HBDEPS = $(am__append_9) $(am__append_18)
+HBLIBS = $(am__append_7) $(am__append_12) $(am__append_16) \
+       $(am__append_34) $(HBNONPCLIBS) $(am__append_37)
+HBNONPCLIBS = $(am__append_5) $(am__append_21) $(am__append_25) \
+       $(am__append_29)
+HBDEPS = $(am__append_8) $(am__append_17)
 HBSOURCES = $(HB_BASE_sources) $(HB_BASE_RAGEL_GENERATED_sources) \
-       $(am__append_2) $(am__append_4) $(am__append_10) \
+       $(am__append_1) $(am__append_3) $(am__append_9) \
+       $(am__append_13) $(am__append_18) $(am__append_22) \
+       $(am__append_26) $(am__append_30) $(am__append_35) \
+       $(am__append_38)
+HBHEADERS = $(HB_BASE_headers) $(am__append_2) $(am__append_10) \
        $(am__append_14) $(am__append_19) $(am__append_23) \
-       $(am__append_27) $(am__append_31) $(am__append_36) \
-       $(am__append_39)
-HBHEADERS = $(HB_BASE_headers) $(am__append_3) $(am__append_11) \
-       $(am__append_15) $(am__append_20) $(am__append_24) \
-       $(am__append_28) $(am__append_32) $(am__append_40)
-@WITH_LIBSTDCXX_TRUE@HBNOLIBCXXCFLAGS = 
-@WITH_LIBSTDCXX_FALSE@HBNOLIBCXXFLAGS = -fno-threadsafe-statics -fno-rtti
+       $(am__append_27) $(am__append_31) $(am__append_39)
 @OS_WIN32_TRUE@export_symbols = -export-symbols harfbuzz.def
 @OS_WIN32_TRUE@harfbuzz_def_dependency = harfbuzz.def
 @OS_WIN32_TRUE@export_symbols_subset = -export-symbols harfbuzz-subset.def
@@ -1369,23 +1421,23 @@ HBHEADERS = $(HB_BASE_headers) $(am__append_3) $(am__append_11) \
 @OS_WIN32_FALSE@@WITH_LIBSTDCXX_TRUE@chosen_linker = $(CXXLINK)
 @OS_WIN32_TRUE@chosen_linker = $(CXXLINK)
 base_link_flags = $(AM_LDFLAGS) -lm -version-info $(HB_LIBTOOL_VERSION_INFO) -no-undefined
-libharfbuzz_la_LINK = $(chosen_linker) $(libharfbuzz_la_LDFLAGS) $(CODE_COVERAGE_LDFLAGS)
+libharfbuzz_la_LINK = $(chosen_linker) $(libharfbuzz_la_LDFLAGS)
 libharfbuzz_la_SOURCES = $(HBSOURCES) $(HBHEADERS)
-libharfbuzz_la_CPPFLAGS = $(HBCFLAGS) $(HBNOLIBCXXFLAGS) $(CODE_COVERAGE_CFLAGS)
-libharfbuzz_la_LDFLAGS = $(base_link_flags) $(export_symbols)
+libharfbuzz_la_CPPFLAGS = $(HBCFLAGS) $(CODE_COVERAGE_CFLAGS)
+libharfbuzz_la_LDFLAGS = $(base_link_flags) $(export_symbols) $(CODE_COVERAGE_LDFLAGS)
 libharfbuzz_la_LIBADD = $(HBLIBS)
 EXTRA_libharfbuzz_la_DEPENDENCIES = $(harfbuzz_def_dependency)
 pkginclude_HEADERS = $(HBHEADERS) $(HB_SUBSET_headers) \
-       $(am__append_42) $(am__append_45)
-nodist_pkginclude_HEADERS = $(am__append_46)
+       $(am__append_41) $(am__append_44)
+nodist_pkginclude_HEADERS = $(am__append_45)
 pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = harfbuzz.pc harfbuzz-subset.pc $(am__append_43) \
-       $(am__append_47)
+pkgconfig_DATA = harfbuzz.pc harfbuzz-subset.pc $(am__append_42) \
+       $(am__append_46)
 cmakedir = $(libdir)/cmake/harfbuzz
 cmake_DATA = harfbuzz-config.cmake
 libharfbuzz_subset_la_SOURCES = $(HB_SUBSET_sources)
-libharfbuzz_subset_la_CPPFLAGS = $(HBCFLAGS)
-libharfbuzz_subset_la_LDFLAGS = $(base_link_flags) $(export_symbols_subset)
+libharfbuzz_subset_la_CPPFLAGS = $(HBCFLAGS) $(CODE_COVERAGE_CFLAGS)
+libharfbuzz_subset_la_LDFLAGS = $(base_link_flags) $(export_symbols_subset) $(CODE_COVERAGE_LDFLAGS)
 libharfbuzz_subset_la_LIBADD = libharfbuzz.la
 EXTRA_libharfbuzz_subset_la_DEPENDENCIES = $(harfbuzz_subset_def_dependency)
 FUZZING_CPPFLAGS = \
@@ -1402,27 +1454,33 @@ FUZZING_CPPFLAGS = \
        -DHB_BUFFER_MAX_OPS_DEFAULT=1024 \
        $(NULL)
 
-EXTRA_LTLIBRARIES = libharfbuzz-fuzzing.la
+EXTRA_LTLIBRARIES = libharfbuzz-fuzzing.la libharfbuzz-subset-fuzzing.la
 libharfbuzz_fuzzing_la_LINK = $(chosen_linker) $(libharfbuzz_fuzzing_la_LDFLAGS)
 libharfbuzz_fuzzing_la_SOURCES = $(libharfbuzz_la_SOURCES)
 libharfbuzz_fuzzing_la_CPPFLAGS = $(HBCFLAGS) $(FUZZING_CPPFLAGS)
 libharfbuzz_fuzzing_la_LDFLAGS = $(AM_LDFLAGS)
 libharfbuzz_fuzzing_la_LIBADD = $(libharfbuzz_la_LIBADD)
 EXTRA_libharfbuzz_fuzzing_la_DEPENDENCIES = $(EXTRA_libharfbuzz_la_DEPENDENCIES)
+libharfbuzz_subset_fuzzing_la_LINK = $(chosen_linker) $(libharfbuzz_subset_fuzzing_la_LDFLAGS)
+libharfbuzz_subset_fuzzing_la_SOURCES = $(libharfbuzz_subset_la_SOURCES)
+libharfbuzz_subset_fuzzing_la_CPPFLAGS = $(HBCFLAGS) $(FUZZING_CPPFLAGS)
+libharfbuzz_subset_fuzzing_la_LDFLAGS = $(AM_LDFLAGS)
+libharfbuzz_subset_fuzzing_la_LIBADD = $(libharfbuzz_subset_la_LIBADD)
+EXTRA_libharfbuzz_subset_fuzzing_la_DEPENDENCIES = $(EXTRA_libharfbuzz_subset_la_DEPENDENCIES)
 @HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@libharfbuzz_icu_la_SOURCES = $(HB_ICU_sources)
-@HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@libharfbuzz_icu_la_CPPFLAGS = $(HBCFLAGS) $(ICU_CFLAGS)
-@HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@libharfbuzz_icu_la_LDFLAGS = $(base_link_flags) $(export_symbols_icu)
+@HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@libharfbuzz_icu_la_CPPFLAGS = $(HBCFLAGS) $(ICU_CFLAGS) $(CODE_COVERAGE_CFLAGS)
+@HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@libharfbuzz_icu_la_LDFLAGS = $(base_link_flags) $(export_symbols_icu) $(CODE_COVERAGE_LDFLAGS)
 @HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@libharfbuzz_icu_la_LIBADD = $(ICU_LIBS) libharfbuzz.la
 @HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@EXTRA_libharfbuzz_icu_la_DEPENDENCIES = $(harfbuzz_icu_def_dependency)
 @HAVE_GOBJECT_TRUE@libharfbuzz_gobject_la_LINK = $(chosen_linker) $(libharfbuzz_gobject_la_LDFLAGS)
 @HAVE_GOBJECT_TRUE@libharfbuzz_gobject_la_SOURCES = $(HB_GOBJECT_DIST_sources)
 @HAVE_GOBJECT_TRUE@nodist_libharfbuzz_gobject_la_SOURCES = $(HB_GOBJECT_NODIST_sources)
-@HAVE_GOBJECT_TRUE@libharfbuzz_gobject_la_CPPFLAGS = $(HBCFLAGS) $(HBNOLIBCXXFLAGS) $(GOBJECT_CFLAGS)
-@HAVE_GOBJECT_TRUE@libharfbuzz_gobject_la_LDFLAGS = $(base_link_flags)
+@HAVE_GOBJECT_TRUE@libharfbuzz_gobject_la_CPPFLAGS = $(HBCFLAGS) $(GOBJECT_CFLAGS) $(CODE_COVERAGE_CFLAGS)
+@HAVE_GOBJECT_TRUE@libharfbuzz_gobject_la_LDFLAGS = $(base_link_flags) $(CODE_COVERAGE_LDFLAGS)
 @HAVE_GOBJECT_TRUE@libharfbuzz_gobject_la_LIBADD = $(GOBJECT_LIBS) libharfbuzz.la
 @HAVE_GOBJECT_TRUE@EXTRA_libharfbuzz_gobject_la_DEPENDENCIES = $(harfbuzz_gobject_def_dependency)
 DEF_FILES = harfbuzz.def harfbuzz-subset.def harfbuzz-icu.def \
-       $(am__append_50)
+       $(am__append_49)
 GENERATORS = \
        gen-arabic-table.py \
        gen-indic-table.py \
@@ -1452,7 +1510,10 @@ test_buffer_serialize_CPPFLAGS = $(HBCFLAGS)
 test_buffer_serialize_LDADD = libharfbuzz.la $(HBLIBS)
 dist_check_SCRIPTS = check-c-linkage-decls.sh check-externs.sh \
        check-header-guards.sh check-includes.sh check-static-inits.sh \
-       check-symbols.sh $(NULL) $(am__append_51)
+       check-symbols.sh $(NULL) $(am__append_50)
+dump_fon_SOURCES = dump-fon.cc
+dump_fon_CPPFLAGS = $(HBCFLAGS)
+dump_fon_LDADD = libharfbuzz.la $(HBLIBS)
 dump_indic_data_SOURCES = dump-indic-data.cc hb-ot-shape-complex-indic-table.cc
 dump_indic_data_CPPFLAGS = $(HBCFLAGS)
 dump_indic_data_LDADD = libharfbuzz.la $(HBLIBS)
@@ -1465,6 +1526,9 @@ dump_myanmar_data_LDADD = libharfbuzz.la $(HBLIBS)
 dump_use_data_SOURCES = dump-use-data.cc hb-ot-shape-complex-use-table.cc
 dump_use_data_CPPFLAGS = $(HBCFLAGS)
 dump_use_data_LDADD = libharfbuzz.la $(HBLIBS)
+@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@dump_emoji_SOURCES = dump-emoji.cc
+@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@dump_emoji_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS) $(CAIRO_FT_CFLAGS)
+@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@dump_emoji_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS) $(CAIRO_LIBS) $(CAIRO_FT_LIBS)
 test_ot_tag_SOURCES = hb-ot-tag.cc
 test_ot_tag_CPPFLAGS = $(HBCFLAGS) -DMAIN
 test_ot_tag_LDADD = libharfbuzz.la $(HBLIBS)
@@ -1545,8 +1609,6 @@ $(top_srcdir)/configure:  $(am__configure_deps)
 $(ACLOCAL_M4):  $(am__aclocal_m4_deps)
        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 $(am__aclocal_m4_deps):
-hb-version.h: $(top_builddir)/config.status $(srcdir)/hb-version.h.in
-       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 harfbuzz-config.cmake: $(top_builddir)/config.status $(srcdir)/harfbuzz-config.cmake.in
        cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 
@@ -1594,6 +1656,9 @@ libharfbuzz-gobject.la: $(libharfbuzz_gobject_la_OBJECTS) $(libharfbuzz_gobject_
 libharfbuzz-icu.la: $(libharfbuzz_icu_la_OBJECTS) $(libharfbuzz_icu_la_DEPENDENCIES) $(EXTRA_libharfbuzz_icu_la_DEPENDENCIES) 
        $(AM_V_CXXLD)$(libharfbuzz_icu_la_LINK) $(am_libharfbuzz_icu_la_rpath) $(libharfbuzz_icu_la_OBJECTS) $(libharfbuzz_icu_la_LIBADD) $(LIBS)
 
+libharfbuzz-subset-fuzzing.la: $(libharfbuzz_subset_fuzzing_la_OBJECTS) $(libharfbuzz_subset_fuzzing_la_DEPENDENCIES) $(EXTRA_libharfbuzz_subset_fuzzing_la_DEPENDENCIES) 
+       $(AM_V_GEN)$(libharfbuzz_subset_fuzzing_la_LINK)  $(libharfbuzz_subset_fuzzing_la_OBJECTS) $(libharfbuzz_subset_fuzzing_la_LIBADD) $(LIBS)
+
 libharfbuzz-subset.la: $(libharfbuzz_subset_la_OBJECTS) $(libharfbuzz_subset_la_DEPENDENCIES) $(EXTRA_libharfbuzz_subset_la_DEPENDENCIES) 
        $(AM_V_CXXLD)$(libharfbuzz_subset_la_LINK) -rpath $(libdir) $(libharfbuzz_subset_la_OBJECTS) $(libharfbuzz_subset_la_LIBADD) $(LIBS)
 
@@ -1683,6 +1748,14 @@ clean-noinstPROGRAMS:
        echo " rm -f" $$list; \
        rm -f $$list
 
+dump-emoji$(EXEEXT): $(dump_emoji_OBJECTS) $(dump_emoji_DEPENDENCIES) $(EXTRA_dump_emoji_DEPENDENCIES) 
+       @rm -f dump-emoji$(EXEEXT)
+       $(AM_V_CXXLD)$(CXXLINK) $(dump_emoji_OBJECTS) $(dump_emoji_LDADD) $(LIBS)
+
+dump-fon$(EXEEXT): $(dump_fon_OBJECTS) $(dump_fon_DEPENDENCIES) $(EXTRA_dump_fon_DEPENDENCIES) 
+       @rm -f dump-fon$(EXEEXT)
+       $(AM_V_CXXLD)$(CXXLINK) $(dump_fon_OBJECTS) $(dump_fon_LDADD) $(LIBS)
+
 dump-indic-data$(EXEEXT): $(dump_indic_data_OBJECTS) $(dump_indic_data_DEPENDENCIES) $(EXTRA_dump_indic_data_DEPENDENCIES) 
        @rm -f dump-indic-data$(EXEEXT)
        $(AM_V_CXXLD)$(CXXLINK) $(dump_indic_data_OBJECTS) $(dump_indic_data_LDADD) $(LIBS)
@@ -1733,6 +1806,8 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dump_emoji-dump-emoji.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dump_fon-dump-fon.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dump_indic_data-dump-indic-data.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dump_indic_data-hb-ot-shape-complex-indic-table.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dump_khmer_data-dump-khmer-data.Po@am__quote@
@@ -1755,6 +1830,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-glib.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-graphite2.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-icu.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-map.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-ot-color.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-ot-font.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-ot-layout.Plo@am__quote@
@@ -1781,6 +1857,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-shape-plan.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-shape.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-shaper.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-static.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-ucdn.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-unicode.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_fuzzing_la-hb-uniscribe.Plo@am__quote@
@@ -1802,6 +1879,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-glib.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-graphite2.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-icu.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-map.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-color.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-font.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-layout.Plo@am__quote@
@@ -1828,10 +1906,17 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-shape-plan.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-shape.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-shaper.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-static.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ucdn.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-unicode.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-uniscribe.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-warning.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-static.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset-glyf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset-input.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset-plan.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_la-hb-static.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-glyf.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-input.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-plan.Plo@am__quote@
@@ -1907,6 +1992,13 @@ libharfbuzz_fuzzing_la-hb-font.lo: hb-font.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_fuzzing_la-hb-font.lo `test -f 'hb-font.cc' || echo '$(srcdir)/'`hb-font.cc
 
+libharfbuzz_fuzzing_la-hb-map.lo: hb-map.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_fuzzing_la-hb-map.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_fuzzing_la-hb-map.Tpo -c -o libharfbuzz_fuzzing_la-hb-map.lo `test -f 'hb-map.cc' || echo '$(srcdir)/'`hb-map.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_fuzzing_la-hb-map.Tpo $(DEPDIR)/libharfbuzz_fuzzing_la-hb-map.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-map.cc' object='libharfbuzz_fuzzing_la-hb-map.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_fuzzing_la-hb-map.lo `test -f 'hb-map.cc' || echo '$(srcdir)/'`hb-map.cc
+
 libharfbuzz_fuzzing_la-hb-ot-tag.lo: hb-ot-tag.cc
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_fuzzing_la-hb-ot-tag.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_fuzzing_la-hb-ot-tag.Tpo -c -o libharfbuzz_fuzzing_la-hb-ot-tag.lo `test -f 'hb-ot-tag.cc' || echo '$(srcdir)/'`hb-ot-tag.cc
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_fuzzing_la-hb-ot-tag.Tpo $(DEPDIR)/libharfbuzz_fuzzing_la-hb-ot-tag.Plo
@@ -1942,6 +2034,13 @@ libharfbuzz_fuzzing_la-hb-shaper.lo: hb-shaper.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_fuzzing_la-hb-shaper.lo `test -f 'hb-shaper.cc' || echo '$(srcdir)/'`hb-shaper.cc
 
+libharfbuzz_fuzzing_la-hb-static.lo: hb-static.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_fuzzing_la-hb-static.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_fuzzing_la-hb-static.Tpo -c -o libharfbuzz_fuzzing_la-hb-static.lo `test -f 'hb-static.cc' || echo '$(srcdir)/'`hb-static.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_fuzzing_la-hb-static.Tpo $(DEPDIR)/libharfbuzz_fuzzing_la-hb-static.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-static.cc' object='libharfbuzz_fuzzing_la-hb-static.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_fuzzing_la-hb-static.lo `test -f 'hb-static.cc' || echo '$(srcdir)/'`hb-static.cc
+
 libharfbuzz_fuzzing_la-hb-unicode.lo: hb-unicode.cc
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_fuzzing_la-hb-unicode.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_fuzzing_la-hb-unicode.Tpo -c -o libharfbuzz_fuzzing_la-hb-unicode.lo `test -f 'hb-unicode.cc' || echo '$(srcdir)/'`hb-unicode.cc
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_fuzzing_la-hb-unicode.Tpo $(DEPDIR)/libharfbuzz_fuzzing_la-hb-unicode.Plo
@@ -2194,6 +2293,48 @@ libharfbuzz_icu_la-hb-icu.lo: hb-icu.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_icu_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_icu_la-hb-icu.lo `test -f 'hb-icu.cc' || echo '$(srcdir)/'`hb-icu.cc
 
+libharfbuzz_subset_fuzzing_la-hb-static.lo: hb-static.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_subset_fuzzing_la-hb-static.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-static.Tpo -c -o libharfbuzz_subset_fuzzing_la-hb-static.lo `test -f 'hb-static.cc' || echo '$(srcdir)/'`hb-static.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-static.Tpo $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-static.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-static.cc' object='libharfbuzz_subset_fuzzing_la-hb-static.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_subset_fuzzing_la-hb-static.lo `test -f 'hb-static.cc' || echo '$(srcdir)/'`hb-static.cc
+
+libharfbuzz_subset_fuzzing_la-hb-subset.lo: hb-subset.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_subset_fuzzing_la-hb-subset.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset.Tpo -c -o libharfbuzz_subset_fuzzing_la-hb-subset.lo `test -f 'hb-subset.cc' || echo '$(srcdir)/'`hb-subset.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset.Tpo $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-subset.cc' object='libharfbuzz_subset_fuzzing_la-hb-subset.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_subset_fuzzing_la-hb-subset.lo `test -f 'hb-subset.cc' || echo '$(srcdir)/'`hb-subset.cc
+
+libharfbuzz_subset_fuzzing_la-hb-subset-glyf.lo: hb-subset-glyf.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_subset_fuzzing_la-hb-subset-glyf.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset-glyf.Tpo -c -o libharfbuzz_subset_fuzzing_la-hb-subset-glyf.lo `test -f 'hb-subset-glyf.cc' || echo '$(srcdir)/'`hb-subset-glyf.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset-glyf.Tpo $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset-glyf.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-subset-glyf.cc' object='libharfbuzz_subset_fuzzing_la-hb-subset-glyf.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_subset_fuzzing_la-hb-subset-glyf.lo `test -f 'hb-subset-glyf.cc' || echo '$(srcdir)/'`hb-subset-glyf.cc
+
+libharfbuzz_subset_fuzzing_la-hb-subset-input.lo: hb-subset-input.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_subset_fuzzing_la-hb-subset-input.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset-input.Tpo -c -o libharfbuzz_subset_fuzzing_la-hb-subset-input.lo `test -f 'hb-subset-input.cc' || echo '$(srcdir)/'`hb-subset-input.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset-input.Tpo $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset-input.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-subset-input.cc' object='libharfbuzz_subset_fuzzing_la-hb-subset-input.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_subset_fuzzing_la-hb-subset-input.lo `test -f 'hb-subset-input.cc' || echo '$(srcdir)/'`hb-subset-input.cc
+
+libharfbuzz_subset_fuzzing_la-hb-subset-plan.lo: hb-subset-plan.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_subset_fuzzing_la-hb-subset-plan.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset-plan.Tpo -c -o libharfbuzz_subset_fuzzing_la-hb-subset-plan.lo `test -f 'hb-subset-plan.cc' || echo '$(srcdir)/'`hb-subset-plan.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset-plan.Tpo $(DEPDIR)/libharfbuzz_subset_fuzzing_la-hb-subset-plan.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-subset-plan.cc' object='libharfbuzz_subset_fuzzing_la-hb-subset-plan.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_fuzzing_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_subset_fuzzing_la-hb-subset-plan.lo `test -f 'hb-subset-plan.cc' || echo '$(srcdir)/'`hb-subset-plan.cc
+
+libharfbuzz_subset_la-hb-static.lo: hb-static.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_subset_la-hb-static.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_subset_la-hb-static.Tpo -c -o libharfbuzz_subset_la-hb-static.lo `test -f 'hb-static.cc' || echo '$(srcdir)/'`hb-static.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_subset_la-hb-static.Tpo $(DEPDIR)/libharfbuzz_subset_la-hb-static.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-static.cc' object='libharfbuzz_subset_la-hb-static.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_subset_la-hb-static.lo `test -f 'hb-static.cc' || echo '$(srcdir)/'`hb-static.cc
+
 libharfbuzz_subset_la-hb-subset.lo: hb-subset.cc
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_subset_la-hb-subset.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_subset_la-hb-subset.Tpo -c -o libharfbuzz_subset_la-hb-subset.lo `test -f 'hb-subset.cc' || echo '$(srcdir)/'`hb-subset.cc
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_subset_la-hb-subset.Tpo $(DEPDIR)/libharfbuzz_subset_la-hb-subset.Plo
@@ -2264,6 +2405,13 @@ libharfbuzz_la-hb-font.lo: hb-font.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-font.lo `test -f 'hb-font.cc' || echo '$(srcdir)/'`hb-font.cc
 
+libharfbuzz_la-hb-map.lo: hb-map.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-map.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-map.Tpo -c -o libharfbuzz_la-hb-map.lo `test -f 'hb-map.cc' || echo '$(srcdir)/'`hb-map.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-map.Tpo $(DEPDIR)/libharfbuzz_la-hb-map.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-map.cc' object='libharfbuzz_la-hb-map.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-map.lo `test -f 'hb-map.cc' || echo '$(srcdir)/'`hb-map.cc
+
 libharfbuzz_la-hb-ot-tag.lo: hb-ot-tag.cc
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-ot-tag.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-ot-tag.Tpo -c -o libharfbuzz_la-hb-ot-tag.lo `test -f 'hb-ot-tag.cc' || echo '$(srcdir)/'`hb-ot-tag.cc
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-ot-tag.Tpo $(DEPDIR)/libharfbuzz_la-hb-ot-tag.Plo
@@ -2299,6 +2447,13 @@ libharfbuzz_la-hb-shaper.lo: hb-shaper.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-shaper.lo `test -f 'hb-shaper.cc' || echo '$(srcdir)/'`hb-shaper.cc
 
+libharfbuzz_la-hb-static.lo: hb-static.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-static.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-static.Tpo -c -o libharfbuzz_la-hb-static.lo `test -f 'hb-static.cc' || echo '$(srcdir)/'`hb-static.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-static.Tpo $(DEPDIR)/libharfbuzz_la-hb-static.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-static.cc' object='libharfbuzz_la-hb-static.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-static.lo `test -f 'hb-static.cc' || echo '$(srcdir)/'`hb-static.cc
+
 libharfbuzz_la-hb-unicode.lo: hb-unicode.cc
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-unicode.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-unicode.Tpo -c -o libharfbuzz_la-hb-unicode.lo `test -f 'hb-unicode.cc' || echo '$(srcdir)/'`hb-unicode.cc
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-unicode.Tpo $(DEPDIR)/libharfbuzz_la-hb-unicode.Plo
@@ -2530,6 +2685,34 @@ libharfbuzz_la-hb-icu.lo: hb-icu.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-icu.lo `test -f 'hb-icu.cc' || echo '$(srcdir)/'`hb-icu.cc
 
+dump_emoji-dump-emoji.o: dump-emoji.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dump_emoji_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dump_emoji-dump-emoji.o -MD -MP -MF $(DEPDIR)/dump_emoji-dump-emoji.Tpo -c -o dump_emoji-dump-emoji.o `test -f 'dump-emoji.cc' || echo '$(srcdir)/'`dump-emoji.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/dump_emoji-dump-emoji.Tpo $(DEPDIR)/dump_emoji-dump-emoji.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='dump-emoji.cc' object='dump_emoji-dump-emoji.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dump_emoji_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dump_emoji-dump-emoji.o `test -f 'dump-emoji.cc' || echo '$(srcdir)/'`dump-emoji.cc
+
+dump_emoji-dump-emoji.obj: dump-emoji.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dump_emoji_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dump_emoji-dump-emoji.obj -MD -MP -MF $(DEPDIR)/dump_emoji-dump-emoji.Tpo -c -o dump_emoji-dump-emoji.obj `if test -f 'dump-emoji.cc'; then $(CYGPATH_W) 'dump-emoji.cc'; else $(CYGPATH_W) '$(srcdir)/dump-emoji.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/dump_emoji-dump-emoji.Tpo $(DEPDIR)/dump_emoji-dump-emoji.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='dump-emoji.cc' object='dump_emoji-dump-emoji.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dump_emoji_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dump_emoji-dump-emoji.obj `if test -f 'dump-emoji.cc'; then $(CYGPATH_W) 'dump-emoji.cc'; else $(CYGPATH_W) '$(srcdir)/dump-emoji.cc'; fi`
+
+dump_fon-dump-fon.o: dump-fon.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dump_fon_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dump_fon-dump-fon.o -MD -MP -MF $(DEPDIR)/dump_fon-dump-fon.Tpo -c -o dump_fon-dump-fon.o `test -f 'dump-fon.cc' || echo '$(srcdir)/'`dump-fon.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/dump_fon-dump-fon.Tpo $(DEPDIR)/dump_fon-dump-fon.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='dump-fon.cc' object='dump_fon-dump-fon.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dump_fon_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dump_fon-dump-fon.o `test -f 'dump-fon.cc' || echo '$(srcdir)/'`dump-fon.cc
+
+dump_fon-dump-fon.obj: dump-fon.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dump_fon_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dump_fon-dump-fon.obj -MD -MP -MF $(DEPDIR)/dump_fon-dump-fon.Tpo -c -o dump_fon-dump-fon.obj `if test -f 'dump-fon.cc'; then $(CYGPATH_W) 'dump-fon.cc'; else $(CYGPATH_W) '$(srcdir)/dump-fon.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/dump_fon-dump-fon.Tpo $(DEPDIR)/dump_fon-dump-fon.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='dump-fon.cc' object='dump_fon-dump-fon.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dump_fon_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dump_fon-dump-fon.obj `if test -f 'dump-fon.cc'; then $(CYGPATH_W) 'dump-fon.cc'; else $(CYGPATH_W) '$(srcdir)/dump-fon.cc'; fi`
+
 dump_indic_data-dump-indic-data.o: dump-indic-data.cc
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dump_indic_data_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dump_indic_data-dump-indic-data.o -MD -MP -MF $(DEPDIR)/dump_indic_data-dump-indic-data.Tpo -c -o dump_indic_data-dump-indic-data.o `test -f 'dump-indic-data.cc' || echo '$(srcdir)/'`dump-indic-data.cc
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/dump_indic_data-dump-indic-data.Tpo $(DEPDIR)/dump_indic_data-dump-indic-data.Po
@@ -3389,19 +3572,24 @@ uninstall-am: uninstall-binPROGRAMS uninstall-cmakeDATA \
 .PRECIOUS: Makefile
 
 
-# The following warning options are useful for debugging: -Wpadded
-#AM_CXXFLAGS =
-
 # Convenience targets:
 lib: $(BUILT_SOURCES) libharfbuzz.la libharfbuzz-subset.la
-fuzzing: $(BUILT_SOURCES) libharfbuzz-fuzzing.la
+fuzzing: $(BUILT_SOURCES) libharfbuzz-fuzzing.la libharfbuzz-subset-fuzzing.la
 @HAVE_UCDN_TRUE@hb-ucdn/libhb-ucdn.la: ucdn
 @HAVE_UCDN_TRUE@ucdn:
 @HAVE_UCDN_TRUE@       @$(MAKE) $(AM_MAKEFLAGS) -C hb-ucdn
 
+$(srcdir)/hb-version.h: hb-version.h.in $(top_srcdir)/configure.ac
+       $(AM_V_GEN) $(SED) \
+               -e 's/[@]HB_VERSION_MAJOR@/$(HB_VERSION_MAJOR)/' \
+               -e 's/[@]HB_VERSION_MINOR@/$(HB_VERSION_MINOR)/' \
+               -e 's/[@]HB_VERSION_MICRO@/$(HB_VERSION_MICRO)/' \
+               -e 's/[@]HB_VERSION@/$(HB_VERSION)/' \
+               "$<" > "$@" || ($(RM) "$@"; false)
+
 @CODE_COVERAGE_RULES@
 @HAVE_GOBJECT_TRUE@hb-gobject-enums.%: hb-gobject-enums.%.tmpl $(HBHEADERS)
-@HAVE_GOBJECT_TRUE@    $(AM_V_GEN) $(GLIB_MKENUMS) \
+@HAVE_GOBJECT_TRUE@    $(AM_V_GEN) PYTHONIOENCODING=UTF-8 $(GLIB_MKENUMS) \
 @HAVE_GOBJECT_TRUE@            --identifier-prefix hb_ --symbol-prefix hb_gobject \
 @HAVE_GOBJECT_TRUE@            --template $^ | \
 @HAVE_GOBJECT_TRUE@    sed 's/_t_get_type/_get_type/g; s/_T (/ (/g' > "$@" \
@@ -3420,27 +3608,27 @@ fuzzing: $(BUILT_SOURCES) libharfbuzz-fuzzing.la
        || ($(RM) "$@"; false)
 check: $(DEF_FILES) # For check-symbols.sh
 harfbuzz.def: $(HBHEADERS) $(HBNODISTHEADERS)
-       $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py $@
+       $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py "$@"
 harfbuzz-subset.def: $(HB_SUBSET_headers)
-       $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py $@
+       $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py "$@"
 harfbuzz-icu.def: $(HB_ICU_headers)
-       $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py $@
+       $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py "$@"
 harfbuzz-gobject.def: $(HB_GOBJECT_headers)
-       $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py $@
+       $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py "$@"
 
 unicode-tables: arabic-table indic-table use-table
 
 arabic-table: gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt
-       $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-arabic-table.hh \
-       || ($(RM) hb-ot-shape-complex-arabic-table.hh; false)
+       $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-arabic-table.hh \
+       || ($(RM) $(srcdir)/hb-ot-shape-complex-arabic-table.hh; false)
 
-indic-table: gen-indic-table.py IndicSyllabicCategory-7.0.0.txt IndicMatraCategory-7.0.0.txt Blocks.txt
-       $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-indic-table.cc \
-       || ($(RM) hb-ot-shape-complex-indic-table.cc; false)
+indic-table: gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt
+       $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-indic-table.cc \
+       || ($(RM) $(srcdir)/hb-ot-shape-complex-indic-table.cc; false)
 
 use-table: gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt
-       $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-use-table.cc \
-       || ($(RM) hb-ot-shape-complex-use-table.cc; false)
+       $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-use-table.cc \
+       || ($(RM) $(srcdir)/hb-ot-shape-complex-use-table.cc; false)
 
 built-sources: $(BUILT_SOURCES)
 
index 787c3c4..0bc9e58 100644 (file)
@@ -2,6 +2,7 @@
 
 HB_BASE_sources = \
        hb-atomic-private.hh \
+       hb-blob-private.hh \
        hb-blob.cc \
        hb-buffer-private.hh \
        hb-buffer-serialize.cc \
@@ -13,6 +14,8 @@ HB_BASE_sources = \
        hb-face.cc \
        hb-font-private.hh \
        hb-font.cc \
+       hb-map-private.hh \
+       hb-map.cc \
        hb-mutex-private.hh \
        hb-object-private.hh \
        hb-open-file-private.hh \
@@ -43,6 +46,7 @@ HB_BASE_sources = \
        hb-shaper-impl-private.hh \
        hb-shaper-private.hh \
        hb-shaper.cc \
+       hb-static.cc \
        hb-string-array.hh \
        hb-unicode-private.hh \
        hb-unicode.cc \
@@ -67,6 +71,7 @@ HB_BASE_headers = \
        hb-deprecated.h \
        hb-face.h \
        hb-font.h \
+       hb-map.h \
        hb-set.h \
        hb-shape.h \
        hb-shape-plan.h \
@@ -82,10 +87,15 @@ HB_OT_sources = \
        hb-aat-layout.cc \
        hb-aat-layout-common-private.hh \
        hb-aat-layout-ankr-table.hh \
+       hb-aat-layout-bsln-table.hh \
+       hb-aat-layout-feat-table.hh \
        hb-aat-layout-kerx-table.hh \
        hb-aat-layout-morx-table.hh \
        hb-aat-layout-trak-table.hh \
        hb-aat-layout-private.hh \
+       hb-aat-fmtx-table.hh \
+       hb-aat-gcid-table.hh \
+       hb-aat-ltag-table.hh \
        hb-ot-font.cc \
        hb-ot-layout.cc \
        hb-ot-layout-base-table.hh \
@@ -99,6 +109,8 @@ HB_OT_sources = \
        hb-ot-color.cc \
        hb-ot-color-colr-table.hh \
        hb-ot-color-cpal-table.hh \
+       hb-ot-color-sbix-table.hh \
+       hb-ot-color-svg-table.hh \
        hb-ot-map.cc \
        hb-ot-map-private.hh \
        hb-ot-math.cc \
@@ -191,6 +203,7 @@ HB_ICU_headers = hb-icu.h
 
 # Sources for libharfbuzz-subset
 HB_SUBSET_sources = \
+       hb-static.cc \
        hb-subset.cc \
        hb-subset-glyf.cc \
        hb-subset-input.cc \
index bfc93b3..d4eca50 100755 (executable)
@@ -30,7 +30,6 @@ for soname in harfbuzz harfbuzz-subset harfbuzz-icu harfbuzz-gobject; do
 
                prefix=$symprefix`basename "$so" | sed 's/libharfbuzz/hb/; s/-/_/g; s/[.].*//'`
 
-               echo
                echo "Checking that $so does not expose internal symbols"
                if echo "$EXPORTED_SYMBOLS" | grep -v "^${prefix}\(_\|$\)"; then
                        echo "Ouch, internal symbols exposed"
@@ -41,7 +40,6 @@ for soname in harfbuzz harfbuzz-subset harfbuzz-icu harfbuzz-gobject; do
                if ! test -f "$def"; then
                        echo "'$def' not found; skipping"
                else
-                       echo
                        echo "Checking that $so has the same symbol list as $def"
                        {
                                echo EXPORTS
diff --git a/src/dump-emoji.cc b/src/dump-emoji.cc
new file mode 100644 (file)
index 0000000..99e8ef9
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+ * Copyright © 2018  Ebrahim Byagowi
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include "hb-static.cc"
+#include "hb-ot-color-cbdt-table.hh"
+#include "hb-ot-color-colr-table.hh"
+#include "hb-ot-color-cpal-table.hh"
+#include "hb-ot-color-sbix-table.hh"
+#include "hb-ot-color-svg-table.hh"
+
+#include "hb-ft.h"
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_GLYPH_H
+
+#include <cairo.h>
+#include <cairo-ft.h>
+#include <cairo-svg.h>
+
+#ifdef HAVE_GLIB
+#include <glib.h>
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+
+void cbdt_callback (const uint8_t* data, unsigned int length,
+                    unsigned int group, unsigned int gid)
+{
+  char output_path[255];
+  sprintf (output_path, "out/cbdt-%d-%d.png", group, gid);
+  FILE *f = fopen (output_path, "wb");
+  fwrite (data, 1, length, f);
+  fclose (f);
+}
+
+void sbix_callback (const uint8_t* data, unsigned int length,
+                    unsigned int group, unsigned int gid)
+{
+  char output_path[255];
+  sprintf (output_path, "out/sbix-%d-%d.png", group, gid);
+  FILE *f = fopen (output_path, "wb");
+  fwrite (data, 1, length, f);
+  fclose (f);
+}
+
+void svg_callback (const uint8_t* data, unsigned int length,
+                   unsigned int start_glyph, unsigned int end_glyph)
+{
+  char output_path[255];
+  if (start_glyph == end_glyph)
+    sprintf (output_path, "out/svg-%d.svg", start_glyph);
+  else
+    sprintf (output_path, "out/svg-%d-%d.svg", start_glyph, end_glyph);
+
+  // append "z" if the content is gzipped
+  if ((data[0] == 0x1F) && (data[1] == 0x8B))
+    strcat (output_path, "z");
+
+  FILE *f = fopen (output_path, "wb");
+  fwrite (data, 1, length, f);
+  fclose (f);
+}
+
+void colr_cpal_rendering (cairo_font_face_t *cairo_face, unsigned int upem, unsigned int num_glyphs,
+                         const OT::COLR *colr, const OT::CPAL *cpal)
+{
+  for (unsigned int i = 0; i < num_glyphs; ++i)
+  {
+    unsigned int first_layer_index, num_layers;
+    if (colr->get_base_glyph_record (i, &first_layer_index, &num_layers))
+    {
+      // Measure
+      cairo_text_extents_t extents;
+      {
+       cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
+       cairo_t *cr = cairo_create (surface);
+       cairo_set_font_face (cr, cairo_face);
+       cairo_set_font_size (cr, upem);
+
+       cairo_glyph_t *glyphs = (cairo_glyph_t *) calloc (num_layers, sizeof (cairo_glyph_t));
+       for (unsigned int j = 0; j < num_layers; ++j)
+       {
+         hb_codepoint_t glyph_id;
+         unsigned int color_index;
+         colr->get_layer_record (first_layer_index + j, &glyph_id, &color_index);
+         glyphs[j].index = glyph_id;
+       }
+       cairo_glyph_extents (cr, glyphs, num_layers, &extents);
+       free (glyphs);
+       cairo_surface_destroy (surface);
+       cairo_destroy (cr);
+      }
+
+      // Add a slight margin
+      extents.width += extents.width / 10;
+      extents.height += extents.height / 10;
+      extents.x_bearing -= extents.width / 20;
+      extents.y_bearing -= extents.height / 20;
+
+      // Render
+      unsigned int pallet_count = cpal->get_palette_count ();
+      for (unsigned int pallet = 0; pallet < pallet_count; ++pallet) {
+       char output_path[255];
+
+       // If we have more than one pallet, use a better namin
+       if (pallet_count == 1)
+         sprintf (output_path, "out/colr-%d.svg", i);
+       else
+         sprintf (output_path, "out/colr-%d-%d.svg", i, pallet);
+
+       cairo_surface_t *surface = cairo_svg_surface_create (output_path, extents.width, extents.height);
+       cairo_t *cr = cairo_create (surface);
+       cairo_set_font_face (cr, cairo_face);
+       cairo_set_font_size (cr, upem);
+
+       for (unsigned int j = 0; j < num_layers; ++j)
+       {
+         hb_codepoint_t glyph_id;
+         unsigned int color_index;
+         colr->get_layer_record (first_layer_index + j, &glyph_id, &color_index);
+
+         uint32_t color = cpal->get_color_record_argb (color_index, pallet);
+         int alpha = color & 0xFF;
+         int r = (color >> 8) & 0xFF;
+         int g = (color >> 16) & 0xFF;
+         int b = (color >> 24) & 0xFF;
+         cairo_set_source_rgba (cr, r / 255.f, g / 255.f, b / 255.f, alpha);
+
+         cairo_glyph_t glyph;
+         glyph.index = glyph_id;
+         glyph.x = -extents.x_bearing;
+         glyph.y = -extents.y_bearing;
+         cairo_show_glyphs (cr, &glyph, 1);
+       }
+
+       cairo_surface_destroy (surface);
+       cairo_destroy (cr);
+      }
+    }
+  }
+}
+
+void dump_glyphs (cairo_font_face_t *cairo_face, unsigned int upem, unsigned int num_glyphs)
+{
+  // Dump every glyph available on the font
+  return; // disabled for now
+  for (unsigned int i = 0; i < num_glyphs; ++i)
+  {
+    cairo_text_extents_t extents;
+    cairo_glyph_t glyph = {0};
+    glyph.index = i;
+
+    // Measure
+    {
+      cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
+      cairo_t *cr = cairo_create (surface);
+      cairo_set_font_face (cr, cairo_face);
+      cairo_set_font_size (cr, upem);
+
+      cairo_glyph_extents (cr, &glyph, 1, &extents);
+      cairo_surface_destroy (surface);
+      cairo_destroy (cr);
+    }
+
+    // Add a slight margin
+    extents.width += extents.width / 10;
+    extents.height += extents.height / 10;
+    extents.x_bearing -= extents.width / 20;
+    extents.y_bearing -= extents.height / 20;
+
+    // Render
+    {
+      char output_path[255];
+      sprintf (output_path, "out/%d.svg", i);
+      cairo_surface_t *surface = cairo_svg_surface_create (output_path, extents.width, extents.height);
+      cairo_t *cr = cairo_create (surface);
+      cairo_set_font_face (cr, cairo_face);
+      cairo_set_font_size (cr, upem);
+      glyph.x = -extents.x_bearing;
+      glyph.y = -extents.y_bearing;
+      cairo_show_glyphs (cr, &glyph, 1);
+      cairo_surface_destroy (surface);
+      cairo_destroy (cr);
+    }
+  }
+}
+
+int main (int argc, char **argv)
+{
+  if (argc != 2) {
+    fprintf (stderr, "usage: %s font-file.ttf\n", argv[0]);
+    exit (1);
+  }
+
+  hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
+  hb_face_t *face = hb_face_create (blob, 0);
+  hb_font_t *font = hb_font_create (face);
+
+  OT::CBDT::accelerator_t cbdt;
+  cbdt.init (face);
+  cbdt.dump (cbdt_callback);
+  cbdt.fini ();
+
+  OT::sbix::accelerator_t sbix;
+  sbix.init (face);
+  sbix.dump (sbix_callback);
+  sbix.fini ();
+
+  OT::SVG::accelerator_t svg;
+  svg.init (face);
+  svg.dump (svg_callback);
+  svg.fini ();
+
+  OT::Sanitizer<OT::COLR> sanitizerCOLR;
+  hb_blob_t* colr_blob = sanitizerCOLR.sanitize (face->reference_table (HB_OT_TAG_COLR));
+  const OT::COLR *colr = colr_blob->as<OT::COLR> ();
+
+  OT::Sanitizer<OT::CPAL> sanitizerCPAL;
+  hb_blob_t* cpal_blob = sanitizerCPAL.sanitize (face->reference_table (HB_OT_TAG_CPAL));
+  const OT::CPAL *cpal = cpal_blob->as<OT::CPAL> ();
+
+  cairo_font_face_t *cairo_face;
+  {
+    FT_Library library;
+    FT_Init_FreeType (&library);
+    FT_Face ftface;
+    FT_New_Face (library, argv[1], 0, &ftface);
+    cairo_face = cairo_ft_font_face_create_for_ft_face (ftface, 0);
+  }
+  unsigned int num_glyphs = hb_face_get_glyph_count (face);
+  unsigned int upem = hb_face_get_upem (face);
+  colr_cpal_rendering (cairo_face, upem, num_glyphs, colr, cpal);
+  dump_glyphs (cairo_face, upem, num_glyphs);
+
+
+  hb_font_destroy (font);
+  hb_face_destroy (face);
+  hb_blob_destroy (blob);
+
+  return 0;
+}
diff --git a/src/dump-fon.cc b/src/dump-fon.cc
new file mode 100644 (file)
index 0000000..4015409
--- /dev/null
@@ -0,0 +1,555 @@
+/*
+ * Copyright © 2018  Ebrahim Byagowi
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include "hb-static.cc"
+#include <stdio.h>
+#include <stdlib.h>
+#include "hb-open-type-private.hh"
+
+template <typename Type, int Bytes> struct LEInt;
+
+template <typename Type>
+struct LEInt<Type, 1>
+{
+  public:
+  inline void set (Type V)
+  {
+    v = V;
+  }
+  inline operator Type (void) const
+  {
+    return v;
+  }
+  private: uint8_t v;
+};
+template <typename Type>
+struct LEInt<Type, 2>
+{
+  public:
+  inline void set (Type V)
+  {
+    v[1] = (V >>  8) & 0xFF;
+    v[0] = (V      ) & 0xFF;
+  }
+  inline operator Type (void) const
+  {
+    return (v[1] <<  8)
+         + (v[0]      );
+  }
+  private: uint8_t v[2];
+};
+template <typename Type>
+struct LEInt<Type, 3>
+{
+  public:
+  inline void set (Type V)
+  {
+    v[2] = (V >> 16) & 0xFF;
+    v[1] = (V >>  8) & 0xFF;
+    v[0] = (V      ) & 0xFF;
+  }
+  inline operator Type (void) const
+  {
+    return (v[2] << 16)
+         + (v[1] <<  8)
+         + (v[0]      );
+  }
+  private: uint8_t v[3];
+};
+template <typename Type>
+struct LEInt<Type, 4>
+{
+  public:
+  inline void set (Type V)
+  {
+    v[3] = (V >> 24) & 0xFF;
+    v[2] = (V >> 16) & 0xFF;
+    v[1] = (V >>  8) & 0xFF;
+    v[0] = (V      ) & 0xFF;
+  }
+  inline operator Type (void) const
+  {
+    return (v[3] << 24)
+         + (v[2] << 16)
+         + (v[1] <<  8)
+         + (v[0]      );
+  }
+  private: uint8_t v[4];
+};
+
+template <typename Type, unsigned int Size>
+struct LEIntType
+{
+  inline void set (Type i) { v.set (i); }
+  inline operator Type(void) const { return v; }
+  inline bool sanitize (OT::hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this)));
+  }
+  protected:
+  LEInt<Type, Size> v;
+  public:
+  DEFINE_SIZE_STATIC (Size);
+};
+
+typedef LEIntType<uint8_t,  1> LEUINT8;                /* 8-bit unsigned integer. */
+typedef LEIntType<int8_t,   1> LEINT8;         /* 8-bit signed integer. */
+typedef LEIntType<uint16_t, 2> LEUINT16;       /* 16-bit unsigned integer. */
+typedef LEIntType<int16_t,  2> LEINT16;                /* 16-bit signed integer. */
+typedef LEIntType<uint32_t, 4> LEUINT32;       /* 32-bit unsigned integer. */
+typedef LEIntType<int32_t,  4> LEINT32;                /* 32-bit signed integer. */
+typedef LEIntType<uint32_t, 3> LEUINT24;       /* 24-bit unsigned integer. */
+
+
+struct LE_FONTINFO16
+{
+  inline bool sanitize (OT::hb_sanitize_context_t *c, unsigned int length) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) && c->check_range (this, length)));
+  }
+
+  // https://msdn.microsoft.com/en-us/library/cc194829.aspx
+  enum charset_t
+  {
+    // dfCharSet possible values and the codepage they are indicating to
+    ANSI       = 0x00, // 1252
+    DEFAULT    = 0x01, //
+    SYMBOL     = 0x02, //
+    SHIFTJIS   = 0x80, // 932
+    HANGUL     = 0x81, // 949
+    GB2312     = 0x86, // 936
+    CHINESEBIG5        = 0x88, // 950
+    GREEK      = 0xA1, // 1253
+    TURKISH    = 0xA2, // 1254
+    HEBREW     = 0xB1, // 1255
+    ARABIC     = 0xB2, // 1256
+    BALTIC     = 0xBA, // 1257
+    RUSSIAN    = 0xCC, // 1251
+    THAI       = 0xDE, // 874
+    EE         = 0xEE, // 1250
+    OEM                = 0xFF  //
+  };
+
+  inline const char* get_charset() const
+  {
+    switch (dfCharSet) {
+    case ANSI: return "ISO8859";
+    case DEFAULT: return "WinDefault";
+    case SYMBOL: return "Symbol";
+    case SHIFTJIS: return "JISX0208.1983";
+    case HANGUL: return "MSHangul";
+    case GB2312: return "GB2312.1980";
+    case CHINESEBIG5: return "Big5";
+    case GREEK: return "CP1253";
+    case TURKISH: return "CP1254";
+    case HEBREW: return "CP1255";
+    case ARABIC: return "CP1256";
+    case BALTIC: return "CP1257";
+    case RUSSIAN: return "CP1251";
+    case THAI: return "CP874";
+    case EE: return "CP1250";
+    case OEM: return "OEM";
+    default: return "Unknown";
+    }
+  }
+
+  inline unsigned int get_version () const
+  {
+    return dfVersion;
+  }
+
+  inline unsigned int get_weight () const
+  {
+    return dfWeight;
+  }
+
+  enum weight_t {
+    DONTCARE   = 0,
+    THIN       = 100,
+    EXTRALIGHT = 200,
+    ULTRALIGHT = 200,
+    LIGHT      = 300,
+    NORMAL     = 400,
+    REGULAR    = 400,
+    MEDIUM     = 500,
+    SEMIBOLD   = 600,
+    DEMIBOLD   = 600,
+    BOLD       = 700,
+    EXTRABOLD  = 800,
+    ULTRABOLD  = 800,
+    HEAVY      = 900,
+    BLACK      = 900
+  };
+
+  inline void dump () const
+  {
+    // With https://github.com/juanitogan/mkwinfont/blob/master/python/dewinfont.py help
+    // Should be implemented differently eventually, but for now
+    unsigned int ctstart;
+    unsigned int ctsize;
+    if (dfVersion == 0x200)
+    {
+      ctstart = 0x76;
+      ctsize = 4;
+    }
+    else
+    {
+      return; // must of ".fon"s are version 2 and even dewinfont V1 implmentation doesn't seem correct
+      ctstart = 0x94;
+      ctsize = 6;
+    }
+    // unsigned int maxwidth = 0;
+    for (unsigned int i = dfFirstChar; i < dfLastChar; ++i)
+    {
+      unsigned int entry = ctstart + ctsize * (i-dfFirstChar);
+      unsigned int w = (uint16_t) OT::StructAtOffset<LEUINT16> (this, entry);
+
+      unsigned int off;
+      if (ctsize == 4)
+        off = (uint16_t) OT::StructAtOffset<LEUINT16> (this, entry+2);
+      else
+        off = (uint32_t) OT::StructAtOffset<LEUINT32> (this, entry+2);
+
+      unsigned int widthbytes = (w + 7) / 8;
+      for (unsigned int j = 0; j < dfPixHeight; ++j)
+      {
+        for (unsigned int k = 0; k < widthbytes; ++k)
+       {
+         unsigned int bytepos = off + k * dfPixHeight + j;
+         const uint8_t b = (uint8_t) OT::StructAtOffset<LEINT8> (this, bytepos);
+         for (unsigned int a = 128; a > 0; a >>= 1)
+           printf (b & a ? "x" : ".");
+       }
+       printf ("\n");
+      }
+      printf ("\n\n");
+    }
+  }
+
+  protected:
+  LEUINT16     dfVersion;
+  LEUINT32     dfSize;
+  LEUINT8      dfCopyright[60];
+  LEUINT16     dfType;
+  LEUINT16     dfPoints;
+  LEUINT16     dfVertRes;
+  LEUINT16     dfHorizRes;
+  LEUINT16     dfAscent;
+  LEUINT16     dfInternalLeading;
+  LEUINT16     dfExternalLeading;
+  LEUINT8      dfItalic;
+  LEUINT8      dfUnderline;
+  LEUINT8      dfStrikeOut;
+  LEUINT16     dfWeight; // see weight_t
+  LEUINT8      dfCharSet;  // see charset_t
+  LEUINT16     dfPixWidth;
+  LEUINT16     dfPixHeight;
+  LEUINT8      dfPitchAndFamily;
+  LEUINT16     dfAvgWidth;
+  LEUINT16     dfMaxWidth;
+  LEUINT8      dfFirstChar;
+  LEUINT8      dfLastChar;
+  LEUINT8      dfDefaultChar;
+  LEUINT8      dfBreakChar;
+  LEUINT16     dfWidthBytes;
+  LEUINT32     dfDevice;
+  LEUINT32     dfFace;
+  LEUINT32     dfBitsPointer;
+  LEUINT32     dfBitsOffset;
+  LEUINT8      dfReserved;
+//   LEUINT32  dfFlags;
+//   LEUINT16  dfAspace;
+//   LEUINT16  dfBspace;
+//   LEUINT16  dfCspace;
+//   LEUINT32  dfColorPointer;
+//   LEUINT32  dfReserved1[4];
+  OT::UnsizedArrayOf<LEUINT8>
+               dataZ;
+  public:
+  DEFINE_SIZE_ARRAY (118, dataZ);
+};
+
+struct NE_NAMEINFO
+{
+  friend struct NE_TYPEINFO;
+
+  inline bool sanitize (OT::hb_sanitize_context_t *c, const void *base, unsigned int shift) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) &&
+                         get_font (base, shift).sanitize (c, length << shift)));
+  }
+
+  inline const LE_FONTINFO16& get_font (const void *base, int shift) const
+  {
+    return OT::StructAtOffset<LE_FONTINFO16> (base, offset << shift);
+  }
+
+  enum resource_type_flag_t {
+    NONE     = 0x0000,
+    MOVEABLE = 0x0010,
+    PURE     = 0x0020,
+    PRELOAD  = 0x0040
+  };
+
+  protected:
+  LEUINT16     offset; // Should be shifted with alignmentShiftCount before use
+  LEUINT16     length; // Should be shifted with alignmentShiftCount before use
+  LEUINT16     flags;  // resource_type_flag_t
+  LEUINT16     id;
+  LEUINT16     handle;
+  LEUINT16     usage;
+  public:
+  DEFINE_SIZE_STATIC (12);
+};
+
+struct NE_TYPEINFO
+{
+  inline bool sanitize (OT::hb_sanitize_context_t *c, const void *base, unsigned int shift) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && resources.sanitize (c, count, base, shift));
+  }
+
+  inline unsigned int get_size (void) const
+  { return 8 + count * NE_NAMEINFO::static_size; }
+
+  inline const NE_TYPEINFO& next () const
+  {
+    const NE_TYPEINFO& next = OT::StructAfter<NE_TYPEINFO> (*this);
+    if (type_id == 0)
+      return Null(NE_TYPEINFO);
+    return next;
+  }
+
+  inline const LE_FONTINFO16& get_font (unsigned int idx, const void *base, int shift) const
+  {
+    if (idx < count)
+      return resources[idx].get_font (base, shift);
+    return Null(LE_FONTINFO16);
+  }
+
+  inline unsigned int get_count () const
+  {
+    return count;
+  }
+
+  inline unsigned int get_type_id () const
+  {
+    return type_id;
+  }
+
+  enum type_id_t {
+    CURSOR             = 0x8001,
+    BITMAP             = 0x8002,
+    ICON               = 0x8003,
+    MENU               = 0x8004,
+    DIALOG             = 0x8005,
+    STRING             = 0x8006,
+    FONT_DIRECTORY     = 0x8007,
+    FONT               = 0x8008,
+    ACCELERATOR_TABLE  = 0x8009,
+    RESOURCE_DATA      = 0x800a,
+    GROUP_CURSOR       = 0x800c,
+    GROUP_ICON         = 0x800e,
+    VERSION            = 0x8010
+  };
+
+  protected:
+  LEUINT16     type_id; // see type_id_t
+  LEUINT16     count;
+  LEUINT32     resloader;
+  OT::UnsizedArrayOf<NE_NAMEINFO>
+               resources;
+  public:
+  DEFINE_SIZE_ARRAY (8, resources);
+};
+
+struct NE_RESOURCE_TABLE
+{
+  inline bool sanitize (OT::hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+
+    if (!c->check_struct (this))
+      return_trace (false);
+
+    const NE_TYPEINFO* n = &chain;
+    while (n != &Null(NE_TYPEINFO) && c->check_struct (n) && n->get_type_id () != 0)
+    {
+      if (n->get_type_id () == NE_TYPEINFO::FONT)
+       return_trace (n->sanitize (c, base, alignmentShiftCount));
+      n = &n->next();
+    }
+    return_trace (false);
+  }
+
+  inline unsigned int get_shift_value () const
+  {
+    return alignmentShiftCount;
+  }
+
+  inline const NE_TYPEINFO& get_fonts_entry () const
+  {
+    const NE_TYPEINFO* n = &chain;
+    while (n != &Null(NE_TYPEINFO) && n->get_type_id () != 0)
+    {
+      if (n->get_type_id () == NE_TYPEINFO::FONT)
+       return *n;
+      n = &n->next();
+    }
+    return Null(NE_TYPEINFO);
+  }
+
+  protected:
+  LEUINT16     alignmentShiftCount;
+  NE_TYPEINFO  chain;
+  // It is followed by an array of OT::ArrayOf<LEUINT8, LEUINT8> chars;
+  public:
+  DEFINE_SIZE_MIN (2);
+};
+
+// https://github.com/wine-mirror/wine/blob/master/include/winnt.h#L2467
+struct LE_IMAGE_OS2_HEADER
+{
+  inline bool sanitize (OT::hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) && (this+rsrctab).sanitize (c, base)));
+  }
+
+  inline const NE_RESOURCE_TABLE& get_resource_table () const
+  {
+    if (magic != 0x454E) // Only NE containers are support for now, NE == 0x454E
+      return Null(NE_RESOURCE_TABLE);
+    return this+rsrctab;
+  }
+
+  protected:
+  LEUINT16     magic;          /* 00 NE signature 'NE' */
+  LEUINT8      ver;            /* 02 Linker version number */
+  LEUINT8      rev;            /* 03 Linker revision number */
+  LEUINT16     enttab;         /* 04 Offset to entry table relative to NE */
+  LEUINT16     cbenttab;       /* 06 Length of entry table in bytes */
+  LEUINT32     crc;            /* 08 Checksum */
+  LEUINT16     flags;          /* 0c Flags about segments in this file */
+  LEUINT16     autodata;       /* 0e Automatic data segment number */
+  LEUINT16     heap;           /* 10 Initial size of local heap */
+  LEUINT16     stack;          /* 12 Initial size of stack */
+  LEUINT32     csip;           /* 14 Initial CS:IP */
+  LEUINT32     sssp;           /* 18 Initial SS:SP */
+  LEUINT16     cseg;           /* 1c # of entries in segment table */
+  LEUINT16     cmod;           /* 1e # of entries in module reference tab. */
+  LEUINT16     cbnrestab;      /* 20 Length of nonresident-name table     */
+  LEUINT16     segtab;         /* 22 Offset to segment table */
+  OT::OffsetTo<NE_RESOURCE_TABLE, LEUINT16>
+               rsrctab;        /* 24 Offset to resource table */
+  LEUINT16     restab;         /* 26 Offset to resident-name table */
+  LEUINT16     modtab;         /* 28 Offset to module reference table */
+  LEUINT16     imptab;         /* 2a Offset to imported name table */
+  LEUINT32     nrestab;        /* 2c Offset to nonresident-name table */
+  LEUINT16     cmovent;        /* 30 # of movable entry points */
+  LEUINT16     align;          /* 32 Logical sector alignment shift count */
+  LEUINT16     cres;           /* 34 # of resource segments */
+  LEUINT8      exetyp;         /* 36 Flags indicating target OS */
+  LEUINT8      flagsothers;    /* 37 Additional information flags */
+  LEUINT16     pretthunks;     /* 38 Offset to return thunks */
+  LEUINT16     psegrefbytes;   /* 3a Offset to segment ref. bytes */
+  LEUINT16     swaparea;       /* 3c Reserved by Microsoft */
+  LEUINT16     expver;         /* 3e Expected Windows version number */
+  public:
+  DEFINE_SIZE_STATIC (64);
+};
+
+struct LE_IMAGE_DOS_HEADER {
+  inline bool sanitize (OT::hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) &&
+                         get_os2_header ().sanitize (c, this)));
+  }
+
+  inline const LE_IMAGE_OS2_HEADER& get_os2_header () const
+  {
+    return this+e_lfanew;
+  }
+
+  protected:
+  LEUINT16     e_magic;        // Magic number
+  LEUINT16     e_cblp;         // Bytes on last page of file
+  LEUINT16     e_cp;           // Pages in file
+  LEUINT16     e_crlc;         // Relocations
+  LEUINT16     e_cparhdr;      // Size of header in paragraphs
+  LEUINT16     e_minalloc;     // Minimum extra paragraphs needed
+  LEUINT16     e_maxalloc;     // Maximum extra paragraphs needed
+  LEUINT16     e_ss;           // Initial (relative) SS value
+  LEUINT16     e_sp;           // Initial SP value
+  LEUINT16     e_csum;         // Checksum
+  LEUINT16     e_ip;           // Initial IP value
+  LEUINT16     e_cs;           // Initial (relative) CS value
+  LEUINT16     e_lfarlc;       // File address of relocation table
+  LEUINT16     e_ovno;         // Overlay number
+  LEUINT16     e_res_0;        // Reserved words
+  LEUINT16     e_res_1;        // Reserved words
+  LEUINT16     e_res_2;        // Reserved words
+  LEUINT16     e_res_3;        // Reserved words
+  LEUINT16     e_oemid;        // OEM identifier (for e_oeminfo)
+  LEUINT16     e_oeminfo;      // OEM information; e_oemid specific
+  LEUINT16     e_res2_0;       // Reserved words
+  LEUINT16     e_res2_1;       // Reserved words
+  LEUINT16     e_res2_2;       // Reserved words
+  LEUINT16     e_res2_3;       // Reserved words
+  LEUINT16     e_res2_4;       // Reserved words
+  LEUINT16     e_res2_5;       // Reserved words
+  LEUINT16     e_res2_6;       // Reserved words
+  LEUINT16     e_res2_7;       // Reserved words
+  LEUINT16     e_res2_8;       // Reserved words
+  LEUINT16     e_res2_9;       // Reserved words
+  OT::OffsetTo<LE_IMAGE_OS2_HEADER, LEUINT32>
+               e_lfanew;       // File address of new exe header
+  public:
+  DEFINE_SIZE_STATIC (64);
+};
+
+int main (int argc, char** argv) {
+  hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
+
+  OT::Sanitizer<LE_IMAGE_DOS_HEADER> sanitizer;
+  hb_blob_t *font_blob = sanitizer.sanitize (blob);
+  const LE_IMAGE_DOS_HEADER* dos_header = font_blob->as<LE_IMAGE_DOS_HEADER> ();
+
+  const NE_RESOURCE_TABLE &rtable = dos_header->get_os2_header ().get_resource_table ();
+  int shift = rtable.get_shift_value ();
+  const NE_TYPEINFO& entry = rtable.get_fonts_entry ();
+  for (unsigned int i = 0; i < entry.get_count (); ++i)
+  {
+    const LE_FONTINFO16& font = entry.get_font (i, dos_header, shift);
+    printf ("version: %x, weight: %d, charset: %s\n", font.get_version (),
+           font.get_weight (), font.get_charset ());
+    // font.dump ();
+  }
+  return 0;
+}
index 59bd760..ccecb40 100755 (executable)
@@ -1,13 +1,14 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 
-import sys
-import os.path
+from __future__ import print_function, division, absolute_import
+
+import io, os.path, sys
 
 if len (sys.argv) != 4:
-       print >>sys.stderr, "usage: ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt"
+       print ("usage: ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt", file=sys.stderr)
        sys.exit (1)
 
-files = [file (x) for x in sys.argv[1:]]
+files = [io.open (x, encoding='utf-8') for x in sys.argv[1:]]
 
 headers = [[files[0].readline (), files[0].readline ()], [files[2].readline (), files[2].readline ()]]
 headers.append (["UnicodeData.txt does not have a header."])
@@ -65,9 +66,9 @@ def print_joining_table(f):
                assert short not in short_value.values()
                short_value[value] = short
 
-       print
+       print ()
        for value,short in short_value.items():
-               print "#define %s       %s" % (short, value)
+               print ("#define %s      %s" % (short, value))
 
        uu = sorted(values.keys())
        num = len(values)
@@ -82,15 +83,15 @@ def print_joining_table(f):
                        ranges.append([u,u])
                last = u
 
-       print
-       print "static const uint8_t joining_table[] ="
-       print "{"
+       print ()
+       print ("static const uint8_t joining_table[] =")
+       print ("{")
        last_block = None
        offset = 0
        for start,end in ranges:
 
-               print
-               print "#define joining_offset_0x%04xu %d" % (start, offset)
+               print ()
+               print ("#define joining_offset_0x%04xu %d" % (start, offset))
 
                for u in range(start, end+1):
 
@@ -99,53 +100,53 @@ def print_joining_table(f):
 
                        if block != last_block or u == start:
                                if u != start:
-                                       print
+                                       print ()
                                if block in all_blocks:
-                                       print "\n  /* %s */" % block
+                                       print ("\n  /* %s */" % block)
                                else:
-                                       print "\n  /* FILLER */"
+                                       print ("\n  /* FILLER */")
                                last_block = block
                                if u % 32 != 0:
-                                       print
-                                       print "  /* %04X */" % (u//32*32), "  " * (u % 32),
+                                       print ()
+                                       print ("  /* %04X */" % (u//32*32), "  " * (u % 32), end="")
 
                        if u % 32 == 0:
-                               print
-                               print "  /* %04X */ " % u,
-                       sys.stdout.write("%s," % short_value[value])
-               print
+                               print ()
+                               print ("  /* %04X */ " % u, end="")
+                       print ("%s," % short_value[value], end="")
+               print ()
 
                offset += end - start + 1
-       print
+       print ()
        occupancy = num * 100. / offset
-       print "}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy)
-       print
+       print ("}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy))
+       print ()
 
        page_bits = 12;
-       print
-       print "static unsigned int"
-       print "joining_type (hb_codepoint_t u)"
-       print "{"
-       print "  switch (u >> %d)" % page_bits
-       print "  {"
+       print ()
+       print ("static unsigned int")
+       print ("joining_type (hb_codepoint_t u)")
+       print ("{")
+       print ("  switch (u >> %d)" % page_bits)
+       print ("  {")
        pages = set([u>>page_bits for u in [s for s,e in ranges]+[e for s,e in ranges]])
        for p in sorted(pages):
-               print "    case 0x%0Xu:" % p
+               print ("    case 0x%0Xu:" % p)
                for (start,end) in ranges:
                        if p not in [start>>page_bits, end>>page_bits]: continue
                        offset = "joining_offset_0x%04xu" % start
-                       print "      if (hb_in_range<hb_codepoint_t> (u, 0x%04Xu, 0x%04Xu)) return joining_table[u - 0x%04Xu + %s];" % (start, end, start, offset)
-               print "      break;"
-               print ""
-       print "    default:"
-       print "      break;"
-       print "  }"
-       print "  return X;"
-       print "}"
-       print
+                       print ("      if (hb_in_range<hb_codepoint_t> (u, 0x%04Xu, 0x%04Xu)) return joining_table[u - 0x%04Xu + %s];" % (start, end, start, offset))
+               print ("      break;")
+               print ("")
+       print ("    default:")
+       print ("      break;")
+       print ("  }")
+       print ("  return X;")
+       print ("}")
+       print ()
        for value,short in short_value.items():
-               print "#undef %s" % (short)
-       print
+               print ("#undef %s" % (short))
+       print ()
 
 def print_shaping_table(f):
 
@@ -186,9 +187,9 @@ def print_shaping_table(f):
                                shapes[items[0]] = {}
                        shapes[items[0]][shape] = c
 
-       print
-       print "static const uint16_t shaping_table[][4] ="
-       print "{"
+       print ()
+       print ("static const uint16_t shaping_table[][4] =")
+       print ("{")
 
        keys = shapes.keys ()
        min_u, max_u = min (keys), max (keys)
@@ -196,13 +197,13 @@ def print_shaping_table(f):
                s = [shapes[u][shape] if u in shapes and shape in shapes[u] else 0
                     for shape in  ['initial', 'medial', 'final', 'isolated']]
                value = ', '.join ("0x%04Xu" % c for c in s)
-               print "  {%s}, /* U+%04X %s */" % (value, u, names[u] if u in names else "")
+               print ("  {%s}, /* U+%04X %s */" % (value, u, names[u] if u in names else ""))
 
-       print "};"
-       print
-       print "#define SHAPING_TABLE_FIRST      0x%04Xu" % min_u
-       print "#define SHAPING_TABLE_LAST       0x%04Xu" % max_u
-       print
+       print ("};")
+       print ()
+       print ("#define SHAPING_TABLE_FIRST     0x%04Xu" % min_u)
+       print ("#define SHAPING_TABLE_LAST      0x%04Xu" % max_u)
+       print ()
 
        ligas = {}
        for pair in ligatures.keys ():
@@ -218,52 +219,49 @@ def print_shaping_table(f):
                                ligas[liga[0]] = []
                        ligas[liga[0]].append ((liga[1], c))
        max_i = max (len (ligas[l]) for l in ligas)
-       print
-       print "static const struct ligature_set_t {"
-       print " uint16_t first;"
-       print " struct ligature_pairs_t {"
-       print "   uint16_t second;"
-       print "   uint16_t ligature;"
-       print " } ligatures[%d];" % max_i
-       print "} ligature_table[] ="
-       print "{"
-       keys = ligas.keys ()
-       keys.sort ()
-       for first in keys:
-
-               print "  { 0x%04Xu, {" % (first)
+       print ()
+       print ("static const struct ligature_set_t {")
+       print (" uint16_t first;")
+       print (" struct ligature_pairs_t {")
+       print ("   uint16_t second;")
+       print ("   uint16_t ligature;")
+       print (" } ligatures[%d];" % max_i)
+       print ("} ligature_table[] =")
+       print ("{")
+       for first in sorted (ligas.keys ()):
+
+               print ("  { 0x%04Xu, {" % (first))
                for liga in ligas[first]:
-                       print "    { 0x%04Xu, 0x%04Xu }, /* %s */" % (liga[0], liga[1], names[liga[1]])
-               print "  }},"
+                       print ("    { 0x%04Xu, 0x%04Xu }, /* %s */" % (liga[0], liga[1], names[liga[1]]))
+               print ("  }},")
 
-       print "};"
-       print
+       print ("};")
+       print ()
 
 
 
-print "/* == Start of generated table == */"
-print "/*"
-print " * The following table is generated by running:"
-print " *"
-print " *   ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt"
-print " *"
-print " * on files with these headers:"
-print " *"
+print ("/* == Start of generated table == */")
+print ("/*")
+print (" * The following table is generated by running:")
+print (" *")
+print (" *   ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt")
+print (" *")
+print (" * on files with these headers:")
+print (" *")
 for h in headers:
        for l in h:
-               print " * %s" % (l.strip())
-print " */"
-print
-print "#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH"
-print "#define HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH"
-print
+               print (" * %s" % (l.strip()))
+print (" */")
+print ()
+print ("#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH")
+print ("#define HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH")
+print ()
 
 read_blocks (files[2])
 print_joining_table (files[0])
 print_shaping_table (files[1])
 
-print
-print "#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH */"
-print
-print "/* == End of generated table == */"
-
+print ()
+print ("#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH */")
+print ()
+print ("/* == End of generated table == */")
index 1673537..9a997d6 100755 (executable)
@@ -1,13 +1,13 @@
 #!/usr/bin/env python
 
-from __future__ import print_function
+from __future__ import print_function, division, absolute_import
 
 import io, os, re, sys
 
 headers_content = []
 for h in os.environ["headers"].split (' '):
        if h.endswith (".h"):
-               with io.open(h, encoding='utf8') as f: headers_content.append (f.read ())
+               with io.open (h, encoding='utf-8') as f: headers_content.append (f.read ())
 
 result = """EXPORTS
 %s
index 735b901..6252664 100755 (executable)
@@ -1,9 +1,11 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 
-import sys
+from __future__ import print_function, division, absolute_import
+
+import io, sys
 
 if len (sys.argv) != 4:
-       print >>sys.stderr, "usage: ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt"
+       print ("usage: ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt", file=sys.stderr)
        sys.exit (1)
 
 ALLOWED_SINGLES = [0x00A0, 0x25CC]
@@ -30,7 +32,7 @@ ALLOWED_BLOCKS = [
        'Myanmar Extended-A',
 ]
 
-files = [file (x) for x in sys.argv[1:]]
+files = [io.open (x, encoding='utf-8') for x in sys.argv[1:]]
 
 headers = [[f.readline () for i in range (2)] for f in files]
 
@@ -87,21 +89,21 @@ for u in ALLOWED_SINGLES:
        singles[u] = data[u]
        del data[u]
 
-print "/* == Start of generated table == */"
-print "/*"
-print " * The following table is generated by running:"
-print " *"
-print " *   ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt"
-print " *"
-print " * on files with these headers:"
-print " *"
+print ("/* == Start of generated table == */")
+print ("/*")
+print (" * The following table is generated by running:")
+print (" *")
+print (" *   ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt")
+print (" *")
+print (" * on files with these headers:")
+print (" *")
 for h in headers:
        for l in h:
-               print " * %s" % (l.strip())
-print " */"
-print
-print '#include "hb-ot-shape-complex-indic-private.hh"'
-print
+               print (" * %s" % (l.strip()))
+print (" */")
+print ()
+print ('#include "hb-ot-shape-complex-indic-private.hh"')
+print ()
 
 # Shorten values
 short = [{
@@ -130,9 +132,8 @@ for i in range (2):
 what = ["INDIC_SYLLABIC_CATEGORY", "INDIC_MATRA_CATEGORY"]
 what_short = ["ISC", "IMC"]
 for i in range (2):
-       print
-       vv = values[i].keys ()
-       vv.sort ()
+       print ()
+       vv = sorted (values[i].keys ())
        for v in vv:
                v_no_and = v.replace ('_And_', '_')
                if v in short[i]:
@@ -143,14 +144,14 @@ for i in range (2):
                                raise Exception ("Duplicate short value alias", v, all_shorts[i][s])
                        all_shorts[i][s] = v
                        short[i][v] = s
-               print "#define %s_%s    %s_%s   %s/* %3d chars; %s */" % \
-                       (what_short[i], s, what[i], v.upper (), \
-                       '       '* ((48-1 - len (what[i]) - 1 - len (v)) / 8), \
-                       values[i][v], v)
-print
-print "#define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M)"
-print
-print
+               print ("#define %s_%s   %s_%s   %s/* %3d chars; %s */" %
+                       (what_short[i], s, what[i], v.upper (),
+                       '       '* ((48-1 - len (what[i]) - 1 - len (v)) // 8),
+                       values[i][v], v))
+print ()
+print ("#define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M)")
+print ()
+print ()
 
 total = 0
 used = 0
@@ -158,35 +159,34 @@ last_block = None
 def print_block (block, start, end, data):
        global total, used, last_block
        if block and block != last_block:
-               print
-               print
-               print "  /* %s */" % block
+               print ()
+               print ()
+               print ("  /* %s */" % block)
        num = 0
        assert start % 8 == 0
        assert (end+1) % 8 == 0
        for u in range (start, end+1):
                if u % 8 == 0:
-                       print
-                       print "  /* %04X */" % u,
+                       print ()
+                       print ("  /* %04X */" % u, end="")
                if u in data:
                        num += 1
                d = data.get (u, defaults)
-               sys.stdout.write ("%9s" % ("_(%s,%s)," % (short[0][d[0]], short[1][d[1]])))
+               print ("%9s" % ("_(%s,%s)," % (short[0][d[0]], short[1][d[1]])), end="")
 
        total += end - start + 1
        used += num
        if block:
                last_block = block
 
-uu = data.keys ()
-uu.sort ()
+uu = sorted (data.keys ())
 
 last = -100000
 num = 0
 offset = 0
 starts = []
 ends = []
-print "static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {"
+print ("static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {")
 for u in uu:
        if u <= last:
                continue
@@ -206,54 +206,53 @@ for u in uu:
                        if last >= 0:
                                ends.append (last + 1)
                                offset += ends[-1] - starts[-1]
-                       print
-                       print
-                       print "#define indic_offset_0x%04xu %d" % (start, offset)
+                       print ()
+                       print ()
+                       print ("#define indic_offset_0x%04xu %d" % (start, offset))
                        starts.append (start)
 
        print_block (block, start, end, data)
        last = end
 ends.append (last + 1)
 offset += ends[-1] - starts[-1]
-print
-print
+print ()
+print ()
 occupancy = used * 100. / total
 page_bits = 12
-print "}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy)
-print
-print "INDIC_TABLE_ELEMENT_TYPE"
-print "hb_indic_get_categories (hb_codepoint_t u)"
-print "{"
-print "  switch (u >> %d)" % page_bits
-print "  {"
-pages = set([u>>page_bits for u in starts+ends+singles.keys()])
+print ("}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy))
+print ()
+print ("INDIC_TABLE_ELEMENT_TYPE")
+print ("hb_indic_get_categories (hb_codepoint_t u)")
+print ("{")
+print ("  switch (u >> %d)" % page_bits)
+print ("  {")
+pages = set ([u>>page_bits for u in starts+ends+list (singles.keys ())])
 for p in sorted(pages):
-       print "    case 0x%0Xu:" % p
+       print ("    case 0x%0Xu:" % p)
        for u,d in singles.items ():
                if p != u>>page_bits: continue
-               print "      if (unlikely (u == 0x%04Xu)) return _(%s,%s);" % (u, short[0][d[0]], short[1][d[1]])
+               print ("      if (unlikely (u == 0x%04Xu)) return _(%s,%s);" % (u, short[0][d[0]], short[1][d[1]]))
        for (start,end) in zip (starts, ends):
                if p not in [start>>page_bits, end>>page_bits]: continue
                offset = "indic_offset_0x%04xu" % start
-               print "      if (hb_in_range<hb_codepoint_t> (u, 0x%04Xu, 0x%04Xu)) return indic_table[u - 0x%04Xu + %s];" % (start, end-1, start, offset)
-       print "      break;"
-       print ""
-print "    default:"
-print "      break;"
-print "  }"
-print "  return _(x,x);"
-print "}"
-print
-print "#undef _"
+               print ("      if (hb_in_range<hb_codepoint_t> (u, 0x%04Xu, 0x%04Xu)) return indic_table[u - 0x%04Xu + %s];" % (start, end-1, start, offset))
+       print ("      break;")
+       print ("")
+print ("    default:")
+print ("      break;")
+print ("  }")
+print ("  return _(x,x);")
+print ("}")
+print ()
+print ("#undef _")
 for i in range (2):
        print
-       vv = values[i].keys ()
-       vv.sort ()
+       vv = sorted (values[i].keys ())
        for v in vv:
-               print "#undef %s_%s" % \
-                       (what_short[i], short[i][v])
-print
-print "/* == End of generated table == */"
+               print ("#undef %s_%s" %
+                       (what_short[i], short[i][v]))
+print ()
+print ("/* == End of generated table == */")
 
 # Maintain at least 30% occupancy in the table */
 if occupancy < 30:
index 0681725..6aa5f88 100755 (executable)
@@ -1,14 +1,16 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 
-import sys
+from __future__ import print_function, division, absolute_import
+
+import io, sys
 
 if len (sys.argv) != 5:
-       print >>sys.stderr, "usage: ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt"
+       print ("usage: ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt", file=sys.stderr)
        sys.exit (1)
 
 BLACKLISTED_BLOCKS = ["Thai", "Lao", "Tibetan"]
 
-files = [file (x) for x in sys.argv[1:]]
+files = [io.open (x, encoding='utf-8') for x in sys.argv[1:]]
 
 headers = [[f.readline () for i in range (2)] for j,f in enumerate(files) if j != 2]
 headers.append (["UnicodeData.txt does not have a header."])
@@ -93,6 +95,7 @@ property_names = [
        'Consonant_Medial',
        'Consonant_Final',
        'Consonant_Head_Letter',
+       'Consonant_Initial_Postfixed',
        'Modifying_Letter',
        'Tone_Letter',
        'Tone_Mark',
@@ -124,6 +127,11 @@ property_names = [
        'Overstruck',
 ]
 
+try:
+       basestring
+except NameError:
+       basestring = str
+
 class PropertyValue(object):
        def __init__(self, name_):
                self.name = name_
@@ -133,6 +141,8 @@ class PropertyValue(object):
                return self.name == (other if isinstance(other, basestring) else other.name)
        def __ne__(self, other):
                return not (self == other)
+       def __hash__(self):
+               return hash(str(self))
 
 property_values = {}
 
@@ -155,7 +165,7 @@ def is_BASE(U, UISC, UGC):
 def is_BASE_IND(U, UISC, UGC):
        #SPEC-DRAFT return (UISC in [Consonant_Dead, Modifying_Letter] or UGC == Po)
        return (UISC in [Consonant_Dead, Modifying_Letter] or
-               (UGC == Po and not U in [0x104E, 0x2022, 0x11A3F, 0x11A45]) or
+               (UGC == Po and not U in [0x104B, 0x104E, 0x2022, 0x11A3F, 0x11A45]) or
                False # SPEC-DRAFT-OUTDATED! U == 0x002D
                )
 def is_BASE_NUM(U, UISC, UGC):
@@ -167,7 +177,9 @@ def is_BASE_OTHER(U, UISC, UGC):
 def is_CGJ(U, UISC, UGC):
        return U == 0x034F
 def is_CONS_FINAL(U, UISC, UGC):
+       # Consonant_Initial_Postfixed is new in Unicode 11; not in the spec.
        return ((UISC == Consonant_Final and UGC != Lo) or
+               UISC == Consonant_Initial_Postfixed or
                UISC == Consonant_Succeeding_Repha)
 def is_CONS_FINAL_MOD(U, UISC, UGC):
        #SPEC-DRAFT return  UISC in [Consonant_Final_Modifier, Syllable_Modifier]
@@ -325,17 +337,18 @@ def map_to_use(data):
                # TODO: These should die, but have UIPC in Unicode 8.0
                if U in [0x953, 0x954]: UIPC = Not_Applicable
 
-               # TODO: In USE's override list but not in Unicode 8.0
+               # TODO: In USE's override list but not in Unicode 11.0
                if U == 0x103C: UIPC = Left
 
-               # TODO: These are not in USE's override list that we have, nor are they in Unicode 8.0
+               # TODO: These are not in USE's override list that we have, nor are they in Unicode 11.0
                if 0xA926 <= U <= 0xA92A: UIPC = Top
                if U == 0x111CA: UIPC = Bottom
                if U == 0x11300: UIPC = Top
-               if U == 0x1133C: UIPC = Bottom
                if U == 0x1171E: UIPC = Left # Correct?!
                if 0x1CF2 <= U <= 0x1CF3: UIPC = Right
                if 0x1CF8 <= U <= 0x1CF9: UIPC = Top
+               # https://github.com/roozbehp/unicode-data/issues/8
+               if U == 0x0A51: UIPC = Bottom
 
                assert (UIPC in [Not_Applicable, Visual_Order_Left] or
                        USE in use_positions), "%s %s %s %s %s" % (hex(U), UIPC, USE, UISC, UGC)
@@ -352,21 +365,21 @@ def map_to_use(data):
 defaults = ('O', 'No_Block')
 data = map_to_use(data)
 
-print "/* == Start of generated table == */"
-print "/*"
-print " * The following table is generated by running:"
-print " *"
-print " *   ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt"
-print " *"
-print " * on files with these headers:"
-print " *"
+print ("/* == Start of generated table == */")
+print ("/*")
+print (" * The following table is generated by running:")
+print (" *")
+print (" *   ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt")
+print (" *")
+print (" * on files with these headers:")
+print (" *")
 for h in headers:
        for l in h:
-               print " * %s" % (l.strip())
-print " */"
-print
-print '#include "hb-ot-shape-complex-use-private.hh"'
-print
+               print (" * %s" % (l.strip()))
+print (" */")
+print ()
+print ('#include "hb-ot-shape-complex-use-private.hh"')
+print ()
 
 total = 0
 used = 0
@@ -374,30 +387,29 @@ last_block = None
 def print_block (block, start, end, data):
        global total, used, last_block
        if block and block != last_block:
-               print
-               print
-               print "  /* %s */" % block
+               print ()
+               print ()
+               print ("  /* %s */" % block)
                if start % 16:
-                       print ' ' * (20 + (start % 16 * 6)),
+                       print (' ' * (20 + (start % 16 * 6)), end='')
        num = 0
        assert start % 8 == 0
        assert (end+1) % 8 == 0
        for u in range (start, end+1):
                if u % 16 == 0:
-                       print
-                       print "  /* %04X */" % u,
+                       print ()
+                       print ("  /* %04X */" % u, end='')
                if u in data:
                        num += 1
                d = data.get (u, defaults)
-               sys.stdout.write ("%6s," % d[0])
+               print ("%6s," % d[0], end='')
 
        total += end - start + 1
        used += num
        if block:
                last_block = block
 
-uu = data.keys ()
-uu.sort ()
+uu = sorted (data.keys ())
 
 last = -100000
 num = 0
@@ -406,14 +418,14 @@ starts = []
 ends = []
 for k,v in sorted(use_mapping.items()):
        if k in use_positions and use_positions[k]: continue
-       print "#define %s       USE_%s  /* %s */" % (k, k, v.__name__[3:])
+       print ("#define %s      USE_%s  /* %s */" % (k, k, v.__name__[3:]))
 for k,v in sorted(use_positions.items()):
        if not v: continue
        for suf in v.keys():
                tag = k + suf
-               print "#define %s       USE_%s" % (tag, tag)
-print ""
-print "static const USE_TABLE_ELEMENT_TYPE use_table[] = {"
+               print ("#define %s      USE_%s" % (tag, tag))
+print ("")
+print ("static const USE_TABLE_ELEMENT_TYPE use_table[] = {")
 for u in uu:
        if u <= last:
                continue
@@ -433,51 +445,51 @@ for u in uu:
                        if last >= 0:
                                ends.append (last + 1)
                                offset += ends[-1] - starts[-1]
-                       print
-                       print
-                       print "#define use_offset_0x%04xu %d" % (start, offset)
+                       print ()
+                       print ()
+                       print ("#define use_offset_0x%04xu %d" % (start, offset))
                        starts.append (start)
 
        print_block (block, start, end, data)
        last = end
 ends.append (last + 1)
 offset += ends[-1] - starts[-1]
-print
-print
+print ()
+print ()
 occupancy = used * 100. / total
 page_bits = 12
-print "}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy)
-print
-print "USE_TABLE_ELEMENT_TYPE"
-print "hb_use_get_category (hb_codepoint_t u)"
-print "{"
-print "  switch (u >> %d)" % page_bits
-print "  {"
+print ("}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy))
+print ()
+print ("USE_TABLE_ELEMENT_TYPE")
+print ("hb_use_get_category (hb_codepoint_t u)")
+print ("{")
+print ("  switch (u >> %d)" % page_bits)
+print ("  {")
 pages = set([u>>page_bits for u in starts+ends])
 for p in sorted(pages):
-       print "    case 0x%0Xu:" % p
+       print ("    case 0x%0Xu:" % p)
        for (start,end) in zip (starts, ends):
                if p not in [start>>page_bits, end>>page_bits]: continue
                offset = "use_offset_0x%04xu" % start
-               print "      if (hb_in_range<hb_codepoint_t> (u, 0x%04Xu, 0x%04Xu)) return use_table[u - 0x%04Xu + %s];" % (start, end-1, start, offset)
-       print "      break;"
-       print ""
-print "    default:"
-print "      break;"
-print "  }"
-print "  return USE_O;"
-print "}"
-print
+               print ("      if (hb_in_range<hb_codepoint_t> (u, 0x%04Xu, 0x%04Xu)) return use_table[u - 0x%04Xu + %s];" % (start, end-1, start, offset))
+       print ("      break;")
+       print ("")
+print ("    default:")
+print ("      break;")
+print ("  }")
+print ("  return USE_O;")
+print ("}")
+print ()
 for k in sorted(use_mapping.keys()):
        if k in use_positions and use_positions[k]: continue
-       print "#undef %s" % k
+       print ("#undef %s" % k)
 for k,v in sorted(use_positions.items()):
        if not v: continue
        for suf in v.keys():
                tag = k + suf
-               print "#undef %s" % tag
-print
-print "/* == End of generated table == */"
+               print ("#undef %s" % tag)
+print ()
+print ("/* == End of generated table == */")
 
 # Maintain at least 50% occupancy in the table */
 if occupancy < 50:
diff --git a/src/hb-aat-fmtx-table.hh b/src/hb-aat-fmtx-table.hh
new file mode 100644 (file)
index 0000000..aa82c88
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright © 2018  Ebrahim Byagowi
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef HB_AAT_FMTX_TABLE_HH
+#define HB_AAT_FMTX_TABLE_HH
+
+#include "hb-aat-layout-common-private.hh"
+
+/*
+ * fmtx -- Font Metrics
+ * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6fmtx.html
+ */
+#define HB_AAT_TAG_fmtx HB_TAG('f','m','t','x')
+
+
+namespace AAT {
+
+
+struct fmtx
+{
+  static const hb_tag_t tableTag = HB_AAT_TAG_fmtx;
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this)));
+  }
+
+  FixedVersion<>version;               /* Version (set to 0x00020000). */
+  HBUINT32     glyphIndex;             /* The glyph whose points represent the metrics. */
+  HBUINT8      horizontalBefore;       /* Point number for the horizontal ascent. */
+  HBUINT8      horizontalAfter;        /* Point number for the horizontal descent. */
+  HBUINT8      horizontalCaretHead;    /* Point number for the horizontal caret head. */
+  HBUINT8      horizontalCaretBase;    /* Point number for the horizontal caret base. */
+  HBUINT8      verticalBefore;         /* Point number for the vertical ascent. */
+  HBUINT8      verticalAfter;          /* Point number for the vertical descent. */
+  HBUINT8      verticalCaretHead;      /* Point number for the vertical caret head. */
+  HBUINT8      verticalCaretBase;      /* Point number for the vertical caret base. */
+  public:
+  DEFINE_SIZE_STATIC (16);
+};
+
+} /* namespace AAT */
+
+
+#endif /* HB_AAT_FMTX_TABLE_HH */
diff --git a/src/hb-aat-gcid-table.hh b/src/hb-aat-gcid-table.hh
new file mode 100644 (file)
index 0000000..b48a279
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright © 2018  Ebrahim Byagowi
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef HB_AAT_GCID_TABLE_HH
+#define HB_AAT_GCID_TABLE_HH
+
+#include "hb-aat-layout-common-private.hh"
+
+/*
+ * gcid -- Glyphs CIDs
+ * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6gcid.html
+ */
+#define HB_AAT_TAG_gcid HB_TAG('g','c','i','d')
+
+
+namespace AAT {
+
+
+struct gcid
+{
+  static const hb_tag_t tableTag = HB_AAT_TAG_gcid;
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) && CIDs.sanitize (c)));
+  }
+
+  protected:
+  HBUINT16     version;        /* Version number (set to 0) */
+  HBUINT16     format;         /* Data format (set to 0) */
+  HBUINT32     size;           /* Size of the table, including header */
+  HBUINT16     registry;       /* The registry ID */
+  HBUINT8      registryName[64];
+                               /* The registry name in ASCII */
+  HBUINT16     order;          /* The order ID */
+  HBUINT8      orderName[64];  /* The order name in ASCII */
+  HBUINT16     supplementVersion;
+                               /* The supplement version */
+  ArrayOf<HBUINT16>
+               CIDs;           /* The CIDs for the glyphs in the font,
+                                * starting with glyph 0. If a glyph does not correspond
+                                * to a CID in the identified collection, 0xFFFF is used.
+                                * This should not exceed the number of glyphs in the font. */
+  public:
+  DEFINE_SIZE_ARRAY (144, CIDs);
+};
+
+} /* namespace AAT */
+
+
+#endif /* HB_AAT_GCID_TABLE_HH */
index d0453bd..3b7912b 100644 (file)
 
 #include "hb-aat-layout-common-private.hh"
 
+/*
+ * ankr -- Anchor Point
+ * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6ankr.html
+ */
 #define HB_AAT_TAG_ankr HB_TAG('a','n','k','r')
 
 
 namespace AAT {
 
 
-/*
- * ankr -- Anchor point
- */
-
 struct Anchor
 {
   inline bool sanitize (hb_sanitize_context_t *c) const
@@ -58,17 +58,19 @@ struct ankr
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && version == 0 &&
-                 lookupTable.sanitize (c, this) &&
-                 anchors.sanitize (c, this));
+    return_trace (likely (c->check_struct (this) &&
+                         version == 0 &&
+                         lookupTable.sanitize (c, this) &&
+                         anchors.sanitize (c, this)));
   }
 
   protected:
-  HBUINT16                     version;        /* Version number (set to zero) */
-  HBUINT16                     flags;          /* Flags (currently unused; set to zero) */
-  LOffsetTo<Lookup<HBUINT16> > lookupTable;    /* Offset to the table's lookup table */
-  LOffsetTo<ArrayOf<Anchor, HBUINT32> >
-                               anchors;        /* Offset to the glyph data table */
+  HBUINT16     version;        /* Version number (set to zero) */
+  HBUINT16     flags;          /* Flags (currently unused; set to zero) */
+  LOffsetTo<Lookup<HBUINT16> >
+               lookupTable;    /* Offset to the table's lookup table */
+  LOffsetTo<LArrayOf<Anchor> >
+               anchors;        /* Offset to the glyph data table */
 
   public:
   DEFINE_SIZE_STATIC (12);
diff --git a/src/hb-aat-layout-bsln-table.hh b/src/hb-aat-layout-bsln-table.hh
new file mode 100644 (file)
index 0000000..df2bf5b
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright © 2018  Ebrahim Byagowi
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef HB_AAT_LAYOUT_BSLN_TABLE_HH
+#define HB_AAT_LAYOUT_BSLN_TABLE_HH
+
+#include "hb-aat-layout-common-private.hh"
+
+/*
+ * bsln -- Baseline
+ * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6bsln.html
+ */
+#define HB_AAT_TAG_bsln HB_TAG('b','s','l','n')
+
+
+namespace AAT {
+
+
+struct BaselineTableFormat0Part
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this)));
+  }
+
+  protected:
+  // Roman, Ideographic centered, Ideographic low, Hanging and Math
+  // are the default defined ones, but any other maybe accessed also.
+  HBINT16      deltas[32];     /* These are the FUnit distance deltas from
+                                * the font's natural baseline to the other
+                                * baselines used in the font. */
+  public:
+  DEFINE_SIZE_STATIC (64);
+};
+
+struct BaselineTableFormat1Part
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) &&
+                         lookupTable.sanitize (c)));
+  }
+
+  protected:
+  HBINT16      deltas[32];     /* ditto */
+  Lookup<HBUINT16>
+               lookupTable;    /* Lookup table that maps glyphs to their
+                                * baseline values. */
+  public:
+  DEFINE_SIZE_MIN (66);
+};
+
+struct BaselineTableFormat2Part
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this)));
+  }
+
+  protected:
+  GlyphID      stdGlyph;       /* The specific glyph index number in this
+                                * font that is used to set the baseline values.
+                                * This is the standard glyph.
+                                * This glyph must contain a set of control points
+                                * (whose numbers are contained in the ctlPoints field)
+                                * that are used to determine baseline distances. */
+  HBUINT16     ctlPoints[32];  /* Set of control point numbers,
+                                * associated with the standard glyph.
+                                * A value of 0xFFFF means there is no corresponding
+                                * control point in the standard glyph. */
+  public:
+  DEFINE_SIZE_STATIC (66);
+};
+
+struct BaselineTableFormat3Part
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && lookupTable.sanitize (c));
+  }
+
+  protected:
+  GlyphID      stdGlyph;       /* ditto */
+  HBUINT16     ctlPoints[32];  /* ditto */
+  Lookup<HBUINT16>
+               lookupTable;    /* Lookup table that maps glyphs to their
+                                * baseline values. */
+  public:
+  DEFINE_SIZE_MIN (68);
+};
+
+struct bsln
+{
+  static const hb_tag_t tableTag = HB_AAT_TAG_bsln;
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!(c->check_struct (this) && defaultBaseline < 32)))
+      return_trace (false);
+
+    switch (format) {
+    case 0: return_trace (parts.format0.sanitize (c));
+    case 1: return_trace (parts.format1.sanitize (c));
+    case 2: return_trace (parts.format2.sanitize (c));
+    case 3: return_trace (parts.format3.sanitize (c));
+    default:return_trace (true);
+    }
+  }
+
+  protected:
+  FixedVersion<>version;       /* Version number of the Baseline table. */
+  HBUINT16     format;         /* Format of the baseline table. Only one baseline
+                                * format may be selected for the font. */
+  HBUINT16     defaultBaseline;/* Default baseline value for all glyphs.
+                                * This value can be from 0 through 31. */
+  union {
+  // Distance-Based Formats
+  BaselineTableFormat0Part     format0;
+  BaselineTableFormat1Part     format1;
+  // Control Point-based Formats
+  BaselineTableFormat2Part     format2;
+  BaselineTableFormat3Part     format3;
+  } parts;
+  public:
+  DEFINE_SIZE_MIN (8);
+};
+
+} /* namespace AAT */
+
+
+#endif /* HB_AAT_LAYOUT_BSLN_TABLE_HH */
index 7c0dfa8..2825b18 100644 (file)
@@ -67,11 +67,11 @@ struct BinSearchArrayOf
   inline const Type& operator [] (unsigned int i) const
   {
     if (unlikely (i >= header.nUnits)) return Null(Type);
-    return StructAtOffset<Type> (bytes, i * header.unitSize);
+    return StructAtOffset<Type> (bytesZ, i * header.unitSize);
   }
   inline Type& operator [] (unsigned int i)
   {
-    return StructAtOffset<Type> (bytes, i * header.unitSize);
+    return StructAtOffset<Type> (bytesZ, i * header.unitSize);
   }
   inline unsigned int get_size (void) const
   { return header.static_size + header.nUnits * header.unitSize; }
@@ -88,7 +88,7 @@ struct BinSearchArrayOf
      * pointed to do have a simple sanitize(), ie. they do not
      * reference other structs via offsets.
      */
-    (void) (false && StructAtOffset<Type> (bytes, 0).sanitize (c));
+    (void) (false && StructAtOffset<Type> (bytesZ, 0).sanitize (c));
 
     return_trace (true);
   }
@@ -111,7 +111,7 @@ struct BinSearchArrayOf
     while (min <= max)
     {
       int mid = (min + max) / 2;
-      const Type *p = (const Type *) (((const char *) bytes) + (mid * size));
+      const Type *p = (const Type *) (((const char *) bytesZ) + (mid * size));
       int c = p->cmp (key);
       if (c < 0)
        max = mid - 1;
@@ -129,98 +129,14 @@ struct BinSearchArrayOf
     TRACE_SANITIZE (this);
     return_trace (header.sanitize (c) &&
                  Type::static_size >= header.unitSize &&
-                 c->check_array (bytes, header.unitSize, header.nUnits));
+                 c->check_array (bytesZ, header.unitSize, header.nUnits));
   }
 
   protected:
   BinSearchHeader      header;
-  HBUINT8                      bytes[VAR];
+  HBUINT8              bytesZ[VAR];
   public:
-  DEFINE_SIZE_ARRAY (10, bytes);
-};
-
-
-/* TODO Move this to hb-open-type-private.hh and use it in ArrayOf, HeadlessArrayOf,
- * and other places around the code base?? */
-template <typename Type>
-struct UnsizedArrayOf
-{
-  inline const Type& operator [] (unsigned int i) const { return arrayZ[i]; }
-  inline Type& operator [] (unsigned int i) { return arrayZ[i]; }
-
-  inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
-  {
-    TRACE_SANITIZE (this);
-    if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
-
-    /* Note: for structs that do not reference other structs,
-     * we do not need to call their sanitize() as we already did
-     * a bound check on the aggregate array size.  We just include
-     * a small unreachable expression to make sure the structs
-     * pointed to do have a simple sanitize(), ie. they do not
-     * reference other structs via offsets.
-     */
-    (void) (false && arrayZ[0].sanitize (c));
-
-    return_trace (true);
-  }
-  inline bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base) const
-  {
-    TRACE_SANITIZE (this);
-    if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
-    for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!arrayZ[i].sanitize (c, base)))
-        return_trace (false);
-    return_trace (true);
-  }
-  template <typename T>
-  inline bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base, T user_data) const
-  {
-    TRACE_SANITIZE (this);
-    if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
-    for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!arrayZ[i].sanitize (c, base, user_data)))
-        return_trace (false);
-    return_trace (true);
-  }
-
-  private:
-  inline bool sanitize_shallow (hb_sanitize_context_t *c, unsigned int count) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_array (arrayZ, arrayZ[0].static_size, count));
-  }
-
-  public:
-  Type arrayZ[VAR];
-  public:
-  DEFINE_SIZE_ARRAY (0, arrayZ);
-};
-
-/* Unsized array of offset's */
-template <typename Type, typename OffsetType>
-struct UnsizedOffsetArrayOf : UnsizedArrayOf<OffsetTo<Type, OffsetType> > {};
-
-/* Unsized array of offsets relative to the beginning of the array itself. */
-template <typename Type, typename OffsetType>
-struct UnsizedOffsetListOf : UnsizedOffsetArrayOf<Type, OffsetType>
-{
-  inline const Type& operator [] (unsigned int i) const
-  {
-    return this+this->arrayZ[i];
-  }
-
-  inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace ((UnsizedOffsetArrayOf<Type, OffsetType>::sanitize (c, count, this)));
-  }
-  template <typename T>
-  inline bool sanitize (hb_sanitize_context_t *c, unsigned int count, T user_data) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace ((UnsizedOffsetArrayOf<Type, OffsetType>::sanitize (c, count, this, user_data)));
-  }
+  DEFINE_SIZE_ARRAY (10, bytesZ);
 };
 
 
@@ -595,11 +511,11 @@ struct StateTable
   protected:
   HBUINT32     nClasses;       /* Number of classes, which is the number of indices
                                 * in a single line in the state array. */
-  OffsetTo<Lookup<HBUINT16>, HBUINT32>
+  LOffsetTo<Lookup<HBUINT16> >
                classTable;     /* Offset to the class table. */
-  OffsetTo<UnsizedArrayOf<HBUINT16>, HBUINT32>
+  LOffsetTo<UnsizedArrayOf<HBUINT16> >
                stateArrayTable;/* Offset to the state array. */
-  OffsetTo<UnsizedArrayOf<Entry<Extra> >, HBUINT32>
+  LOffsetTo<UnsizedArrayOf<Entry<Extra> > >
                entryTable;     /* Offset to the entry array. */
 
   public:
diff --git a/src/hb-aat-layout-feat-table.hh b/src/hb-aat-layout-feat-table.hh
new file mode 100644 (file)
index 0000000..3e070d7
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright © 2018  Ebrahim Byagowi
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef HB_AAT_LAYOUT_FEAT_TABLE_HH
+#define HB_AAT_LAYOUT_FEAT_TABLE_HH
+
+#include "hb-aat-layout-common-private.hh"
+
+/*
+ * feat -- Feature Name
+ * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6feat.html
+ */
+#define HB_AAT_TAG_feat HB_TAG('f','e','a','t')
+
+
+namespace AAT {
+
+
+struct SettingName
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this)));
+  }
+
+  protected:
+  HBUINT16     setting;        /* The setting. */
+  NameID       nameIndex;      /* The name table index for the setting's name. */
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+struct FeatureName
+{
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) &&
+                         (base+settingTable).sanitize (c, nSettings)));
+  }
+
+  enum {
+    Exclusive = 0x8000,                /* If set, the feature settings are mutually exclusive. */
+    NotDefault = 0x4000,       /* If clear, then the setting with an index of 0 in
+                                * the setting name array for this feature should
+                                * be taken as the default for the feature
+                                * (if one is required). If set, then bits 0-15 of this
+                                * featureFlags field contain the index of the setting
+                                * which is to be taken as the default. */
+    IndexMask = 0x00FF         /* If bits 30 and 31 are set, then these sixteen bits
+                                * indicate the index of the setting in the setting name
+                                * array for this feature which should be taken
+                                * as the default. */
+  };
+
+  protected:
+  HBUINT16     feature;        /* Feature type. */
+  HBUINT16     nSettings;      /* The number of records in the setting name array. */
+  LOffsetTo<UnsizedArrayOf<SettingName> >
+               settingTable;   /* Offset in bytes from the beginning of this table to
+                                * this feature's setting name array. The actual type of
+                                * record this offset refers to will depend on the
+                                * exclusivity value, as described below. */
+  HBUINT16     featureFlags;   /* Single-bit flags associated with the feature type. */
+  HBINT16      nameIndex;      /* The name table index for the feature's name.
+                                * This index has values greater than 255 and
+                                * less than 32768. */
+  public:
+  DEFINE_SIZE_STATIC (12);
+};
+
+struct feat
+{
+  static const hb_tag_t tableTag = HB_AAT_TAG_feat;
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) &&
+                         names.sanitize (c, featureNameCount, this)));
+  }
+
+  protected:
+  FixedVersion<>version;       /* Version number of the feature name table
+                                * (0x00010000 for the current version). */
+  HBUINT16     featureNameCount;
+                               /* The number of entries in the feature name array. */
+  HBUINT16     reserved1;      /* Reserved (set to zero). */
+  HBUINT32     reserved2;      /* Reserved (set to zero). */
+  UnsizedArrayOf<FeatureName>
+               names;          /* The feature name array. */
+  public:
+  DEFINE_SIZE_STATIC (24);
+};
+
+} /* namespace AAT */
+
+#endif /* HB_AAT_LAYOUT_FEAT_TABLE_HH */
index ce7ca10..cc03d62 100644 (file)
 
 #include "hb-open-type-private.hh"
 #include "hb-aat-layout-common-private.hh"
+#include "hb-aat-layout-ankr-table.hh"
 
-#define HB_AAT_TAG_KERX HB_TAG('k','e','r','x')
+/*
+ * kerx -- Extended Kerning
+ * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6kerx.html
+ */
+#define HB_AAT_TAG_kerx HB_TAG('k','e','r','x')
 
 
 namespace AAT {
@@ -44,7 +49,7 @@ struct KerxFormat0Records
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
+    return_trace (likely (c->check_struct (this)));
   }
 
   protected:
@@ -70,22 +75,23 @@ struct KerxSubTableFormat0
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-      c->check_array (records, records[0].static_size, nPairs));
+    return_trace (likely (c->check_struct (this) &&
+                         recordsZ.sanitize (c, nPairs)));
   }
 
   protected:
   // TODO(ebraminio): A custom version of "BinSearchArrayOf<KerxPair> pairs;" is
   // needed here to use HBUINT32 instead
-  HBUINT32 nPairs;     /* The number of kerning pairs in this subtable */
-  HBUINT32 searchRange; /* The largest power of two less than or equal to the value of nPairs,
-                         * multiplied by the size in bytes of an entry in the subtable. */
-  HBUINT32 entrySelector; /* This is calculated as log2 of the largest power of two less
-                           * than or equal to the value of nPairs. */
-  HBUINT32 rangeShift; /* The value of nPairs minus the largest power of two less than or equal to nPairs. */
-  KerxFormat0Records records[VAR]; /* VAR=nPairs */
+  HBUINT32     nPairs;         /* The number of kerning pairs in this subtable */
+  HBUINT32     searchRange;    /* The largest power of two less than or equal to the value of nPairs,
+                                * multiplied by the size in bytes of an entry in the subtable. */
+  HBUINT32     entrySelector;  /* This is calculated as log2 of the largest power of two less
+                                * than or equal to the value of nPairs. */
+  HBUINT32     rangeShift;     /* The value of nPairs minus the largest power of two less than or equal to nPairs. */
+  UnsizedArrayOf<KerxFormat0Records>
+               recordsZ;       /* VAR=nPairs */
   public:
-  DEFINE_SIZE_ARRAY (16, records);
+  DEFINE_SIZE_ARRAY (16, recordsZ);
 };
 
 struct KerxSubTableFormat1
@@ -93,8 +99,8 @@ struct KerxSubTableFormat1
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-      stateHeader.sanitize (c));
+    return_trace (likely (c->check_struct (this) &&
+                         stateHeader.sanitize (c)));
   }
 
   protected:
@@ -112,7 +118,8 @@ struct KerxClassTable
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (firstGlyph.sanitize (c) && classes.sanitize (c));
+    return_trace (likely (firstGlyph.sanitize (c) &&
+                         classes.sanitize (c)));
   }
 
   protected:
@@ -141,11 +148,11 @@ struct KerxSubTableFormat2
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-      rowWidth.sanitize (c) &&
-                 leftClassTable.sanitize (c, this) &&
-                 rightClassTable.sanitize (c, this) &&
-                 array.sanitize (c, this));
+    return_trace (likely (c->check_struct (this) &&
+                         rowWidth.sanitize (c) &&
+                         leftClassTable.sanitize (c, this) &&
+                         rightClassTable.sanitize (c, this) &&
+                         array.sanitize (c, this)));
   }
 
   protected:
@@ -168,11 +175,11 @@ struct KerxSubTableFormat4
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-      rowWidth.sanitize (c) &&
-                 leftClassTable.sanitize (c, this) &&
-                 rightClassTable.sanitize (c, this) &&
-                 array.sanitize (c, this));
+    return_trace (likely (c->check_struct (this) &&
+                         rowWidth.sanitize (c) &&
+                         leftClassTable.sanitize (c, this) &&
+                         rightClassTable.sanitize (c, this) &&
+                         array.sanitize (c, this)));
   }
 
   protected:
@@ -195,11 +202,11 @@ struct KerxSubTableFormat6
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-      rowIndexTable.sanitize (c, this) &&
-      columnIndexTable.sanitize (c, this) &&
-      kerningArray.sanitize (c, this) &&
-      kerningVector.sanitize (c, this));
+    return_trace (likely (c->check_struct (this) &&
+                         rowIndexTable.sanitize (c, this) &&
+                         columnIndexTable.sanitize (c, this) &&
+                         kerningArray.sanitize (c, this) &&
+                         kerningVector.sanitize (c, this)));
   }
 
   protected:
@@ -236,7 +243,7 @@ struct KerxTable
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (!c->check_struct (this))
+    if (unlikely (!c->check_struct (this)))
       return_trace (false);
 
     switch (format) {
@@ -271,7 +278,7 @@ struct SubtableGlyphCoverageArray
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
+    return_trace (likely (c->check_struct (this)));
   }
 
   protected:
@@ -284,7 +291,7 @@ struct SubtableGlyphCoverageArray
 
 struct kerx
 {
-  static const hb_tag_t tableTag = HB_AAT_TAG_KERX;
+  static const hb_tag_t tableTag = HB_AAT_TAG_kerx;
 
   inline bool apply (hb_aat_apply_context_t *c, const AAT::ankr *ankr) const
   {
@@ -296,18 +303,18 @@ struct kerx
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (!(c->check_struct (this)))
+    if (unlikely (!(c->check_struct (this))))
      return_trace (false);
 
     /* TODO: Something like `morx`s ChainSubtable should be done here instead */
     const KerxTable *table = &StructAfter<KerxTable> (*this);
-    if (!(table->sanitize (c)))
+    if (unlikely (!(table->sanitize (c))))
       return_trace (false);
 
     for (unsigned int i = 0; i < nTables - 1; ++i)
     {
       table = &StructAfter<KerxTable> (*table);
-      if (!(table->sanitize (c)))
+      if (unlikely (!(table->sanitize (c))))
         return_trace (false);
     }
 
@@ -327,7 +334,7 @@ struct kerx
   HBUINT16             version;
   HBUINT16             padding;
   HBUINT32             nTables;
-/*KerxTable tables[VAR];*/
+/*KerxTable tablesZ[VAR]; XXX ArrayOf??? */
 /*SubtableGlyphCoverageArray coverage_array;*/
   public:
   DEFINE_SIZE_STATIC (8);
index 4cc2824..f258424 100644 (file)
 
 #include "hb-open-type-private.hh"
 #include "hb-aat-layout-common-private.hh"
+#include "hb-ot-layout-common-private.hh"
 
-#define HB_AAT_TAG_MORX HB_TAG('m','o','r','x')
+/*
+ * morx -- Extended Glyph Metamorphosis
+ * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6morx.html
+ */
+#define HB_AAT_TAG_morx HB_TAG('m','o','r','x')
 
 
 namespace AAT {
@@ -302,9 +307,10 @@ struct ContextualSubtable
   }
 
   protected:
-  StateTable<EntryData>        machine;
-  OffsetTo<UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT32>, HBUINT32>
-                       substitutionTables;
+  StateTable<EntryData>
+               machine;
+  LOffsetTo<UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT32> >
+               substitutionTables;
   public:
   DEFINE_SIZE_STATIC (20);
 };
@@ -461,12 +467,13 @@ struct LigatureSubtable
   }
 
   protected:
-  StateTable<EntryData>        machine;
-  OffsetTo<UnsizedArrayOf<HBUINT32>, HBUINT32>
+  StateTable<EntryData>
+               machine;
+  LOffsetTo<UnsizedArrayOf<HBUINT32> >
                ligAction;      /* Offset to the ligature action table. */
-  OffsetTo<UnsizedArrayOf<HBUINT16>, HBUINT32>
+  LOffsetTo<UnsizedArrayOf<HBUINT16> >
                component;      /* Offset to the component table. */
-  OffsetTo<UnsizedArrayOf<GlyphID>, HBUINT32>
+  LOffsetTo<UnsizedArrayOf<GlyphID> >
                ligature;       /* Offset to the actual ligature lists. */
   public:
   DEFINE_SIZE_STATIC (28);
@@ -663,8 +670,8 @@ struct Chain
   HBUINT32     subtableCount;  /* The number of subtables in the chain. */
 
   Feature      featureZ[VAR];  /* Features. */
-  ChainSubtable        subtableX[VAR]; /* Subtables. */
-  // subtableGlyphCoverageArray if major == 3
+/*ChainSubtable        subtableX[VAR];*//* Subtables. */
+/*subtableGlyphCoverageArray*/ /* Only if major == 3. */
 
   public:
   DEFINE_SIZE_MIN (16);
@@ -677,12 +684,12 @@ struct Chain
 
 struct morx
 {
-  static const hb_tag_t tableTag = HB_AAT_TAG_MORX;
+  static const hb_tag_t tableTag = HB_AAT_TAG_morx;
 
   inline void apply (hb_aat_apply_context_t *c) const
   {
     c->set_lookup_index (0);
-    const Chain *chain = chains;
+    const Chain *chain = chainsZ;
     unsigned int count = chainCount;
     for (unsigned int i = 0; i < count; i++)
     {
@@ -699,7 +706,7 @@ struct morx
        !chainCount.sanitize (c))
       return_trace (false);
 
-    const Chain *chain = chains;
+    const Chain *chain = chainsZ;
     unsigned int count = chainCount;
     for (unsigned int i = 0; i < count; i++)
     {
@@ -716,7 +723,7 @@ struct morx
                                 * 1 for mort, 2 or 3 for morx. */
   HBUINT32     chainCount;     /* Number of metamorphosis chains contained in this
                                 * table. */
-  Chain                chains[VAR];    /* Chains. */
+  Chain                chainsZ[VAR];   /* Chains. */
 
   public:
   DEFINE_SIZE_MIN (8);
index 5767b11..0617e23 100644 (file)
 #define HB_AAT_LAYOUT_TRAK_TABLE_HH
 
 #include "hb-aat-layout-common-private.hh"
+#include "hb-ot-layout-private.hh"
 #include "hb-open-type-private.hh"
 
+/*
+ * trak -- Tracking
+ * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6trak.html
+ */
 #define HB_AAT_TAG_trak HB_TAG('t','r','a','k')
 
 
@@ -39,12 +44,17 @@ namespace AAT {
 
 struct TrackTableEntry
 {
-  inline bool sanitize (hb_sanitize_context_t *c, const void *base, unsigned int size) const
+  friend struct TrackData;
+
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base,
+                       unsigned int size) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && (values.sanitize (c, base, size)));
+    return_trace (likely (c->check_struct (this) &&
+                         (valuesZ.sanitize (c, base, size))));
   }
 
+  private:
   inline float get_track_value () const
   {
     return track.to_float ();
@@ -52,15 +62,15 @@ struct TrackTableEntry
 
   inline int get_value (const void *base, unsigned int index) const
   {
-    return (base+values)[index];
+    return (base+valuesZ)[index];
   }
 
   protected:
-  Fixed                        track;          /* Track value for this record. */
-  HBUINT16             trackNameID;    /* The 'name' table index for this track */
+  Fixed                track;          /* Track value for this record. */
+  NameID       trackNameID;    /* The 'name' table index for this track */
   OffsetTo<UnsizedArrayOf<FWORD> >
-                       values;         /* Offset from start of tracking table to
-                                        * per-size tracking values for this track. */
+               valuesZ;        /* Offset from start of tracking table to
+                                * per-size tracking values for this track. */
 
   public:
   DEFINE_SIZE_STATIC (8);
@@ -94,7 +104,7 @@ struct TrackData
     const TrackTableEntry *trackTableEntry = nullptr;
     for (unsigned int i = 0; i < sizes; ++i)
       // For now we only seek for track entries with zero tracking value
-      if (trackTable[i].get_track_value () == 0.)
+      if (trackTable[i].get_track_value () == 0.f)
         trackTableEntry = &trackTable[0];
 
     // We couldn't match any, exit
@@ -117,17 +127,17 @@ struct TrackData
     float s0 = size_table[size_index - 1].to_float ();
     float s1 = size_table[size_index].to_float ();
     float t = (csspx - s0) / (s1 - s0);
-    return t * trackTableEntry->get_value (base, size_index) +
-      (1.0 - t) * trackTableEntry->get_value (base, size_index - 1);
+    return (float) t * trackTableEntry->get_value (base, size_index) +
+          ((float) 1.0 - t) * trackTableEntry->get_value (base, size_index - 1);
   }
 
   protected:
-  HBUINT16             nTracks;        /* Number of separate tracks included in this table. */
-  HBUINT16             nSizes;         /* Number of point sizes included in this table. */
-  LOffsetTo<UnsizedArrayOf<Fixed> >    /* Offset to array[nSizes] of size values. */
-                       sizeTable;
+  HBUINT16     nTracks;        /* Number of separate tracks included in this table. */
+  HBUINT16     nSizes;         /* Number of point sizes included in this table. */
+  LOffsetTo<UnsizedArrayOf<Fixed> >
+               sizeTable;      /* Offset to array[nSizes] of size values. */
   UnsizedArrayOf<TrackTableEntry>
-                       trackTable;     /* Array[nTracks] of TrackTableEntry records. */
+               trackTable;     /* Array[nTracks] of TrackTableEntry records. */
 
   public:
   DEFINE_SIZE_ARRAY (8, trackTable);
@@ -141,9 +151,9 @@ struct trak
   {
     TRACE_SANITIZE (this);
 
-    return_trace (c->check_struct (this) &&
-                 horizData.sanitize (c, this, this) &&
-                 vertData.sanitize (c, this, this));
+    return_trace (unlikely (c->check_struct (this) &&
+                           horizData.sanitize (c, this, this) &&
+                           vertData.sanitize (c, this, this)));
   }
 
   inline bool apply (hb_aat_apply_context_t *c) const
@@ -151,7 +161,7 @@ struct trak
     TRACE_APPLY (this);
 
     const float ptem = c->font->ptem;
-    if (ptem <= 0.f)
+    if (unlikely (ptem <= 0.f))
       return_trace (false);
 
     hb_buffer_t *buffer = c->buffer;
index 45268e3..7784fae 100644 (file)
 
 #include "hb-aat-layout-private.hh"
 #include "hb-aat-layout-ankr-table.hh"
+#include "hb-aat-layout-bsln-table.hh" // Just so we compile it; unused otherwise.
+#include "hb-aat-layout-feat-table.hh" // Just so we compile it; unused otherwise.
 #include "hb-aat-layout-kerx-table.hh"
 #include "hb-aat-layout-morx-table.hh"
 #include "hb-aat-layout-trak-table.hh"
+#include "hb-aat-fmtx-table.hh" // Just so we compile it; unused otherwise.
+#include "hb-aat-gcid-table.hh" // Just so we compile it; unused otherwise.
+#include "hb-aat-ltag-table.hh" // Just so we compile it; unused otherwise.
 
 /*
  * morx/kerx/trak
  */
 
+#if 0
 static inline const AAT::ankr&
 _get_ankr (hb_face_t *face, hb_blob_t **blob = nullptr)
 {
@@ -46,7 +52,7 @@ _get_ankr (hb_face_t *face, hb_blob_t **blob = nullptr)
   {
     if (blob)
       *blob = hb_blob_get_empty ();
-    return OT::Null(AAT::ankr);
+    return Null(AAT::ankr);
   }
   hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
   const AAT::ankr& ankr = *(layout->ankr.get ());
@@ -62,7 +68,7 @@ _get_kerx (hb_face_t *face, hb_blob_t **blob = nullptr)
   {
     if (blob)
       *blob = hb_blob_get_empty ();
-    return OT::Null(AAT::kerx);
+    return Null(AAT::kerx);
   }
   hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
   /* XXX this doesn't call set_num_glyphs on sanitizer. */
@@ -79,7 +85,7 @@ _get_morx (hb_face_t *face, hb_blob_t **blob = nullptr)
   {
     if (blob)
       *blob = hb_blob_get_empty ();
-    return OT::Null(AAT::morx);
+    return Null(AAT::morx);
   }
   hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
   /* XXX this doesn't call set_num_glyphs on sanitizer. */
@@ -96,7 +102,7 @@ _get_trak (hb_face_t *face, hb_blob_t **blob = nullptr)
   {
     if (blob)
       *blob = hb_blob_get_empty ();
-    return OT::Null(AAT::trak);
+    return Null(AAT::trak);
   }
   hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
   const AAT::trak& trak = *(layout->trak.get ());
@@ -104,34 +110,38 @@ _get_trak (hb_face_t *face, hb_blob_t **blob = nullptr)
     *blob = layout->trak.blob;
   return trak;
 }
+#endif
 
 // static inline void
 // _hb_aat_layout_create (hb_face_t *face)
 // {
 //   OT::Sanitizer<AAT::morx> sanitizer;
 //   sanitizer.set_num_glyphs (face->get_num_glyphs ());
-//   hb_blob_t *morx_blob = sanitizer.sanitize (face->reference_table (HB_AAT_TAG_MORX));
-//   OT::Sanitizer<AAT::morx>::lock_instance (morx_blob);
+//   hb_blob_t *morx_blob = sanitizer.sanitize (face->reference_table (HB_AAT_TAG_morx));
+//   morx_blob->as<AAT::morx> ();
 
 //   if (0)
 //   {
-//     OT::Sanitizer<AAT::Lookup<OT::GlyphID> >::lock_instance (morx_blob)->get_value (1, face->get_num_glyphs ());
+//     morx_blob->as<AAT::Lookup<OT::GlyphID> > ()->get_value (1, face->get_num_glyphs ());
 //   }
 // }
 
 void
 hb_aat_layout_substitute (hb_font_t *font, hb_buffer_t *buffer)
 {
+#if 0
   hb_blob_t *blob;
   const AAT::morx& morx = _get_morx (font->face, &blob);
 
   AAT::hb_aat_apply_context_t c (font, buffer, blob);
   morx.apply (&c);
+#endif
 }
 
 void
 hb_aat_layout_position (hb_font_t *font, hb_buffer_t *buffer)
 {
+#if 0
   hb_blob_t *blob;
   const AAT::ankr& ankr = _get_ankr (font->face, &blob);
   const AAT::kerx& kerx = _get_kerx (font->face, &blob);
@@ -140,4 +150,5 @@ hb_aat_layout_position (hb_font_t *font, hb_buffer_t *buffer)
   AAT::hb_aat_apply_context_t c (font, buffer, blob);
   kerx.apply (&c, &ankr);
   trak.apply (&c);
+#endif
 }
diff --git a/src/hb-aat-ltag-table.hh b/src/hb-aat-ltag-table.hh
new file mode 100644 (file)
index 0000000..15c4e89
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright © 2018  Ebrahim Byagowi
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef HB_AAT_LTAG_TABLE_HH
+#define HB_AAT_LTAG_TABLE_HH
+
+#include "hb-aat-layout-common-private.hh"
+
+/*
+ * ltag -- Language Tag
+ * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6ltag.html
+ */
+#define HB_AAT_TAG_ltag HB_TAG('l','t','a','g')
+
+
+namespace AAT {
+
+
+struct FTStringRange
+{
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && (base+tag).sanitize (c, length));
+  }
+
+  protected:
+  OffsetTo<UnsizedArrayOf<HBUINT8> >
+               tag;            /* Offset from the start of the table to
+                                * the beginning of the string */
+  HBUINT16     length;         /* String length (in bytes) */
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+struct ltag
+{
+  static const hb_tag_t tableTag = HB_AAT_TAG_ltag;
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) && tagRanges.sanitize (c, this)));
+  }
+
+  protected:
+  HBUINT32     version;        /* Table version; currently 1 */
+  HBUINT32     flags;          /* Table flags; currently none defined */
+  LArrayOf<FTStringRange>
+               tagRanges;      /* Range for each tag's string */
+  public:
+  DEFINE_SIZE_ARRAY (12, tagRanges);
+};
+
+} /* namespace AAT */
+
+
+#endif /* HB_AAT_LTAG_TABLE_HH */
index a7e9b11..12caaca 100644 (file)
@@ -63,7 +63,6 @@ static inline void _HBMemoryBarrier (void) {
 }
 
 typedef LONG hb_atomic_int_impl_t;
-#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
 #define hb_atomic_int_impl_add(AI, V)          InterlockedExchangeAdd (&(AI), (V))
 
 #define hb_atomic_ptr_impl_get(P)              (_HBMemoryBarrier (), (void *) *(P))
@@ -73,7 +72,6 @@ typedef LONG hb_atomic_int_impl_t;
 #elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
 
 typedef int hb_atomic_int_impl_t;
-#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
 #define hb_atomic_int_impl_add(AI, V)          __sync_fetch_and_add (&(AI), (V))
 
 #define hb_atomic_ptr_impl_get(P)              (void *) (__sync_synchronize (), *(P))
@@ -86,7 +84,6 @@ typedef int hb_atomic_int_impl_t;
 #include <mbarrier.h>
 
 typedef unsigned int hb_atomic_int_impl_t;
-#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
 #define hb_atomic_int_impl_add(AI, V)          ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V))
 
 #define hb_atomic_ptr_impl_get(P)              ( ({__machine_rw_barrier ();}), (void *) *(P))
@@ -104,7 +101,6 @@ typedef unsigned int hb_atomic_int_impl_t;
 
 
 typedef int32_t hb_atomic_int_impl_t;
-#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
 #define hb_atomic_int_impl_add(AI, V)          (OSAtomicAdd32Barrier ((V), &(AI)) - (V))
 
 #define hb_atomic_ptr_impl_get(P)              (OSMemoryBarrier (), (void *) *(P))
@@ -138,7 +134,6 @@ static inline int _hb_compare_and_swaplp(volatile long* P, long O, long N) {
 }
 
 typedef int hb_atomic_int_impl_t;
-#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
 #define hb_atomic_int_impl_add(AI, V)           _hb_fetch_and_add (&(AI), (V))
 
 #define hb_atomic_ptr_impl_get(P)               (__sync(), (void *) *(P))
@@ -149,7 +144,6 @@ typedef int hb_atomic_int_impl_t;
 #define HB_ATOMIC_INT_NIL 1 /* Warn that fallback implementation is in use. */
 
 typedef volatile int hb_atomic_int_impl_t;
-#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
 #define hb_atomic_int_impl_add(AI, V)          (((AI) += (V)) - (V))
 
 #define hb_atomic_ptr_impl_get(P)              ((void *) *(P))
@@ -159,7 +153,6 @@ typedef volatile int hb_atomic_int_impl_t;
 #else /* HB_NO_MT */
 
 typedef int hb_atomic_int_impl_t;
-#define HB_ATOMIC_INT_IMPL_INIT(V)             (V)
 #define hb_atomic_int_impl_add(AI, V)          (((AI) += (V)) - (V))
 
 #define hb_atomic_ptr_impl_get(P)              ((void *) *(P))
@@ -169,7 +162,7 @@ typedef int hb_atomic_int_impl_t;
 #endif
 
 
-#define HB_ATOMIC_INT_INIT(V)          {HB_ATOMIC_INT_IMPL_INIT(V)}
+#define HB_ATOMIC_INT_INIT(V)          {V}
 
 struct hb_atomic_int_t
 {
diff --git a/src/hb-blob-private.hh b/src/hb-blob-private.hh
new file mode 100644 (file)
index 0000000..b72fa72
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright © 2009  Red Hat, Inc.
+ * Copyright © 2018  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_BLOB_PRIVATE_HH
+#define HB_BLOB_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-object-private.hh"
+
+
+/*
+ * hb_blob_t
+ */
+
+struct hb_blob_t
+{
+  inline void fini_shallow (void)
+  {
+    destroy_user_data ();
+  }
+
+  inline void destroy_user_data (void)
+  {
+    if (destroy)
+    {
+      destroy (user_data);
+      user_data = nullptr;
+      destroy = nullptr;
+    }
+  }
+
+  HB_INTERNAL bool try_make_writable (void);
+  HB_INTERNAL bool try_make_writable_inplace (void);
+  HB_INTERNAL bool try_make_writable_inplace_unix (void);
+
+  inline void lock (void)
+  {
+    hb_blob_make_immutable (this);
+  }
+
+  template <typename Type>
+  inline const Type* as (void) const
+  {
+    return unlikely (!data) ? &Null(Type) : reinterpret_cast<const Type *> (data);
+  }
+
+  public:
+  hb_object_header_t header;
+  ASSERT_POD ();
+
+  bool immutable;
+
+  const char *data;
+  unsigned int length;
+  hb_memory_mode_t mode;
+
+  void *user_data;
+  hb_destroy_func_t destroy;
+};
+
+
+#endif /* HB_BLOB_PRIVATE_HH */
index b5291f6..c138648 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright © 2009  Red Hat, Inc.
+ * Copyright © 2018  Ebrahim Byagowi
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
@@ -31,8 +32,7 @@
 
 #include "hb-private.hh"
 #include "hb-debug.hh"
-
-#include "hb-object-private.hh"
+#include "hb-blob-private.hh"
 
 #ifdef HAVE_SYS_MMAN_H
 #ifdef HAVE_UNISTD_H
 
 #include <stdio.h>
 #include <errno.h>
+#include <stdlib.h>
 
 
-struct hb_blob_t {
-  hb_object_header_t header;
-  ASSERT_POD ();
-
-  bool immutable;
-
-  const char *data;
-  unsigned int length;
-  hb_memory_mode_t mode;
-
-  void *user_data;
-  hb_destroy_func_t destroy;
-};
-
-
-static bool _try_writable (hb_blob_t *blob);
-
-static void
-_hb_blob_destroy_user_data (hb_blob_t *blob)
-{
-  if (blob->destroy) {
-    blob->destroy (blob->user_data);
-    blob->user_data = nullptr;
-    blob->destroy = nullptr;
-  }
-}
-
 /**
  * hb_blob_create: (skip)
  * @data: Pointer to blob data.
@@ -114,7 +88,7 @@ hb_blob_create (const char        *data,
 
   if (blob->mode == HB_MEMORY_MODE_DUPLICATE) {
     blob->mode = HB_MEMORY_MODE_READONLY;
-    if (!_try_writable (blob)) {
+    if (!blob->try_make_writable ()) {
       hb_blob_destroy (blob);
       return hb_blob_get_empty ();
     }
@@ -260,7 +234,7 @@ hb_blob_destroy (hb_blob_t *blob)
 {
   if (!hb_object_destroy (blob)) return;
 
-  _hb_blob_destroy_user_data (blob);
+  blob->fini_shallow ();
 
   free (blob);
 }
@@ -273,7 +247,7 @@ hb_blob_destroy (hb_blob_t *blob)
  * @destroy: callback to call when @data is not needed anymore.
  * @replace: whether to replace an existing data with the same key.
  *
- * Return value: 
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -292,9 +266,9 @@ hb_blob_set_user_data (hb_blob_t          *blob,
  * @blob: a blob.
  * @key: key for data to get.
  *
- * 
  *
- * Return value: (transfer none): 
+ *
+ * Return value: (transfer none):
  *
  * Since: 0.9.2
  **/
@@ -310,7 +284,7 @@ hb_blob_get_user_data (hb_blob_t          *blob,
  * hb_blob_make_immutable:
  * @blob: a blob.
  *
- * 
+ *
  *
  * Since: 0.9.2
  **/
@@ -327,7 +301,7 @@ hb_blob_make_immutable (hb_blob_t *blob)
  * hb_blob_is_immutable:
  * @blob: a blob.
  *
- * 
+ *
  *
  * Return value: TODO
  *
@@ -344,7 +318,7 @@ hb_blob_is_immutable (hb_blob_t *blob)
  * hb_blob_get_length:
  * @blob: a blob.
  *
- * 
+ *
  *
  * Return value: the length of blob data in bytes.
  *
@@ -361,9 +335,9 @@ hb_blob_get_length (hb_blob_t *blob)
  * @blob: a blob.
  * @length: (out):
  *
- * 
  *
- * Returns: (transfer none) (array length=length): 
+ *
+ * Returns: (transfer none) (array length=length):
  *
  * Since: 0.9.2
  **/
@@ -395,7 +369,7 @@ hb_blob_get_data (hb_blob_t *blob, unsigned int *length)
 char *
 hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length)
 {
-  if (!_try_writable (blob)) {
+  if (!blob->try_make_writable ()) {
     if (length)
       *length = 0;
 
@@ -409,8 +383,8 @@ hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length)
 }
 
 
-static hb_bool_t
-_try_make_writable_inplace_unix (hb_blob_t *blob)
+bool
+hb_blob_t::try_make_writable_inplace_unix (void)
 {
 #if defined(HAVE_SYS_MMAN_H) && defined(HAVE_MPROTECT)
   uintptr_t pagesize = -1, mask, length;
@@ -425,25 +399,25 @@ _try_make_writable_inplace_unix (hb_blob_t *blob)
 #endif
 
   if ((uintptr_t) -1L == pagesize) {
-    DEBUG_MSG_FUNC (BLOB, blob, "failed to get pagesize: %s", strerror (errno));
+    DEBUG_MSG_FUNC (BLOB, this, "failed to get pagesize: %s", strerror (errno));
     return false;
   }
-  DEBUG_MSG_FUNC (BLOB, blob, "pagesize is %lu", (unsigned long) pagesize);
+  DEBUG_MSG_FUNC (BLOB, this, "pagesize is %lu", (unsigned long) pagesize);
 
   mask = ~(pagesize-1);
-  addr = (const char *) (((uintptr_t) blob->data) & mask);
-  length = (const char *) (((uintptr_t) blob->data + blob->length + pagesize-1) & mask)  - addr;
-  DEBUG_MSG_FUNC (BLOB, blob,
+  addr = (const char *) (((uintptr_t) this->data) & mask);
+  length = (const char *) (((uintptr_t) this->data + this->length + pagesize-1) & mask)  - addr;
+  DEBUG_MSG_FUNC (BLOB, this,
                  "calling mprotect on [%p..%p] (%lu bytes)",
                  addr, addr+length, (unsigned long) length);
   if (-1 == mprotect ((void *) addr, length, PROT_READ | PROT_WRITE)) {
-    DEBUG_MSG_FUNC (BLOB, blob, "mprotect failed: %s", strerror (errno));
+    DEBUG_MSG_FUNC (BLOB, this, "mprotect failed: %s", strerror (errno));
     return false;
   }
 
-  blob->mode = HB_MEMORY_MODE_WRITABLE;
+  this->mode = HB_MEMORY_MODE_WRITABLE;
 
-  DEBUG_MSG_FUNC (BLOB, blob,
+  DEBUG_MSG_FUNC (BLOB, this,
                  "successfully made [%p..%p] (%lu bytes) writable\n",
                  addr, addr+length, (unsigned long) length);
   return true;
@@ -452,53 +426,185 @@ _try_make_writable_inplace_unix (hb_blob_t *blob)
 #endif
 }
 
-static bool
-_try_writable_inplace (hb_blob_t *blob)
+bool
+hb_blob_t::try_make_writable_inplace (void)
 {
-  DEBUG_MSG_FUNC (BLOB, blob, "making writable inplace\n");
+  DEBUG_MSG_FUNC (BLOB, this, "making writable inplace\n");
 
-  if (_try_make_writable_inplace_unix (blob))
+  if (this->try_make_writable_inplace_unix ())
     return true;
 
-  DEBUG_MSG_FUNC (BLOB, blob, "making writable -> FAILED\n");
+  DEBUG_MSG_FUNC (BLOB, this, "making writable -> FAILED\n");
 
   /* Failed to make writable inplace, mark that */
-  blob->mode = HB_MEMORY_MODE_READONLY;
+  this->mode = HB_MEMORY_MODE_READONLY;
   return false;
 }
 
-static bool
-_try_writable (hb_blob_t *blob)
+bool
+hb_blob_t::try_make_writable (void)
 {
-  if (blob->immutable)
+  if (this->immutable)
     return false;
 
-  if (blob->mode == HB_MEMORY_MODE_WRITABLE)
+  if (this->mode == HB_MEMORY_MODE_WRITABLE)
     return true;
 
-  if (blob->mode == HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE && _try_writable_inplace (blob))
+  if (this->mode == HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE && this->try_make_writable_inplace ())
     return true;
 
-  if (blob->mode == HB_MEMORY_MODE_WRITABLE)
+  if (this->mode == HB_MEMORY_MODE_WRITABLE)
     return true;
 
 
-  DEBUG_MSG_FUNC (BLOB, blob, "current data is -> %p\n", blob->data);
+  DEBUG_MSG_FUNC (BLOB, this, "current data is -> %p\n", this->data);
 
   char *new_data;
 
-  new_data = (char *) malloc (blob->length);
+  new_data = (char *) malloc (this->length);
   if (unlikely (!new_data))
     return false;
 
-  DEBUG_MSG_FUNC (BLOB, blob, "dupped successfully -> %p\n", blob->data);
+  DEBUG_MSG_FUNC (BLOB, this, "dupped successfully -> %p\n", this->data);
 
-  memcpy (new_data, blob->data, blob->length);
-  _hb_blob_destroy_user_data (blob);
-  blob->mode = HB_MEMORY_MODE_WRITABLE;
-  blob->data = new_data;
-  blob->user_data = new_data;
-  blob->destroy = free;
+  memcpy (new_data, this->data, this->length);
+  this->destroy_user_data ();
+  this->mode = HB_MEMORY_MODE_WRITABLE;
+  this->data = new_data;
+  this->user_data = new_data;
+  this->destroy = free;
 
   return true;
 }
+
+/*
+ * Mmap
+ */
+
+#ifdef HAVE_MMAP
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <fcntl.h>
+#endif
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+# include <windows.h>
+#endif
+
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#ifndef MAP_NORESERVE
+# define MAP_NORESERVE 0
+#endif
+
+struct hb_mapped_file_t
+{
+  char *contents;
+  unsigned long length;
+#if defined(_WIN32) || defined(__CYGWIN__)
+  HANDLE mapping;
+#endif
+};
+
+static void
+_hb_mapped_file_destroy (hb_mapped_file_t *file)
+{
+#ifdef HAVE_MMAP
+  munmap (file->contents, file->length);
+#elif defined(_WIN32) || defined(__CYGWIN__)
+  UnmapViewOfFile (file->contents);
+  CloseHandle (file->mapping);
+#else
+  free (file->contents);
+#endif
+
+  free (file);
+}
+
+/**
+ * hb_blob_create_from_file:
+ * @file_name: font filename.
+ *
+ * Returns: A hb_blob_t pointer with the content of the file
+ *
+ * Since: 1.7.7
+ **/
+hb_blob_t *
+hb_blob_create_from_file (const char *file_name)
+{
+  // Adopted from glib's gmappedfile.c with Matthias Clasen and
+  // Allison Lortie permission but changed a lot to suit our need.
+  bool writable = false;
+  hb_memory_mode_t mm = HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE;
+  hb_mapped_file_t *file = (hb_mapped_file_t *) calloc (1, sizeof (hb_mapped_file_t));
+  if (unlikely (!file)) return hb_blob_get_empty ();
+
+#ifdef HAVE_MMAP
+  int fd = open (file_name, (writable ? O_RDWR : O_RDONLY) | _O_BINARY, 0);
+# define CLOSE close
+  if (unlikely (fd == -1)) goto fail_without_close;
+
+  struct stat st;
+  if (unlikely (fstat (fd, &st) == -1)) goto fail;
+
+  // See https://github.com/GNOME/glib/blob/f9faac7/glib/gmappedfile.c#L139-L142
+  if (unlikely (st.st_size == 0 && S_ISREG (st.st_mode))) goto fail;
+
+  file->length = (unsigned long) st.st_size;
+  file->contents = (char *) mmap (nullptr, file->length,
+                                 writable ? PROT_READ|PROT_WRITE : PROT_READ,
+                                 MAP_PRIVATE | MAP_NORESERVE, fd, 0);
+
+  if (unlikely (file->contents == MAP_FAILED)) goto fail;
+
+#elif defined(_WIN32) || defined(__CYGWIN__)
+  HANDLE fd = CreateFile (file_name,
+                         writable ? GENERIC_READ|GENERIC_WRITE : GENERIC_READ,
+                         FILE_SHARE_READ, nullptr, OPEN_EXISTING,
+                         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, nullptr);
+# define CLOSE CloseHandle
+
+  if (unlikely (fd == INVALID_HANDLE_VALUE)) goto fail_without_close;
+
+  file->length = (unsigned long) GetFileSize (fd, nullptr);
+  file->mapping = CreateFileMapping (fd, nullptr,
+                                    writable ? PAGE_WRITECOPY : PAGE_READONLY,
+                                    0, 0, nullptr);
+  if (unlikely (file->mapping == nullptr)) goto fail;
+
+  file->contents = (char *) MapViewOfFile (file->mapping,
+                                          writable ? FILE_MAP_COPY : FILE_MAP_READ,
+                                          0, 0, 0);
+  if (unlikely (file->contents == nullptr)) goto fail;
+
+#else
+  mm = HB_MEMORY_MODE_WRITABLE;
+
+  FILE *fd = fopen (file_name, "rb");
+# define CLOSE fclose
+  if (unlikely (!fd)) goto fail_without_close;
+
+  fseek (fd, 0, SEEK_END);
+  file->length = ftell (fd);
+  rewind (fd);
+  file->contents = (char *) malloc (file->length);
+  if (unlikely (!file->contents)) goto fail;
+
+  if (unlikely (fread (file->contents, 1, file->length, fd) != file->length))
+    goto fail;
+
+#endif
+
+  CLOSE (fd);
+  return hb_blob_create (file->contents, file->length, mm, (void *) file,
+                        (hb_destroy_func_t) _hb_mapped_file_destroy);
+
+fail:
+  CLOSE (fd);
+#undef CLOSE
+fail_without_close:
+  free (file);
+  return hb_blob_get_empty ();
+}
index fd561f7..d1d9134 100644 (file)
@@ -123,6 +123,8 @@ hb_blob_get_data (hb_blob_t *blob, unsigned int *length);
 HB_EXTERN char *
 hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length);
 
+HB_EXTERN hb_blob_t *
+hb_blob_create_from_file (const char *file_name);
 
 HB_END_DECLS
 
index be374c7..380f3c5 100644 (file)
 
 #line 36 "hb-buffer-deserialize-json.hh"
 static const unsigned char _deserialize_json_trans_keys[] = {
-       0u, 0u, 9u, 123u, 9u, 34u, 97u, 103u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u,
-       48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u,
-       9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u,
-       120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u,
-       9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u,
+       0u, 0u, 9u, 123u, 9u, 34u, 97u, 103u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 
+       48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 
+       9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, 
+       120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 
+       9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 
        65u, 122u, 34u, 122u, 9u, 125u, 9u, 125u, 9u, 93u, 9u, 123u, 0u, 0u, 0
 };
 
 static const char _deserialize_json_key_spans[] = {
-       0, 115, 26, 7, 2, 1, 50, 49,
-       10, 117, 117, 117, 1, 50, 49, 10,
-       117, 117, 1, 1, 50, 49, 117, 117,
-       2, 1, 50, 49, 10, 117, 117, 1,
-       50, 49, 10, 117, 117, 1, 50, 49,
+       0, 115, 26, 7, 2, 1, 50, 49, 
+       10, 117, 117, 117, 1, 50, 49, 10, 
+       117, 117, 1, 1, 50, 49, 117, 117, 
+       2, 1, 50, 49, 10, 117, 117, 1, 
+       50, 49, 10, 117, 117, 1, 50, 49, 
        58, 89, 117, 117, 85, 115, 0
 };
 
 static const short _deserialize_json_index_offsets[] = {
-       0, 0, 116, 143, 151, 154, 156, 207,
-       257, 268, 386, 504, 622, 624, 675, 725,
-       736, 854, 972, 974, 976, 1027, 1077, 1195,
-       1313, 1316, 1318, 1369, 1419, 1430, 1548, 1666,
-       1668, 1719, 1769, 1780, 1898, 2016, 2018, 2069,
+       0, 0, 116, 143, 151, 154, 156, 207, 
+       257, 268, 386, 504, 622, 624, 675, 725, 
+       736, 854, 972, 974, 976, 1027, 1077, 1195, 
+       1313, 1316, 1318, 1369, 1419, 1430, 1548, 1666, 
+       1668, 1719, 1769, 1780, 1898, 2016, 2018, 2069, 
        2119, 2178, 2268, 2386, 2504, 2590, 2706
 };
 
 static const char _deserialize_json_indicies[] = {
-       0, 0, 0, 0, 0, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       0, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 2, 1, 3, 3, 3,
-       3, 3, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 3, 1, 4, 1,
-       5, 1, 6, 7, 1, 1, 8, 1,
-       9, 10, 1, 11, 1, 11, 11, 11,
-       11, 11, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 11, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 12, 1,
-       12, 12, 12, 12, 12, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 12,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 13, 1, 1, 14,
-       15, 15, 15, 15, 15, 15, 15, 15,
-       15, 1, 16, 17, 17, 17, 17, 17,
-       17, 17, 17, 17, 1, 18, 18, 18,
-       18, 18, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 18, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       19, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 20, 1, 21, 21, 21, 21, 21,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 21, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 3, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 22,
-       1, 18, 18, 18, 18, 18, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       18, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 19, 1, 1, 1,
-       17, 17, 17, 17, 17, 17, 17, 17,
-       17, 17, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 20, 1, 23,
-       1, 23, 23, 23, 23, 23, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       23, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 24, 1, 24, 24, 24, 24,
-       24, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 24, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       25, 1, 1, 26, 27, 27, 27, 27,
-       27, 27, 27, 27, 27, 1, 28, 29,
-       29, 29, 29, 29, 29, 29, 29, 29,
-       1, 30, 30, 30, 30, 30, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       30, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 31, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 32, 1, 30,
-       30, 30, 30, 30, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 30, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 31, 1, 1, 1, 29, 29,
-       29, 29, 29, 29, 29, 29, 29, 29,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 32, 1, 33, 1, 34,
-       1, 34, 34, 34, 34, 34, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       34, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 35, 1, 35, 35, 35, 35,
-       35, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 35, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 36, 37, 37, 37, 37,
-       37, 37, 37, 37, 37, 1, 38, 38,
-       38, 38, 38, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 38, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 39, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 40, 1, 38, 38, 38, 38,
-       38, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 38, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 39,
-       1, 1, 1, 41, 41, 41, 41, 41,
-       41, 41, 41, 41, 41, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       40, 1, 42, 43, 1, 44, 1, 44,
-       44, 44, 44, 44, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 44, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       45, 1, 45, 45, 45, 45, 45, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 45, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 46, 1,
-       1, 47, 48, 48, 48, 48, 48, 48,
-       48, 48, 48, 1, 49, 50, 50, 50,
-       50, 50, 50, 50, 50, 50, 1, 51,
-       51, 51, 51, 51, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 51, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 52, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 53, 1, 51, 51, 51,
-       51, 51, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 51, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       52, 1, 1, 1, 50, 50, 50, 50,
-       50, 50, 50, 50, 50, 50, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 53, 1, 54, 1, 54, 54, 54,
-       54, 54, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 54, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 55, 1,
-       55, 55, 55, 55, 55, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 55,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 56, 1, 1, 57,
-       58, 58, 58, 58, 58, 58, 58, 58,
-       58, 1, 59, 60, 60, 60, 60, 60,
-       60, 60, 60, 60, 1, 61, 61, 61,
-       61, 61, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 61, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       62, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 63, 1, 61, 61, 61, 61, 61,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 61, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 62, 1,
-       1, 1, 60, 60, 60, 60, 60, 60,
-       60, 60, 60, 60, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 63,
-       1, 64, 1, 64, 64, 64, 64, 64,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 64, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 65, 1, 65, 65,
-       65, 65, 65, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 65, 1, 66,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 67, 68, 68,
-       68, 68, 68, 68, 68, 68, 68, 1,
-       69, 69, 69, 69, 69, 69, 69, 69,
-       69, 69, 69, 69, 69, 69, 69, 69,
-       69, 69, 69, 69, 69, 69, 69, 69,
-       69, 69, 1, 1, 1, 1, 1, 1,
-       69, 69, 69, 69, 69, 69, 69, 69,
-       69, 69, 69, 69, 69, 69, 69, 69,
-       69, 69, 69, 69, 69, 69, 69, 69,
-       69, 69, 1, 70, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 71, 71,
-       1, 71, 71, 71, 71, 71, 71, 71,
-       71, 71, 71, 1, 1, 1, 1, 1,
-       1, 1, 71, 71, 71, 71, 71, 71,
-       71, 71, 71, 71, 71, 71, 71, 71,
-       71, 71, 71, 71, 71, 71, 71, 71,
-       71, 71, 71, 71, 1, 1, 1, 1,
-       71, 1, 71, 71, 71, 71, 71, 71,
-       71, 71, 71, 71, 71, 71, 71, 71,
-       71, 71, 71, 71, 71, 71, 71, 71,
-       71, 71, 71, 71, 1, 72, 72, 72,
-       72, 72, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 72, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       73, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 74, 1, 72, 72, 72, 72, 72,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 72, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 73, 1,
-       1, 1, 75, 75, 75, 75, 75, 75,
-       75, 75, 75, 75, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 74,
-       1, 76, 76, 76, 76, 76, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       76, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 77, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 78, 1, 0,
-       0, 0, 0, 0, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 0, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
+       0, 0, 0, 0, 0, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       0, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 2, 1, 3, 3, 3, 
+       3, 3, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 3, 1, 4, 1, 
+       5, 1, 6, 7, 1, 1, 8, 1, 
+       9, 10, 1, 11, 1, 11, 11, 11, 
+       11, 11, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 11, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 12, 1, 
+       12, 12, 12, 12, 12, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 12, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 13, 1, 1, 14, 
+       15, 15, 15, 15, 15, 15, 15, 15, 
+       15, 1, 16, 17, 17, 17, 17, 17, 
+       17, 17, 17, 17, 1, 18, 18, 18, 
+       18, 18, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 18, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       19, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 20, 1, 21, 21, 21, 21, 21, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 21, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 3, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 22, 
+       1, 18, 18, 18, 18, 18, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       18, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 19, 1, 1, 1, 
+       17, 17, 17, 17, 17, 17, 17, 17, 
+       17, 17, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 20, 1, 23, 
+       1, 23, 23, 23, 23, 23, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       23, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 24, 1, 24, 24, 24, 24, 
+       24, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 24, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       25, 1, 1, 26, 27, 27, 27, 27, 
+       27, 27, 27, 27, 27, 1, 28, 29, 
+       29, 29, 29, 29, 29, 29, 29, 29, 
+       1, 30, 30, 30, 30, 30, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       30, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 31, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 32, 1, 30, 
+       30, 30, 30, 30, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 30, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 31, 1, 1, 1, 29, 29, 
+       29, 29, 29, 29, 29, 29, 29, 29, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 32, 1, 33, 1, 34, 
+       1, 34, 34, 34, 34, 34, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       34, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 35, 1, 35, 35, 35, 35, 
+       35, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 35, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 36, 37, 37, 37, 37, 
+       37, 37, 37, 37, 37, 1, 38, 38, 
+       38, 38, 38, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 38, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 39, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 40, 1, 38, 38, 38, 38, 
+       38, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 38, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 39, 
+       1, 1, 1, 41, 41, 41, 41, 41, 
+       41, 41, 41, 41, 41, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       40, 1, 42, 43, 1, 44, 1, 44, 
+       44, 44, 44, 44, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 44, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       45, 1, 45, 45, 45, 45, 45, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 45, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 46, 1, 
+       1, 47, 48, 48, 48, 48, 48, 48, 
+       48, 48, 48, 1, 49, 50, 50, 50, 
+       50, 50, 50, 50, 50, 50, 1, 51, 
+       51, 51, 51, 51, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 51, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 52, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 53, 1, 51, 51, 51, 
+       51, 51, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 51, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       52, 1, 1, 1, 50, 50, 50, 50, 
+       50, 50, 50, 50, 50, 50, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 53, 1, 54, 1, 54, 54, 54, 
+       54, 54, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 54, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 55, 1, 
+       55, 55, 55, 55, 55, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 55, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 56, 1, 1, 57, 
+       58, 58, 58, 58, 58, 58, 58, 58, 
+       58, 1, 59, 60, 60, 60, 60, 60, 
+       60, 60, 60, 60, 1, 61, 61, 61, 
+       61, 61, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 61, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       62, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 63, 1, 61, 61, 61, 61, 61, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 61, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 62, 1, 
+       1, 1, 60, 60, 60, 60, 60, 60, 
+       60, 60, 60, 60, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 63, 
+       1, 64, 1, 64, 64, 64, 64, 64, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 64, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 65, 1, 65, 65, 
+       65, 65, 65, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 65, 1, 66, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 67, 68, 68, 
+       68, 68, 68, 68, 68, 68, 68, 1, 
+       69, 69, 69, 69, 69, 69, 69, 69, 
+       69, 69, 69, 69, 69, 69, 69, 69, 
+       69, 69, 69, 69, 69, 69, 69, 69, 
+       69, 69, 1, 1, 1, 1, 1, 1, 
+       69, 69, 69, 69, 69, 69, 69, 69, 
+       69, 69, 69, 69, 69, 69, 69, 69, 
+       69, 69, 69, 69, 69, 69, 69, 69, 
+       69, 69, 1, 70, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 71, 71, 
+       1, 71, 71, 71, 71, 71, 71, 71, 
+       71, 71, 71, 1, 1, 1, 1, 1, 
+       1, 1, 71, 71, 71, 71, 71, 71, 
+       71, 71, 71, 71, 71, 71, 71, 71, 
+       71, 71, 71, 71, 71, 71, 71, 71, 
+       71, 71, 71, 71, 1, 1, 1, 1, 
+       71, 1, 71, 71, 71, 71, 71, 71, 
+       71, 71, 71, 71, 71, 71, 71, 71, 
+       71, 71, 71, 71, 71, 71, 71, 71, 
+       71, 71, 71, 71, 1, 72, 72, 72, 
+       72, 72, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 72, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       73, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 74, 1, 72, 72, 72, 72, 72, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 72, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 73, 1, 
+       1, 1, 75, 75, 75, 75, 75, 75, 
+       75, 75, 75, 75, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 74, 
+       1, 76, 76, 76, 76, 76, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       76, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 77, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 78, 1, 0, 
+       0, 0, 0, 0, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 0, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
        1, 2, 1, 1, 0
 };
 
 static const char _deserialize_json_trans_targs[] = {
-       1, 0, 2, 2, 3, 4, 18, 24,
-       37, 5, 12, 6, 7, 8, 9, 11,
-       9, 11, 10, 2, 44, 10, 44, 13,
-       14, 15, 16, 17, 16, 17, 10, 2,
-       44, 19, 20, 21, 22, 23, 10, 2,
-       44, 23, 25, 31, 26, 27, 28, 29,
-       30, 29, 30, 10, 2, 44, 32, 33,
-       34, 35, 36, 35, 36, 10, 2, 44,
-       38, 39, 40, 42, 43, 41, 10, 41,
+       1, 0, 2, 2, 3, 4, 18, 24, 
+       37, 5, 12, 6, 7, 8, 9, 11, 
+       9, 11, 10, 2, 44, 10, 44, 13, 
+       14, 15, 16, 17, 16, 17, 10, 2, 
+       44, 19, 20, 21, 22, 23, 10, 2, 
+       44, 23, 25, 31, 26, 27, 28, 29, 
+       30, 29, 30, 10, 2, 44, 32, 33, 
+       34, 35, 36, 35, 36, 10, 2, 44, 
+       38, 39, 40, 42, 43, 41, 10, 41, 
        10, 2, 44, 43, 44, 45, 46
 };
 
 static const char _deserialize_json_trans_actions[] = {
-       0, 0, 1, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 2, 2, 2,
-       0, 0, 3, 3, 4, 0, 5, 0,
-       0, 2, 2, 2, 0, 0, 6, 6,
-       7, 0, 0, 0, 2, 2, 8, 8,
-       9, 0, 0, 0, 0, 0, 2, 2,
-       2, 0, 0, 10, 10, 11, 0, 0,
-       2, 2, 2, 0, 0, 12, 12, 13,
-       0, 0, 0, 2, 2, 2, 14, 0,
+       0, 0, 1, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 2, 2, 2, 
+       0, 0, 3, 3, 4, 0, 5, 0, 
+       0, 2, 2, 2, 0, 0, 6, 6, 
+       7, 0, 0, 0, 2, 2, 8, 8, 
+       9, 0, 0, 0, 0, 0, 2, 2, 
+       2, 0, 0, 10, 10, 11, 0, 0, 
+       2, 2, 2, 0, 0, 12, 12, 13, 
+       0, 0, 0, 2, 2, 2, 14, 0, 
        15, 15, 16, 0, 0, 0, 0
 };
 
@@ -461,7 +461,7 @@ _hb_buffer_deserialize_glyphs_json (hb_buffer_t *buffer,
   int cs;
   hb_glyph_info_t info = {0};
   hb_glyph_position_t pos = {0};
-
+  
 #line 466 "hb-buffer-deserialize-json.hh"
        {
        cs = deserialize_json_start;
@@ -503,7 +503,7 @@ _resume:
 #line 43 "hb-buffer-deserialize-json.rl"
        {
        buffer->add_info (info);
-       if (buffer->in_error)
+       if (unlikely (!buffer->successful))
          return false;
        buffer->pos[buffer->len - 1] = pos;
        *end_ptr = p;
@@ -554,7 +554,7 @@ _resume:
 #line 43 "hb-buffer-deserialize-json.rl"
        {
        buffer->add_info (info);
-       if (buffer->in_error)
+       if (unlikely (!buffer->successful))
          return false;
        buffer->pos[buffer->len - 1] = pos;
        *end_ptr = p;
@@ -566,7 +566,7 @@ _resume:
 #line 43 "hb-buffer-deserialize-json.rl"
        {
        buffer->add_info (info);
-       if (buffer->in_error)
+       if (unlikely (!buffer->successful))
          return false;
        buffer->pos[buffer->len - 1] = pos;
        *end_ptr = p;
@@ -578,7 +578,7 @@ _resume:
 #line 43 "hb-buffer-deserialize-json.rl"
        {
        buffer->add_info (info);
-       if (buffer->in_error)
+       if (unlikely (!buffer->successful))
          return false;
        buffer->pos[buffer->len - 1] = pos;
        *end_ptr = p;
@@ -590,7 +590,7 @@ _resume:
 #line 43 "hb-buffer-deserialize-json.rl"
        {
        buffer->add_info (info);
-       if (buffer->in_error)
+       if (unlikely (!buffer->successful))
          return false;
        buffer->pos[buffer->len - 1] = pos;
        *end_ptr = p;
@@ -602,7 +602,7 @@ _resume:
 #line 43 "hb-buffer-deserialize-json.rl"
        {
        buffer->add_info (info);
-       if (buffer->in_error)
+       if (unlikely (!buffer->successful))
          return false;
        buffer->pos[buffer->len - 1] = pos;
        *end_ptr = p;
@@ -614,7 +614,7 @@ _resume:
 #line 43 "hb-buffer-deserialize-json.rl"
        {
        buffer->add_info (info);
-       if (buffer->in_error)
+       if (unlikely (!buffer->successful))
          return false;
        buffer->pos[buffer->len - 1] = pos;
        *end_ptr = p;
index 0f7d48e..ec9bc7c 100644 (file)
@@ -42,7 +42,7 @@ action clear_item {
 
 action add_item {
        buffer->add_info (info);
-       if (buffer->in_error)
+       if (unlikely (!buffer->successful))
          return false;
        buffer->pos[buffer->len - 1] = pos;
        *end_ptr = p;
index a6ab0bb..5bca369 100644 (file)
 
 #line 36 "hb-buffer-deserialize-text.hh"
 static const unsigned char _deserialize_text_trans_keys[] = {
-       0u, 0u, 9u, 122u, 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u,
-       48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, 9u, 124u, 9u, 124u, 0u, 0u,
-       9u, 122u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u,
+       0u, 0u, 9u, 122u, 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u, 
+       48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, 9u, 124u, 9u, 124u, 0u, 0u, 
+       9u, 122u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 
        9u, 124u, 9u, 124u, 9u, 124u, 0
 };
 
 static const char _deserialize_text_key_spans[] = {
-       0, 114, 13, 10, 13, 10, 10, 13,
-       10, 1, 13, 10, 14, 116, 116, 0,
-       114, 116, 116, 116, 116, 116, 116, 116,
+       0, 114, 13, 10, 13, 10, 10, 13, 
+       10, 1, 13, 10, 14, 116, 116, 0, 
+       114, 116, 116, 116, 116, 116, 116, 116, 
        116, 116, 116
 };
 
 static const short _deserialize_text_index_offsets[] = {
-       0, 0, 115, 129, 140, 154, 165, 176,
-       190, 201, 203, 217, 228, 243, 360, 477,
-       478, 593, 710, 827, 944, 1061, 1178, 1295,
+       0, 0, 115, 129, 140, 154, 165, 176, 
+       190, 201, 203, 217, 228, 243, 360, 477, 
+       478, 593, 710, 827, 944, 1061, 1178, 1295, 
        1412, 1529, 1646
 };
 
 static const char _deserialize_text_indicies[] = {
-       0, 0, 0, 0, 0, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       0, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       2, 3, 3, 3, 3, 3, 3, 3,
-       3, 3, 1, 1, 1, 1, 1, 1,
-       1, 4, 4, 4, 4, 4, 4, 4,
-       4, 4, 4, 4, 4, 4, 4, 4,
-       4, 4, 4, 4, 4, 4, 4, 4,
-       4, 4, 4, 1, 1, 1, 1, 1,
-       1, 4, 4, 4, 4, 4, 4, 4,
-       4, 4, 4, 4, 4, 4, 4, 4,
-       4, 4, 4, 4, 4, 4, 4, 4,
-       4, 4, 4, 1, 5, 1, 1, 6,
-       7, 7, 7, 7, 7, 7, 7, 7,
-       7, 1, 8, 9, 9, 9, 9, 9,
-       9, 9, 9, 9, 1, 10, 1, 1,
-       11, 12, 12, 12, 12, 12, 12, 12,
-       12, 12, 1, 13, 14, 14, 14, 14,
-       14, 14, 14, 14, 14, 1, 15, 16,
-       16, 16, 16, 16, 16, 16, 16, 16,
-       1, 17, 1, 1, 18, 19, 19, 19,
-       19, 19, 19, 19, 19, 19, 1, 20,
-       21, 21, 21, 21, 21, 21, 21, 21,
-       21, 1, 22, 1, 23, 1, 1, 24,
-       25, 25, 25, 25, 25, 25, 25, 25,
-       25, 1, 26, 27, 27, 27, 27, 27,
-       27, 27, 27, 27, 1, 22, 1, 1,
-       1, 21, 21, 21, 21, 21, 21, 21,
-       21, 21, 21, 1, 28, 28, 28, 28,
-       28, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 28, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 29, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       30, 1, 1, 31, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       32, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 33,
-       1, 34, 34, 34, 34, 34, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       34, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 35, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 36, 1, 1, 0,
-       0, 0, 0, 0, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 0, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 2, 3,
-       3, 3, 3, 3, 3, 3, 3, 3,
-       1, 1, 1, 1, 1, 1, 1, 4,
-       4, 4, 4, 4, 4, 4, 4, 4,
-       4, 4, 4, 4, 4, 4, 4, 4,
-       4, 4, 4, 4, 4, 4, 4, 4,
-       4, 1, 1, 1, 1, 1, 1, 4,
-       4, 4, 4, 4, 4, 4, 4, 4,
-       4, 4, 4, 4, 4, 4, 4, 4,
-       4, 4, 4, 4, 4, 4, 4, 4,
-       4, 1, 28, 28, 28, 28, 28, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 28, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 29, 1, 1, 1,
-       1, 37, 37, 37, 37, 37, 37, 37,
-       37, 37, 37, 1, 1, 1, 30, 1,
-       1, 31, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 32, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 33, 1, 38,
-       38, 38, 38, 38, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 38, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 39, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 40, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 41, 1, 42, 42, 42, 42,
-       42, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 42, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       43, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 44,
-       1, 42, 42, 42, 42, 42, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       42, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       14, 14, 14, 14, 14, 14, 14, 14,
-       14, 14, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 43, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 44, 1, 38, 38,
-       38, 38, 38, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 38, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 39, 1, 1, 1, 9, 9, 9,
-       9, 9, 9, 9, 9, 9, 9, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 40, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 41, 1, 45, 45, 45, 45, 45,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 45, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 46, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 47, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 48,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 49, 1,
-       50, 50, 50, 50, 50, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 50,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 51, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 52, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 53, 1, 50, 50, 50,
-       50, 50, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 50, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 51,
-       1, 1, 1, 1, 27, 27, 27, 27,
-       27, 27, 27, 27, 27, 27, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 52, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       53, 1, 45, 45, 45, 45, 45, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 45, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 46, 1, 1, 1,
-       1, 54, 54, 54, 54, 54, 54, 54,
-       54, 54, 54, 1, 1, 1, 1, 1,
-       1, 47, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 48, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 49, 1, 28,
-       28, 28, 28, 28, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 28, 1,
-       1, 1, 1, 1, 1, 1, 1, 1,
-       1, 29, 1, 55, 55, 1, 55, 55,
-       55, 55, 55, 55, 55, 55, 55, 55,
-       1, 1, 1, 30, 1, 1, 31, 55,
-       55, 55, 55, 55, 55, 55, 55, 55,
-       55, 55, 55, 55, 55, 55, 55, 55,
-       55, 55, 55, 55, 55, 55, 55, 55,
-       55, 1, 1, 32, 1, 55, 1, 55,
-       55, 55, 55, 55, 55, 55, 55, 55,
-       55, 55, 55, 55, 55, 55, 55, 55,
-       55, 55, 55, 55, 55, 55, 55, 55,
+       0, 0, 0, 0, 0, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       0, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       2, 3, 3, 3, 3, 3, 3, 3, 
+       3, 3, 1, 1, 1, 1, 1, 1, 
+       1, 4, 4, 4, 4, 4, 4, 4, 
+       4, 4, 4, 4, 4, 4, 4, 4, 
+       4, 4, 4, 4, 4, 4, 4, 4, 
+       4, 4, 4, 1, 1, 1, 1, 1, 
+       1, 4, 4, 4, 4, 4, 4, 4, 
+       4, 4, 4, 4, 4, 4, 4, 4, 
+       4, 4, 4, 4, 4, 4, 4, 4, 
+       4, 4, 4, 1, 5, 1, 1, 6, 
+       7, 7, 7, 7, 7, 7, 7, 7, 
+       7, 1, 8, 9, 9, 9, 9, 9, 
+       9, 9, 9, 9, 1, 10, 1, 1, 
+       11, 12, 12, 12, 12, 12, 12, 12, 
+       12, 12, 1, 13, 14, 14, 14, 14, 
+       14, 14, 14, 14, 14, 1, 15, 16, 
+       16, 16, 16, 16, 16, 16, 16, 16, 
+       1, 17, 1, 1, 18, 19, 19, 19, 
+       19, 19, 19, 19, 19, 19, 1, 20, 
+       21, 21, 21, 21, 21, 21, 21, 21, 
+       21, 1, 22, 1, 23, 1, 1, 24, 
+       25, 25, 25, 25, 25, 25, 25, 25, 
+       25, 1, 26, 27, 27, 27, 27, 27, 
+       27, 27, 27, 27, 1, 22, 1, 1, 
+       1, 21, 21, 21, 21, 21, 21, 21, 
+       21, 21, 21, 1, 28, 28, 28, 28, 
+       28, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 28, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 29, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       30, 1, 1, 31, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       32, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 33, 
+       1, 34, 34, 34, 34, 34, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       34, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 35, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 36, 1, 1, 0, 
+       0, 0, 0, 0, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 0, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 2, 3, 
+       3, 3, 3, 3, 3, 3, 3, 3, 
+       1, 1, 1, 1, 1, 1, 1, 4, 
+       4, 4, 4, 4, 4, 4, 4, 4, 
+       4, 4, 4, 4, 4, 4, 4, 4, 
+       4, 4, 4, 4, 4, 4, 4, 4, 
+       4, 1, 1, 1, 1, 1, 1, 4, 
+       4, 4, 4, 4, 4, 4, 4, 4, 
+       4, 4, 4, 4, 4, 4, 4, 4, 
+       4, 4, 4, 4, 4, 4, 4, 4, 
+       4, 1, 28, 28, 28, 28, 28, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 28, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 29, 1, 1, 1, 
+       1, 37, 37, 37, 37, 37, 37, 37, 
+       37, 37, 37, 1, 1, 1, 30, 1, 
+       1, 31, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 32, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 33, 1, 38, 
+       38, 38, 38, 38, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 38, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 39, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 40, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 41, 1, 42, 42, 42, 42, 
+       42, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 42, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       43, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 44, 
+       1, 42, 42, 42, 42, 42, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       42, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       14, 14, 14, 14, 14, 14, 14, 14, 
+       14, 14, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 43, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 44, 1, 38, 38, 
+       38, 38, 38, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 38, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 39, 1, 1, 1, 9, 9, 9, 
+       9, 9, 9, 9, 9, 9, 9, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 40, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 41, 1, 45, 45, 45, 45, 45, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 45, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 46, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 47, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 48, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 49, 1, 
+       50, 50, 50, 50, 50, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 50, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 51, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 52, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 53, 1, 50, 50, 50, 
+       50, 50, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 50, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 51, 
+       1, 1, 1, 1, 27, 27, 27, 27, 
+       27, 27, 27, 27, 27, 27, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 52, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       53, 1, 45, 45, 45, 45, 45, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 45, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 46, 1, 1, 1, 
+       1, 54, 54, 54, 54, 54, 54, 54, 
+       54, 54, 54, 1, 1, 1, 1, 1, 
+       1, 47, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 48, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 49, 1, 28, 
+       28, 28, 28, 28, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 28, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 29, 1, 55, 55, 1, 55, 55, 
+       55, 55, 55, 55, 55, 55, 55, 55, 
+       1, 1, 1, 30, 1, 1, 31, 55, 
+       55, 55, 55, 55, 55, 55, 55, 55, 
+       55, 55, 55, 55, 55, 55, 55, 55, 
+       55, 55, 55, 55, 55, 55, 55, 55, 
+       55, 1, 1, 32, 1, 55, 1, 55, 
+       55, 55, 55, 55, 55, 55, 55, 55, 
+       55, 55, 55, 55, 55, 55, 55, 55, 
+       55, 55, 55, 55, 55, 55, 55, 55, 
        55, 1, 33, 1, 0
 };
 
 static const char _deserialize_text_trans_targs[] = {
-       1, 0, 13, 17, 26, 3, 18, 21,
-       18, 21, 5, 19, 20, 19, 20, 22,
-       25, 8, 9, 12, 9, 12, 10, 11,
-       23, 24, 23, 24, 14, 2, 6, 7,
-       15, 16, 14, 15, 16, 17, 14, 4,
-       15, 16, 14, 15, 16, 14, 2, 7,
+       1, 0, 13, 17, 26, 3, 18, 21, 
+       18, 21, 5, 19, 20, 19, 20, 22, 
+       25, 8, 9, 12, 9, 12, 10, 11, 
+       23, 24, 23, 24, 14, 2, 6, 7, 
+       15, 16, 14, 15, 16, 17, 14, 4, 
+       15, 16, 14, 15, 16, 14, 2, 7, 
        15, 16, 14, 2, 15, 16, 25, 26
 };
 
 static const char _deserialize_text_trans_actions[] = {
-       0, 0, 1, 1, 1, 2, 2, 2,
-       0, 0, 2, 2, 2, 0, 0, 2,
-       2, 2, 2, 2, 0, 0, 3, 2,
-       2, 2, 0, 0, 4, 5, 5, 5,
-       4, 4, 0, 0, 0, 0, 6, 7,
-       6, 6, 8, 8, 8, 9, 10, 10,
+       0, 0, 1, 1, 1, 2, 2, 2, 
+       0, 0, 2, 2, 2, 0, 0, 2, 
+       2, 2, 2, 2, 0, 0, 3, 2, 
+       2, 2, 0, 0, 4, 5, 5, 5, 
+       4, 4, 0, 0, 0, 0, 6, 7, 
+       6, 6, 8, 8, 8, 9, 10, 10, 
        9, 9, 11, 12, 11, 11, 0, 0
 };
 
 static const char _deserialize_text_eof_actions[] = {
-       0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 4, 0, 0,
-       0, 4, 6, 8, 8, 6, 9, 11,
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 4, 0, 0, 
+       0, 4, 6, 8, 8, 6, 9, 11, 
        11, 9, 4
 };
 
@@ -338,7 +338,7 @@ _hb_buffer_deserialize_glyphs_text (hb_buffer_t *buffer,
   int cs;
   hb_glyph_info_t info = {0};
   hb_glyph_position_t pos = {0};
-
+  
 #line 343 "hb-buffer-deserialize-text.hh"
        {
        cs = deserialize_text_start;
@@ -422,7 +422,7 @@ _resume:
 #line 43 "hb-buffer-deserialize-text.rl"
        {
        buffer->add_info (info);
-       if (buffer->in_error)
+       if (unlikely (!buffer->successful))
          return false;
        buffer->pos[buffer->len - 1] = pos;
        *end_ptr = p;
@@ -434,7 +434,7 @@ _resume:
 #line 43 "hb-buffer-deserialize-text.rl"
        {
        buffer->add_info (info);
-       if (buffer->in_error)
+       if (unlikely (!buffer->successful))
          return false;
        buffer->pos[buffer->len - 1] = pos;
        *end_ptr = p;
@@ -446,7 +446,7 @@ _resume:
 #line 43 "hb-buffer-deserialize-text.rl"
        {
        buffer->add_info (info);
-       if (buffer->in_error)
+       if (unlikely (!buffer->successful))
          return false;
        buffer->pos[buffer->len - 1] = pos;
        *end_ptr = p;
@@ -458,7 +458,7 @@ _resume:
 #line 43 "hb-buffer-deserialize-text.rl"
        {
        buffer->add_info (info);
-       if (buffer->in_error)
+       if (unlikely (!buffer->successful))
          return false;
        buffer->pos[buffer->len - 1] = pos;
        *end_ptr = p;
@@ -470,7 +470,7 @@ _resume:
 #line 43 "hb-buffer-deserialize-text.rl"
        {
        buffer->add_info (info);
-       if (buffer->in_error)
+       if (unlikely (!buffer->successful))
          return false;
        buffer->pos[buffer->len - 1] = pos;
        *end_ptr = p;
@@ -499,7 +499,7 @@ _again:
 #line 43 "hb-buffer-deserialize-text.rl"
        {
        buffer->add_info (info);
-       if (buffer->in_error)
+       if (unlikely (!buffer->successful))
          return false;
        buffer->pos[buffer->len - 1] = pos;
        *end_ptr = p;
@@ -511,7 +511,7 @@ _again:
 #line 43 "hb-buffer-deserialize-text.rl"
        {
        buffer->add_info (info);
-       if (buffer->in_error)
+       if (unlikely (!buffer->successful))
          return false;
        buffer->pos[buffer->len - 1] = pos;
        *end_ptr = p;
@@ -523,7 +523,7 @@ _again:
 #line 43 "hb-buffer-deserialize-text.rl"
        {
        buffer->add_info (info);
-       if (buffer->in_error)
+       if (unlikely (!buffer->successful))
          return false;
        buffer->pos[buffer->len - 1] = pos;
        *end_ptr = p;
@@ -535,7 +535,7 @@ _again:
 #line 43 "hb-buffer-deserialize-text.rl"
        {
        buffer->add_info (info);
-       if (buffer->in_error)
+       if (unlikely (!buffer->successful))
          return false;
        buffer->pos[buffer->len - 1] = pos;
        *end_ptr = p;
@@ -547,7 +547,7 @@ _again:
 #line 43 "hb-buffer-deserialize-text.rl"
        {
        buffer->add_info (info);
-       if (buffer->in_error)
+       if (unlikely (!buffer->successful))
          return false;
        buffer->pos[buffer->len - 1] = pos;
        *end_ptr = p;
index fd9be42..1d90979 100644 (file)
@@ -42,7 +42,7 @@ action clear_item {
 
 action add_item {
        buffer->add_info (info);
-       if (buffer->in_error)
+       if (unlikely (!buffer->successful))
          return false;
        buffer->pos[buffer->len - 1] = pos;
        *end_ptr = p;
index af4767f..dd6f1dc 100644 (file)
@@ -101,7 +101,7 @@ struct hb_buffer_t {
   hb_buffer_content_type_t content_type;
   hb_segment_properties_t props; /* Script, language, direction */
 
-  bool in_error; /* Allocation failed */
+  bool successful; /* Allocations successful */
   bool have_output; /* Whether we have an output buffer going on */
   bool have_positions; /* Whether we have positions */
 
index dc0639f..7b95aea 100644 (file)
@@ -111,11 +111,11 @@ hb_segment_properties_hash (const hb_segment_properties_t *p)
 bool
 hb_buffer_t::enlarge (unsigned int size)
 {
-  if (unlikely (in_error))
+  if (unlikely (!successful))
     return false;
   if (unlikely (size > max_len))
   {
-    in_error = true;
+    successful = false;
     return false;
   }
 
@@ -139,7 +139,7 @@ hb_buffer_t::enlarge (unsigned int size)
 
 done:
   if (unlikely (!new_pos || !new_info))
-    in_error = true;
+    successful = false;
 
   if (likely (new_pos))
     pos = new_pos;
@@ -148,10 +148,10 @@ done:
     info = new_info;
 
   out_info = separate_out ? (hb_glyph_info_t *) pos : info;
-  if (likely (!in_error))
+  if (likely (successful))
     allocated = new_allocated;
 
-  return likely (!in_error);
+  return likely (successful);
 }
 
 bool
@@ -234,7 +234,7 @@ hb_buffer_t::clear (void)
   scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
 
   content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
-  in_error = false;
+  successful = true;
   have_output = false;
   have_positions = false;
 
@@ -324,7 +324,7 @@ hb_buffer_t::clear_positions (void)
 void
 hb_buffer_t::swap_buffers (void)
 {
-  if (unlikely (in_error)) return;
+  if (unlikely (!successful)) return;
 
   assert (have_output);
   have_output = false;
@@ -409,7 +409,7 @@ hb_buffer_t::move_to (unsigned int i)
     idx = i;
     return true;
   }
-  if (unlikely (in_error))
+  if (unlikely (!successful))
     return false;
 
   assert (i <= out_len + (len - idx));
@@ -687,6 +687,8 @@ hb_buffer_t::guess_segment_properties (void)
   /* If direction is set to INVALID, guess from script */
   if (props.direction == HB_DIRECTION_INVALID) {
     props.direction = hb_script_get_horizontal_direction (props.script);
+    if (props.direction == HB_DIRECTION_INVALID)
+      props.direction = HB_DIRECTION_LTR;
   }
 
   /* If language is not set, use default language from locale */
@@ -754,7 +756,7 @@ hb_buffer_get_empty (void)
 
     HB_BUFFER_CONTENT_TYPE_INVALID,
     HB_SEGMENT_PROPERTIES_DEFAULT,
-    true, /* in_error */
+    false, /* successful */
     true, /* have_output */
     true  /* have_positions */
 
@@ -1269,7 +1271,7 @@ hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size)
 hb_bool_t
 hb_buffer_allocation_successful (hb_buffer_t  *buffer)
 {
-  return !buffer->in_error;
+  return buffer->successful;
 }
 
 /**
@@ -1489,6 +1491,8 @@ hb_buffer_reverse_clusters (hb_buffer_t *buffer)
  * Next, if buffer direction is not set (ie. is %HB_DIRECTION_INVALID),
  * it will be set to the natural horizontal direction of the
  * buffer script as returned by hb_script_get_horizontal_direction().
+ * If hb_script_get_horizontal_direction() returns %HB_DIRECTION_INVALID,
+ * then %HB_DIRECTION_LTR is used.
  *
  * Finally, if buffer language is not set (ie. is %HB_LANGUAGE_INVALID),
  * it will be set to the process's default language as returned by
@@ -1750,13 +1754,13 @@ hb_buffer_append (hb_buffer_t *buffer,
 
   if (buffer->len + (end - start) < buffer->len) /* Overflows. */
   {
-    buffer->in_error = true;
+    buffer->successful = false;
     return;
   }
 
   unsigned int orig_len = buffer->len;
   hb_buffer_set_length (buffer, buffer->len + (end - start));
-  if (buffer->in_error)
+  if (unlikely (!buffer->successful))
     return;
 
   memcpy (buffer->info + orig_len, source->info + start, (end - start) * sizeof (buffer->info[0]));
index d1fcf79..a67fcf8 100644 (file)
@@ -60,12 +60,12 @@ _hb_options_init (void)
 
 /**
  * hb_tag_from_string:
- * @str: (array length=len) (element-type uint8_t): 
- * @len: 
+ * @str: (array length=len) (element-type uint8_t):
+ * @len:
  *
- * 
  *
- * Return value: 
+ *
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -90,10 +90,10 @@ hb_tag_from_string (const char *str, int len)
 
 /**
  * hb_tag_to_string:
- * @tag: 
- * @buf: (out caller-allocates) (array fixed-size=4) (element-type uint8_t): 
+ * @tag:
+ * @buf: (out caller-allocates) (array fixed-size=4) (element-type uint8_t):
+ *
  *
- * 
  *
  * Since: 0.9.5
  **/
@@ -118,12 +118,12 @@ const char direction_strings[][4] = {
 
 /**
  * hb_direction_from_string:
- * @str: (array length=len) (element-type uint8_t): 
- * @len: 
+ * @str: (array length=len) (element-type uint8_t):
+ * @len:
  *
- * 
  *
- * Return value: 
+ *
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -146,11 +146,11 @@ hb_direction_from_string (const char *str, int len)
 
 /**
  * hb_direction_to_string:
- * @direction: 
+ * @direction:
+ *
  *
- * 
  *
- * Return value: (transfer none): 
+ * Return value: (transfer none):
  *
  * Since: 0.9.2
  **/
@@ -225,7 +225,7 @@ struct hb_language_item_t {
 
   inline hb_language_item_t & operator = (const char *s) {
     /* If a custom allocated is used calling strdup() pairs
-    badly with a call to the custom free() in finish() below.
+    badly with a call to the custom free() in fini() below.
     Therefore don't call strdup(), implement its behavior.
     */
     size_t len = strlen(s) + 1;
@@ -240,7 +240,7 @@ struct hb_language_item_t {
     return *this;
   }
 
-  void finish (void) { free ((void *) lang); }
+  void fini (void) { free ((void *) lang); }
 };
 
 
@@ -252,11 +252,16 @@ static hb_language_item_t *langs;
 static void
 free_langs (void)
 {
-  while (langs) {
-    hb_language_item_t *next = langs->next;
-    langs->finish ();
-    free (langs);
-    langs = next;
+retry:
+  hb_language_item_t *first_lang = (hb_language_item_t *) hb_atomic_ptr_get (&langs);
+  if (!hb_atomic_ptr_cmpexch (&langs, first_lang, nullptr))
+    goto retry;
+
+  while (first_lang) {
+    hb_language_item_t *next = first_lang->next;
+    first_lang->fini ();
+    free (first_lang);
+    first_lang = next;
   }
 }
 #endif
@@ -284,7 +289,7 @@ retry:
   }
 
   if (!hb_atomic_ptr_cmpexch (&langs, first_lang, lang)) {
-    lang->finish ();
+    lang->fini ();
     free (lang);
     goto retry;
   }
@@ -356,7 +361,7 @@ hb_language_to_string (hb_language_t language)
 /**
  * hb_language_get_default:
  *
- * 
+ *
  *
  * Return value: (transfer none):
  *
@@ -385,7 +390,7 @@ hb_language_get_default (void)
  *
  * Converts an ISO 15924 script tag to a corresponding #hb_script_t.
  *
- * Return value: 
+ * Return value:
  * An #hb_script_t corresponding to the ISO 15924 tag.
  *
  * Since: 0.9.2
@@ -407,7 +412,7 @@ hb_script_from_iso15924_tag (hb_tag_t tag)
     case HB_TAG('Q','a','a','i'): return HB_SCRIPT_INHERITED;
     case HB_TAG('Q','a','a','c'): return HB_SCRIPT_COPTIC;
 
-    /* Script variants from http://unicode.org/iso15924/ */
+    /* Script variants from https://unicode.org/iso15924/ */
     case HB_TAG('C','y','r','s'): return HB_SCRIPT_CYRILLIC;
     case HB_TAG('L','a','t','f'): return HB_SCRIPT_LATIN;
     case HB_TAG('L','a','t','g'): return HB_SCRIPT_LATIN;
@@ -434,7 +439,7 @@ hb_script_from_iso15924_tag (hb_tag_t tag)
  * corresponding #hb_script_t. Shorthand for hb_tag_from_string() then
  * hb_script_from_iso15924_tag().
  *
- * Return value: 
+ * Return value:
  * An #hb_script_t corresponding to the ISO 15924 tag.
  *
  * Since: 0.9.2
@@ -464,18 +469,18 @@ hb_script_to_iso15924_tag (hb_script_t script)
 
 /**
  * hb_script_get_horizontal_direction:
- * @script: 
+ * @script:
+ *
  *
- * 
  *
- * Return value: 
+ * Return value:
  *
  * Since: 0.9.2
  **/
 hb_direction_t
 hb_script_get_horizontal_direction (hb_script_t script)
 {
-  /* http://goo.gl/x9ilM */
+  /* https://docs.google.com/spreadsheets/d/1Y90M0Ie3MUJ6UVCRDOypOtijlMDLNNyyLk36T6iMu0o */
   switch ((hb_tag_t) script)
   {
     /* Unicode-1.1 additions */
@@ -530,7 +535,18 @@ hb_script_get_horizontal_direction (hb_script_t script)
     /* Unicode-9.0 additions */
     case HB_SCRIPT_ADLAM:
 
+    /* Unicode-11.0 additions */
+    case HB_SCRIPT_HANIFI_ROHINGYA:
+    case HB_SCRIPT_OLD_SOGDIAN:
+    case HB_SCRIPT_SOGDIAN:
+
       return HB_DIRECTION_RTL;
+
+
+    /* https://github.com/harfbuzz/harfbuzz/issues/1000 */
+    case HB_SCRIPT_OLD_ITALIC:
+
+      return HB_DIRECTION_INVALID;
   }
 
   return HB_DIRECTION_LTR;
@@ -608,13 +624,13 @@ hb_version_string (void)
 
 /**
  * hb_version_atleast:
- * @major: 
- * @minor: 
- * @micro: 
+ * @major:
+ * @minor:
+ * @micro:
  *
- * 
  *
- * Return value: 
+ *
+ * Return value:
  *
  * Since: 0.9.30
  **/
@@ -719,8 +735,14 @@ static HB_LOCALE_T C_locale;
 static void
 free_C_locale (void)
 {
-  if (C_locale)
-    HB_FREE_LOCALE (C_locale);
+retry:
+  HB_LOCALE_T locale = (HB_LOCALE_T) hb_atomic_ptr_get (&C_locale);
+
+  if (!hb_atomic_ptr_cmpexch (&C_locale, locale, nullptr))
+    goto retry;
+
+  if (locale)
+    HB_FREE_LOCALE (locale);
 }
 #endif
 
index 26200ce..5dc1ebc 100644 (file)
 #  include <inttypes.h>
 #elif defined (_AIX)
 #  include <sys/inttypes.h>
+#elif defined (_MSC_VER) && _MSC_VER < 1600
+/* VS 2010 (_MSC_VER 1600) has stdint.h */
+typedef __int8 int8_t;
+typedef unsigned __int8 uint8_t;
+typedef __int16 int16_t;
+typedef unsigned __int16 uint16_t;
+typedef __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
 #else
 #  include <stdint.h>
 #endif
@@ -142,8 +152,8 @@ hb_language_get_default (void);
 
 /* hb_script_t */
 
-/* http://unicode.org/iso15924/ */
-/* http://goo.gl/x9ilM */
+/* https://unicode.org/iso15924/ */
+/* https://docs.google.com/spreadsheets/d/1Y90M0Ie3MUJ6UVCRDOypOtijlMDLNNyyLk36T6iMu0o */
 /* Unicode Character Database property: Script (sc) */
 typedef enum
 {
@@ -315,6 +325,17 @@ typedef enum
   /*10.0*/HB_SCRIPT_SOYOMBO                    = HB_TAG ('S','o','y','o'),
   /*10.0*/HB_SCRIPT_ZANABAZAR_SQUARE           = HB_TAG ('Z','a','n','b'),
 
+  /*
+   * Since 1.8.0
+   */
+  /*11.0*/HB_SCRIPT_DOGRA                      = HB_TAG ('D','o','g','r'),
+  /*11.0*/HB_SCRIPT_GUNJALA_GONDI              = HB_TAG ('G','o','n','g'),
+  /*11.0*/HB_SCRIPT_HANIFI_ROHINGYA            = HB_TAG ('R','o','h','g'),
+  /*11.0*/HB_SCRIPT_MAKASAR                    = HB_TAG ('M','a','k','a'),
+  /*11.0*/HB_SCRIPT_MEDEFAIDRIN                        = HB_TAG ('M','e','d','f'),
+  /*11.0*/HB_SCRIPT_OLD_SOGDIAN                        = HB_TAG ('S','o','g','o'),
+  /*11.0*/HB_SCRIPT_SOGDIAN                    = HB_TAG ('S','o','g','d'),
+
   /* No script set. */
   HB_SCRIPT_INVALID                            = HB_TAG_NONE,
 
@@ -323,7 +344,7 @@ typedef enum
    * since technically enums are int, and indeed, hb_script_t ends up being signed.
    * See this thread for technicalities:
    *
-   *   http://lists.freedesktop.org/archives/harfbuzz/2014-March/004150.html
+   *   https://lists.freedesktop.org/archives/harfbuzz/2014-March/004150.html
    */
   _HB_SCRIPT_MAX_VALUE                         = HB_TAG_MAX, /*< skip >*/
   _HB_SCRIPT_MAX_VALUE_SIGNED                  = HB_TAG_MAX_SIGNED /*< skip >*/
index aba7cf4..61f9c35 100644 (file)
@@ -168,6 +168,10 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size)
   if (CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSText")) ||
       CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSDisplay")))
   {
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080
+# define kCTFontUIFontSystem kCTFontSystemFontType
+# define kCTFontUIFontEmphasizedSystem kCTFontEmphasizedSystemFontType
+#endif
     CTFontUIFontType font_type = kCTFontUIFontSystem;
     if (CFStringHasSuffix (cg_postscript_name, CFSTR ("-Bold")))
       font_type = kCTFontUIFontEmphasizedSystem;
@@ -206,7 +210,18 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size)
       return ct_font;
   }
 
-  CFURLRef original_url = (CFURLRef)CTFontCopyAttribute(ct_font, kCTFontURLAttribute);
+  CFURLRef original_url = nullptr;
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+  ATSFontRef atsFont;
+  FSRef fsref;
+  OSStatus status;
+  atsFont = CTFontGetPlatformFont (ct_font, NULL);
+  status = ATSFontGetFileReference (atsFont, &fsref);
+  if (status == noErr)
+    original_url = CFURLCreateFromFSRef (NULL, &fsref);
+#else
+  original_url = (CFURLRef) CTFontCopyAttribute (ct_font, kCTFontURLAttribute);
+#endif
 
   /* Create font copy with cascade list that has LastResort first; this speeds up CoreText
    * font fallback which we don't need anyway. */
@@ -225,7 +240,15 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size)
        * system locations that we cannot access from the sandboxed renderer
        * process in Blink. This can be detected by the new file URL location
        * that the newly found font points to. */
-      CFURLRef new_url = (CFURLRef) CTFontCopyAttribute (new_ct_font, kCTFontURLAttribute);
+      CFURLRef new_url = nullptr;
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+      atsFont = CTFontGetPlatformFont (new_ct_font, NULL);
+      status = ATSFontGetFileReference (atsFont, &fsref);
+      if (status == noErr)
+        new_url = CFURLCreateFromFSRef (NULL, &fsref);
+#else
+      new_url = (CFURLRef) CTFontCopyAttribute (new_ct_font, kCTFontURLAttribute);
+#endif
       // Keep reconfigured font if URL cannot be retrieved (seems to be the case
       // on Mac OS 10.12 Sierra), speculative fix for crbug.com/625606
       if (!original_url || !new_url || CFEqual (original_url, new_url)) {
@@ -618,8 +641,8 @@ _hb_coretext_shape (hb_shape_plan_t    *shape_plan,
        buffer->merge_clusters (i - 1, i + 1);
   }
 
-  hb_auto_array_t<feature_record_t> feature_records;
-  hb_auto_array_t<range_record_t> range_records;
+  hb_auto_t<hb_vector_t<feature_record_t> > feature_records;
+  hb_auto_t<hb_vector_t<range_record_t> > range_records;
 
   /*
    * Set up features.
@@ -628,7 +651,7 @@ _hb_coretext_shape (hb_shape_plan_t    *shape_plan,
   if (num_features)
   {
     /* Sort features by start/end events. */
-    hb_auto_array_t<feature_event_t> feature_events;
+    hb_auto_t<hb_vector_t<feature_event_t> > feature_events;
     for (unsigned int i = 0; i < num_features; i++)
     {
       const feature_mapping_t * mapping = (const feature_mapping_t *) bsearch (&features[i].tag,
@@ -647,15 +670,11 @@ _hb_coretext_shape (hb_shape_plan_t    *shape_plan,
       feature_event_t *event;
 
       event = feature_events.push ();
-      if (unlikely (!event))
-       goto fail_features;
       event->index = features[i].start;
       event->start = true;
       event->feature = feature;
 
       event = feature_events.push ();
-      if (unlikely (!event))
-       goto fail_features;
       event->index = features[i].end;
       event->start = false;
       event->feature = feature;
@@ -669,15 +688,13 @@ _hb_coretext_shape (hb_shape_plan_t    *shape_plan,
       feature.order = num_features + 1;
 
       feature_event_t *event = feature_events.push ();
-      if (unlikely (!event))
-       goto fail_features;
       event->index = 0; /* This value does magic. */
       event->start = false;
       event->feature = feature;
     }
 
     /* Scan events and save features for each range. */
-    hb_auto_array_t<active_feature_t> active_features;
+    hb_auto_t<hb_vector_t<active_feature_t> > active_features;
     unsigned int last_index = 0;
     for (unsigned int i = 0; i < feature_events.len; i++)
     {
@@ -687,8 +704,6 @@ _hb_coretext_shape (hb_shape_plan_t    *shape_plan,
       {
         /* Save a snapshot of active features and the range. */
        range_record_t *range = range_records.push ();
-       if (unlikely (!range))
-         goto fail_features;
 
        if (active_features.len)
        {
@@ -746,23 +761,16 @@ _hb_coretext_shape (hb_shape_plan_t    *shape_plan,
        last_index = event->index;
       }
 
-      if (event->start) {
-        active_feature_t *feature = active_features.push ();
-       if (unlikely (!feature))
-         goto fail_features;
-       *feature = event->feature;
+      if (event->start)
+      {
+        active_features.push (event->feature);
       } else {
         active_feature_t *feature = active_features.find (&event->feature);
        if (feature)
-         active_features.remove (feature - active_features.array);
+         active_features.remove (feature - active_features.arrayZ);
       }
     }
   }
-  else
-  {
-  fail_features:
-    num_features = 0;
-  }
 
   unsigned int scratch_size;
   hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size);
@@ -944,6 +952,9 @@ resize_and_retry:
 
       int level = HB_DIRECTION_IS_FORWARD (buffer->props.direction) ? 0 : 1;
       CFNumberRef level_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &level);
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+      extern const CFStringRef kCTTypesetterOptionForcedEmbeddingLevel;
+#endif
       CFDictionaryRef options = CFDictionaryCreate (kCFAllocatorDefault,
                                                    (const void **) &kCTTypesetterOptionForcedEmbeddingLevel,
                                                    (const void **) &level_number,
@@ -979,7 +990,7 @@ resize_and_retry:
     /* For right-to-left runs, CoreText returns the glyphs positioned such that
      * any trailing whitespace is to the left of (0,0).  Adjust coordinate system
      * to fix for that.  Test with any RTL string with trailing spaces.
-     * https://code.google.com/p/chromium/issues/detail?id=469028
+     * https://crbug.com/469028
      */
     if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
     {
@@ -1032,7 +1043,7 @@ resize_and_retry:
         * However, even that wouldn't work if we were passed in the CGFont to
         * construct a hb_face to begin with.
         *
-        * See: http://github.com/harfbuzz/harfbuzz/pull/36
+        * See: https://github.com/harfbuzz/harfbuzz/pull/36
         *
         * Also see: https://bugs.chromium.org/p/chromium/issues/detail?id=597098
         */
@@ -1222,7 +1233,7 @@ resize_and_retry:
      * directions.  As such, disable the assert...  It wouldn't crash, but
      * cursoring will be off...
      *
-     * http://crbug.com/419769
+     * https://crbug.com/419769
      */
     if (0)
     {
index 69a8aa2..187ab3f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2015-2016  Ebrahim Byagowi
+ * Copyright © 2015-2018  Ebrahim Byagowi
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
 #include "hb-directwrite.h"
 
 
-HB_SHAPER_DATA_ENSURE_DEFINE(directwrite, face)
-HB_SHAPER_DATA_ENSURE_DEFINE(directwrite, font)
+HB_SHAPER_DATA_ENSURE_DEFINE (directwrite, face)
+HB_SHAPER_DATA_ENSURE_DEFINE (directwrite, font)
+
+
+/*
+ * hb-directwrite uses new/delete syntatically but as we let users
+ * to override malloc/free, we will redefine new/delete so users
+ * won't need to do that by their own.
+ */
+void* operator new (size_t size) { return malloc (size); }
+void* operator new [] (size_t size) { return malloc (size); }
+void operator delete (void* pointer) { free (pointer); }
+void operator delete [] (void* pointer) { free (pointer); }
 
 
 /*
@@ -48,18 +59,19 @@ class DWriteFontFileLoader : public IDWriteFontFileLoader
 private:
   IDWriteFontFileStream *mFontFileStream;
 public:
-  DWriteFontFileLoader (IDWriteFontFileStream *fontFileStream) {
+  DWriteFontFileLoader (IDWriteFontFileStream *fontFileStream)
+  {
     mFontFileStream = fontFileStream;
   }
 
   // IUnknown interface
-  IFACEMETHOD(QueryInterface)(IID const& iid, OUT void** ppObject) { return S_OK; }
-  IFACEMETHOD_(ULONG, AddRef)() { return 1; }
-  IFACEMETHOD_(ULONG, Release)() { return 1; }
+  IFACEMETHOD (QueryInterface) (IID const& iid, OUT void** ppObject) { return S_OK; }
+  IFACEMETHOD_ (ULONG, AddRef) () { return 1; }
+  IFACEMETHOD_ (ULONG, Release) () { return 1; }
 
   // IDWriteFontFileLoader methods
-  virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const* fontFileReferenceKey,
-    UINT32 fontFileReferenceKeySize,
+  virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey (void const* fontFileReferenceKey,
+    uint32_t fontFileReferenceKeySize,
     OUT IDWriteFontFileStream** fontFileStream)
   {
     *fontFileStream = mFontFileStream;
@@ -73,27 +85,26 @@ private:
   uint8_t *mData;
   uint32_t mSize;
 public:
-  DWriteFontFileStream(uint8_t *aData, uint32_t aSize)
+  DWriteFontFileStream (uint8_t *aData, uint32_t aSize)
   {
     mData = aData;
     mSize = aSize;
   }
 
   // IUnknown interface
-  IFACEMETHOD(QueryInterface)(IID const& iid, OUT void** ppObject) { return S_OK; }
-  IFACEMETHOD_(ULONG, AddRef)() { return 1; }
-  IFACEMETHOD_(ULONG, Release)() { return 1; }
+  IFACEMETHOD (QueryInterface) (IID const& iid, OUT void** ppObject) { return S_OK; }
+  IFACEMETHOD_ (ULONG, AddRef) () { return 1; }
+  IFACEMETHOD_ (ULONG, Release) () { return 1; }
 
   // IDWriteFontFileStream methods
-  virtual HRESULT STDMETHODCALLTYPE ReadFileFragment(void const** fragmentStart,
+  virtual HRESULT STDMETHODCALLTYPE ReadFileFragment (void const** fragmentStart,
     UINT64 fileOffset,
     UINT64 fragmentSize,
     OUT void** fragmentContext)
   {
     // We are required to do bounds checking.
-    if (fileOffset + fragmentSize > mSize) {
+    if (fileOffset + fragmentSize > mSize)
       return E_FAIL;
-    }
 
     // truncate the 64 bit fileOffset to size_t sized index into mData
     size_t index = static_cast<size_t> (fileOffset);
@@ -104,15 +115,15 @@ public:
     return S_OK;
   }
 
-  virtual void STDMETHODCALLTYPE ReleaseFileFragment(void* fragmentContext) { }
+  virtual void STDMETHODCALLTYPE ReleaseFileFragment (void* fragmentContext) { }
 
-  virtual HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64* fileSize)
+  virtual HRESULT STDMETHODCALLTYPE GetFileSize (OUT UINT64* fileSize)
   {
     *fileSize = mSize;
     return S_OK;
   }
 
-  virtual HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64* lastWriteTime)
+  virtual HRESULT STDMETHODCALLTYPE GetLastWriteTime (OUT UINT64* lastWriteTime)
   {
     return E_NOTIMPL;
   }
@@ -123,7 +134,8 @@ public:
 * shaper face data
 */
 
-struct hb_directwrite_shaper_face_data_t {
+struct hb_directwrite_shaper_face_data_t
+{
   IDWriteFactory *dwriteFactory;
   IDWriteFontFile *fontFile;
   IDWriteFontFileStream *fontFileStream;
@@ -133,10 +145,9 @@ struct hb_directwrite_shaper_face_data_t {
 };
 
 hb_directwrite_shaper_face_data_t *
-_hb_directwrite_shaper_face_data_create(hb_face_t *face)
+_hb_directwrite_shaper_face_data_create (hb_face_t *face)
 {
-  hb_directwrite_shaper_face_data_t *data =
-    (hb_directwrite_shaper_face_data_t *) malloc (sizeof (hb_directwrite_shaper_face_data_t));
+  hb_directwrite_shaper_face_data_t *data = new hb_directwrite_shaper_face_data_t;
   if (unlikely (!data))
     return nullptr;
 
@@ -150,10 +161,11 @@ _hb_directwrite_shaper_face_data_create(hb_face_t *face)
 
   HRESULT hr;
   hb_blob_t *blob = hb_face_reference_blob (face);
-  IDWriteFontFileStream *fontFileStream = new DWriteFontFileStream (
-    (uint8_t*) hb_blob_get_data (blob, nullptr), hb_blob_get_length (blob));
+  DWriteFontFileStream *fontFileStream = new DWriteFontFileStream (
+    (uint8_t *) hb_blob_get_data (blob, nullptr),
+    hb_blob_get_length (blob));
 
-  IDWriteFontFileLoader *fontFileLoader = new DWriteFontFileLoader (fontFileStream);
+  DWriteFontFileLoader *fontFileLoader = new DWriteFontFileLoader (fontFileStream);
   dwriteFactory->RegisterFontFileLoader (fontFileLoader);
 
   IDWriteFontFile *fontFile;
@@ -164,23 +176,19 @@ _hb_directwrite_shaper_face_data_create(hb_face_t *face)
 #define FAIL(...) \
   HB_STMT_START { \
     DEBUG_MSG (DIRECTWRITE, nullptr, __VA_ARGS__); \
-    return false; \
+    return nullptr; \
   } HB_STMT_END;
 
-  if (FAILED (hr)) {
+  if (FAILED (hr))
     FAIL ("Failed to load font file from data!");
-    return false;
-  }
 
   BOOL isSupported;
   DWRITE_FONT_FILE_TYPE fileType;
   DWRITE_FONT_FACE_TYPE faceType;
-  UINT32 numberOfFaces;
+  uint32_t numberOfFaces;
   hr = fontFile->Analyze (&isSupported, &fileType, &faceType, &numberOfFaces);
-  if (FAILED (hr) || !isSupported) {
+  if (FAILED (hr) || !isSupported)
     FAIL ("Font file is not supported.");
-    return false;
-  }
 
 #undef FAIL
 
@@ -199,13 +207,14 @@ _hb_directwrite_shaper_face_data_create(hb_face_t *face)
 }
 
 void
-_hb_directwrite_shaper_face_data_destroy(hb_directwrite_shaper_face_data_t *data)
+_hb_directwrite_shaper_face_data_destroy (hb_directwrite_shaper_face_data_t *data)
 {
   if (data->fontFace)
     data->fontFace->Release ();
   if (data->fontFile)
     data->fontFile->Release ();
-  if (data->dwriteFactory) {
+  if (data->dwriteFactory)
+  {
     if (data->fontFileLoader)
       data->dwriteFactory->UnregisterFontFileLoader (data->fontFileLoader);
     data->dwriteFactory->Release ();
@@ -217,7 +226,7 @@ _hb_directwrite_shaper_face_data_destroy(hb_directwrite_shaper_face_data_t *data
   if (data->faceBlob)
     hb_blob_destroy (data->faceBlob);
   if (data)
-    free (data);
+    delete data;
 }
 
 
@@ -225,7 +234,8 @@ _hb_directwrite_shaper_face_data_destroy(hb_directwrite_shaper_face_data_t *data
  * shaper font data
  */
 
-struct hb_directwrite_shaper_font_data_t {
+struct hb_directwrite_shaper_font_data_t
+{
 };
 
 hb_directwrite_shaper_font_data_t *
@@ -233,8 +243,7 @@ _hb_directwrite_shaper_font_data_create (hb_font_t *font)
 {
   if (unlikely (!hb_directwrite_shaper_face_data_ensure (font->face))) return nullptr;
 
-  hb_directwrite_shaper_font_data_t *data =
-    (hb_directwrite_shaper_font_data_t *) malloc (sizeof (hb_directwrite_shaper_font_data_t));
+  hb_directwrite_shaper_font_data_t *data = new hb_directwrite_shaper_font_data_t;
   if (unlikely (!data))
     return nullptr;
 
@@ -244,7 +253,7 @@ _hb_directwrite_shaper_font_data_create (hb_font_t *font)
 void
 _hb_directwrite_shaper_font_data_destroy (hb_directwrite_shaper_font_data_t *data)
 {
-  free (data);
+  delete data;
 }
 
 
@@ -276,54 +285,57 @@ class TextAnalysis
 {
 public:
 
-  IFACEMETHOD(QueryInterface)(IID const& iid, OUT void** ppObject) { return S_OK; }
-  IFACEMETHOD_(ULONG, AddRef)() { return 1; }
-  IFACEMETHOD_(ULONG, Release)() { return 1; }
+  IFACEMETHOD (QueryInterface) (IID const& iid, OUT void** ppObject) { return S_OK; }
+  IFACEMETHOD_ (ULONG, AddRef) () { return 1; }
+  IFACEMETHOD_ (ULONG, Release) () { return 1; }
 
-  // A single contiguous run of characters containing the same analysis 
+  // A single contiguous run of characters containing the same analysis
   // results.
   struct Run
   {
     uint32_t mTextStart;   // starting text position of this run
     uint32_t mTextLength;  // number of contiguous code units covered
     uint32_t mGlyphStart;  // starting glyph in the glyphs array
-    uint32_t mGlyphCount;  // number of glyphs associated with this run of 
+    uint32_t mGlyphCount;  // number of glyphs associated with this run
     // text
     DWRITE_SCRIPT_ANALYSIS mScript;
     uint8_t mBidiLevel;
     bool mIsSideways;
 
-    inline bool ContainsTextPosition(uint32_t aTextPosition) const
+    inline bool ContainsTextPosition (uint32_t aTextPosition) const
     {
-      return aTextPosition >= mTextStart
-        && aTextPosition <  mTextStart + mTextLength;
+      return aTextPosition >= mTextStart &&
+            aTextPosition <  mTextStart + mTextLength;
     }
 
     Run *nextRun;
   };
 
 public:
-  TextAnalysis(const wchar_t* text,
+  TextAnalysis (const wchar_t* text,
     uint32_t textLength,
     const wchar_t* localeName,
     DWRITE_READING_DIRECTION readingDirection)
-    : mText(text)
-    , mTextLength(textLength)
-    , mLocaleName(localeName)
-    , mReadingDirection(readingDirection)
-    , mCurrentRun(nullptr) { };
+    : mText (text)
+    , mTextLength (textLength)
+    , mLocaleName (localeName)
+    , mReadingDirection (readingDirection)
+    , mCurrentRun (nullptr) { };
 
-  ~TextAnalysis() {
+  ~TextAnalysis ()
+  {
     // delete runs, except mRunHead which is part of the TextAnalysis object
-    for (Run *run = mRunHead.nextRun; run;) {
+    for (Run *run = mRunHead.nextRun; run;)
+    {
       Run *origRun = run;
       run = run->nextRun;
-      free (origRun);
+      delete origRun;
     }
   }
 
-  STDMETHODIMP GenerateResults(IDWriteTextAnalyzer* textAnalyzer,
-    Run **runHead) {
+  STDMETHODIMP GenerateResults (IDWriteTextAnalyzer* textAnalyzer,
+    Run **runHead)
+  {
     // Analyzes the text using the script analyzer and returns
     // the result as a series of runs.
 
@@ -339,52 +351,55 @@ public:
     mCurrentRun = &mRunHead;
 
     // Call each of the analyzers in sequence, recording their results.
-    if (SUCCEEDED (hr = textAnalyzer->AnalyzeScript (this, 0, mTextLength, this))) {
+    if (SUCCEEDED (hr = textAnalyzer->AnalyzeScript (this, 0, mTextLength, this)))
       *runHead = &mRunHead;
-    }
 
     return hr;
   }
 
   // IDWriteTextAnalysisSource implementation
 
-  IFACEMETHODIMP GetTextAtPosition(uint32_t textPosition,
+  IFACEMETHODIMP GetTextAtPosition (uint32_t textPosition,
     OUT wchar_t const** textString,
     OUT uint32_t* textLength)
   {
-    if (textPosition >= mTextLength) {
+    if (textPosition >= mTextLength)
+    {
       // No text at this position, valid query though.
       *textString = nullptr;
       *textLength = 0;
     }
-    else {
+    else
+    {
       *textString = mText + textPosition;
       *textLength = mTextLength - textPosition;
     }
     return S_OK;
   }
 
-  IFACEMETHODIMP GetTextBeforePosition(uint32_t textPosition,
+  IFACEMETHODIMP GetTextBeforePosition (uint32_t textPosition,
     OUT wchar_t const** textString,
     OUT uint32_t* textLength)
   {
-    if (textPosition == 0 || textPosition > mTextLength) {
+    if (textPosition == 0 || textPosition > mTextLength)
+    {
       // Either there is no text before here (== 0), or this
       // is an invalid position. The query is considered valid though.
       *textString = nullptr;
       *textLength = 0;
     }
-    else {
+    else
+    {
       *textString = mText;
       *textLength = textPosition;
     }
     return S_OK;
   }
 
-  IFACEMETHODIMP_(DWRITE_READING_DIRECTION)
-    GetParagraphReadingDirection() { return mReadingDirection; }
+  IFACEMETHODIMP_ (DWRITE_READING_DIRECTION)
+    GetParagraphReadingDirection () { return mReadingDirection; }
 
-  IFACEMETHODIMP GetLocaleName(uint32_t textPosition,
+  IFACEMETHODIMP GetLocaleName (uint32_t textPosition,
     uint32_t* textLength,
     wchar_t const** localeName)
   {
@@ -392,7 +407,7 @@ public:
   }
 
   IFACEMETHODIMP
-    GetNumberSubstitution(uint32_t textPosition,
+    GetNumberSubstitution (uint32_t textPosition,
     OUT uint32_t* textLength,
     OUT IDWriteNumberSubstitution** numberSubstitution)
   {
@@ -406,15 +421,15 @@ public:
   // IDWriteTextAnalysisSink implementation
 
   IFACEMETHODIMP
-    SetScriptAnalysis(uint32_t textPosition,
+    SetScriptAnalysis (uint32_t textPosition,
     uint32_t textLength,
     DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis)
   {
-    SetCurrentRun(textPosition);
-    SplitCurrentRun(textPosition);
+    SetCurrentRun (textPosition);
+    SplitCurrentRun (textPosition);
     while (textLength > 0)
     {
-      Run *run = FetchNextRun(&textLength);
+      Run *run = FetchNextRun (&textLength);
       run->mScript = *scriptAnalysis;
     }
 
@@ -422,22 +437,22 @@ public:
   }
 
   IFACEMETHODIMP
-    SetLineBreakpoints(uint32_t textPosition,
+    SetLineBreakpoints (uint32_t textPosition,
     uint32_t textLength,
     const DWRITE_LINE_BREAKPOINT* lineBreakpoints) { return S_OK; }
 
-  IFACEMETHODIMP SetBidiLevel(uint32_t textPosition,
+  IFACEMETHODIMP SetBidiLevel (uint32_t textPosition,
     uint32_t textLength,
     uint8_t explicitLevel,
     uint8_t resolvedLevel) { return S_OK; }
 
   IFACEMETHODIMP
-    SetNumberSubstitution(uint32_t textPosition,
+    SetNumberSubstitution (uint32_t textPosition,
     uint32_t textLength,
     IDWriteNumberSubstitution* numberSubstitution) { return S_OK; }
 
 protected:
-  Run *FetchNextRun(IN OUT uint32_t* textLength)
+  Run *FetchNextRun (IN OUT uint32_t* textLength)
   {
     // Used by the sink setters, this returns a reference to the next run.
     // Position and length are adjusted to now point after the current run
@@ -447,21 +462,17 @@ protected:
     // Split the tail if needed (the length remaining is less than the
     // current run's size).
     if (*textLength < mCurrentRun->mTextLength)
-    {
       SplitCurrentRun (mCurrentRun->mTextStart + *textLength);
-    }
     else
-    {
       // Just advance the current run.
       mCurrentRun = mCurrentRun->nextRun;
-    }
     *textLength -= origRun->mTextLength;
 
     // Return a reference to the run that was just current.
     return origRun;
   }
 
-  void SetCurrentRun(uint32_t textPosition)
+  void SetCurrentRun (uint32_t textPosition)
   {
     // Move the current run to the given position.
     // Since the analyzers generally return results in a forward manner,
@@ -469,26 +480,22 @@ protected:
     // corresponding run for the text position.
 
     if (mCurrentRun && mCurrentRun->ContainsTextPosition (textPosition))
-    {
       return;
-    }
 
-    for (Run *run = &mRunHead; run; run = run->nextRun) {
+    for (Run *run = &mRunHead; run; run = run->nextRun)
       if (run->ContainsTextPosition (textPosition))
       {
-        mCurrentRun = run;
-        return;
+       mCurrentRun = run;
+       return;
       }
-    }
-    //NS_NOTREACHED("We should always be able to find the text position in one \
-            //                of our runs");
+    assert (0); // We should always be able to find the text position in one of our runs
   }
 
-  void SplitCurrentRun(uint32_t splitPosition)
+  void SplitCurrentRun (uint32_t splitPosition)
   {
     if (!mCurrentRun)
     {
-      //NS_ASSERTION(false, "SplitCurrentRun called without current run.");
+      assert (0); // SplitCurrentRun called without current run
       // Shouldn't be calling this when no current run is set!
       return;
     }
@@ -499,7 +506,7 @@ protected:
       // or before it. Usually the first.
       return;
     }
-    Run *newRun = (Run*) malloc (sizeof (Run));
+    Run *newRun = new Run;
 
     *newRun = *mCurrentRun;
 
@@ -534,14 +541,14 @@ protected:
 static inline uint16_t hb_uint16_swap (const uint16_t v)
 { return (v >> 8) | (v << 8); }
 static inline uint32_t hb_uint32_swap (const uint32_t v)
-{ return (hb_uint16_swap(v) << 16) | hb_uint16_swap(v >> 16); }
+{ return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); }
 
 /*
  * shaper
  */
 
 static hb_bool_t
-_hb_directwrite_shape_full(hb_shape_plan_t    *shape_plan,
+_hb_directwrite_shape_full (hb_shape_plan_t    *shape_plan,
   hb_font_t          *font,
   hb_buffer_t        *buffer,
   const hb_feature_t *features,
@@ -555,7 +562,7 @@ _hb_directwrite_shape_full(hb_shape_plan_t    *shape_plan,
   IDWriteFontFace *fontFace = face_data->fontFace;
 
   IDWriteTextAnalyzer* analyzer;
-  dwriteFactory->CreateTextAnalyzer(&analyzer);
+  dwriteFactory->CreateTextAnalyzer (&analyzer);
 
   unsigned int scratch_size;
   hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size);
@@ -570,41 +577,39 @@ _hb_directwrite_shape_full(hb_shape_plan_t    *shape_plan,
 
 #define utf16_index() var1.u32
 
-  ALLOCATE_ARRAY(wchar_t, textString, buffer->len * 2);
+  ALLOCATE_ARRAY (wchar_t, textString, buffer->len * 2);
 
   unsigned int chars_len = 0;
   for (unsigned int i = 0; i < buffer->len; i++)
   {
     hb_codepoint_t c = buffer->info[i].codepoint;
-    buffer->info[i].utf16_index() = chars_len;
-    if (likely(c <= 0xFFFFu))
+    buffer->info[i].utf16_index () = chars_len;
+    if (likely (c <= 0xFFFFu))
       textString[chars_len++] = c;
-    else if (unlikely(c > 0x10FFFFu))
+    else if (unlikely (c > 0x10FFFFu))
       textString[chars_len++] = 0xFFFDu;
-    else {
+    else
+    {
       textString[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10);
       textString[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1u << 10) - 1));
     }
   }
 
-  ALLOCATE_ARRAY(WORD, log_clusters, chars_len);
-  // if (num_features)
+  ALLOCATE_ARRAY (WORD, log_clusters, chars_len);
+  /* Need log_clusters to assign features. */
+  chars_len = 0;
+  for (unsigned int i = 0; i < buffer->len; i++)
   {
-    /* Need log_clusters to assign features. */
-    chars_len = 0;
-    for (unsigned int i = 0; i < buffer->len; i++)
-    {
-      hb_codepoint_t c = buffer->info[i].codepoint;
-      unsigned int cluster = buffer->info[i].cluster;
-      log_clusters[chars_len++] = cluster;
-      if (hb_in_range(c, 0x10000u, 0x10FFFFu))
-        log_clusters[chars_len++] = cluster; /* Surrogates. */
-    }
+    hb_codepoint_t c = buffer->info[i].codepoint;
+    unsigned int cluster = buffer->info[i].cluster;
+    log_clusters[chars_len++] = cluster;
+    if (hb_in_range (c, 0x10000u, 0x10FFFFu))
+      log_clusters[chars_len++] = cluster; /* Surrogates. */
   }
 
   // TODO: Handle TEST_DISABLE_OPTIONAL_LIGATURES
 
-  DWRITE_READING_DIRECTION readingDirection = buffer->props.direction ? 
+  DWRITE_READING_DIRECTION readingDirection = buffer->props.direction ?
     DWRITE_READING_DIRECTION_RIGHT_TO_LEFT :
     DWRITE_READING_DIRECTION_LEFT_TO_RIGHT;
 
@@ -615,10 +620,10 @@ _hb_directwrite_shape_full(hb_shape_plan_t    *shape_plan,
   */
   uint32_t textLength = buffer->len;
 
-  TextAnalysis analysis(textString, textLength, nullptr, readingDirection);
+  TextAnalysis analysis (textString, textLength, nullptr, readingDirection);
   TextAnalysis::Run *runHead;
   HRESULT hr;
-  hr = analysis.GenerateResults(analyzer, &runHead);
+  hr = analysis.GenerateResults (analyzer, &runHead);
 
 #define FAIL(...) \
   HB_STMT_START { \
@@ -627,10 +632,7 @@ _hb_directwrite_shape_full(hb_shape_plan_t    *shape_plan,
   } HB_STMT_END;
 
   if (FAILED (hr))
-  {
     FAIL ("Analyzer failed to generate results.");
-    return false;
-  }
 
   uint32_t maxGlyphCount = 3 * textLength / 2 + 16;
   uint32_t glyphCount;
@@ -643,31 +645,31 @@ _hb_directwrite_shape_full(hb_shape_plan_t    *shape_plan,
       hb_language_to_string (buffer->props.language), 20);
   }
 
-  DWRITE_TYPOGRAPHIC_FEATURES singleFeatures;
-  singleFeatures.featureCount = num_features;
+  // TODO: it does work but doesn't care about ranges
+  DWRITE_TYPOGRAPHIC_FEATURES typographic_features;
+  typographic_features.featureCount = num_features;
   if (num_features)
   {
-    DWRITE_FONT_FEATURE* dwfeatureArray = (DWRITE_FONT_FEATURE*)
-      malloc (sizeof (DWRITE_FONT_FEATURE) * num_features);
+    typographic_features.features = new DWRITE_FONT_FEATURE[num_features];
     for (unsigned int i = 0; i < num_features; ++i)
     {
-      dwfeatureArray[i].nameTag = (DWRITE_FONT_FEATURE_TAG)
-        hb_uint32_swap (features[i].tag);
-      dwfeatureArray[i].parameter = features[i].value;
+      typographic_features.features[i].nameTag = (DWRITE_FONT_FEATURE_TAG)
+       hb_uint32_swap (features[i].tag);
+      typographic_features.features[i].parameter = features[i].value;
     }
-    singleFeatures.features = dwfeatureArray;
   }
   const DWRITE_TYPOGRAPHIC_FEATURES* dwFeatures =
-    (const DWRITE_TYPOGRAPHIC_FEATURES*) &singleFeatures;
+    (const DWRITE_TYPOGRAPHIC_FEATURES*) &typographic_features;
   const uint32_t featureRangeLengths[] = { textLength };
+  //
 
-  uint16_t* clusterMap = (uint16_t*) malloc (textLength * sizeof (uint16_t));
-  DWRITE_SHAPING_TEXT_PROPERTIES* textProperties = (DWRITE_SHAPING_TEXT_PROPERTIES*)
-    malloc (textLength * sizeof (DWRITE_SHAPING_TEXT_PROPERTIES));
+  uint16_t* clusterMap = new uint16_t[textLength];
+  DWRITE_SHAPING_TEXT_PROPERTIES* textProperties =
+    new DWRITE_SHAPING_TEXT_PROPERTIES[textLength];
 retry_getglyphs:
-  uint16_t* glyphIndices = (uint16_t*) malloc (maxGlyphCount * sizeof (uint16_t));
-  DWRITE_SHAPING_GLYPH_PROPERTIES* glyphProperties = (DWRITE_SHAPING_GLYPH_PROPERTIES*)
-    malloc (maxGlyphCount * sizeof (DWRITE_SHAPING_GLYPH_PROPERTIES));
+  uint16_t* glyphIndices = new uint16_t[maxGlyphCount];
+  DWRITE_SHAPING_GLYPH_PROPERTIES* glyphProperties =
+    new DWRITE_SHAPING_GLYPH_PROPERTIES[maxGlyphCount];
 
   hr = analyzer->GetGlyphs (textString, textLength, fontFace, false,
     isRightToLeft, &runHead->mScript, localeName, nullptr, &dwFeatures,
@@ -676,36 +678,32 @@ retry_getglyphs:
 
   if (unlikely (hr == HRESULT_FROM_WIN32 (ERROR_INSUFFICIENT_BUFFER)))
   {
-    free (glyphIndices);
-    free (glyphProperties);
+    delete [] glyphIndices;
+    delete [] glyphProperties;
 
     maxGlyphCount *= 2;
 
     goto retry_getglyphs;
   }
   if (FAILED (hr))
-  {
     FAIL ("Analyzer failed to get glyphs.");
-    return false;
-  }
 
-  float* glyphAdvances = (float*) malloc (maxGlyphCount * sizeof (float));
-  DWRITE_GLYPH_OFFSET* glyphOffsets = (DWRITE_GLYPH_OFFSET*)
-    malloc(maxGlyphCount * sizeof (DWRITE_GLYPH_OFFSET));
+  float* glyphAdvances = new float[maxGlyphCount];
+  DWRITE_GLYPH_OFFSET* glyphOffsets = new DWRITE_GLYPH_OFFSET[maxGlyphCount];
 
   /* The -2 in the following is to compensate for possible
-   * alignment needed after the WORD array.  sizeof(WORD) == 2. */
-  unsigned int glyphs_size = (scratch_size * sizeof(int) - 2)
-         / (sizeof(WORD) +
-            sizeof(DWRITE_SHAPING_GLYPH_PROPERTIES) +
-            sizeof(int) +
-            sizeof(DWRITE_GLYPH_OFFSET) +
-            sizeof(uint32_t));
+   * alignment needed after the WORD array.  sizeof (WORD) == 2. */
+  unsigned int glyphs_size = (scratch_size * sizeof (int) - 2)
+         / (sizeof (WORD) +
+            sizeof (DWRITE_SHAPING_GLYPH_PROPERTIES) +
+            sizeof (int) +
+            sizeof (DWRITE_GLYPH_OFFSET) +
+            sizeof (uint32_t));
   ALLOCATE_ARRAY (uint32_t, vis_clusters, glyphs_size);
 
 #undef ALLOCATE_ARRAY
 
-  int fontEmSize = font->face->get_upem();
+  int fontEmSize = font->face->get_upem ();
   if (fontEmSize < 0)
     fontEmSize = -fontEmSize;
 
@@ -722,10 +720,7 @@ retry_getglyphs:
     glyphAdvances, glyphOffsets);
 
   if (FAILED (hr))
-  {
     FAIL ("Analyzer failed to get glyph placements.");
-    return false;
-  }
 
   IDWriteTextAnalyzer1* analyzer1;
   analyzer->QueryInterface (&analyzer1);
@@ -734,77 +729,62 @@ retry_getglyphs:
   {
 
     DWRITE_JUSTIFICATION_OPPORTUNITY* justificationOpportunities =
-      (DWRITE_JUSTIFICATION_OPPORTUNITY*)
-      malloc (maxGlyphCount * sizeof (DWRITE_JUSTIFICATION_OPPORTUNITY));
+      new DWRITE_JUSTIFICATION_OPPORTUNITY[maxGlyphCount];
     hr = analyzer1->GetJustificationOpportunities (fontFace, fontEmSize,
       runHead->mScript, textLength, glyphCount, textString, clusterMap,
       glyphProperties, justificationOpportunities);
 
     if (FAILED (hr))
-    {
       FAIL ("Analyzer failed to get justification opportunities.");
-      return false;
-    }
 
-    float* justifiedGlyphAdvances =
-      (float*) malloc (maxGlyphCount * sizeof (float));
-    DWRITE_GLYPH_OFFSET* justifiedGlyphOffsets = (DWRITE_GLYPH_OFFSET*)
-      malloc (glyphCount * sizeof (DWRITE_GLYPH_OFFSET));
+    float* justifiedGlyphAdvances = new float[maxGlyphCount];
+    DWRITE_GLYPH_OFFSET* justifiedGlyphOffsets = new DWRITE_GLYPH_OFFSET[glyphCount];
     hr = analyzer1->JustifyGlyphAdvances (lineWidth, glyphCount, justificationOpportunities,
       glyphAdvances, glyphOffsets, justifiedGlyphAdvances, justifiedGlyphOffsets);
 
     if (FAILED (hr))
-    {
-      FAIL("Analyzer failed to get justified glyph advances.");
-      return false;
-    }
+      FAIL ("Analyzer failed to get justified glyph advances.");
 
     DWRITE_SCRIPT_PROPERTIES scriptProperties;
     hr = analyzer1->GetScriptProperties (runHead->mScript, &scriptProperties);
     if (FAILED (hr))
-    {
-      FAIL("Analyzer failed to get script properties.");
-      return false;
-    }
+      FAIL ("Analyzer failed to get script properties.");
     uint32_t justificationCharacter = scriptProperties.justificationCharacter;
 
     // if a script justificationCharacter is not space, it can have GetJustifiedGlyphs
     if (justificationCharacter != 32)
     {
-      uint16_t* modifiedClusterMap = (uint16_t*) malloc (textLength * sizeof (uint16_t));
+      uint16_t* modifiedClusterMap = new uint16_t[textLength];
     retry_getjustifiedglyphs:
-      uint16_t* modifiedGlyphIndices = (uint16_t*) malloc (maxGlyphCount * sizeof (uint16_t));
-      float* modifiedGlyphAdvances = (float*) malloc (maxGlyphCount * sizeof (float));
-      DWRITE_GLYPH_OFFSET* modifiedGlyphOffsets = (DWRITE_GLYPH_OFFSET*)
-        malloc (maxGlyphCount * sizeof (DWRITE_GLYPH_OFFSET));
+      uint16_t* modifiedGlyphIndices = new uint16_t[maxGlyphCount];
+      float* modifiedGlyphAdvances = new float[maxGlyphCount];
+      DWRITE_GLYPH_OFFSET* modifiedGlyphOffsets =
+       new DWRITE_GLYPH_OFFSET[maxGlyphCount];
       uint32_t actualGlyphsCount;
       hr = analyzer1->GetJustifiedGlyphs (fontFace, fontEmSize, runHead->mScript,
-        textLength, glyphCount, maxGlyphCount, clusterMap, glyphIndices,
-        glyphAdvances, justifiedGlyphAdvances, justifiedGlyphOffsets,
-        glyphProperties, &actualGlyphsCount, modifiedClusterMap, modifiedGlyphIndices,
-        modifiedGlyphAdvances, modifiedGlyphOffsets);
+       textLength, glyphCount, maxGlyphCount, clusterMap, glyphIndices,
+       glyphAdvances, justifiedGlyphAdvances, justifiedGlyphOffsets,
+       glyphProperties, &actualGlyphsCount, modifiedClusterMap, modifiedGlyphIndices,
+       modifiedGlyphAdvances, modifiedGlyphOffsets);
 
       if (hr == HRESULT_FROM_WIN32 (ERROR_INSUFFICIENT_BUFFER))
       {
-        maxGlyphCount = actualGlyphsCount;
-        free (modifiedGlyphIndices);
-        free (modifiedGlyphAdvances);
-        free (modifiedGlyphOffsets);
+       maxGlyphCount = actualGlyphsCount;
+       delete [] modifiedGlyphIndices;
+       delete [] modifiedGlyphAdvances;
+       delete [] modifiedGlyphOffsets;
 
-        maxGlyphCount = actualGlyphsCount;
+       maxGlyphCount = actualGlyphsCount;
 
-        goto retry_getjustifiedglyphs;
+       goto retry_getjustifiedglyphs;
       }
       if (FAILED (hr))
-      {
-        FAIL ("Analyzer failed to get justified glyphs.");
-        return false;
-      }
+       FAIL ("Analyzer failed to get justified glyphs.");
 
-      free (clusterMap);
-      free (glyphIndices);
-      free (glyphAdvances);
-      free (glyphOffsets);
+      delete [] clusterMap;
+      delete [] glyphIndices;
+      delete [] glyphAdvances;
+      delete [] glyphOffsets;
 
       glyphCount = actualGlyphsCount;
       clusterMap = modifiedClusterMap;
@@ -812,19 +792,19 @@ retry_getglyphs:
       glyphAdvances = modifiedGlyphAdvances;
       glyphOffsets = modifiedGlyphOffsets;
 
-      free (justifiedGlyphAdvances);
-      free (justifiedGlyphOffsets);
+      delete [] justifiedGlyphAdvances;
+      delete [] justifiedGlyphOffsets;
     }
     else
     {
-      free (glyphAdvances);
-      free (glyphOffsets);
+      delete [] glyphAdvances;
+      delete [] glyphOffsets;
 
       glyphAdvances = justifiedGlyphAdvances;
       glyphOffsets = justifiedGlyphOffsets;
     }
 
-    free (justificationOpportunities);
+    delete [] justificationOpportunities;
 
   }
 
@@ -837,7 +817,7 @@ retry_getglyphs:
   for (unsigned int i = 0; i < buffer->len; i++)
   {
     uint32_t *p =
-      &vis_clusters[log_clusters[buffer->info[i].utf16_index()]];
+      &vis_clusters[log_clusters[buffer->info[i].utf16_index ()]];
     *p = MIN (*p, buffer->info[i].cluster);
   }
   for (unsigned int i = 1; i < glyphCount; i++)
@@ -883,28 +863,28 @@ retry_getglyphs:
   if (isRightToLeft)
     hb_buffer_reverse (buffer);
 
-  free (clusterMap);
-  free (glyphIndices);
-  free (textProperties);
-  free (glyphProperties);
-  free (glyphAdvances);
-  free (glyphOffsets);
+  delete [] clusterMap;
+  delete [] glyphIndices;
+  delete [] textProperties;
+  delete [] glyphProperties;
+  delete [] glyphAdvances;
+  delete [] glyphOffsets;
 
   if (num_features)
-    free (singleFeatures.features);
+    delete [] typographic_features.features;
 
   /* Wow, done! */
   return true;
 }
 
 hb_bool_t
-_hb_directwrite_shape(hb_shape_plan_t    *shape_plan,
+_hb_directwrite_shape (hb_shape_plan_t    *shape_plan,
   hb_font_t          *font,
   hb_buffer_t        *buffer,
   const hb_feature_t *features,
   unsigned int        num_features)
 {
-  return _hb_directwrite_shape_full(shape_plan, font, buffer,
+  return _hb_directwrite_shape_full (shape_plan, font, buffer,
     features, num_features, 0);
 }
 
@@ -913,13 +893,13 @@ _hb_directwrite_shape(hb_shape_plan_t    *shape_plan,
  */
 
 hb_bool_t
-hb_directwrite_shape_experimental_width(hb_font_t          *font,
+hb_directwrite_shape_experimental_width (hb_font_t          *font,
   hb_buffer_t        *buffer,
   const hb_feature_t *features,
   unsigned int        num_features,
   float               width)
 {
-  static char *shapers = "directwrite";
+  static const char *shapers = "directwrite";
   hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face,
     &buffer->props, features, num_features, &shapers);
   hb_bool_t res = _hb_directwrite_shape_full (shape_plan, font, buffer,
index e743af2..9bfd1f7 100644 (file)
@@ -30,8 +30,9 @@
 HB_BEGIN_DECLS
 
 HB_EXTERN hb_bool_t
-hb_directwrite_shape_experimental_width(hb_font_t *font, hb_buffer_t *buffer,
-  const hb_feature_t *features, unsigned int num_features, float width);
+hb_directwrite_shape_experimental_width (hb_font_t *font, hb_buffer_t *buffer,
+                                        const hb_feature_t *features,
+                                        unsigned int num_features, float width);
 
 HB_END_DECLS
 
index e413847..9586871 100644 (file)
@@ -49,7 +49,7 @@ hb_bsearch_r (const void *key, const void *base,
     else
       return (void *) p;
   }
-  return NULL;
+  return nullptr;
 }
 
 
index d8af8c1..2fef09d 100644 (file)
 #include "hb-private.hh"
 
 #include "hb-face-private.hh"
+#include "hb-blob-private.hh"
 #include "hb-open-file-private.hh"
 #include "hb-ot-head-table.hh"
 #include "hb-ot-maxp-table.hh"
 
 
+
+/**
+ * hb_face_count: Get number of faces on the blob
+ * @blob:
+ *
+ *
+ *
+ * Return value: Number of faces on the blob
+ *
+ * Since: 1.7.7
+ **/
+unsigned int
+hb_face_count (hb_blob_t *blob)
+{
+  if (unlikely (!blob))
+    return 0;
+
+  hb_blob_t *sanitized = OT::Sanitizer<OT::OpenTypeFontFile> ().sanitize (blob);
+  const OT::OpenTypeFontFile& ot = *sanitized->as<OT::OpenTypeFontFile> ();
+
+  return ot.get_face_count ();
+}
+
 /*
  * hb_face_t
  */
@@ -64,10 +88,10 @@ const hb_face_t _hb_face_nil = {
 /**
  * hb_face_create_for_tables:
  * @reference_table_func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data: 
- * @destroy: 
+ * @user_data:
+ * @destroy:
+ *
  *
- * 
  *
  * Return value: (transfer full)
  *
@@ -134,7 +158,7 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void
   if (tag == HB_TAG_NONE)
     return hb_blob_reference (data->blob);
 
-  const OT::OpenTypeFontFile &ot_file = *OT::Sanitizer<OT::OpenTypeFontFile>::lock_instance (data->blob);
+  const OT::OpenTypeFontFile &ot_file = *data->blob->as<OT::OpenTypeFontFile> ();
   const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index);
 
   const OT::OpenTypeTable &table = ot_face.get_table_by_tag (tag);
@@ -146,10 +170,10 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void
 
 /**
  * hb_face_create: (Xconstructor)
- * @blob: 
- * @index: 
+ * @blob:
+ * @index:
+ *
  *
- * 
  *
  * Return value: (transfer full):
  *
@@ -181,7 +205,7 @@ hb_face_create (hb_blob_t    *blob,
 /**
  * hb_face_get_empty:
  *
- * 
+ *
  *
  * Return value: (transfer full)
  *
@@ -198,9 +222,9 @@ hb_face_get_empty (void)
  * hb_face_reference: (skip)
  * @face: a face.
  *
- * 
  *
- * Return value: 
+ *
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -214,7 +238,7 @@ hb_face_reference (hb_face_t *face)
  * hb_face_destroy: (skip)
  * @face: a face.
  *
- * 
+ *
  *
  * Since: 0.9.2
  **/
@@ -244,14 +268,14 @@ hb_face_destroy (hb_face_t *face)
 /**
  * hb_face_set_user_data: (skip)
  * @face: a face.
- * @key: 
- * @data: 
- * @destroy: 
- * @replace: 
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
  *
- * 
  *
- * Return value: 
+ *
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -268,9 +292,9 @@ hb_face_set_user_data (hb_face_t          *face,
 /**
  * hb_face_get_user_data: (skip)
  * @face: a face.
- * @key: 
+ * @key:
+ *
  *
- * 
  *
  * Return value: (transfer none):
  *
@@ -287,7 +311,7 @@ hb_face_get_user_data (hb_face_t          *face,
  * hb_face_make_immutable:
  * @face: a face.
  *
- * 
+ *
  *
  * Since: 0.9.2
  **/
@@ -304,9 +328,9 @@ hb_face_make_immutable (hb_face_t *face)
  * hb_face_is_immutable:
  * @face: a face.
  *
- * 
  *
- * Return value: 
+ *
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -320,9 +344,9 @@ hb_face_is_immutable (hb_face_t *face)
 /**
  * hb_face_reference_table:
  * @face: a face.
- * @tag: 
+ * @tag:
+ *
  *
- * 
  *
  * Return value: (transfer full):
  *
@@ -339,7 +363,7 @@ hb_face_reference_table (hb_face_t *face,
  * hb_face_reference_blob:
  * @face: a face.
  *
- * 
+ *
  *
  * Return value: (transfer full):
  *
@@ -354,9 +378,9 @@ hb_face_reference_blob (hb_face_t *face)
 /**
  * hb_face_set_index:
  * @face: a face.
- * @index: 
+ * @index:
+ *
  *
- * 
  *
  * Since: 0.9.2
  **/
@@ -374,9 +398,9 @@ hb_face_set_index (hb_face_t    *face,
  * hb_face_get_index:
  * @face: a face.
  *
- * 
  *
- * Return value: 
+ *
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -389,9 +413,9 @@ hb_face_get_index (hb_face_t    *face)
 /**
  * hb_face_set_upem:
  * @face: a face.
- * @upem: 
+ * @upem:
+ *
  *
- * 
  *
  * Since: 0.9.2
  **/
@@ -409,9 +433,9 @@ hb_face_set_upem (hb_face_t    *face,
  * hb_face_get_upem:
  * @face: a face.
  *
- * 
  *
- * Return value: 
+ *
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -425,7 +449,7 @@ void
 hb_face_t::load_upem (void) const
 {
   hb_blob_t *head_blob = OT::Sanitizer<OT::head>().sanitize (reference_table (HB_OT_TAG_head));
-  const OT::head *head_table = OT::Sanitizer<OT::head>::lock_instance (head_blob);
+  const OT::head *head_table = head_blob->as<OT::head> ();
   upem = head_table->get_upem ();
   hb_blob_destroy (head_blob);
 }
@@ -433,9 +457,9 @@ hb_face_t::load_upem (void) const
 /**
  * hb_face_set_glyph_count:
  * @face: a face.
- * @glyph_count: 
+ * @glyph_count:
+ *
  *
- * 
  *
  * Since: 0.9.7
  **/
@@ -453,9 +477,9 @@ hb_face_set_glyph_count (hb_face_t    *face,
  * hb_face_get_glyph_count:
  * @face: a face.
  *
- * 
  *
- * Return value: 
+ *
+ * Return value:
  *
  * Since: 0.9.7
  **/
@@ -469,7 +493,7 @@ void
 hb_face_t::load_num_glyphs (void) const
 {
   hb_blob_t *maxp_blob = OT::Sanitizer<OT::maxp>().sanitize (reference_table (HB_OT_TAG_maxp));
-  const OT::maxp *maxp_table = OT::Sanitizer<OT::maxp>::lock_instance (maxp_blob);
+  const OT::maxp *maxp_table = maxp_blob->as<OT::maxp> ();
   num_glyphs = maxp_table->get_num_glyphs ();
   hb_blob_destroy (maxp_blob);
 }
@@ -490,7 +514,7 @@ hb_face_get_table_tags (hb_face_t    *face,
                        unsigned int *table_count, /* IN/OUT */
                        hb_tag_t     *table_tags /* OUT */)
 {
-  if (face->destroy != _hb_face_for_data_closure_destroy)
+  if (face->destroy != (hb_destroy_func_t) _hb_face_for_data_closure_destroy)
   {
     if (table_count)
       *table_count = 0;
@@ -499,7 +523,7 @@ hb_face_get_table_tags (hb_face_t    *face,
 
   hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) face->user_data;
 
-  const OT::OpenTypeFontFile &ot_file = *OT::Sanitizer<OT::OpenTypeFontFile>::lock_instance (data->blob);
+  const OT::OpenTypeFontFile &ot_file = *data->blob->as<OT::OpenTypeFontFile> ();
   const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index);
 
   return ot_face.get_table_tags (start_offset, table_count, table_tags);
index 0ce8d04..983ee56 100644 (file)
 HB_BEGIN_DECLS
 
 
+HB_EXTERN unsigned int
+hb_face_count (hb_blob_t *blob);
+
+
 /*
  * hb_face_t
  */
index 992152f..7ba16cd 100644 (file)
@@ -83,7 +83,11 @@ struct hb_font_funcs_t {
       HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
 #undef HB_FONT_FUNC_IMPLEMENT
     } f;
-    void (*array[VAR]) (void);
+    void (*array[0
+#define HB_FONT_FUNC_IMPLEMENT(name) +1
+      HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
+               ]) (void);
   } get;
 };
 
index f3534b6..4d62b9e 100644 (file)
@@ -127,7 +127,7 @@ hb_font_get_variation_glyph_parent (hb_font_t *font,
 
 
 static hb_position_t
-hb_font_get_glyph_h_advance_nil (hb_font_t *font HB_UNUSED,
+hb_font_get_glyph_h_advance_nil (hb_font_t *font,
                                 void *font_data HB_UNUSED,
                                 hb_codepoint_t glyph,
                                 void *user_data HB_UNUSED)
@@ -144,7 +144,7 @@ hb_font_get_glyph_h_advance_parent (hb_font_t *font,
 }
 
 static hb_position_t
-hb_font_get_glyph_v_advance_nil (hb_font_t *font HB_UNUSED,
+hb_font_get_glyph_v_advance_nil (hb_font_t *font,
                                 void *font_data HB_UNUSED,
                                 hb_codepoint_t glyph,
                                 void *user_data HB_UNUSED)
index fc4b112..7caafba 100644 (file)
@@ -109,7 +109,7 @@ _hb_ft_font_destroy (void *data)
  * @font:
  * @load_flags:
  *
- * 
+ *
  *
  * Since: 1.0.5
  **/
@@ -119,7 +119,7 @@ hb_ft_font_set_load_flags (hb_font_t *font, int load_flags)
   if (font->immutable)
     return;
 
-  if (font->destroy != _hb_ft_font_destroy)
+  if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
     return;
 
   hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data;
@@ -131,7 +131,7 @@ hb_ft_font_set_load_flags (hb_font_t *font, int load_flags)
  * hb_ft_font_get_load_flags:
  * @font:
  *
- * 
+ *
  *
  * Return value:
  * Since: 1.0.5
@@ -139,7 +139,7 @@ hb_ft_font_set_load_flags (hb_font_t *font, int load_flags)
 int
 hb_ft_font_get_load_flags (hb_font_t *font)
 {
-  if (font->destroy != _hb_ft_font_destroy)
+  if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
     return 0;
 
   const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data;
@@ -150,7 +150,7 @@ hb_ft_font_get_load_flags (hb_font_t *font)
 FT_Face
 hb_ft_font_get_face (hb_font_t *font)
 {
-  if (font->destroy != _hb_ft_font_destroy)
+  if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
     return nullptr;
 
   const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data;
@@ -177,7 +177,7 @@ hb_ft_get_nominal_glyph (hb_font_t *font HB_UNUSED,
       /* For symbol-encoded OpenType fonts, we duplicate the
        * U+F000..F0FF range at U+0000..U+00FF.  That's what
        * Windows seems to do, and that's hinted about at:
-       * http://www.microsoft.com/typography/otspec/recom.htm
+       * https://docs.microsoft.com/en-us/typography/opentype/spec/recom
        * under "Non-Standard (Symbol) Fonts". */
       g = FT_Get_Char_Index (ft_font->ft_face, 0xF000u + unicode);
       if (!g)
@@ -210,7 +210,7 @@ hb_ft_get_variation_glyph (hb_font_t *font HB_UNUSED,
 }
 
 static hb_position_t
-hb_ft_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
+hb_ft_get_glyph_h_advance (hb_font_t *font,
                           void *font_data,
                           hb_codepoint_t glyph,
                           void *user_data HB_UNUSED)
@@ -228,7 +228,7 @@ hb_ft_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
 }
 
 static hb_position_t
-hb_ft_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
+hb_ft_get_glyph_v_advance (hb_font_t *font,
                           void *font_data,
                           hb_codepoint_t glyph,
                           void *user_data HB_UNUSED)
@@ -248,7 +248,7 @@ hb_ft_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
 }
 
 static hb_bool_t
-hb_ft_get_glyph_v_origin (hb_font_t *font HB_UNUSED,
+hb_ft_get_glyph_v_origin (hb_font_t *font,
                          void *font_data,
                          hb_codepoint_t glyph,
                          hb_position_t *x,
@@ -292,7 +292,7 @@ hb_ft_get_glyph_h_kerning (hb_font_t *font,
 }
 
 static hb_bool_t
-hb_ft_get_glyph_extents (hb_font_t *font HB_UNUSED,
+hb_ft_get_glyph_extents (hb_font_t *font,
                         void *font_data,
                         hb_codepoint_t glyph,
                         hb_glyph_extents_t *extents,
@@ -423,7 +423,12 @@ static hb_font_funcs_t *static_ft_funcs = nullptr;
 static
 void free_static_ft_funcs (void)
 {
-  hb_font_funcs_destroy (static_ft_funcs);
+retry:
+  hb_font_funcs_t *ft_funcs = (hb_font_funcs_t *) hb_atomic_ptr_get (&static_ft_funcs);
+  if (!hb_atomic_ptr_cmpexch (&static_ft_funcs, ft_funcs, nullptr))
+    goto retry;
+
+  hb_font_funcs_destroy (ft_funcs);
 }
 #endif
 
@@ -502,12 +507,12 @@ reference_table  (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
 
 /**
  * hb_ft_face_create:
- * @ft_face: (destroy destroy) (scope notified): 
+ * @ft_face: (destroy destroy) (scope notified):
  * @destroy:
  *
- * 
  *
- * Return value: (transfer full): 
+ *
+ * Return value: (transfer full):
  * Since: 0.9.2
  **/
 hb_face_t *
@@ -539,9 +544,9 @@ hb_ft_face_create (FT_Face           ft_face,
  * hb_ft_face_create_referenced:
  * @ft_face:
  *
- * 
  *
- * Return value: (transfer full): 
+ *
+ * Return value: (transfer full):
  * Since: 0.9.38
  **/
 hb_face_t *
@@ -559,11 +564,11 @@ hb_ft_face_finalize (FT_Face ft_face)
 
 /**
  * hb_ft_face_create_cached:
- * @ft_face: 
+ * @ft_face:
  *
- * 
  *
- * Return value: (transfer full): 
+ *
+ * Return value: (transfer full):
  * Since: 0.9.2
  **/
 hb_face_t *
@@ -584,12 +589,12 @@ hb_ft_face_create_cached (FT_Face ft_face)
 
 /**
  * hb_ft_font_create:
- * @ft_face: (destroy destroy) (scope notified): 
+ * @ft_face: (destroy destroy) (scope notified):
  * @destroy:
  *
- * 
  *
- * Return value: (transfer full): 
+ *
+ * Return value: (transfer full):
  * Since: 0.9.2
  **/
 hb_font_t *
@@ -610,7 +615,7 @@ hb_ft_font_create (FT_Face           ft_face,
 void
 hb_ft_font_changed (hb_font_t *font)
 {
-  if (font->destroy != _hb_ft_font_destroy)
+  if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
     return;
 
   hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data;
@@ -664,9 +669,9 @@ hb_ft_font_changed (hb_font_t *font)
  * hb_ft_font_create_referenced:
  * @ft_face:
  *
- * 
  *
- * Return value: (transfer full): 
+ *
+ * Return value: (transfer full):
  * Since: 0.9.38
  **/
 hb_font_t *
@@ -685,7 +690,12 @@ static FT_Library ft_library;
 static
 void free_ft_library (void)
 {
-  FT_Done_FreeType (ft_library);
+retry:
+  FT_Library library = (FT_Library) hb_atomic_ptr_get (&ft_library);
+  if (!hb_atomic_ptr_cmpexch (&ft_library, library, nullptr))
+    goto retry;
+
+  FT_Done_FreeType (library);
 }
 #endif
 
index 50c30e9..246380a 100644 (file)
@@ -370,7 +370,12 @@ static hb_unicode_funcs_t *static_glib_funcs = nullptr;
 static
 void free_static_glib_funcs (void)
 {
-  hb_unicode_funcs_destroy (static_glib_funcs);
+retry:
+  hb_unicode_funcs_t *glib_funcs = (hb_unicode_funcs_t *) hb_atomic_ptr_get (&static_glib_funcs);
+  if (!hb_atomic_ptr_cmpexch (&static_glib_funcs, glib_funcs, nullptr))
+    goto retry;
+
+  hb_unicode_funcs_destroy (glib_funcs);
 }
 #endif
 
index 46fe139..c20f6be 100644 (file)
@@ -79,10 +79,12 @@ static const void *hb_graphite2_get_table (const void *data, unsigned int tag, s
     p->blob = blob;
     p->tag = tag;
 
-    /* TODO Not thread-safe, but fairly harmless.
-     * We can do the double-checked pointer cmpexch thing here. */
-    p->next = face_data->tlist;
-    face_data->tlist = p;
+retry:
+    hb_graphite2_tablelist_t *tlist = (hb_graphite2_tablelist_t *) hb_atomic_ptr_get (&face_data->tlist);
+    p->next = tlist;
+
+    if (!hb_atomic_ptr_cmpexch (&face_data->tlist, tlist, p))
+      goto retry;
   }
 
   unsigned int tlen;
@@ -381,11 +383,11 @@ _hb_graphite2_shape (hb_shape_plan_t    *shape_plan,
       pPos->x_offset = gr_slot_origin_X (is) * xscale - curradvx;
       pPos->y_offset = gr_slot_origin_Y (is) * yscale - curradvy;
       if (info->cluster != currclus) {
-        pPos->x_advance = info->var1.i32 * xscale;
-        curradvx += pPos->x_advance;
-        currclus = info->cluster;
+       pPos->x_advance = info->var1.i32 * xscale;
+       curradvx += pPos->x_advance;
+       currclus = info->cluster;
       } else
-        pPos->x_advance = 0.;
+       pPos->x_advance = 0.;
 
       pPos->y_advance = gr_slot_advance_Y (is, grface, nullptr) * yscale;
       curradvy += pPos->y_advance;
@@ -398,11 +400,11 @@ _hb_graphite2_shape (hb_shape_plan_t    *shape_plan,
     {
       if (info->cluster != currclus)
       {
-        pPos->x_advance = info->var1.i32 * xscale;
-        curradvx -= pPos->x_advance;
-        currclus = info->cluster;
+       pPos->x_advance = info->var1.i32 * xscale;
+       curradvx -= pPos->x_advance;
+       currclus = info->cluster;
       } else
-        pPos->x_advance = 0.;
+       pPos->x_advance = 0.;
 
       pPos->y_advance = gr_slot_advance_Y (is, grface, nullptr) * yscale;
       curradvy -= pPos->y_advance;
index 82b1e64..05c55de 100644 (file)
@@ -1,6 +1,6 @@
 /*
- * Copyright (C) 2011  Martin Hosken
- * Copyright (C) 2011  SIL International
+ * Copyright © 2011  Martin Hosken
+ * Copyright © 2011  SIL International
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
index 552eaec..c52e165 100644 (file)
@@ -351,7 +351,12 @@ static hb_unicode_funcs_t *static_icu_funcs = nullptr;
 static
 void free_static_icu_funcs (void)
 {
-  hb_unicode_funcs_destroy (static_icu_funcs);
+retry:
+  hb_unicode_funcs_t *icu_funcs = (hb_unicode_funcs_t *) hb_atomic_ptr_get (&static_icu_funcs);
+  if (!hb_atomic_ptr_cmpexch (&static_icu_funcs, icu_funcs, nullptr))
+    goto retry;
+
+  hb_unicode_funcs_destroy (icu_funcs);
 }
 #endif
 
diff --git a/src/hb-map-private.hh b/src/hb-map-private.hh
new file mode 100644 (file)
index 0000000..d3d4dde
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ * Copyright © 2018  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_MAP_PRIVATE_HH
+#define HB_MAP_PRIVATE_HH
+
+#include "hb-private.hh"
+#include "hb-object-private.hh"
+
+
+template <typename T>
+inline uint32_t Hash (const T &v)
+{
+  /* Knuth's multiplicative method: */
+  return (uint32_t) v * 2654435761u;
+}
+
+
+/*
+ * hb_map_t
+ */
+
+struct hb_map_t
+{
+  struct item_t
+  {
+    hb_codepoint_t key;
+    hb_codepoint_t value;
+
+    inline bool is_unused (void) const { return key == INVALID; }
+    inline bool is_tombstone (void) const { return key != INVALID && value == INVALID; }
+  };
+
+  hb_object_header_t header;
+  bool successful; /* Allocations successful */
+  unsigned int population; /* Not including tombstones. */
+  unsigned int occupancy; /* Including tombstones. */
+  unsigned int mask;
+  unsigned int prime;
+  item_t *items;
+
+  inline void init_shallow (void)
+  {
+    successful = true;
+    population = occupancy = 0;
+    mask = 0;
+    prime = 0;
+    items = nullptr;
+  }
+  inline void init (void)
+  {
+    hb_object_init (this);
+    init_shallow ();
+  }
+  inline void fini_shallow (void)
+  {
+    free (items);
+  }
+  inline void fini (void)
+  {
+    hb_object_fini (this);
+    fini_shallow ();
+  }
+
+  inline bool resize (void)
+  {
+    if (unlikely (!successful)) return false;
+
+    unsigned int power = _hb_bit_storage (population * 2 + 8);
+    unsigned int new_size = 1u << power;
+    item_t *new_items = (item_t *) malloc ((size_t) new_size * sizeof (item_t));
+    if (unlikely (!new_items))
+    {
+      successful = false;
+      return false;
+    }
+    memset (new_items, 0xFF, (size_t) new_size * sizeof (item_t));
+
+    unsigned int old_size = mask + 1;
+    item_t *old_items = items;
+
+    /* Switch to new, empty, array. */
+    population = occupancy = 0;
+    mask = new_size - 1;
+    prime = prime_for (power);
+    items = new_items;
+
+    /* Insert back old items. */
+    if (old_items)
+      for (unsigned int i = 0; i < old_size; i++)
+       if (old_items[i].key != INVALID && old_items[i].value != INVALID)
+         set (old_items[i].key, old_items[i].value);
+
+    free (old_items);
+
+    return true;
+  }
+
+  inline void set (hb_codepoint_t key, hb_codepoint_t value)
+  {
+    if (unlikely (!successful)) return;
+    if (unlikely (key == INVALID)) return;
+    if ((occupancy + occupancy / 2) >= mask && !resize ()) return;
+    unsigned int i = bucket_for (key);
+
+    if (value == INVALID && 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++;
+
+  }
+  inline hb_codepoint_t get (hb_codepoint_t key) const
+  {
+    if (unlikely (!items)) return INVALID;
+    unsigned int i = bucket_for (key);
+    return items[i].key == key ? items[i].value : INVALID;
+  }
+
+  inline void del (hb_codepoint_t key)
+  {
+    set (key, INVALID);
+  }
+  inline bool has (hb_codepoint_t key) const
+  {
+    return get (key) != INVALID;
+  }
+
+  inline hb_codepoint_t operator [] (unsigned int key) const
+  { return get (key); }
+
+  static const hb_codepoint_t INVALID = HB_MAP_VALUE_INVALID;
+
+  inline void clear (void)
+  {
+    memset (items, 0xFF, ((size_t) mask + 1) * sizeof (item_t));
+    population = occupancy = 0;
+  }
+
+  inline bool is_empty (void) const
+  {
+    return population != 0;
+  }
+
+  inline unsigned int get_population () const
+  {
+    return population;
+  }
+
+  protected:
+
+  inline unsigned int bucket_for (hb_codepoint_t key) const
+  {
+    unsigned int i = Hash (key) % prime;
+    unsigned int step = 0;
+    unsigned int tombstone = INVALID;
+    while (!items[i].is_unused ())
+    {
+      if (items[i].key == key)
+        return i;
+      if (tombstone == INVALID && items[i].is_tombstone ())
+        tombstone = i;
+      i = (i + ++step) & mask;
+    }
+    return tombstone == INVALID ? i : tombstone;
+  }
+
+  static inline unsigned int prime_for (unsigned int shift)
+  {
+    /* Following comment and table copied from glib. */
+    /* Each table size has an associated prime modulo (the first prime
+     * lower than the table size) used to find the initial bucket. Probing
+     * then works modulo 2^n. The prime modulo is necessary to get a
+     * good distribution with poor hash functions.
+     */
+    /* Not declaring static to make all kinds of compilers happy... */
+    /*static*/ const unsigned int prime_mod [32] =
+    {
+      1,          /* For 1 << 0 */
+      2,
+      3,
+      7,
+      13,
+      31,
+      61,
+      127,
+      251,
+      509,
+      1021,
+      2039,
+      4093,
+      8191,
+      16381,
+      32749,
+      65521,      /* For 1 << 16 */
+      131071,
+      262139,
+      524287,
+      1048573,
+      2097143,
+      4194301,
+      8388593,
+      16777213,
+      33554393,
+      67108859,
+      134217689,
+      268435399,
+      536870909,
+      1073741789,
+      2147483647  /* For 1 << 31 */
+    };
+
+    if (unlikely (shift >= ARRAY_LENGTH (prime_mod)))
+      return prime_mod[ARRAY_LENGTH (prime_mod) - 1];
+
+    return prime_mod[shift];
+  }
+};
+
+
+#endif /* HB_MAP_PRIVATE_HH */
diff --git a/src/hb-map.cc b/src/hb-map.cc
new file mode 100644 (file)
index 0000000..e3ddae4
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ * Copyright © 2018  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-map-private.hh"
+
+
+/* Public API */
+
+
+/**
+ * hb_map_create: (Xconstructor)
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.7.7
+ **/
+hb_map_t *
+hb_map_create (void)
+{
+  hb_map_t *map;
+
+  if (!(map = hb_object_create<hb_map_t> ()))
+    return hb_map_get_empty ();
+
+  map->init_shallow ();
+
+  return map;
+}
+
+/**
+ * hb_map_get_empty:
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.7.7
+ **/
+hb_map_t *
+hb_map_get_empty (void)
+{
+  return const_cast<hb_map_t *> (&Null(hb_map_t));
+}
+
+/**
+ * hb_map_reference: (skip)
+ * @map: a map.
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.7.7
+ **/
+hb_map_t *
+hb_map_reference (hb_map_t *map)
+{
+  return hb_object_reference (map);
+}
+
+/**
+ * hb_map_destroy: (skip)
+ * @map: a map.
+ *
+ * Since: 1.7.7
+ **/
+void
+hb_map_destroy (hb_map_t *map)
+{
+  if (!hb_object_destroy (map)) return;
+
+  map->fini_shallow ();
+
+  free (map);
+}
+
+/**
+ * hb_map_set_user_data: (skip)
+ * @map: a map.
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
+ *
+ * Return value:
+ *
+ * Since: 1.7.7
+ **/
+hb_bool_t
+hb_map_set_user_data (hb_map_t           *map,
+                     hb_user_data_key_t *key,
+                     void *              data,
+                     hb_destroy_func_t   destroy,
+                     hb_bool_t           replace)
+{
+  return hb_object_set_user_data (map, key, data, destroy, replace);
+}
+
+/**
+ * hb_map_get_user_data: (skip)
+ * @map: a map.
+ * @key:
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.7.7
+ **/
+void *
+hb_map_get_user_data (hb_map_t           *map,
+                     hb_user_data_key_t *key)
+{
+  return hb_object_get_user_data (map, key);
+}
+
+
+/**
+ * hb_map_allocation_successful:
+ * @map: a map.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.7.7
+ **/
+hb_bool_t
+hb_map_allocation_successful (const hb_map_t  *map)
+{
+  return map->successful;
+}
+
+
+/**
+ * hb_map_set:
+ * @map: a map.
+ * @key:
+ * @value:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.7.7
+ **/
+void
+hb_map_set (hb_map_t       *map,
+           hb_codepoint_t  key,
+           hb_codepoint_t  value)
+{
+  map->set (key, value);
+}
+
+/**
+ * hb_map_get:
+ * @map: a map.
+ * @key:
+ *
+ *
+ *
+ * Since: 1.7.7
+ **/
+hb_codepoint_t
+hb_map_get (const hb_map_t *map,
+           hb_codepoint_t  key)
+{
+  return map->get (key);
+}
+
+/**
+ * hb_map_del:
+ * @map: a map.
+ * @codepoint:
+ *
+ *
+ *
+ * Since: 1.7.7
+ **/
+void
+hb_map_del (hb_map_t       *map,
+           hb_codepoint_t  key)
+{
+  map->del (key);
+}
+
+/**
+ * hb_map_has:
+ * @map: a map.
+ * @codepoint:
+ *
+ *
+ *
+ * Since: 1.7.7
+ **/
+hb_bool_t
+hb_map_has (const hb_map_t *map,
+           hb_codepoint_t  key)
+{
+  return map->has (key);
+}
+
+
+/**
+ * hb_map_clear:
+ * @map: a map.
+ *
+ *
+ *
+ * Since: 1.7.7
+ **/
+void
+hb_map_clear (hb_map_t *map)
+{
+  return map->clear ();
+}
+
+/**
+ * hb_map_is_empty:
+ * @map: a map.
+ *
+ *
+ *
+ * Since: 1.7.7
+ **/
+hb_bool_t
+hb_map_is_empty (const hb_map_t *map)
+{
+  return map->is_empty ();
+}
+
+/**
+ * hb_map_get_population:
+ * @map: a map.
+ *
+ *
+ *
+ * Since: 1.7.7
+ **/
+unsigned int
+hb_map_get_population (const hb_map_t *map)
+{
+  return map->get_population ();
+}
diff --git a/src/hb-map.h b/src/hb-map.h
new file mode 100644 (file)
index 0000000..b77843c
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright © 2018  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_H_IN
+#error "Include <hb.h> instead."
+#endif
+
+#ifndef HB_MAP_H
+#define HB_MAP_H
+
+#include "hb-common.h"
+
+HB_BEGIN_DECLS
+
+
+/*
+ * Since: 1.7.7
+ */
+#define HB_MAP_VALUE_INVALID ((hb_codepoint_t) -1)
+
+typedef struct hb_map_t hb_map_t;
+
+
+HB_EXTERN hb_map_t *
+hb_map_create (void);
+
+HB_EXTERN hb_map_t *
+hb_map_get_empty (void);
+
+HB_EXTERN hb_map_t *
+hb_map_reference (hb_map_t *map);
+
+HB_EXTERN void
+hb_map_destroy (hb_map_t *map);
+
+HB_EXTERN hb_bool_t
+hb_map_set_user_data (hb_map_t           *map,
+                     hb_user_data_key_t *key,
+                     void *              data,
+                     hb_destroy_func_t   destroy,
+                     hb_bool_t           replace);
+
+HB_EXTERN void *
+hb_map_get_user_data (hb_map_t           *map,
+                     hb_user_data_key_t *key);
+
+
+/* Returns false if allocation has failed before */
+HB_EXTERN hb_bool_t
+hb_map_allocation_successful (const hb_map_t *map);
+
+HB_EXTERN void
+hb_map_clear (hb_map_t *map);
+
+HB_EXTERN hb_bool_t
+hb_map_is_empty (const hb_map_t *map);
+
+HB_EXTERN unsigned int
+hb_map_get_population (const hb_map_t *map);
+
+HB_EXTERN void
+hb_map_set (hb_map_t       *map,
+           hb_codepoint_t  key,
+           hb_codepoint_t  value);
+
+HB_EXTERN hb_codepoint_t
+hb_map_get (const hb_map_t *map,
+           hb_codepoint_t  key);
+
+HB_EXTERN void
+hb_map_del (hb_map_t       *map,
+           hb_codepoint_t  key);
+
+HB_EXTERN hb_bool_t
+hb_map_has (const hb_map_t *map,
+           hb_codepoint_t  key);
+
+
+HB_END_DECLS
+
+#endif /* HB_MAP_H */
index 49ed10e..14bde31 100644 (file)
@@ -134,7 +134,7 @@ struct hb_mutex_t
   inline void init   (void) { hb_mutex_impl_init   (&m); }
   inline void lock   (void) { hb_mutex_impl_lock   (&m); }
   inline void unlock (void) { hb_mutex_impl_unlock (&m); }
-  inline void finish (void) { hb_mutex_impl_finish (&m); }
+  inline void fini (void) { hb_mutex_impl_finish (&m); }
 };
 
 
index baa1f8f..fc48a91 100644 (file)
@@ -41,9 +41,9 @@
 
 /* reference_count */
 
-#define HB_REFERENCE_COUNT_INERT_VALUE -1
+#define HB_REFERENCE_COUNT_INERT_VALUE 0
 #define HB_REFERENCE_COUNT_POISON_VALUE -0x0000DEAD
-#define HB_REFERENCE_COUNT_INIT {HB_ATOMIC_INT_INIT(HB_REFERENCE_COUNT_INERT_VALUE)}
+#define HB_REFERENCE_COUNT_INIT {HB_ATOMIC_INT_INIT (HB_REFERENCE_COUNT_INERT_VALUE)}
 
 struct hb_reference_count_t
 {
@@ -53,7 +53,7 @@ struct hb_reference_count_t
   inline int get_unsafe (void) const { return ref_count.get_unsafe (); }
   inline int inc (void) { return ref_count.inc (); }
   inline int dec (void) { return ref_count.dec (); }
-  inline void finish (void) { ref_count.set_unsafe (HB_REFERENCE_COUNT_POISON_VALUE); }
+  inline void fini (void) { ref_count.set_unsafe (HB_REFERENCE_COUNT_POISON_VALUE); }
 
   inline bool is_inert (void) const { return ref_count.get_unsafe () == HB_REFERENCE_COUNT_INERT_VALUE; }
   inline bool is_valid (void) const { return ref_count.get_unsafe () > 0; }
@@ -62,7 +62,6 @@ struct hb_reference_count_t
 
 /* user_data */
 
-#define HB_USER_DATA_ARRAY_INIT {HB_MUTEX_INIT, HB_LOCKABLE_SET_INIT}
 struct hb_user_data_array_t
 {
   struct hb_user_data_item_t {
@@ -73,7 +72,7 @@ struct hb_user_data_array_t
     inline bool operator == (hb_user_data_key_t *other_key) const { return key == other_key; }
     inline bool operator == (hb_user_data_item_t &other) const { return key == other.key; }
 
-    void finish (void) { if (destroy) destroy (data); }
+    void fini (void) { if (destroy) destroy (data); }
   };
 
   hb_mutex_t lock;
@@ -88,7 +87,7 @@ struct hb_user_data_array_t
 
   HB_INTERNAL void *get (hb_user_data_key_t *key);
 
-  inline void finish (void) { items.finish (lock); lock.finish (); }
+  inline void fini (void) { items.fini (lock); lock.fini (); }
 };
 
 
@@ -97,9 +96,9 @@ struct hb_user_data_array_t
 struct hb_object_header_t
 {
   hb_reference_count_t ref_count;
-  hb_user_data_array_t user_data;
+  hb_user_data_array_t *user_data;
 
-#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INIT, HB_USER_DATA_ARRAY_INIT}
+#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INIT, nullptr}
 
   private:
   ASSERT_POD ();
@@ -133,7 +132,7 @@ template <typename Type>
 static inline void hb_object_init (Type *obj)
 {
   obj->header.ref_count.init (1);
-  obj->header.user_data.init ();
+  obj->header.user_data = nullptr;
 }
 template <typename Type>
 static inline bool hb_object_is_inert (const Type *obj)
@@ -165,11 +164,20 @@ static inline bool hb_object_destroy (Type *obj)
   if (obj->header.ref_count.dec () != 1)
     return false;
 
-  obj->header.ref_count.finish (); /* Do this before user_data */
-  obj->header.user_data.finish ();
+  hb_object_fini (obj);
   return true;
 }
 template <typename Type>
+static inline void hb_object_fini (Type *obj)
+{
+  obj->header.ref_count.fini (); /* Do this before user_data */
+  if (obj->header.user_data)
+  {
+    obj->header.user_data->fini ();
+    free (obj->header.user_data);
+  }
+}
+template <typename Type>
 static inline bool hb_object_set_user_data (Type               *obj,
                                            hb_user_data_key_t *key,
                                            void *              data,
@@ -179,17 +187,34 @@ static inline bool hb_object_set_user_data (Type               *obj,
   if (unlikely (!obj || hb_object_is_inert (obj)))
     return false;
   assert (hb_object_is_valid (obj));
-  return obj->header.user_data.set (key, data, destroy, replace);
+
+retry:
+  hb_user_data_array_t *user_data = (hb_user_data_array_t *) hb_atomic_ptr_get (&obj->header.user_data);
+  if (unlikely (!user_data))
+  {
+    user_data = (hb_user_data_array_t *) calloc (sizeof (hb_user_data_array_t), 1);
+    if (unlikely (!user_data))
+      return false;
+    user_data->init ();
+    if (unlikely (!hb_atomic_ptr_cmpexch (&obj->header.user_data, nullptr, user_data)))
+    {
+      user_data->fini ();
+      free (user_data);
+      goto retry;
+    }
+  }
+
+  return user_data->set (key, data, destroy, replace);
 }
 
 template <typename Type>
 static inline void *hb_object_get_user_data (Type               *obj,
                                             hb_user_data_key_t *key)
 {
-  if (unlikely (!obj || hb_object_is_inert (obj)))
+  if (unlikely (!obj || hb_object_is_inert (obj) || !obj->header.user_data))
     return nullptr;
   assert (hb_object_is_valid (obj));
-  return obj->header.user_data.get (key);
+  return obj->header.user_data->get (key);
 }
 
 
index e2644ea..2965b46 100644 (file)
@@ -100,7 +100,7 @@ typedef struct OffsetTable
       else
         *table_count = MIN<unsigned int> (*table_count, tables.len - start_offset);
 
-      const TableRecord *sub_tables = tables.array + start_offset;
+      const TableRecord *sub_tables = tables.arrayZ + start_offset;
       unsigned int count = *table_count;
       for (unsigned int i = 0; i < count; i++)
        table_tags[i] = sub_tables[i].tag;
@@ -148,7 +148,7 @@ typedef struct OffsetTable
     /* Write OffsetTables, alloc for and write actual table blobs. */
     for (unsigned int i = 0; i < table_count; i++)
     {
-      TableRecord &rec = tables.array[i];
+      TableRecord &rec = tables.arrayZ[i];
       hb_blob_t *blob = blobs[i];
       rec.tag.set (tags[i]);
       rec.length.set (hb_blob_get_length (blob));
@@ -188,7 +188,7 @@ typedef struct OffsetTable
       checksum.set_for_data (this, dir_end - (const char *) this);
       for (unsigned int i = 0; i < table_count; i++)
       {
-       TableRecord &rec = tables.array[i];
+       TableRecord &rec = tables.arrayZ[i];
        checksum.set (checksum + rec.checkSum);
       }
 
@@ -234,7 +234,7 @@ struct TTCHeaderVersion1
   Tag          ttcTag;         /* TrueType Collection ID string: 'ttcf' */
   FixedVersion<>version;       /* Version of the TTC Header (1.0),
                                 * 0x00010000u */
-  ArrayOf<LOffsetTo<OffsetTable>, HBUINT32>
+  LArrayOf<LOffsetTo<OffsetTable> >
                table;          /* Array of offsets to the OffsetTable for each font
                                 * from the beginning of the file */
   public:
@@ -295,11 +295,13 @@ struct OpenTypeFontFile
 {
   static const hb_tag_t tableTag       = HB_TAG ('_','_','_','_'); /* Sanitizer needs this. */
 
-  static const hb_tag_t CFFTag         = HB_TAG ('O','T','T','O'); /* OpenType with Postscript outlines */
-  static const hb_tag_t TrueTypeTag    = HB_TAG ( 0 , 1 , 0 , 0 ); /* OpenType with TrueType outlines */
-  static const hb_tag_t TTCTag         = HB_TAG ('t','t','c','f'); /* TrueType Collection */
-  static const hb_tag_t TrueTag                = HB_TAG ('t','r','u','e'); /* Obsolete Apple TrueType */
-  static const hb_tag_t Typ1Tag                = HB_TAG ('t','y','p','1'); /* Obsolete Apple Type1 font in SFNT container */
+  enum {
+    CFFTag             = HB_TAG ('O','T','T','O'), /* OpenType with Postscript outlines */
+    TrueTypeTag        = HB_TAG ( 0 , 1 , 0 , 0 ), /* OpenType with TrueType outlines */
+    TTCTag             = HB_TAG ('t','t','c','f'), /* TrueType Collection */
+    TrueTag            = HB_TAG ('t','r','u','e'), /* Obsolete Apple TrueType */
+    Typ1Tag            = HB_TAG ('t','y','p','1')  /* Obsolete Apple Type1 font in SFNT container */
+  };
 
   inline hb_tag_t get_tag (void) const { return u.tag; }
 
index 5d33199..8180287 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "hb-private.hh"
 #include "hb-debug.hh"
+#include "hb-blob-private.hh"
 #include "hb-face-private.hh"
 
 
@@ -127,46 +128,6 @@ static inline Type& StructAfter(TObject &X)
 
 
 /*
- * Null objects
- */
-
-/* Global nul-content Null pool.  Enlarge as necessary. */
-
-#define HB_NULL_POOL_SIZE 264
-static_assert (HB_NULL_POOL_SIZE % sizeof (void *) == 0, "Align HB_NULL_POOL_SIZE.");
-
-#ifdef HB_NO_VISIBILITY
-static
-#else
-extern HB_INTERNAL
-#endif
-const void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)]
-#ifdef HB_NO_VISIBILITY
-= {}
-#endif
-;
-
-/* Generic nul-content Null objects. */
-template <typename Type>
-static inline const Type& Null (void) {
-  static_assert (sizeof (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE.");
-  return *CastP<Type> (_hb_NullPool);
-}
-
-/* Specializaiton for arbitrary-content arbitrary-sized Null objects. */
-#define DEFINE_NULL_DATA(Type, data) \
-static const char _Null##Type[sizeof (Type) + 1] = data; /* +1 is for nul-termination in data */ \
-template <> \
-/*static*/ inline const Type& Null<Type> (void) { \
-  return *CastP<Type> (_Null##Type); \
-} /* The following line really exists such that we end in a place needing semicolon */ \
-static_assert (Type::min_size + 1 <= sizeof (_Null##Type), "Null pool too small.  Enlarge.")
-
-/* Accessor macro. */
-#define Null(Type) Null<Type>()
-
-
-/*
  * Dispatch
  */
 
@@ -225,7 +186,7 @@ struct hb_sanitize_context_t :
   inline void start_processing (void)
   {
     this->start = hb_blob_get_data (this->blob, nullptr);
-    this->end = this->start + hb_blob_get_length (this->blob);
+    this->end = this->start + this->blob->length;
     assert (this->start <= this->end); /* Must not overflow. */
     this->max_ops = MAX ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR,
                         (unsigned) HB_SANITIZE_MAX_OPS_MIN);
@@ -288,7 +249,7 @@ struct hb_sanitize_context_t :
     return likely (this->check_range (obj, obj->min_size));
   }
 
-  inline bool may_edit (const void *base HB_UNUSED, unsigned int len HB_UNUSED)
+  inline bool may_edit (const void *base, unsigned int len)
   {
     if (this->edit_count >= HB_SANITIZE_MAX_EDITS)
       return false;
@@ -368,7 +329,7 @@ struct Sanitizer
       unsigned int edit_count = c->edit_count;
       if (edit_count && !c->writable) {
         c->start = hb_blob_get_data_writable (blob, nullptr);
-       c->end = c->start + hb_blob_get_length (blob);
+       c->end = c->start + blob->length;
 
        if (c->start) {
          c->writable = true;
@@ -383,19 +344,17 @@ struct Sanitizer
 
     DEBUG_MSG_FUNC (SANITIZE, c->start, sane ? "PASSED" : "FAILED");
     if (sane)
+    {
+      blob->lock ();
       return blob;
-    else {
+    }
+    else
+    {
       hb_blob_destroy (blob);
       return hb_blob_get_empty ();
     }
   }
 
-  static const Type* lock_instance (hb_blob_t *blob) {
-    hb_blob_make_immutable (blob);
-    const char *base = hb_blob_get_data (blob, nullptr);
-    return unlikely (!base) ? &Null(Type) : CastP<Type> (base);
-  }
-
   inline void set_num_glyphs (unsigned int num_glyphs) { c->num_glyphs = num_glyphs; }
 
   private:
@@ -672,7 +631,7 @@ typedef IntType<uint16_t, 2> HBUINT16;      /* 16-bit unsigned integer. */
 typedef IntType<int16_t,  2> HBINT16;  /* 16-bit signed integer. */
 typedef IntType<uint32_t, 4> HBUINT32; /* 32-bit unsigned integer. */
 typedef IntType<int32_t,  4> HBINT32;  /* 32-bit signed integer. */
-typedef IntType<uint32_t, 3> UINT24;   /* 24-bit unsigned integer. */
+typedef IntType<uint32_t, 3> HBUINT24; /* 24-bit unsigned integer. */
 
 /* 16-bit signed integer (HBINT16) that describes a quantity in FUnits. */
 typedef HBINT16 FWORD;
@@ -683,17 +642,19 @@ typedef HBUINT16 UFWORD;
 /* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */
 struct F2DOT14 : HBINT16
 {
-  //inline float to_float (void) const { return ???; }
-  //inline void set_float (float f) { v.set (f * ???); }
+  // 16384 means 1<<14
+  inline float to_float (void) const { return ((int32_t) v) / 16384.f; }
+  inline void set_float (float f) { v.set (round (f * 16384.f)); }
   public:
   DEFINE_SIZE_STATIC (2);
 };
 
 /* 32-bit signed fixed-point number (16.16). */
-struct Fixed: HBINT32
+struct Fixed : HBINT32
 {
-  inline float to_float (void) const { return ((int32_t) v) / 65536.0; }
-  inline void set_float (float f) { v.set (round (f * 65536.0)); }
+  // 65536 means 1<<16
+  inline float to_float (void) const { return ((int32_t) v) / 65536.f; }
+  inline void set_float (float f) { v.set (round (f * 65536.f)); }
   public:
   DEFINE_SIZE_STATIC (4);
 };
@@ -724,16 +685,19 @@ struct Tag : HBUINT32
   public:
   DEFINE_SIZE_STATIC (4);
 };
-DEFINE_NULL_DATA (Tag, "    ");
+DEFINE_NULL_DATA (OT, Tag, "    ");
 
 /* Glyph index number, same as uint16 (length = 16 bits) */
 typedef HBUINT16 GlyphID;
 
+/* Name-table index, same as uint16 (length = 16 bits) */
+typedef HBUINT16 NameID;
+
 /* Script/language-system/feature index */
 struct Index : HBUINT16 {
   static const unsigned int NOT_FOUND_INDEX = 0xFFFFu;
 };
-DEFINE_NULL_DATA (Index, "\xff\xff");
+DEFINE_NULL_DATA (OT, Index, "\xff\xff");
 
 /* Offset, Null offset = 0 */
 template <typename Type>
@@ -815,6 +779,12 @@ struct OffsetTo : Offset<OffsetType>
   {
     unsigned int offset = *this;
     if (unlikely (!offset)) return Null(Type);
+    return StructAtOffset<const Type> (base, offset);
+  }
+  inline Type& operator () (void *base) const
+  {
+    unsigned int offset = *this;
+    if (unlikely (!offset)) return Crap(Type);
     return StructAtOffset<Type> (base, offset);
   }
 
@@ -862,6 +832,89 @@ static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType> &offset)
  * Array Types
  */
 
+
+/* TODO Use it in ArrayOf, HeadlessArrayOf, and other places around the code base?? */
+template <typename Type>
+struct UnsizedArrayOf
+{
+  inline const Type& operator [] (unsigned int i) const { return arrayZ[i]; }
+  inline Type& operator [] (unsigned int i) { return arrayZ[i]; }
+
+  inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
+
+    /* Note: for structs that do not reference other structs,
+     * we do not need to call their sanitize() as we already did
+     * a bound check on the aggregate array size.  We just include
+     * a small unreachable expression to make sure the structs
+     * pointed to do have a simple sanitize(), ie. they do not
+     * reference other structs via offsets.
+     */
+    (void) (false && arrayZ[0].sanitize (c));
+
+    return_trace (true);
+  }
+  inline bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
+    for (unsigned int i = 0; i < count; i++)
+      if (unlikely (!arrayZ[i].sanitize (c, base)))
+        return_trace (false);
+    return_trace (true);
+  }
+  template <typename T>
+  inline bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base, T user_data) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
+    for (unsigned int i = 0; i < count; i++)
+      if (unlikely (!arrayZ[i].sanitize (c, base, user_data)))
+        return_trace (false);
+    return_trace (true);
+  }
+
+  inline bool sanitize_shallow (hb_sanitize_context_t *c, unsigned int count) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_array (arrayZ, arrayZ[0].static_size, count));
+  }
+
+  public:
+  Type arrayZ[VAR];
+  public:
+  DEFINE_SIZE_ARRAY (0, arrayZ);
+};
+
+/* Unsized array of offset's */
+template <typename Type, typename OffsetType>
+struct UnsizedOffsetArrayOf : UnsizedArrayOf<OffsetTo<Type, OffsetType> > {};
+
+/* Unsized array of offsets relative to the beginning of the array itself. */
+template <typename Type, typename OffsetType>
+struct UnsizedOffsetListOf : UnsizedOffsetArrayOf<Type, OffsetType>
+{
+  inline const Type& operator [] (unsigned int i) const
+  {
+    return this+this->arrayZ[i];
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace ((UnsizedOffsetArrayOf<Type, OffsetType>::sanitize (c, count, this)));
+  }
+  template <typename T>
+  inline bool sanitize (hb_sanitize_context_t *c, unsigned int count, T user_data) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace ((UnsizedOffsetArrayOf<Type, OffsetType>::sanitize (c, count, this, user_data)));
+  }
+};
+
+
 /* An array with a number of elements. */
 template <typename Type, typename LenType=HBUINT16>
 struct ArrayOf
@@ -875,17 +928,18 @@ struct ArrayOf
       count -= start_offset;
     count = MIN (count, *pcount);
     *pcount = count;
-    return array + start_offset;
+    return arrayZ + start_offset;
   }
 
   inline const Type& operator [] (unsigned int i) const
   {
     if (unlikely (i >= len)) return Null(Type);
-    return array[i];
+    return arrayZ[i];
   }
   inline Type& operator [] (unsigned int i)
   {
-    return array[i];
+    if (unlikely (i >= len)) return Crap(Type);
+    return arrayZ[i];
   }
   inline unsigned int get_size (void) const
   { return len.static_size + len * Type::static_size; }
@@ -907,7 +961,7 @@ struct ArrayOf
     TRACE_SERIALIZE (this);
     if (unlikely (!serialize (c, items_len))) return_trace (false);
     for (unsigned int i = 0; i < items_len; i++)
-      array[i] = items[i];
+      arrayZ[i] = items[i];
     items += items_len;
     return_trace (true);
   }
@@ -924,7 +978,7 @@ struct ArrayOf
      * pointed to do have a simple sanitize(), ie. they do not
      * reference other structs via offsets.
      */
-    (void) (false && array[0].sanitize (c));
+    (void) (false && arrayZ[0].sanitize (c));
 
     return_trace (true);
   }
@@ -934,7 +988,7 @@ struct ArrayOf
     if (unlikely (!sanitize_shallow (c))) return_trace (false);
     unsigned int count = len;
     for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!array[i].sanitize (c, base)))
+      if (unlikely (!arrayZ[i].sanitize (c, base)))
         return_trace (false);
     return_trace (true);
   }
@@ -945,7 +999,7 @@ struct ArrayOf
     if (unlikely (!sanitize_shallow (c))) return_trace (false);
     unsigned int count = len;
     for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!array[i].sanitize (c, base, user_data)))
+      if (unlikely (!arrayZ[i].sanitize (c, base, user_data)))
         return_trace (false);
     return_trace (true);
   }
@@ -955,28 +1009,28 @@ struct ArrayOf
   {
     unsigned int count = len;
     for (unsigned int i = 0; i < count; i++)
-      if (!this->array[i].cmp (x))
+      if (!this->arrayZ[i].cmp (x))
         return i;
     return -1;
   }
 
   inline void qsort (void)
   {
-    ::qsort (array, len, sizeof (Type), Type::cmp);
+    ::qsort (arrayZ, len, sizeof (Type), Type::cmp);
   }
 
   private:
   inline bool sanitize_shallow (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (len.sanitize (c) && c->check_array (array, Type::static_size, len));
+    return_trace (len.sanitize (c) && c->check_array (arrayZ, Type::static_size, len));
   }
 
   public:
   LenType len;
-  Type array[VAR];
+  Type arrayZ[VAR];
   public:
-  DEFINE_SIZE_ARRAY (sizeof (LenType), array);
+  DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
 };
 template <typename Type> struct LArrayOf : ArrayOf<Type, HBUINT32> {};
 
@@ -991,7 +1045,12 @@ struct OffsetListOf : OffsetArrayOf<Type>
   inline const Type& operator [] (unsigned int i) const
   {
     if (unlikely (i >= this->len)) return Null(Type);
-    return this+this->array[i];
+    return this+this->arrayZ[i];
+  }
+  inline const Type& operator [] (unsigned int i)
+  {
+    if (unlikely (i >= this->len)) return Crap(Type);
+    return this+this->arrayZ[i];
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
@@ -1015,7 +1074,12 @@ struct HeadlessArrayOf
   inline const Type& operator [] (unsigned int i) const
   {
     if (unlikely (i >= len || !i)) return Null(Type);
-    return array[i-1];
+    return arrayZ[i-1];
+  }
+  inline Type& operator [] (unsigned int i)
+  {
+    if (unlikely (i >= len || !i)) return Crap(Type);
+    return arrayZ[i-1];
   }
   inline unsigned int get_size (void) const
   { return len.static_size + (len ? len - 1 : 0) * Type::static_size; }
@@ -1030,7 +1094,7 @@ struct HeadlessArrayOf
     if (unlikely (!items_len)) return_trace (true);
     if (unlikely (!c->extend (*this))) return_trace (false);
     for (unsigned int i = 0; i < items_len - 1; i++)
-      array[i] = items[i];
+      arrayZ[i] = items[i];
     items += items_len - 1;
     return_trace (true);
   }
@@ -1047,7 +1111,7 @@ struct HeadlessArrayOf
      * pointed to do have a simple sanitize(), ie. they do not
      * reference other structs via offsets.
      */
-    (void) (false && array[0].sanitize (c));
+    (void) (false && arrayZ[0].sanitize (c));
 
     return_trace (true);
   }
@@ -1057,14 +1121,14 @@ struct HeadlessArrayOf
   {
     TRACE_SANITIZE (this);
     return_trace (len.sanitize (c) &&
-                 (!len || c->check_array (array, Type::static_size, len - 1)));
+                 (!len || c->check_array (arrayZ, Type::static_size, len - 1)));
   }
 
   public:
   LenType len;
-  Type array[VAR];
+  Type arrayZ[VAR];
   public:
-  DEFINE_SIZE_ARRAY (sizeof (LenType), array);
+  DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
 };
 
 
@@ -1078,7 +1142,7 @@ struct SortedArrayOf : ArrayOf<Type, LenType>
   inline int bsearch (const SearchType &x) const
   {
     /* Hand-coded bsearch here since this is in the hot inner loop. */
-    const Type *arr = this->array;
+    const Type *arr = this->arrayZ;
     int min = 0, max = (int) this->len - 1;
     while (min <= max)
     {
@@ -1113,18 +1177,18 @@ struct BinSearchHeader
   {
     len.set (v);
     assert (len == v);
-    entrySelectorZ.set (MAX (1u, _hb_bit_storage (v)) - 1);
-    searchRangeZ.set (16 * (1u << entrySelectorZ));
-    rangeShiftZ.set (v * 16 > searchRangeZ
-                     ? 16 * v - searchRangeZ
-                     : 0);
+    entrySelector.set (MAX (1u, _hb_bit_storage (v)) - 1);
+    searchRange.set (16 * (1u << entrySelector));
+    rangeShift.set (v * 16 > searchRange
+                   ? 16 * v - searchRange
+                   : 0);
   }
 
   protected:
   HBUINT16     len;
-  HBUINT16     searchRangeZ;
-  HBUINT16     entrySelectorZ;
-  HBUINT16     rangeShiftZ;
+  HBUINT16     searchRange;
+  HBUINT16     entrySelector;
+  HBUINT16     rangeShift;
 
   public:
   DEFINE_SIZE_STATIC (8);
@@ -1136,7 +1200,7 @@ struct BinSearchArrayOf : SortedArrayOf<Type, BinSearchHeader> {};
 
 /* Lazy struct and blob loaders. */
 
-/* Logic is shared between hb_lazy_loader_t and hb_lazy_table_loader_t */
+/* Logic is shared between hb_lazy_loader_t and hb_table_lazy_loader_t */
 template <typename T>
 struct hb_lazy_loader_t
 {
@@ -1148,7 +1212,7 @@ struct hb_lazy_loader_t
 
   inline void fini (void)
   {
-    if (instance && instance != &OT::Null(T))
+    if (instance && instance != &Null(T))
     {
       instance->fini();
       free (instance);
@@ -1163,12 +1227,12 @@ struct hb_lazy_loader_t
     {
       p = (T *) calloc (1, sizeof (T));
       if (unlikely (!p))
-        p = const_cast<T *> (&OT::Null(T));
+        p = const_cast<T *> (&Null(T));
       else
        p->init (face);
       if (unlikely (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), nullptr, p)))
       {
-       if (p != &OT::Null(T))
+       if (p != &Null(T))
          p->fini ();
        goto retry;
       }
@@ -1186,15 +1250,14 @@ struct hb_lazy_loader_t
   T *instance;
 };
 
-/* Logic is shared between hb_lazy_loader_t and hb_lazy_table_loader_t */
+/* Logic is shared between hb_lazy_loader_t and hb_table_lazy_loader_t */
 template <typename T>
-struct hb_lazy_table_loader_t
+struct hb_table_lazy_loader_t
 {
   inline void init (hb_face_t *face_)
   {
     face = face_;
     blob = nullptr;
-    instance = nullptr;
   }
 
   inline void fini (void)
@@ -1205,19 +1268,18 @@ struct hb_lazy_table_loader_t
   inline const T* get (void) const
   {
   retry:
-    T *p = (T *) hb_atomic_ptr_get (&instance);
-    if (unlikely (!p))
+    hb_blob_t *blob_ = (hb_blob_t *) hb_atomic_ptr_get (&blob);
+    if (unlikely (!blob_))
     {
-      hb_blob_t *blob_ = OT::Sanitizer<T>().sanitize (face->reference_table (T::tableTag));
-      p = const_cast<T *>(OT::Sanitizer<T>::lock_instance (blob_));
-      if (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), nullptr, p))
+      blob_ = OT::Sanitizer<T>().sanitize (face->reference_table (T::tableTag));
+      if (!hb_atomic_ptr_cmpexch (&blob, nullptr, blob_))
       {
        hb_blob_destroy (blob_);
        goto retry;
       }
       blob = blob_;
     }
-    return p;
+    return blob_->as<T> ();
   }
 
   inline const T* operator-> (void) const
@@ -1225,10 +1287,9 @@ struct hb_lazy_table_loader_t
     return get();
   }
 
+  private:
   hb_face_t *face;
   mutable hb_blob_t *blob;
-  private:
-  mutable T *instance;
 };
 
 
index 0207989..c1903f6 100644 (file)
 #define HB_OT_CMAP_TABLE_HH
 
 #include "hb-open-type-private.hh"
+#include "hb-set-private.hh"
 #include "hb-subset-plan.hh"
 
-namespace OT {
-
-
 /*
- * cmap -- Character To Glyph Index Mapping Table
+ * cmap -- Character to Glyph Index Mapping
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/cmap
  */
-
 #define HB_OT_TAG_cmap HB_TAG('c','m','a','p')
 
 
+namespace OT {
+
+
 struct CmapSubtableFormat0
 {
   inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
@@ -59,8 +60,8 @@ struct CmapSubtableFormat0
 
   protected:
   HBUINT16     format;         /* Format number is set to 0. */
-  HBUINT16     lengthZ;        /* Byte length of this subtable. */
-  HBUINT16     languageZ;      /* Ignore. */
+  HBUINT16     length        /* Byte length of this subtable. */
+  HBUINT16     language      /* Ignore. */
   HBUINT8      glyphIdArray[256];/* An array that maps character
                                 * code to glyph index values. */
   public:
@@ -69,6 +70,158 @@ struct CmapSubtableFormat0
 
 struct CmapSubtableFormat4
 {
+  struct segment_plan
+  {
+    HBUINT16 start_code;
+    HBUINT16 end_code;
+    bool use_delta;
+  };
+
+  bool serialize (hb_serialize_context_t *c,
+                  const hb_subset_plan_t *plan,
+                  const hb_vector_t<segment_plan> &segments)
+  {
+    TRACE_SERIALIZE (this);
+
+    if (unlikely (!c->extend_min (*this))) return_trace (false);
+
+    this->format.set (4);
+    this->length.set (get_sub_table_size (segments));
+
+    this->segCountX2.set (segments.len * 2);
+    this->entrySelector.set (MAX (1u, _hb_bit_storage (segments.len)) - 1);
+    this->searchRange.set (2 * (1u << this->entrySelector));
+    this->rangeShift.set (segments.len * 2 > this->searchRange
+                          ? 2 * segments.len - this->searchRange
+                          : 0);
+
+    HBUINT16 *end_count = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.len);
+    c->allocate_size<HBUINT16> (HBUINT16::static_size); // 2 bytes of padding.
+    HBUINT16 *start_count = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.len);
+    HBINT16 *id_delta = c->allocate_size<HBINT16> (HBUINT16::static_size * segments.len);
+    HBUINT16 *id_range_offset = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.len);
+
+    if (id_range_offset == nullptr)
+      return_trace (false);
+
+    for (unsigned int i = 0; i < segments.len; i++)
+    {
+      end_count[i].set (segments[i].end_code);
+      start_count[i].set (segments[i].start_code);
+      if (segments[i].use_delta)
+      {
+        hb_codepoint_t cp = segments[i].start_code;
+        hb_codepoint_t start_gid = 0;
+        if (unlikely (!plan->new_gid_for_codepoint (cp, &start_gid) && cp != 0xFFFF))
+          return_trace (false);
+        id_delta[i].set (start_gid - segments[i].start_code);
+      } else {
+        id_delta[i].set (0);
+        unsigned int num_codepoints = segments[i].end_code - segments[i].start_code + 1;
+        HBUINT16 *glyph_id_array = c->allocate_size<HBUINT16> (HBUINT16::static_size * num_codepoints);
+        if (glyph_id_array == nullptr)
+          return_trace (false);
+        // From the cmap spec:
+        //
+        // id_range_offset[i]/2
+        // + (cp - segments[i].start_code)
+        // + (id_range_offset + i)
+        // =
+        // glyph_id_array + (cp - segments[i].start_code)
+        //
+        // So, solve for id_range_offset[i]:
+        //
+        // id_range_offset[i]
+        // =
+        // 2 * (glyph_id_array - id_range_offset - i)
+        id_range_offset[i].set (2 * (
+            glyph_id_array - id_range_offset - i));
+        for (unsigned int j = 0; j < num_codepoints; j++)
+        {
+          hb_codepoint_t cp = segments[i].start_code + j;
+          hb_codepoint_t new_gid;
+          if (unlikely (!plan->new_gid_for_codepoint (cp, &new_gid)))
+            return_trace (false);
+          glyph_id_array[j].set (new_gid);
+        }
+      }
+    }
+
+    return_trace (true);
+  }
+
+  static inline size_t get_sub_table_size (const hb_vector_t<segment_plan> &segments)
+  {
+    size_t segment_size = 0;
+    for (unsigned int i = 0; i < segments.len; i++)
+    {
+      // Parallel array entries
+      segment_size +=
+            2  // end count
+          + 2  // start count
+          + 2  // delta
+          + 2; // range offset
+
+      if (!segments[i].use_delta)
+        // Add bytes for the glyph index array entries for this segment.
+        segment_size += (segments[i].end_code - segments[i].start_code + 1) * 2;
+    }
+
+    return min_size
+        + 2 // Padding
+        + segment_size;
+  }
+
+  static inline bool create_sub_table_plan (const hb_subset_plan_t *plan,
+                                            hb_vector_t<segment_plan> *segments)
+  {
+    segment_plan *segment = nullptr;
+    hb_codepoint_t last_gid = 0;
+
+    hb_codepoint_t cp = HB_SET_VALUE_INVALID;
+    while (plan->unicodes->next (&cp)) {
+      hb_codepoint_t new_gid;
+      if (unlikely (!plan->new_gid_for_codepoint (cp, &new_gid)))
+      {
+       DEBUG_MSG(SUBSET, nullptr, "Unable to find new gid for %04x", cp);
+       return false;
+      }
+
+      if (cp > 0xFFFF) {
+        // We are now outside of unicode BMP, stop adding to this cmap.
+        break;
+      }
+
+      if (!segment
+          || cp != segment->end_code + 1u)
+      {
+        segment = segments->push ();
+        segment->start_code.set (cp);
+        segment->end_code.set (cp);
+        segment->use_delta = true;
+      } else {
+        segment->end_code.set (cp);
+        if (last_gid + 1u != new_gid)
+          // gid's are not consecutive in this segment so delta
+          // cannot be used.
+          segment->use_delta = false;
+      }
+
+      last_gid = new_gid;
+    }
+
+    // There must be a final entry with end_code == 0xFFFF. Check if we need to add one.
+    if (segment == nullptr || segment->end_code != 0xFFFF)
+    {
+      segment = segments->push ();
+      segment->start_code.set (0xFFFF);
+      segment->end_code.set (0xFFFF);
+      segment->use_delta = true;
+    }
+
+    return true;
+  }
+
   struct accelerator_t
   {
     inline void init (const CmapSubtableFormat4 *subtable)
@@ -127,6 +280,17 @@ struct CmapSubtableFormat4
       return true;
     }
 
+    static inline void get_all_codepoints_func (const void *obj, hb_set_t *out)
+    {
+      const accelerator_t *thiz = (const accelerator_t *) obj;
+      for (unsigned int i = 0; i < thiz->segCount; i++)
+      {
+       if (thiz->startCount[i] != 0xFFFFu
+           || thiz->endCount[i] != 0xFFFFu) // Skip the last segment (0xFFFF)
+         hb_set_add_range (out, thiz->startCount[i], thiz->endCount[i]);
+      }
+    }
+
     const HBUINT16 *endCount;
     const HBUINT16 *startCount;
     const HBUINT16 *idDelta;
@@ -164,15 +328,17 @@ struct CmapSubtableFormat4
     return_trace (16 + 4 * (unsigned int) segCountX2 <= length);
   }
 
+
+
   protected:
   HBUINT16     format;         /* Format number is set to 4. */
   HBUINT16     length;         /* This is the length in bytes of the
                                 * subtable. */
-  HBUINT16     languageZ;      /* Ignore. */
+  HBUINT16     language      /* Ignore. */
   HBUINT16     segCountX2;     /* 2 x segCount. */
-  HBUINT16     searchRangeZ;   /* 2 * (2**floor(log2(segCount))) */
-  HBUINT16     entrySelectorZ; /* log2(searchRange/2) */
-  HBUINT16     rangeShiftZ;    /* 2 x segCount - searchRange */
+  HBUINT16     searchRange   /* 2 * (2**floor(log2(segCount))) */
+  HBUINT16     entrySelector /* log2(searchRange/2) */
+  HBUINT16     rangeShift    /* 2 x segCount - searchRange */
 
   HBUINT16     values[VAR];
 #if 0
@@ -193,6 +359,8 @@ struct CmapSubtableLongGroup
 {
   friend struct CmapSubtableFormat12;
   friend struct CmapSubtableFormat13;
+  template<typename U>
+  friend struct CmapSubtableLongSegmented;
   friend struct cmap;
 
   int cmp (hb_codepoint_t codepoint) const
@@ -238,8 +406,8 @@ struct CmapSubtableTrimmed
 
   protected:
   UINT         formatReserved; /* Subtable format and (maybe) padding. */
-  UINT         lengthZ;        /* Byte length of this subtable. */
-  UINT         languageZ;      /* Ignore. */
+  UINT         length        /* Byte length of this subtable. */
+  UINT         language      /* Ignore. */
   UINT         startCharCode;  /* First character code covered. */
   ArrayOf<GlyphID, UINT>
                glyphIdArray;   /* Array of glyph index values for character
@@ -265,6 +433,15 @@ struct CmapSubtableLongSegmented
     return true;
   }
 
+  inline void get_all_codepoints (hb_set_t *out) const
+  {
+    for (unsigned int i = 0; i < this->groups.len; i++) {
+      hb_set_add_range (out,
+                       this->groups[i].startCharCode,
+                       this->groups[i].endCharCode);
+    }
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -272,20 +449,20 @@ struct CmapSubtableLongSegmented
   }
 
   inline bool serialize (hb_serialize_context_t *c,
-                         hb_prealloced_array_t<CmapSubtableLongGroup> &group_data)
+                         const hb_vector_t<CmapSubtableLongGroup> &group_data)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
-    Supplier<CmapSubtableLongGroup> supplier (group_data.array, group_data.len);
+    Supplier<CmapSubtableLongGroup> supplier (group_data.arrayZ, group_data.len);
     if (unlikely (!groups.serialize (c, supplier, group_data.len))) return_trace (false);
     return true;
   }
 
   protected:
   HBUINT16     format;         /* Subtable format; set to 12. */
-  HBUINT16     reservedZ;      /* Reserved; set to 0. */
-  HBUINT32             lengthZ;        /* Byte length of this subtable. */
-  HBUINT32             languageZ;      /* Ignore. */
+  HBUINT16     reserved      /* Reserved; set to 0. */
+  HBUINT32     length;         /* Byte length of this subtable. */
+  HBUINT32     language;       /* Ignore. */
   SortedArrayOf<CmapSubtableLongGroup, HBUINT32>
                groups;         /* Groupings. */
   public:
@@ -297,6 +474,69 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12>
   static inline hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group,
                                                hb_codepoint_t u)
   { return group.glyphID + (u - group.startCharCode); }
+
+
+  bool serialize (hb_serialize_context_t *c,
+                  const hb_vector_t<CmapSubtableLongGroup> &groups)
+  {
+    if (unlikely (!c->extend_min (*this))) return false;
+
+    this->format.set (12);
+    this->reserved.set (0);
+    this->length.set (get_sub_table_size (groups));
+
+    return CmapSubtableLongSegmented<CmapSubtableFormat12>::serialize (c, groups);
+  }
+
+  static inline size_t get_sub_table_size (const hb_vector_t<CmapSubtableLongGroup> &groups)
+  {
+    return 16 + 12 * groups.len;
+  }
+
+  static inline bool create_sub_table_plan (const hb_subset_plan_t *plan,
+                                            hb_vector_t<CmapSubtableLongGroup> *groups)
+  {
+    CmapSubtableLongGroup *group = nullptr;
+
+    hb_codepoint_t cp = HB_SET_VALUE_INVALID;
+    while (plan->unicodes->next (&cp)) {
+      hb_codepoint_t new_gid;
+      if (unlikely (!plan->new_gid_for_codepoint (cp, &new_gid)))
+      {
+       DEBUG_MSG(SUBSET, nullptr, "Unable to find new gid for %04x", cp);
+       return false;
+      }
+
+      if (!group || !_is_gid_consecutive (group, cp, new_gid))
+      {
+        group = groups->push ();
+        group->startCharCode.set (cp);
+        group->endCharCode.set (cp);
+        group->glyphID.set (new_gid);
+      } else
+      {
+        group->endCharCode.set (cp);
+      }
+    }
+
+    DEBUG_MSG(SUBSET, nullptr, "cmap");
+    for (unsigned int i = 0; i < groups->len; i++) {
+      CmapSubtableLongGroup& group = (*groups)[i];
+      DEBUG_MSG(SUBSET, nullptr, "  %d: U+%04X-U+%04X, gid %d-%d", i, (uint32_t) group.startCharCode, (uint32_t) group.endCharCode, (uint32_t) group.glyphID, (uint32_t) group.glyphID + ((uint32_t) group.endCharCode - (uint32_t) group.startCharCode));
+    }
+
+    return true;
+  }
+
+ private:
+  static inline bool _is_gid_consecutive (CmapSubtableLongGroup *group,
+                                         hb_codepoint_t cp,
+                                         hb_codepoint_t new_gid)
+  {
+    return (cp - 1 == group->endCharCode) &&
+       new_gid == group->glyphID + (cp - group->startCharCode);
+  }
+
 };
 
 struct CmapSubtableFormat13 : CmapSubtableLongSegmented<CmapSubtableFormat13>
@@ -328,7 +568,7 @@ struct UnicodeValueRange
     return_trace (c->check_struct (this));
   }
 
-  UINT24       startUnicodeValue;      /* First value in this range. */
+  HBUINT24     startUnicodeValue;      /* First value in this range. */
   HBUINT8              additionalCount;        /* Number of additional values in this
                                         * range. */
   public:
@@ -350,7 +590,7 @@ struct UVSMapping
     return_trace (c->check_struct (this));
   }
 
-  UINT24       unicodeValue;   /* Base Unicode value of the UVS */
+  HBUINT24     unicodeValue;   /* Base Unicode value of the UVS */
   GlyphID      glyphID;        /* Glyph ID of the UVS */
   public:
   DEFINE_SIZE_STATIC (5);
@@ -392,7 +632,7 @@ struct VariationSelectorRecord
                  nonDefaultUVS.sanitize (c, base));
   }
 
-  UINT24       varSelector;    /* Variation selector. */
+  HBUINT24     varSelector;    /* Variation selector. */
   LOffsetTo<DefaultUVS>
                defaultUVS;     /* Offset to Default UVS Table. May be 0. */
   LOffsetTo<NonDefaultUVS>
@@ -419,7 +659,7 @@ struct CmapSubtableFormat14
 
   protected:
   HBUINT16     format;         /* Format number is set to 14. */
-  HBUINT32             lengthZ;        /* Byte length of this subtable. */
+  HBUINT32     length;         /* Byte length of this subtable. */
   SortedArrayOf<VariationSelectorRecord, HBUINT32>
                record;         /* Variation selector records; sorted
                                 * in increasing order of `varSelector'. */
@@ -509,6 +749,33 @@ struct cmap
 {
   static const hb_tag_t tableTag       = HB_OT_TAG_cmap;
 
+  struct subset_plan {
+    subset_plan(void)
+    {
+      format4_segments.init();
+      format12_groups.init();
+    }
+
+    ~subset_plan(void)
+    {
+      format4_segments.fini();
+      format12_groups.fini();
+    }
+
+    inline size_t final_size() const
+    {
+      return 4 // header
+          +  8 * 3 // 3 EncodingRecord
+          +  CmapSubtableFormat4::get_sub_table_size (this->format4_segments)
+          +  CmapSubtableFormat12::get_sub_table_size (this->format12_groups);
+    }
+
+    // Format 4
+    hb_vector_t<CmapSubtableFormat4::segment_plan> format4_segments;
+    // Format 12
+    hb_vector_t<CmapSubtableLongGroup> format12_groups;
+  };
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -517,41 +784,17 @@ struct cmap
                  encodingRecord.sanitize (c, this));
   }
 
-  inline bool populate_groups (hb_subset_plan_t *plan,
-                              hb_prealloced_array_t<CmapSubtableLongGroup> *groups) const
+  inline bool _create_plan (const hb_subset_plan_t *plan,
+                            subset_plan *cmap_plan) const
   {
-    CmapSubtableLongGroup *group = nullptr;
-    for (unsigned int i = 0; i < plan->codepoints.len; i++) {
-
-      hb_codepoint_t cp = plan->codepoints[i];
-      if (!group || cp - 1 != group->endCharCode)
-      {
-        group = groups->push ();
-        group->startCharCode.set (cp);
-        group->endCharCode.set (cp);
-        hb_codepoint_t new_gid;
-        if (unlikely (!hb_subset_plan_new_gid_for_codepoint (plan, cp, &new_gid)))
-        {
-          DEBUG_MSG(SUBSET, nullptr, "Unable to find new gid for %04x", cp);
-          return false;
-        }
-        group->glyphID.set (new_gid);
-      } else
-      {
-        group->endCharCode.set (cp);
-      }
-    }
-
-    DEBUG_MSG(SUBSET, nullptr, "cmap");
-    for (unsigned int i = 0; i < groups->len; i++) {
-      CmapSubtableLongGroup& group = (*groups)[i];
-      DEBUG_MSG(SUBSET, nullptr, "  %d: U+%04X-U+%04X, gid %d-%d", i, (uint32_t) group.startCharCode, (uint32_t) group.endCharCode, (uint32_t) group.glyphID, (uint32_t) group.glyphID + ((uint32_t) group.endCharCode - (uint32_t) group.startCharCode));
-    }
+    if (unlikely( !CmapSubtableFormat4::create_sub_table_plan (plan, &cmap_plan->format4_segments)))
+      return false;
 
-    return true;
+    return CmapSubtableFormat12::create_sub_table_plan (plan, &cmap_plan->format12_groups);
   }
 
-  inline bool _subset (hb_prealloced_array_t<CmapSubtableLongGroup> &groups,
+  inline bool _subset (const hb_subset_plan_t *plan,
+                       const subset_plan &cmap_subset_plan,
                       size_t dest_sz,
                       void *dest) const
   {
@@ -565,25 +808,46 @@ struct cmap
 
     cmap->version.set (0);
 
-    if (unlikely (!cmap->encodingRecord.serialize (&c, /* numTables */ 1))) return false;
+    if (unlikely (!cmap->encodingRecord.serialize (&c, /* numTables */ 3)))
+      return false;
+
+    // TODO(grieger): Convert the below to a for loop
 
-    EncodingRecord &rec = cmap->encodingRecord[0];
-    rec.platformID.set (3); // Windows
-    rec.encodingID.set (10); // Unicode UCS-4
+    // Format 4, Plat 0 Encoding Record
+    EncodingRecord &format4_plat0_rec = cmap->encodingRecord[0];
+    format4_plat0_rec.platformID.set (0); // Unicode
+    format4_plat0_rec.encodingID.set (3);
 
-    /* capture offset to subtable */
-    CmapSubtable &subtable = rec.subtable.serialize (&c, cmap);
+    // Format 4, Plat 3 Encoding Record
+    EncodingRecord &format4_plat3_rec = cmap->encodingRecord[1];
+    format4_plat3_rec.platformID.set (3); // Windows
+    format4_plat3_rec.encodingID.set (1); // Unicode BMP
 
-    subtable.u.format.set (12);
+    // Format 12 Encoding Record
+    EncodingRecord &format12_rec = cmap->encodingRecord[2];
+    format12_rec.platformID.set (3); // Windows
+    format12_rec.encodingID.set (10); // Unicode UCS-4
 
-    CmapSubtableFormat12 &format12 = subtable.u.format12;
-    if (unlikely (!c.extend_min (format12))) return false;
+    // Write out format 4 sub table
+    {
+      CmapSubtable &subtable = format4_plat0_rec.subtable.serialize (&c, cmap);
+      format4_plat3_rec.subtable.set (format4_plat0_rec.subtable);
+      subtable.u.format.set (4);
 
-    format12.format.set (12);
-    format12.reservedZ.set (0);
-    format12.lengthZ.set (16 + 12 * groups.len);
+      CmapSubtableFormat4 &format4 = subtable.u.format4;
+      if (unlikely (!format4.serialize (&c, plan, cmap_subset_plan.format4_segments)))
+        return false;
+    }
 
-    if (unlikely (!format12.serialize (&c, groups))) return false;
+    // Write out format 12 sub table.
+    {
+      CmapSubtable &subtable = format12_rec.subtable.serialize (&c, cmap);
+      subtable.u.format.set (12);
+
+      CmapSubtableFormat12 &format12 = subtable.u.format12;
+      if (unlikely (!format12.serialize (&c, cmap_subset_plan.format12_groups)))
+        return false;
+    }
 
     c.end_serialize ();
 
@@ -592,24 +856,25 @@ struct cmap
 
   inline bool subset (hb_subset_plan_t *plan) const
   {
-    hb_auto_array_t<CmapSubtableLongGroup> groups;
+    subset_plan cmap_subset_plan;
 
-    if (unlikely (!populate_groups (plan, &groups))) return false;
+    if (unlikely (!_create_plan (plan, &cmap_subset_plan)))
+    {
+      DEBUG_MSG(SUBSET, nullptr, "Failed to generate a cmap subsetting plan.");
+      return false;
+    }
 
     // We now know how big our blob needs to be
-    // TODO use APIs from the structs to get size?
-    size_t dest_sz = 4 // header
-                   + 8 // 1 EncodingRecord
-                   + 16 // Format 12 header
-                   + 12 * groups.len; // SequentialMapGroup records
+    size_t dest_sz = cmap_subset_plan.final_size();
     void *dest = malloc (dest_sz);
     if (unlikely (!dest)) {
       DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %lu for cmap subset output", (unsigned long) dest_sz);
       return false;
     }
 
-    if (unlikely (!_subset (groups, dest_sz, dest)))
+    if (unlikely (!_subset (plan, cmap_subset_plan, dest_sz, dest)))
     {
+      DEBUG_MSG(SUBSET, nullptr, "Failed to perform subsetting of cmap.");
       free (dest);
       return false;
     }
@@ -620,7 +885,7 @@ struct cmap
                                             HB_MEMORY_MODE_READONLY,
                                             dest,
                                             free);
-    bool result =  hb_subset_plan_add_table (plan, HB_OT_TAG_cmap, cmap_prime);
+    bool result =  plan->add_table (HB_OT_TAG_cmap, cmap_prime);
     hb_blob_destroy (cmap_prime);
     return result;
   }
@@ -630,7 +895,7 @@ struct cmap
     inline void init (hb_face_t *face)
     {
       this->blob = OT::Sanitizer<OT::cmap>().sanitize (face->reference_table (HB_OT_TAG_cmap));
-      const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (this->blob);
+      const OT::cmap *cmap = this->blob->as<OT::cmap> ();
       const OT::CmapSubtable *subtable = nullptr;
       const OT::CmapSubtableFormat14 *subtable_uvs = nullptr;
 
@@ -651,7 +916,7 @@ struct cmap
        if (subtable) symbol = true;
       }
       /* Meh. */
-      if (!subtable) subtable = &OT::Null(OT::CmapSubtable);
+      if (!subtable) subtable = &Null(OT::CmapSubtable);
 
       /* UVS subtable. */
       if (!subtable_uvs)
@@ -661,26 +926,36 @@ struct cmap
          subtable_uvs = &st->u.format14;
       }
       /* Meh. */
-      if (!subtable_uvs) subtable_uvs = &OT::Null(OT::CmapSubtableFormat14);
+      if (!subtable_uvs) subtable_uvs = &Null(OT::CmapSubtableFormat14);
 
       this->uvs_table = subtable_uvs;
 
       this->get_glyph_data = subtable;
       if (unlikely (symbol))
+      {
        this->get_glyph_func = get_glyph_from_symbol<OT::CmapSubtable>;
-      else
+       this->get_all_codepoints_func = null_get_all_codepoints_func;
+      } else {
        switch (subtable->u.format) {
        /* Accelerate format 4 and format 12. */
-       default: this->get_glyph_func = get_glyph_from<OT::CmapSubtable>;               break;
-       case 12: this->get_glyph_func = get_glyph_from<OT::CmapSubtableFormat12>;       break;
+       default:
+         this->get_glyph_func = get_glyph_from<OT::CmapSubtable>;
+         this->get_all_codepoints_func = null_get_all_codepoints_func;
+         break;
+       case 12:
+         this->get_glyph_func = get_glyph_from<OT::CmapSubtableFormat12>;
+         this->get_all_codepoints_func = get_all_codepoints_from<OT::CmapSubtableFormat12>;
+         break;
        case  4:
          {
            this->format4_accel.init (&subtable->u.format4);
            this->get_glyph_data = &this->format4_accel;
            this->get_glyph_func = this->format4_accel.get_glyph_func;
+           this->get_all_codepoints_func = this->format4_accel.get_all_codepoints_func;
          }
          break;
        }
+      }
     }
 
     inline void fini (void)
@@ -710,10 +985,22 @@ struct cmap
       return get_nominal_glyph (unicode, glyph);
     }
 
+    inline void get_all_codepoints (hb_set_t *out) const
+    {
+      this->get_all_codepoints_func (get_glyph_data, out);
+    }
+
     protected:
     typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj,
                                              hb_codepoint_t codepoint,
                                              hb_codepoint_t *glyph);
+    typedef void (*hb_cmap_get_all_codepoints_func_t) (const void *obj,
+                                                      hb_set_t *out);
+
+    static inline void null_get_all_codepoints_func (const void *obj, hb_set_t *out)
+    {
+      // NOOP
+    }
 
     template <typename Type>
     static inline bool get_glyph_from (const void *obj,
@@ -725,6 +1012,14 @@ struct cmap
     }
 
     template <typename Type>
+    static inline void get_all_codepoints_from (const void *obj,
+                                               hb_set_t *out)
+    {
+      const Type *typed_obj = (const Type *) obj;
+      typed_obj->get_all_codepoints (out);
+    }
+
+    template <typename Type>
     static inline bool get_glyph_from_symbol (const void *obj,
                                              hb_codepoint_t codepoint,
                                              hb_codepoint_t *glyph)
@@ -738,7 +1033,7 @@ struct cmap
        /* For symbol-encoded OpenType fonts, we duplicate the
         * U+F000..F0FF range at U+0000..U+00FF.  That's what
         * Windows seems to do, and that's hinted about at:
-        * http://www.microsoft.com/typography/otspec/recom.htm
+        * https://docs.microsoft.com/en-us/typography/opentype/spec/recom
         * under "Non-Standard (Symbol) Fonts". */
        return typed_obj->get_glyph (0xF000u + codepoint, glyph);
       }
@@ -749,6 +1044,8 @@ struct cmap
     private:
     hb_cmap_get_glyph_func_t get_glyph_func;
     const void *get_glyph_data;
+    hb_cmap_get_all_codepoints_func_t get_all_codepoints_func;
+
     OT::CmapSubtableFormat4::accelerator_t format4_accel;
 
     const OT::CmapSubtableFormat14 *uvs_table;
index e7ab917..d1dd9de 100644 (file)
 
 #include "hb-open-type-private.hh"
 
+/*
+ * CBLC -- Color Bitmap Location
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/cblc
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/eblc
+ * CBDT -- Color Bitmap Data
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/cbdt
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/ebdt
+ */
+#define HB_OT_TAG_CBLC HB_TAG('C','B','L','C')
+#define HB_OT_TAG_CBDT HB_TAG('C','B','D','T')
+
+
 namespace OT {
 
 struct SmallGlyphMetrics
@@ -47,21 +59,21 @@ struct SmallGlyphMetrics
     extents->height = -height;
   }
 
-  HBUINT8 height;
-  HBUINT8 width;
-  HBINT8 bearingX;
-  HBINT8 bearingY;
-  HBUINT8 advance;
-
+  HBUINT8      height;
+  HBUINT8      width;
+  HBINT8       bearingX;
+  HBINT8       bearingY;
+  HBUINT8      advance;
+  public:
   DEFINE_SIZE_STATIC(5);
 };
 
 struct BigGlyphMetrics : SmallGlyphMetrics
 {
-  HBINT8 vertBearingX;
-  HBINT8 vertBearingY;
-  HBUINT8 vertAdvance;
-
+  HBINT8       vertBearingX;
+  HBINT8       vertBearingY;
+  HBUINT8      vertAdvance;
+  public:
   DEFINE_SIZE_STATIC(8);
 };
 
@@ -73,19 +85,19 @@ struct SBitLineMetrics
     return_trace (c->check_struct (this));
   }
 
-  HBINT8 ascender;
-  HBINT8 decender;
-  HBUINT8 widthMax;
-  HBINT8 caretSlopeNumerator;
-  HBINT8 caretSlopeDenominator;
-  HBINT8 caretOffset;
-  HBINT8 minOriginSB;
-  HBINT8 minAdvanceSB;
-  HBINT8 maxBeforeBL;
-  HBINT8 minAfterBL;
-  HBINT8 padding1;
-  HBINT8 padding2;
-
+  HBINT8       ascender;
+  HBINT8       decender;
+  HBUINT8      widthMax;
+  HBINT8       caretSlopeNumerator;
+  HBINT8       caretSlopeDenominator;
+  HBINT8       caretOffset;
+  HBINT8       minOriginSB;
+  HBINT8       minAdvanceSB;
+  HBINT8       maxBeforeBL;
+  HBINT8       minAfterBL;
+  HBINT8       padding1;
+  HBINT8       padding2;
+  public:
   DEFINE_SIZE_STATIC(12);
 };
 
@@ -102,10 +114,10 @@ struct IndexSubtableHeader
     return_trace (c->check_struct (this));
   }
 
-  HBUINT16 indexFormat;
-  HBUINT16 imageFormat;
-  HBUINT32 imageDataOffset;
-
+  HBUINT16     indexFormat;
+  HBUINT16     imageFormat;
+  HBUINT32     imageDataOffset;
+  public:
   DEFINE_SIZE_STATIC(8);
 };
 
@@ -131,9 +143,9 @@ struct IndexSubtableFormat1Or3
     return true;
   }
 
-  IndexSubtableHeader header;
-  Offset<OffsetType> offsetArrayZ[VAR];
-
+  IndexSubtableHeader  header;
+  Offset<OffsetType>   offsetArrayZ[VAR];
+  public:
   DEFINE_SIZE_ARRAY(8, offsetArrayZ);
 };
 
@@ -214,15 +226,17 @@ struct IndexSubtableRecord
                                                   offset, length, format);
   }
 
-  HBUINT16 firstGlyphIndex;
-  HBUINT16 lastGlyphIndex;
-  LOffsetTo<IndexSubtable> offsetToSubtable;
-
+  GlyphID                      firstGlyphIndex;
+  GlyphID                      lastGlyphIndex;
+  LOffsetTo<IndexSubtable>     offsetToSubtable;
+  public:
   DEFINE_SIZE_STATIC(8);
 };
 
 struct IndexSubtableArray
 {
+  friend struct CBDT;
+
   inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
   {
     TRACE_SANITIZE (this);
@@ -249,8 +263,7 @@ struct IndexSubtableArray
   }
 
   protected:
-  IndexSubtableRecord indexSubtablesZ[VAR];
-
+  IndexSubtableRecord  indexSubtablesZ[VAR];
   public:
   DEFINE_SIZE_ARRAY(0, indexSubtablesZ);
 };
@@ -258,6 +271,7 @@ struct IndexSubtableArray
 struct BitmapSizeTable
 {
   friend struct CBLC;
+  friend struct CBDT;
 
   inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
   {
@@ -275,19 +289,19 @@ struct BitmapSizeTable
   }
 
   protected:
-  LOffsetTo<IndexSubtableArray> indexSubtableArrayOffset;
-  HBUINT32 indexTablesSize;
-  HBUINT32 numberOfIndexSubtables;
-  HBUINT32 colorRef;
-  SBitLineMetrics horizontal;
-  SBitLineMetrics vertical;
-  HBUINT16 startGlyphIndex;
-  HBUINT16 endGlyphIndex;
-  HBUINT8 ppemX;
-  HBUINT8 ppemY;
-  HBUINT8 bitDepth;
-  HBINT8 flags;
-
+  LOffsetTo<IndexSubtableArray>
+                       indexSubtableArrayOffset;
+  HBUINT32             indexTablesSize;
+  HBUINT32             numberOfIndexSubtables;
+  HBUINT32             colorRef;
+  SBitLineMetrics      horizontal;
+  SBitLineMetrics      vertical;
+  GlyphID              startGlyphIndex;
+  GlyphID              endGlyphIndex;
+  HBUINT8              ppemX;
+  HBUINT8              ppemY;
+  HBUINT8              bitDepth;
+  HBINT8               flags;
   public:
   DEFINE_SIZE_STATIC(48);
 };
@@ -299,19 +313,26 @@ struct BitmapSizeTable
 
 struct GlyphBitmapDataFormat17
 {
-  SmallGlyphMetrics glyphMetrics;
-  HBUINT32 dataLen;
-  HBUINT8 dataZ[VAR];
-
-  DEFINE_SIZE_ARRAY(9, dataZ);
+  SmallGlyphMetrics    glyphMetrics;
+  LArrayOf<HBUINT8>    data;
+  public:
+  DEFINE_SIZE_ARRAY(9, data);
 };
 
+struct GlyphBitmapDataFormat18
+{
+  BigGlyphMetrics      glyphMetrics;
+  LArrayOf<HBUINT8>    data;
+  public:
+  DEFINE_SIZE_ARRAY(12, data);
+};
 
-/*
- * CBLC -- Color Bitmap Location Table
- */
-
-#define HB_OT_TAG_CBLC HB_TAG('C','B','L','C')
+struct GlyphBitmapDataFormat19
+{
+  LArrayOf<HBUINT8>    data;
+  public:
+  DEFINE_SIZE_ARRAY(4, data);
+};
 
 struct CBLC
 {
@@ -336,8 +357,8 @@ struct CBLC
     unsigned int count = sizeTables.len;
     for (uint32_t i = 0; i < count; ++i)
     {
-      unsigned int startGlyphIndex = sizeTables.array[i].startGlyphIndex;
-      unsigned int endGlyphIndex = sizeTables.array[i].endGlyphIndex;
+      unsigned int startGlyphIndex = sizeTables.arrayZ[i].startGlyphIndex;
+      unsigned int endGlyphIndex = sizeTables.arrayZ[i].endGlyphIndex;
       if (startGlyphIndex <= glyph && glyph <= endGlyphIndex)
       {
        *x_ppem = sizeTables[i].ppemX;
@@ -352,16 +373,10 @@ struct CBLC
   protected:
   FixedVersion<>               version;
   LArrayOf<BitmapSizeTable>    sizeTables;
-
   public:
   DEFINE_SIZE_ARRAY(8, sizeTables);
 };
 
-/*
- * CBDT -- Color Bitmap Data Table
- */
-#define HB_OT_TAG_CBDT HB_TAG('C','B','D','T')
-
 struct CBDT
 {
   static const hb_tag_t tableTag = HB_OT_TAG_CBDT;
@@ -388,8 +403,8 @@ struct CBDT
        cbdt = nullptr;
        return;  /* Not a bitmap font. */
       }
-      cblc = Sanitizer<CBLC>::lock_instance (cblc_blob);
-      cbdt = Sanitizer<CBDT>::lock_instance (cbdt_blob);
+      cblc = cblc_blob->as<CBLC> ();
+      cbdt = cbdt_blob->as<CBDT> ();
 
     }
 
@@ -447,6 +462,59 @@ struct CBDT
       return true;
     }
 
+    inline void dump (void (*callback) (const uint8_t* data, unsigned int length,
+        unsigned int group, unsigned int gid)) const
+    {
+      if (!cblc)
+       return;  // Not a color bitmap font.
+
+      for (unsigned int i = 0; i < cblc->sizeTables.len; ++i)
+      {
+        const BitmapSizeTable &sizeTable = cblc->sizeTables[i];
+        const IndexSubtableArray &subtable_array = cblc+sizeTable.indexSubtableArrayOffset;
+        for (unsigned int j = 0; j < sizeTable.numberOfIndexSubtables; ++j)
+        {
+          const IndexSubtableRecord &subtable_record = subtable_array.indexSubtablesZ[j];
+          for (unsigned int gid = subtable_record.firstGlyphIndex;
+                gid <= subtable_record.lastGlyphIndex; ++gid)
+          {
+            unsigned int image_offset = 0, image_length = 0, image_format = 0;
+
+            if (!subtable_record.get_image_data (gid,
+                  &image_offset, &image_length, &image_format))
+              continue;
+
+            switch (image_format)
+            {
+            case 17: {
+              const GlyphBitmapDataFormat17& glyphFormat17 =
+                StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset);
+              callback ((const uint8_t *) &glyphFormat17.data.arrayZ,
+                glyphFormat17.data.len, i, gid);
+            }
+            break;
+            case 18: {
+              const GlyphBitmapDataFormat18& glyphFormat18 =
+                StructAtOffset<GlyphBitmapDataFormat18> (this->cbdt, image_offset);
+              callback ((const uint8_t *) &glyphFormat18.data.arrayZ,
+                glyphFormat18.data.len, i, gid);
+            }
+            break;
+            case 19: {
+              const GlyphBitmapDataFormat19& glyphFormat19 =
+                StructAtOffset<GlyphBitmapDataFormat19> (this->cbdt, image_offset);
+              callback ((const uint8_t *) &glyphFormat19.data.arrayZ,
+                glyphFormat19.data.len, i, gid);
+            }
+            break;
+            default:
+              continue;
+            }
+          }
+        }
+      }
+    }
+
     private:
     hb_blob_t *cblc_blob;
     hb_blob_t *cbdt_blob;
@@ -459,9 +527,8 @@ struct CBDT
 
 
   protected:
-  FixedVersion<>version;
-  HBUINT8 dataZ[VAR];
-
+  FixedVersion<>       version;
+  HBUINT8              dataZ[VAR];
   public:
   DEFINE_SIZE_ARRAY(4, dataZ);
 };
index 2c3b1cc..ce6702d 100644 (file)
 #include "hb-open-type-private.hh"
 
 /*
- * Color Palette
- * http://www.microsoft.com/typography/otspec/colr.htm
+ * COLR -- Color
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/colr
  */
-
 #define HB_OT_TAG_COLR HB_TAG('C','O','L','R')
 
+
 namespace OT {
 
 
@@ -48,8 +48,8 @@ struct LayerRecord
   }
 
   protected:
-  GlyphID gID;                 /* Glyph ID of layer glyph */
-  HBUINT16 paletteIndex;       /* Index value to use with a selected color palette */
+  GlyphID      glyphid;        /* Glyph ID of layer glyph */
+  HBUINT16     colorIdx;       /* Index value to use with a selected color palette */
   public:
   DEFINE_SIZE_STATIC (4);
 };
@@ -61,17 +61,28 @@ struct BaseGlyphRecord
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
+    return_trace (likely (c->check_struct (this)));
+  }
+
+  inline int cmp (hb_codepoint_t g) const {
+    return g < glyphid ? -1 : g > glyphid ? 1 : 0;
   }
 
   protected:
-  GlyphID gID;                 /* Glyph ID of reference glyph */
-  HBUINT16 firstLayerIndex;    /* Index to the layer record */
-  HBUINT16 numLayers;          /* Number of color layers associated with this glyph */
+  GlyphID      glyphid;        /* Glyph ID of reference glyph */
+  HBUINT16     firstLayerIdx;  /* Index to the layer record */
+  HBUINT16     numLayers;      /* Number of color layers associated with this glyph */
   public:
   DEFINE_SIZE_STATIC (6);
 };
 
+static int compare_bgr (const void *pa, const void *pb)
+{
+  const hb_codepoint_t *a = (const hb_codepoint_t *) pa;
+  const BaseGlyphRecord *b = (const BaseGlyphRecord *) pb;
+  return b->cmp (*a);
+}
+
 struct COLR
 {
   static const hb_tag_t tableTag = HB_OT_TAG_COLR;
@@ -79,59 +90,50 @@ struct COLR
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (!(c->check_struct (this) &&
-        c->check_array ((const void*) &layerRecordsOffsetZ, sizeof (LayerRecord), numLayerRecords) &&
-        c->check_array ((const void*) &baseGlyphRecordsZ, sizeof (BaseGlyphRecord), numBaseGlyphRecords)))
-      return_trace (false);
-
-    const BaseGlyphRecord* base_glyph_records = &baseGlyphRecordsZ (this);
-    for (unsigned int i = 0; i < numBaseGlyphRecords; ++i)
-      if (base_glyph_records[i].firstLayerIndex +
-          base_glyph_records[i].numLayers > numLayerRecords)
-        return_trace (false);
-
-    return_trace (true);
+    return_trace (likely (c->check_struct (this) &&
+                         (this+baseGlyphsZ).sanitize (c, numBaseGlyphs) &&
+                         (this+layersZ).sanitize (c, numLayers)));
   }
 
-  inline bool get_base_glyph_record (
-    hb_codepoint_t glyph_id, unsigned int &first_layer, unsigned int &num_layers) const
+  inline bool get_base_glyph_record (hb_codepoint_t glyph_id,
+                                    unsigned int *first_layer /* OUT */,
+                                    unsigned int *num_layers /* OUT */) const
   {
-    const BaseGlyphRecord* base_glyph_records = &baseGlyphRecordsZ (this);
-    unsigned int min = 0, max = numBaseGlyphRecords - 1;
-    while (min <= max)
-    {
-      unsigned int mid = (min + max) / 2;
-      hb_codepoint_t gID = base_glyph_records[mid].gID;
-      if (gID > glyph_id)
-        max = mid - 1;
-      else if (gID < glyph_id)
-        min = mid + 1;
-      else
-      {
-        first_layer = base_glyph_records[mid].firstLayerIndex;
-        num_layers = base_glyph_records[mid].numLayers;
-        return true;
-      }
-    }
-    return false;
+    const BaseGlyphRecord* record;
+    record = (BaseGlyphRecord *) bsearch (&glyph_id, &(this+baseGlyphsZ), numBaseGlyphs,
+                                         sizeof (BaseGlyphRecord), compare_bgr);
+    if (unlikely (!record))
+      return false;
+
+    *first_layer = record->firstLayerIdx;
+    *num_layers = record->numLayers;
+    return true;
   }
 
-  inline void get_layer_record (int layer,
-    hb_codepoint_t &glyph_id, unsigned int &palette_index) const
+  inline bool get_layer_record (unsigned int record,
+                               hb_codepoint_t *glyph_id /* OUT */,
+                               unsigned int *palette_index /* OUT */) const
   {
-    const LayerRecord* records = &layerRecordsOffsetZ (this);
-    glyph_id = records[layer].gID;
-    palette_index = records[layer].paletteIndex;
+    if (unlikely (record >= numLayers))
+    {
+      *glyph_id = 0;
+      *palette_index = 0xFFFF;
+      return false;
+    }
+    const LayerRecord &layer = (this+layersZ)[record];
+    *glyph_id = layer.glyphid;
+    *palette_index = layer.colorIdx;
+    return true;
   }
 
   protected:
-  HBUINT16     version;                /* Table version number */
-  HBUINT16     numBaseGlyphRecords;    /* Number of Base Glyph Records */
-  LOffsetTo<BaseGlyphRecord>
-               baseGlyphRecordsZ;      /* Offset to Base Glyph records. */
-  LOffsetTo<LayerRecord>
-               layerRecordsOffsetZ;    /* Offset to Layer Records */
-  HBUINT16     numLayerRecords;        /* Number of Layer Records */
+  HBUINT16     version;        /* Table version number */
+  HBUINT16     numBaseGlyphs;  /* Number of Base Glyph Records */
+  LOffsetTo<UnsizedArrayOf<BaseGlyphRecord> >
+               baseGlyphsZ;    /* Offset to Base Glyph records. */
+  LOffsetTo<UnsizedArrayOf<LayerRecord> >
+               layersZ;        /* Offset to Layer Records */
+  HBUINT16     numLayers;      /* Number of Layer Records */
   public:
   DEFINE_SIZE_STATIC (14);
 };
index e364c8a..2c31274 100644 (file)
@@ -79,12 +79,12 @@ typedef enum { /*< flags >*/
 
 
 /*
- * Color Palette
- * http://www.microsoft.com/typography/otspec/cpal.htm
+ * CPAL -- Color Palette
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/cpal
  */
-
 #define HB_OT_TAG_CPAL HB_TAG('C','P','A','L')
 
+
 namespace OT {
 
 
@@ -92,35 +92,44 @@ struct CPALV1Tail
 {
   friend struct CPAL;
 
-  inline bool sanitize (hb_sanitize_context_t *c, unsigned int palettes) const
+  inline bool
+  sanitize (hb_sanitize_context_t *c, const void *base, unsigned int palettes) const
   {
     TRACE_SANITIZE (this);
-    return_trace (
-      c->check_struct (this) &&
-      c->check_array ((const void*) &paletteFlags, sizeof (HBUINT32), palettes) &&
-      c->check_array ((const void*) &paletteLabel, sizeof (HBUINT16), palettes) &&
-      c->check_array ((const void*) &paletteEntryLabel, sizeof (HBUINT16), palettes));
+    return_trace (c->check_struct (this) &&
+                 (base+paletteFlagsZ).sanitize (c, palettes) &&
+                 (base+paletteLabelZ).sanitize (c, palettes) &&
+                 (base+paletteEntryLabelZ).sanitize (c, palettes));
   }
 
   private:
   inline hb_ot_color_palette_flags_t
   get_palette_flags (const void *base, unsigned int palette) const
   {
-    const HBUINT32* flags = &paletteFlags (base);
-    return (hb_ot_color_palette_flags_t) (uint32_t) flags[palette];
+    // range checked at the CPAL caller
+    return (hb_ot_color_palette_flags_t) (uint32_t) (base+paletteFlagsZ)[palette];
   }
 
   inline unsigned int
   get_palette_name_id (const void *base, unsigned int palette) const
   {
-    const HBUINT16* name_ids = &paletteLabel (base);
-    return name_ids[palette];
+    // range checked at the CPAL caller
+    return (base+paletteLabelZ)[palette];
   }
 
   protected:
-  LOffsetTo<HBUINT32> paletteFlags;
-  LOffsetTo<HBUINT16> paletteLabel;
-  LOffsetTo<HBUINT16> paletteEntryLabel;
+  LOffsetTo<UnsizedArrayOf<HBUINT32> >
+               paletteFlagsZ;          /* Offset from the beginning of CPAL table to
+                                        * the Palette Type Array. Set to 0 if no array
+                                        * is provided. */
+  LOffsetTo<UnsizedArrayOf<HBUINT16> >
+               paletteLabelZ;          /* Offset from the beginning of CPAL table to
+                                        * the Palette Labels Array. Set to 0 if no
+                                        * array is provided. */
+  LOffsetTo<UnsizedArrayOf<HBUINT16> >
+               paletteEntryLabelZ;     /* Offset from the beginning of CPAL table to
+                                        * the Palette Entry Label Array. Set to 0
+                                        * if no array is provided. */
   public:
   DEFINE_SIZE_STATIC (12);
 };
@@ -134,21 +143,22 @@ struct CPAL
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (!(c->check_struct (this) && // This checks colorRecordIndicesX sanity also, see #get_size
-        c->check_array ((const void*) &colorRecordsZ, sizeof (BGRAColor), numColorRecords)))
+    if (unlikely (!(c->check_struct (this) &&  // it checks colorRecordIndices also
+                                               // see #get_size
+                   (this+colorRecordsZ).sanitize (c, numColorRecords))))
       return_trace (false);
 
     // Check for indices sanity so no need for doing it runtime
     for (unsigned int i = 0; i < numPalettes; ++i)
-      if (colorRecordIndicesX[i] + numPaletteEntries > numColorRecords)
-        return_trace (false);
+      if (unlikely (colorRecordIndicesZ[i] + numPaletteEntries > numColorRecords))
+       return_trace (false);
 
     // If version is zero, we are done here; otherwise we need to check tail also
     if (version == 0)
       return_trace (true);
 
     const CPALV1Tail &v1 = StructAfter<CPALV1Tail> (*this);
-    return_trace (v1.sanitize (c, numPalettes));
+    return_trace (likely (v1.sanitize (c, this, numPalettes)));
   }
 
   inline unsigned int get_size (void) const
@@ -158,7 +168,7 @@ struct CPAL
 
   inline hb_ot_color_palette_flags_t get_palette_flags (unsigned int palette) const
   {
-    if (version == 0 || palette >= numPalettes)
+    if (unlikely (version == 0 || palette >= numPalettes))
       return HB_OT_COLOR_PALETTE_FLAG_DEFAULT;
 
     const CPALV1Tail& cpal1 = StructAfter<CPALV1Tail> (*this);
@@ -167,7 +177,7 @@ struct CPAL
 
   inline unsigned int get_palette_name_id (unsigned int palette) const
   {
-    if (version == 0 || palette >= numPalettes)
+    if (unlikely (version == 0 || palette >= numPalettes))
       return 0xFFFF;
 
     const CPALV1Tail& cpal1 = StructAfter<CPALV1Tail> (*this);
@@ -179,27 +189,33 @@ struct CPAL
     return numPalettes;
   }
 
-  inline hb_ot_color_t get_color_record_argb (unsigned int color_index, unsigned int palette) const
+  inline hb_ot_color_t
+  get_color_record_argb (unsigned int color_index, unsigned int palette) const
   {
-    if (color_index >= numPaletteEntries || palette >= numPalettes)
+    if (unlikely (color_index >= numPaletteEntries || palette >= numPalettes))
       return 0;
 
-    const BGRAColor* records = &colorRecordsZ(this);
     // No need for more range check as it is already done on #sanitize
-    return records[colorRecordIndicesX[palette] + color_index];
+    const UnsizedArrayOf<BGRAColor>& color_records = this+colorRecordsZ;
+    return color_records[colorRecordIndicesZ[palette] + color_index];
   }
 
   protected:
-  HBUINT16     version;
+  HBUINT16     version;                /* Table version number */
   /* Version 0 */
-  HBUINT16     numPaletteEntries;
-  HBUINT16     numPalettes;
-  HBUINT16     numColorRecords;
-  LOffsetTo<HBUINT32>  colorRecordsZ;
-  HBUINT16     colorRecordIndicesX[VAR];  // VAR=numPalettes
-/*CPALV1Tail   v1[VAR];*/
+  HBUINT16     numPaletteEntries;      /* Number of palette entries in each palette. */
+  HBUINT16     numPalettes;            /* Number of palettes in the table. */
+  HBUINT16     numColorRecords;        /* Total number of color records, combined for
+                                        * all palettes. */
+  LOffsetTo<UnsizedArrayOf<BGRAColor> >
+               colorRecordsZ;          /* Offset from the beginning of CPAL table to
+                                        * the first ColorRecord. */
+  UnsizedArrayOf<HBUINT16>
+               colorRecordIndicesZ;    /* Index of each palette’s first color record in
+                                        * the combined color record array. */
+/*CPALV1Tail   v1;*/
   public:
-  DEFINE_SIZE_ARRAY (12, colorRecordIndicesX);
+  DEFINE_SIZE_ARRAY (12, colorRecordIndicesZ);
 };
 
 } /* namespace OT */
diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh
new file mode 100644 (file)
index 0000000..09a9517
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright © 2018  Ebrahim Byagowi
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef HB_OT_COLOR_SBIX_TABLE_HH
+#define HB_OT_COLOR_SBIX_TABLE_HH
+
+#include "hb-open-type-private.hh"
+
+/*
+ * sbix -- Standard Bitmap Graphics
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/sbix
+ * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6sbix.html
+ */
+#define HB_OT_TAG_sbix HB_TAG('s','b','i','x')
+
+
+namespace OT {
+
+
+struct SBIXGlyph
+{
+  HBINT16      xOffset;        /* The horizontal (x-axis) offset from the left
+                                * edge of the graphic to the glyph’s origin.
+                                * That is, the x-coordinate of the point on the
+                                * baseline at the left edge of the glyph. */
+  HBINT16      yOffset;        /* The vertical (y-axis) offset from the bottom
+                                * edge of the graphic to the glyph’s origin.
+                                * That is, the y-coordinate of the point on the
+                                * baseline at the left edge of the glyph. */
+  Tag          graphicType;    /* Indicates the format of the embedded graphic
+                                * data: one of 'jpg ', 'png ' or 'tiff', or the
+                                * special format 'dupe'. */
+  UnsizedArrayOf<HBUINT8>
+               data;           /* The actual embedded graphic data. The total
+                                * length is inferred from sequential entries in
+                                * the glyphDataOffsets array and the fixed size
+                                * (8 bytes) of the preceding fields. */
+  public:
+  DEFINE_SIZE_ARRAY (8, data);
+};
+
+struct SBIXStrike
+{
+  friend struct sbix;
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                 imageOffsetsZ.sanitize_shallow (c, c->num_glyphs + 1));
+  }
+
+  protected:
+  HBUINT16     ppem;           /* The PPEM size for which this strike was designed. */
+  HBUINT16     resolution;     /* The device pixel density (in PPI) for which this
+                                * strike was designed. (E.g., 96 PPI, 192 PPI.) */
+  UnsizedArrayOf<LOffsetTo<SBIXGlyph> >
+               imageOffsetsZ;  /* Offset from the beginning of the strike data header
+                                * to bitmap data for an individual glyph ID. */
+  public:
+  DEFINE_SIZE_STATIC (8);
+};
+
+struct sbix
+{
+  static const hb_tag_t tableTag = HB_OT_TAG_sbix;
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) && strikes.sanitize (c, this)));
+  }
+
+  struct accelerator_t
+  {
+    inline void init (hb_face_t *face)
+    {
+      num_glyphs = hb_face_get_glyph_count (face);
+
+      OT::Sanitizer<OT::sbix> sanitizer;
+      sanitizer.set_num_glyphs (num_glyphs);
+      sbix_blob = sanitizer.sanitize (face->reference_table (HB_OT_TAG_sbix));
+      sbix_len = hb_blob_get_length (sbix_blob);
+      sbix_table = sbix_blob->as<OT::sbix> ();
+
+    }
+
+    inline void fini (void)
+    {
+      hb_blob_destroy (sbix_blob);
+    }
+
+    inline void dump (void (*callback) (const uint8_t* data, unsigned int length,
+                                       unsigned int group, unsigned int gid)) const
+    {
+      for (unsigned group = 0; group < sbix_table->strikes.len; ++group)
+      {
+       const SBIXStrike &strike = sbix_table->strikes[group](sbix_table);
+       for (unsigned int glyph = 0; glyph < num_glyphs; ++glyph)
+         if (strike.imageOffsetsZ[glyph + 1] - strike.imageOffsetsZ[glyph] > 0)
+         {
+           const SBIXGlyph &sbixGlyph = strike.imageOffsetsZ[glyph]((const void *) &strike);
+           callback ((const uint8_t*) &sbixGlyph.data,
+                     strike.imageOffsetsZ[glyph + 1] - strike.imageOffsetsZ[glyph] - 8,
+                     group, glyph);
+         }
+      }
+    }
+
+    private:
+    hb_blob_t *sbix_blob;
+    const sbix *sbix_table;
+
+    unsigned int sbix_len;
+    unsigned int num_glyphs;
+
+  };
+
+  protected:
+  HBUINT16     version;        /* Table version number — set to 1 */
+  HBUINT16     flags;          /* Bit 0: Set to 1. Bit 1: Draw outlines.
+                                * Bits 2 to 15: reserved (set to 0). */
+  LArrayOf<LOffsetTo<SBIXStrike> >
+               strikes;        /* Offsets from the beginning of the 'sbix'
+                                * table to data for each individual bitmap strike. */
+  public:
+  DEFINE_SIZE_ARRAY (8, strikes);
+};
+
+} /* namespace OT */
+
+#endif /* HB_OT_COLOR_SBIX_TABLE_HH */
diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh
new file mode 100644 (file)
index 0000000..ed6cf97
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright © 2018  Ebrahim Byagowi
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef HB_OT_COLOR_SVG_TABLE_HH
+#define HB_OT_COLOR_SVG_TABLE_HH
+
+#include "hb-open-type-private.hh"
+
+/*
+ * SVG -- SVG (Scalable Vector Graphics)
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/svg
+ */
+
+#define HB_OT_TAG_SVG HB_TAG('S','V','G',' ')
+
+
+namespace OT {
+
+
+struct SVGDocumentIndexEntry
+{
+  friend struct SVG;
+
+  inline bool sanitize (hb_sanitize_context_t *c, const void* base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                 (base+svgDoc).sanitize (c, svgDocLength));
+  }
+
+  protected:
+  HBUINT16     startGlyphID;   /* The first glyph ID in the range described by
+                                * this index entry. */
+  HBUINT16     endGlyphID;     /* The last glyph ID in the range described by
+                                * this index entry. Must be >= startGlyphID. */
+  LOffsetTo<UnsizedArrayOf<HBUINT8> >
+               svgDoc;         /* Offset from the beginning of the SVG Document Index
+                                * to an SVG document. Must be non-zero. */
+  HBUINT32 svgDocLength;       /* Length of the SVG document.
+                                * Must be non-zero. */
+  public:
+  DEFINE_SIZE_STATIC (12);
+};
+
+struct SVGDocumentIndex
+{
+  friend struct SVG;
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                 entries.sanitize (c, this));
+  }
+
+  protected:
+  ArrayOf<SVGDocumentIndexEntry>
+               entries;        /* Array of SVG Document Index Entries. */
+  public:
+  DEFINE_SIZE_ARRAY (2, entries);
+};
+
+struct SVG
+{
+  static const hb_tag_t tableTag = HB_OT_TAG_SVG;
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) &&
+                         (this+svgDocIndex).sanitize (c)));
+  }
+
+  struct accelerator_t
+  {
+    inline void init (hb_face_t *face)
+    {
+      OT::Sanitizer<OT::SVG> sanitizer;
+      svg_blob = sanitizer.sanitize (face->reference_table (HB_OT_TAG_SVG));
+      svg_len = hb_blob_get_length (svg_blob);
+      svg = svg_blob->as<OT::SVG> ();
+
+    }
+
+    inline void fini (void)
+    {
+      hb_blob_destroy (svg_blob);
+    }
+
+    inline void
+    dump (void (*callback) (const uint8_t* data, unsigned int length,
+                           unsigned int start_glyph, unsigned int end_glyph)) const
+    {
+      const SVGDocumentIndex &index = svg+svg->svgDocIndex;
+      const ArrayOf<SVGDocumentIndexEntry> &entries = index.entries;
+      for (unsigned int i = 0; i < entries.len; ++i)
+      {
+       const SVGDocumentIndexEntry &entry = entries[i];
+       callback ((const uint8_t*) &entry.svgDoc (&index), entry.svgDocLength,
+                                                 entry.startGlyphID, entry.endGlyphID);
+      }
+    }
+
+    private:
+    hb_blob_t *svg_blob;
+    const SVG *svg;
+
+    unsigned int svg_len;
+  };
+
+  protected:
+  HBUINT16     version;        /* Table version (starting at 0). */
+  LOffsetTo<SVGDocumentIndex>
+               svgDocIndex;    /* Offset (relative to the start of the SVG table) to the
+                                * SVG Documents Index. Must be non-zero. */
+  HBUINT32     reserved;       /* Set to 0. */
+  public:
+  DEFINE_SIZE_STATIC (10);
+};
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_COLOR_SVG_TABLE_HH */
index ceebe0b..86171c6 100644 (file)
@@ -44,7 +44,7 @@ HB_MARK_AS_FLAG_T (hb_ot_color_palette_flags_t)
 static inline const OT::COLR&
 _get_colr (hb_face_t *face)
 {
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::COLR);
+  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::COLR);
   hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
   return *(layout->colr.get ());
 }
@@ -52,7 +52,7 @@ _get_colr (hb_face_t *face)
 static inline const OT::CPAL&
 _get_cpal (hb_face_t *face)
 {
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::CPAL);
+  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::CPAL);
   hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
   return *(layout->cpal.get ());
 }
index 0e373d3..8310230 100644 (file)
@@ -143,7 +143,7 @@ hb_ot_get_glyph_h_kerning (hb_font_t *font,
 }
 
 static hb_bool_t
-hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED,
+hb_ot_get_glyph_extents (hb_font_t *font,
                         void *font_data,
                         hb_codepoint_t glyph,
                         hb_glyph_extents_t *extents,
@@ -184,7 +184,7 @@ hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED,
 }
 
 static hb_bool_t
-hb_ot_get_font_h_extents (hb_font_t *font HB_UNUSED,
+hb_ot_get_font_h_extents (hb_font_t *font,
                          void *font_data,
                          hb_font_extents_t *metrics,
                          void *user_data HB_UNUSED)
@@ -198,7 +198,7 @@ hb_ot_get_font_h_extents (hb_font_t *font HB_UNUSED,
 }
 
 static hb_bool_t
-hb_ot_get_font_v_extents (hb_font_t *font HB_UNUSED,
+hb_ot_get_font_v_extents (hb_font_t *font,
                          void *font_data,
                          hb_font_extents_t *metrics,
                          void *user_data HB_UNUSED)
@@ -217,7 +217,12 @@ static hb_font_funcs_t *static_ot_funcs = nullptr;
 static
 void free_static_ot_funcs (void)
 {
-  hb_font_funcs_destroy (static_ot_funcs);
+retry:
+  hb_font_funcs_t *ot_funcs = (hb_font_funcs_t *) hb_atomic_ptr_get (&static_ot_funcs);
+  if (!hb_atomic_ptr_cmpexch (&static_ot_funcs, ot_funcs, nullptr))
+    goto retry;
+
+  hb_font_funcs_destroy (ot_funcs);
 }
 #endif
 
index d62f24b..89c867d 100644 (file)
@@ -38,8 +38,8 @@ namespace OT {
 
 /*
  * loca -- Index to Location
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/loca
  */
-
 #define HB_OT_TAG_loca HB_TAG('l','o','c','a')
 
 
@@ -56,15 +56,15 @@ struct loca
   }
 
   protected:
-  HBUINT8              dataX[VAR];             /* Location data. */
-  DEFINE_SIZE_ARRAY (0, dataX);
+  HBUINT8              dataZ[VAR];             /* Location data. */
+  DEFINE_SIZE_ARRAY (0, dataZ);
 };
 
 
 /*
  * glyf -- TrueType Glyph Data
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/glyf
  */
-
 #define HB_OT_TAG_glyf HB_TAG('g','l','y','f')
 
 
@@ -88,9 +88,9 @@ struct glyf
     bool success = true;
     bool use_short_loca = false;
     if (hb_subset_glyf_and_loca (plan, &use_short_loca, &glyf_prime, &loca_prime)) {
-      success = success && hb_subset_plan_add_table (plan, HB_OT_TAG_glyf, glyf_prime);
-      success = success && hb_subset_plan_add_table (plan, HB_OT_TAG_loca, loca_prime);
-      success = success && _add_head_and_set_loca_version (plan->source, use_short_loca, plan->dest);
+      success = success && plan->add_table (HB_OT_TAG_glyf, glyf_prime);
+      success = success && plan->add_table (HB_OT_TAG_loca, loca_prime);
+      success = success && _add_head_and_set_loca_version (plan, use_short_loca);
     } else {
       success = false;
     }
@@ -101,9 +101,9 @@ struct glyf
   }
 
   static bool
-  _add_head_and_set_loca_version (hb_face_t *source, bool use_short_loca, hb_face_t *dest)
+  _add_head_and_set_loca_version (hb_subset_plan_t *plan, bool use_short_loca)
   {
-    hb_blob_t *head_blob = OT::Sanitizer<OT::head>().sanitize (hb_face_reference_table (source, HB_OT_TAG_head));
+    hb_blob_t *head_blob = OT::Sanitizer<OT::head>().sanitize (hb_face_reference_table (plan->source, HB_OT_TAG_head));
     hb_blob_t *head_prime_blob = hb_blob_copy_writable_or_fail (head_blob);
     hb_blob_destroy (head_blob);
 
@@ -112,7 +112,7 @@ struct glyf
 
     OT::head *head_prime = (OT::head *) hb_blob_get_data_writable (head_prime_blob, nullptr);
     head_prime->indexToLocFormat.set (use_short_loca ? 0 : 1);
-    bool success = hb_subset_face_add_table (dest, HB_OT_TAG_head, head_prime_blob);
+    bool success = plan->add_table (HB_OT_TAG_head, head_prime_blob);
 
     hb_blob_destroy (head_prime_blob);
     return success;
@@ -134,18 +134,20 @@ struct glyf
 
   struct CompositeGlyphHeader
   {
-    static const uint16_t ARG_1_AND_2_ARE_WORDS =      0x0001;
-    static const uint16_t ARGS_ARE_XY_VALUES =         0x0002;
-    static const uint16_t ROUND_XY_TO_GRID =           0x0004;
-    static const uint16_t WE_HAVE_A_SCALE =            0x0008;
-    static const uint16_t MORE_COMPONENTS =            0x0020;
-    static const uint16_t WE_HAVE_AN_X_AND_Y_SCALE =   0x0040;
-    static const uint16_t WE_HAVE_A_TWO_BY_TWO =       0x0080;
-    static const uint16_t WE_HAVE_INSTRUCTIONS =       0x0100;
-    static const uint16_t USE_MY_METRICS =             0x0200;
-    static const uint16_t OVERLAP_COMPOUND =           0x0400;
-    static const uint16_t SCALED_COMPONENT_OFFSET =    0x0800;
-    static const uint16_t UNSCALED_COMPONENT_OFFSET =  0x1000;
+    enum composite_glyph_flag_t {
+      ARG_1_AND_2_ARE_WORDS =      0x0001,
+      ARGS_ARE_XY_VALUES =         0x0002,
+      ROUND_XY_TO_GRID =           0x0004,
+      WE_HAVE_A_SCALE =            0x0008,
+      MORE_COMPONENTS =            0x0020,
+      WE_HAVE_AN_X_AND_Y_SCALE =   0x0040,
+      WE_HAVE_A_TWO_BY_TWO =       0x0080,
+      WE_HAVE_INSTRUCTIONS =       0x0100,
+      USE_MY_METRICS =             0x0200,
+      OVERLAP_COMPOUND =           0x0400,
+      SCALED_COMPONENT_OFFSET =    0x0800,
+      UNSCALED_COMPONENT_OFFSET =  0x1000
+    };
 
     HBUINT16 flags;
     HBUINT16 glyphIndex;
@@ -232,11 +234,13 @@ struct glyf
   {
     inline void init (hb_face_t *face)
     {
+      memset (this, 0, sizeof (accelerator_t));
+
       hb_blob_t *head_blob = Sanitizer<head>().sanitize (face->reference_table (HB_OT_TAG_head));
-      const head *head_table = Sanitizer<head>::lock_instance (head_blob);
-      if ((unsigned int) head_table->indexToLocFormat > 1 || head_table->glyphDataFormat != 0)
+      const head *head_table = head_blob->as<head> ();
+      if (head_table == &Null(head) || (unsigned int) head_table->indexToLocFormat > 1 || head_table->glyphDataFormat != 0)
       {
-       /* Unknown format.  Leave num_glyphs=0, that takes care of disabling us. */
+       /* head table is not present, or in an unknown format.  Leave num_glyphs=0, that takes care of disabling us. */
        hb_blob_destroy (head_blob);
        return;
       }
@@ -244,9 +248,9 @@ struct glyf
       hb_blob_destroy (head_blob);
 
       loca_blob = Sanitizer<loca>().sanitize (face->reference_table (HB_OT_TAG_loca));
-      loca_table = Sanitizer<loca>::lock_instance (loca_blob);
+      loca_table = loca_blob->as<loca> ();
       glyf_blob = Sanitizer<glyf>().sanitize (face->reference_table (HB_OT_TAG_glyf));
-      glyf_table = Sanitizer<glyf>::lock_instance (glyf_blob);
+      glyf_table = glyf_blob->as<glyf> ();
 
       num_glyphs = MAX (1u, hb_blob_get_length (loca_blob) / (short_offset ? 2 : 4)) - 1;
       glyf_len = hb_blob_get_length (glyf_blob);
@@ -266,6 +270,9 @@ struct glyf
     inline bool get_composite (hb_codepoint_t glyph,
                               CompositeGlyphHeader::Iterator *composite /* OUT */) const
     {
+      if (this->glyf_table == &Null(glyf) || !num_glyphs)
+       return false;
+
       unsigned int start_offset, end_offset;
       if (!get_offsets (glyph, &start_offset, &end_offset))
         return false; /* glyph not found */
@@ -275,16 +282,18 @@ struct glyf
                                                 composite);
     }
 
+    enum simple_glyph_flag_t {
+      FLAG_X_SHORT = 0x02,
+      FLAG_Y_SHORT = 0x04,
+      FLAG_REPEAT = 0x08,
+      FLAG_X_SAME = 0x10,
+      FLAG_Y_SAME = 0x20
+    };
+
     /* based on FontTools _g_l_y_f.py::trim */
     inline bool remove_padding(unsigned int start_offset,
                                unsigned int *end_offset) const
     {
-      static const int FLAG_X_SHORT = 0x02;
-      static const int FLAG_Y_SHORT = 0x04;
-      static const int FLAG_REPEAT = 0x08;
-      static const int FLAG_X_SAME = 0x10;
-      static const int FLAG_Y_SAME = 0x20;
-
       if (*end_offset - start_offset < GlyphHeader::static_size)
         return true;
 
@@ -368,13 +377,13 @@ struct glyf
 
       if (short_offset)
       {
-        const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataX;
+        const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataZ;
        *start_offset = 2 * offsets[glyph];
        *end_offset   = 2 * offsets[glyph + 1];
       }
       else
       {
-        const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataX;
+        const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataZ;
 
        *start_offset = offsets[glyph];
        *end_offset   = offsets[glyph + 1];
@@ -411,7 +420,7 @@ struct glyf
         } while (composite_it.move_to_next());
 
         if ( (uint16_t) last->flags & CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS)
-          *instruction_start = ((char *) last - (char *) glyf_table->dataX) + last->get_size();
+          *instruction_start = ((char *) last - (char *) glyf_table->dataZ) + last->get_size();
         else
           *instruction_start = end_offset;
         *instruction_end = end_offset;
@@ -424,9 +433,23 @@ struct glyf
       else
       {
         unsigned int instruction_length_offset = start_offset + GlyphHeader::static_size + 2 * num_contours;
+       if (unlikely (instruction_length_offset + 2 > end_offset))
+       {
+         DEBUG_MSG(SUBSET, nullptr, "Glyph size is too short, missing field instructionLength.");
+         return false;
+       }
+
         const HBUINT16 &instruction_length = StructAtOffset<HBUINT16> (glyf_table, instruction_length_offset);
-        *instruction_start = instruction_length_offset + 2;
-        *instruction_end = *instruction_start + (uint16_t) instruction_length;
+       unsigned int start = instruction_length_offset + 2;
+       unsigned int end = start + (uint16_t) instruction_length;
+       if (unlikely (end > end_offset)) // Out of bounds of the current glyph
+       {
+         DEBUG_MSG(SUBSET, nullptr, "The instructions array overruns the glyph's boundaries.");
+         return false;
+       }
+
+       *instruction_start = start;
+        *instruction_end = end;
       }
       return true;
     }
@@ -462,9 +485,9 @@ struct glyf
   };
 
   protected:
-  HBUINT8              dataX[VAR];             /* Glyphs data. */
+  HBUINT8              dataZ[VAR];             /* Glyphs data. */
 
-  DEFINE_SIZE_ARRAY (0, dataX);
+  DEFINE_SIZE_ARRAY (0, dataZ);
 };
 
 } /* namespace OT */
index f08fe39..d406e3e 100644 (file)
 #define HB_OT_HDMX_TABLE_HH
 
 #include "hb-open-type-private.hh"
-
-namespace OT {
-
+#include "hb-subset-plan.hh"
 
 /*
- * hdmx - Horizontal Device Metric
+ * hdmx -- Horizontal Device Metrics
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/hdmx
  */
-
 #define HB_OT_TAG_hdmx HB_TAG('h','d','m','x')
 
+
+namespace OT {
+
+
 struct DeviceRecord
 {
   struct SubsetView
   {
     const DeviceRecord *source_device_record;
+    unsigned int size_device_record;
     hb_subset_plan_t *subset_plan;
 
     inline void init(const DeviceRecord *source_device_record,
+                    unsigned int size_device_record,
                     hb_subset_plan_t   *subset_plan)
     {
       this->source_device_record = source_device_record;
+      this->size_device_record = size_device_record;
       this->subset_plan = subset_plan;
     }
 
     inline unsigned int len () const
     {
-      return this->subset_plan->gids_to_retain_sorted.len;
+      return this->subset_plan->glyphs.len;
     }
 
-    inline const HBUINT8& operator [] (unsigned int i) const
+    inline const HBUINT8* operator [] (unsigned int i) const
     {
-      if (unlikely (i >= len())) return Null(HBUINT8);
-      hb_codepoint_t gid = this->subset_plan->gids_to_retain_sorted [i];
-      return this->source_device_record->widths[gid];
+      if (unlikely (i >= len())) return nullptr;
+      hb_codepoint_t gid = this->subset_plan->glyphs [i];
+
+      const HBUINT8* width = &(this->source_device_record->widths[gid]);
+
+      if (width < ((const HBUINT8 *) this->source_device_record) + size_device_record)
+       return width;
+      else
+       return nullptr;
     }
   };
 
@@ -85,7 +96,15 @@ struct DeviceRecord
     this->max_width.set (subset_view.source_device_record->max_width);
 
     for (unsigned int i = 0; i < subset_view.len(); i++)
-      widths[i].set (subset_view[i]);
+    {
+      const HBUINT8 *width = subset_view[i];
+      if (!width)
+      {
+       DEBUG_MSG(SUBSET, nullptr, "HDMX width for new gid %d is missing.", i);
+       return_trace (false);
+      }
+      widths[i].set (*width);
+    }
 
     return_trace (true);
   }
@@ -117,7 +136,7 @@ struct hdmx
   inline const DeviceRecord& operator [] (unsigned int i) const
   {
     if (unlikely (i >= num_records)) return Null(DeviceRecord);
-    return StructAtOffset<DeviceRecord> (this, min_size + i * size_device_record);
+    return StructAtOffset<DeviceRecord> (this->data, i * size_device_record);
   }
 
   inline bool serialize (hb_serialize_context_t *c, const hdmx *source_hdmx, hb_subset_plan_t *plan)
@@ -128,14 +147,15 @@ struct hdmx
 
     this->version.set (source_hdmx->version);
     this->num_records.set (source_hdmx->num_records);
-    this->size_device_record.set (DeviceRecord::get_size (plan->gids_to_retain_sorted.len));
+    this->size_device_record.set (DeviceRecord::get_size (plan->glyphs.len));
 
     for (unsigned int i = 0; i < source_hdmx->num_records; i++)
     {
       DeviceRecord::SubsetView subset_view;
-      subset_view.init (&(*source_hdmx)[i], plan);
+      subset_view.init (&(*source_hdmx)[i], source_hdmx->size_device_record, plan);
 
-      c->start_embed<DeviceRecord> ()->serialize (c, subset_view);
+      if (!c->start_embed<DeviceRecord> ()->serialize (c, subset_view))
+       return_trace (false);
     }
 
     return_trace (true);
@@ -143,7 +163,7 @@ struct hdmx
 
   static inline size_t get_subsetted_size (hb_subset_plan_t *plan)
   {
-    return min_size + DeviceRecord::get_size (plan->gids_to_retain_sorted.len);
+    return min_size + DeviceRecord::get_size (plan->glyphs.len);
   }
 
   inline bool subset (hb_subset_plan_t *plan) const
@@ -169,7 +189,7 @@ struct hdmx
                                                 HB_MEMORY_MODE_READONLY,
                                                 dest,
                                                 free);
-    bool result = hb_subset_plan_add_table (plan, HB_OT_TAG_hdmx, hdmx_prime_blob);
+    bool result = plan->add_table (HB_OT_TAG_hdmx, hdmx_prime_blob);
     hb_blob_destroy (hdmx_prime_blob);
 
     return result;
@@ -180,6 +200,7 @@ struct hdmx
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) && version == 0 &&
                  !_hb_unsigned_int_mul_overflows (num_records, size_device_record) &&
+                 size_device_record >= DeviceRecord::min_size &&
                  c->check_range (this, get_size()));
   }
 
index 1d45840..965e30a 100644 (file)
 
 #include "hb-open-type-private.hh"
 
-
-namespace OT {
-
-
 /*
  * head -- Font Header
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/head
  */
-
 #define HB_OT_TAG_head HB_TAG('h','e','a','d')
 
+
+namespace OT {
+
+
 struct head
 {
   friend struct OffsetTable;
index 97952b4..efb42b6 100644 (file)
 
 #include "hb-open-type-private.hh"
 
-
-namespace OT {
-
-
 /*
- * hhea -- The Horizontal Header Table
- * vhea -- The Vertical Header Table
+ * hhea -- Horizontal Header
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/hhea
+ * vhea -- Vertical Header
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/vhea
  */
-
 #define HB_OT_TAG_hhea HB_TAG('h','h','e','a')
 #define HB_OT_TAG_vhea HB_TAG('v','h','e','a')
 
+
+namespace OT {
+
+
 template <typename T>
 struct _hea
 {
index 3cd48a6..2c62664 100644 (file)
 #include "hb-ot-hhea-table.hh"
 #include "hb-ot-os2-table.hh"
 #include "hb-ot-var-hvar-table.hh"
-
-
-namespace OT {
-
+#include "hb-subset-plan.hh"
 
 /*
- * hmtx -- The Horizontal Metrics Table
- * vmtx -- The Vertical Metrics Table
+ * hmtx -- Horizontal Metrics
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/hmtx
+ * vmtx -- Vertical Metrics
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/vmtx
  */
-
 #define HB_OT_TAG_hmtx HB_TAG('h','m','t','x')
 #define HB_OT_TAG_vmtx HB_TAG('v','m','t','x')
 
 
+namespace OT {
+
+
 struct LongMetric
 {
   UFWORD       advance; /* Advance width/height. */
@@ -80,7 +81,7 @@ struct hmtxvmtx
     H *table = (H *) hb_blob_get_data (dest_blob, &length);
     table->numberOfLongMetrics.set (num_hmetrics);
 
-    bool result = hb_subset_plan_add_table (plan, H::tableTag, dest_blob);
+    bool result = plan->add_table (H::tableTag, dest_blob);
     hb_blob_destroy (dest_blob);
 
     return result;
@@ -93,7 +94,7 @@ struct hmtxvmtx
 
     /* All the trailing glyphs with the same advance can use one LongMetric
      * and just keep LSB */
-    hb_prealloced_array_t<hb_codepoint_t> &gids = plan->gids_to_retain_sorted;
+    hb_vector_t<hb_codepoint_t> &gids = plan->glyphs;
     unsigned int num_advances = gids.len;
     unsigned int last_advance = _mtx.get_advance (gids[num_advances - 1]);
     while (num_advances > 1
@@ -118,6 +119,8 @@ struct hmtxvmtx
     LongMetric * old_metrics = (LongMetric *) source_table;
     FWORD *lsbs = (FWORD *) (old_metrics + _mtx.num_advances);
     char * dest_pos = (char *) dest;
+
+    bool failed = false;
     for (unsigned int i = 0; i < gids.len; i++)
     {
       /* the last metric or the one for gids[i] */
@@ -138,7 +141,14 @@ struct hmtxvmtx
       }
       else
       {
-        FWORD src_lsb = *(lsbs + gids[i] - _mtx.num_advances);
+       if (gids[i] >= _mtx.num_metrics)
+       {
+         DEBUG_MSG(SUBSET, nullptr, "gid %d is >= number of source metrics %d",
+                   gids[i], _mtx.num_metrics);
+         failed = true;
+         break;
+       }
+       FWORD src_lsb = *(lsbs + gids[i] - _mtx.num_advances);
         if (i < num_advances)
         {
           /* dest needs a full LongMetric */
@@ -157,7 +167,7 @@ struct hmtxvmtx
     _mtx.fini ();
 
     // Amend header num hmetrics
-    if (unlikely (!subset_update_header (plan, num_advances)))
+    if (failed || unlikely (!subset_update_header (plan, num_advances)))
     {
       free (dest);
       return false;
@@ -168,7 +178,7 @@ struct hmtxvmtx
                                         HB_MEMORY_MODE_READONLY,
                                         dest,
                                         free);
-    bool success = hb_subset_plan_add_table (plan, T::tableTag, result);
+    bool success = plan->add_table (T::tableTag, result);
     hb_blob_destroy (result);
     return success;
   }
@@ -186,7 +196,7 @@ struct hmtxvmtx
       if (T::os2Tag)
       {
        hb_blob_t *os2_blob = Sanitizer<os2> ().sanitize (face->reference_table (T::os2Tag));
-       const os2 *os2_table = Sanitizer<os2>::lock_instance (os2_blob);
+       const os2 *os2_table = os2_blob->as<os2> ();
 #define USE_TYPO_METRICS (1u<<7)
        if (0 != (os2_table->fsSelection & USE_TYPO_METRICS))
        {
@@ -199,7 +209,7 @@ struct hmtxvmtx
       }
 
       hb_blob_t *_hea_blob = Sanitizer<H> ().sanitize (face->reference_table (H::tableTag));
-      const H *_hea_table = Sanitizer<H>::lock_instance (_hea_blob);
+      const H *_hea_table = _hea_blob->as<H> ();
       num_advances = _hea_table->numberOfLongMetrics;
       if (!got_font_extents)
       {
@@ -228,10 +238,10 @@ struct hmtxvmtx
        hb_blob_destroy (blob);
        blob = hb_blob_get_empty ();
       }
-      table = Sanitizer<hmtxvmtx>::lock_instance (blob);
+      table = blob->as<hmtxvmtx> ();
 
       var_blob = Sanitizer<HVARVVAR> ().sanitize (face->reference_table (T::variationsTag));
-      var_table = Sanitizer<HVARVVAR>::lock_instance (var_blob);
+      var_table = var_blob->as<HVARVVAR> ();
     }
 
     inline void fini (void)
@@ -264,7 +274,7 @@ struct hmtxvmtx
       {
         advance += (font->num_coords ? var_table->get_advance_var (glyph, font->coords, font->num_coords) : 0); // TODO Optimize?!
       }
-      return advance;          
+      return advance;
     }
 
     public:
index 368f547..b0fdea4 100644 (file)
 
 #include "hb-open-type-private.hh"
 
-namespace OT {
-
-
 /*
  * kern -- Kerning
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/kern
+ * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6kern.html
  */
-
 #define HB_OT_TAG_kern HB_TAG('k','e','r','n')
 
+
+namespace OT {
+
+
 struct hb_glyph_pair_t
 {
   hb_codepoint_t left;
@@ -205,7 +207,7 @@ struct KernSubTableWrapper
   {
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (thiz()) &&
-                 thiz()->length >= thiz()->min_size &&
+                 thiz()->length >= T::min_size &&
                  c->check_array (thiz(), 1, thiz()->length) &&
                  thiz()->subtable.sanitize (c, thiz()->format));
   }
@@ -361,8 +363,8 @@ struct kern
     inline void init (hb_face_t *face)
     {
       blob = Sanitizer<kern>().sanitize (face->reference_table (HB_OT_TAG_kern));
-      table = Sanitizer<kern>::lock_instance (blob);
-      table_length = hb_blob_get_length (blob);
+      table = blob->as<kern> ();
+      table_length = blob->length;
     }
     inline void fini (void)
     {
index 20b8bd7..33dce89 100644 (file)
@@ -36,7 +36,8 @@ namespace OT {
 #define NOT_INDEXED   ((unsigned int) -1)
 
 /*
- * BASE -- The BASE Table
+ * BASE -- Baseline
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/base
  */
 
 struct BaseCoordFormat1
index c5e7f52..763ea92 100644 (file)
@@ -165,7 +165,7 @@ struct RangeRecord
   public:
   DEFINE_SIZE_STATIC (6);
 };
-DEFINE_NULL_DATA (RangeRecord, "\000\001");
+DEFINE_NULL_DATA (OT, RangeRecord, "\000\001");
 
 
 struct IndexArray : ArrayOf<Index>
@@ -225,7 +225,7 @@ struct LangSys
   public:
   DEFINE_SIZE_ARRAY (6, featureIndex);
 };
-DEFINE_NULL_DATA (LangSys, "\0\0\xFF\xFF");
+DEFINE_NULL_DATA (OT, LangSys, "\0\0\xFF\xFF");
 
 
 struct Script
@@ -270,7 +270,7 @@ struct Script
 typedef RecordListOf<Script> ScriptList;
 
 
-/* http://www.microsoft.com/typography/otspec/features_pt.htm#size */
+/* https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#size */
 struct FeatureParamsSize
 {
   inline bool sanitize (hb_sanitize_context_t *c) const
@@ -292,7 +292,7 @@ struct FeatureParamsSize
      *
      * The specification for this feature tag is in the "OpenType Layout Tag
      * Registry". You can see a copy of this at:
-     * http://partners.adobe.com/public/developer/opentype/index_tag8.html#size
+     * https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#tag-size
      *
      * Here is one set of rules to determine if the 'size' feature is built
      * correctly, or as by the older versions of MakeOTF. You may be able to do
@@ -382,7 +382,7 @@ struct FeatureParamsSize
   DEFINE_SIZE_STATIC (10);
 };
 
-/* http://www.microsoft.com/typography/otspec/features_pt.htm#ssxx */
+/* https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#ssxx */
 struct FeatureParamsStylisticSet
 {
   inline bool sanitize (hb_sanitize_context_t *c) const
@@ -398,7 +398,7 @@ struct FeatureParamsStylisticSet
                                 * added to the end of this Feature Parameters
                                 * table in the future. */
 
-  HBUINT16     uiNameID;       /* The 'name' table name ID that specifies a
+  NameID       uiNameID;       /* The 'name' table name ID that specifies a
                                 * string (or strings, for multiple languages)
                                 * for a user-interface label for this
                                 * feature.  The values of uiLabelNameId and
@@ -416,7 +416,7 @@ struct FeatureParamsStylisticSet
   DEFINE_SIZE_STATIC (4);
 };
 
-/* http://www.microsoft.com/typography/otspec/features_ae.htm#cv01-cv99 */
+/* https://docs.microsoft.com/en-us/typography/opentype/spec/features_ae#cv01-cv99 */
 struct FeatureParamsCharacterVariants
 {
   inline bool sanitize (hb_sanitize_context_t *c) const
@@ -427,29 +427,29 @@ struct FeatureParamsCharacterVariants
   }
 
   HBUINT16     format;                 /* Format number is set to 0. */
-  HBUINT16     featUILableNameID;      /* The ‘name’ table name ID that
+  NameID       featUILableNameID;      /* The ‘name’ table name ID that
                                         * specifies a string (or strings,
                                         * for multiple languages) for a
                                         * user-interface label for this
                                         * feature. (May be nullptr.) */
-  HBUINT16     featUITooltipTextNameID;/* The ‘name’ table name ID that
+  NameID       featUITooltipTextNameID;/* The ‘name’ table name ID that
                                         * specifies a string (or strings,
                                         * for multiple languages) that an
                                         * application can use for tooltip
                                         * text for this feature. (May be
                                         * nullptr.) */
-  HBUINT16     sampleTextNameID;       /* The ‘name’ table name ID that
+  NameID       sampleTextNameID;       /* The ‘name’ table name ID that
                                         * specifies sample text that
                                         * illustrates the effect of this
                                         * feature. (May be nullptr.) */
   HBUINT16     numNamedParameters;     /* Number of named parameters. (May
                                         * be zero.) */
-  HBUINT16     firstParamUILabelNameID;/* The first ‘name’ table name ID
+  NameID       firstParamUILabelNameID;/* The first ‘name’ table name ID
                                         * used to specify strings for
                                         * user-interface labels for the
                                         * feature parameters. (Must be zero
                                         * if numParameters is zero.) */
-  ArrayOf<UINT24>
+  ArrayOf<HBUINT24>
                characters;             /* Array of the Unicode Scalar Value
                                         * of the characters for which this
                                         * feature provides glyph variants.
@@ -716,7 +716,7 @@ struct CoverageFormat1
 
   template <typename set_t>
   inline bool add_coverage (set_t *glyphs) const {
-    return glyphs->add_sorted_array (glyphArray.array, glyphArray.len);
+    return glyphs->add_sorted_array (glyphArray.arrayZ, glyphArray.len);
   }
 
   public:
@@ -1272,7 +1272,7 @@ struct VarRegionList
     if (unlikely (region_index >= regionCount))
       return 0.;
 
-    const VarRegionAxis *axes = axesZ + (region_index * axisCount);
+    const VarRegionAxis *axes = axesZ.arrayZ + (region_index * axisCount);
 
     float v = 1.;
     unsigned int count = axisCount;
@@ -1280,7 +1280,7 @@ struct VarRegionList
     {
       int coord = i < coord_len ? coords[i] : 0;
       float factor = axes[i].evaluate (coord);
-      if (factor == 0.)
+      if (factor == 0.f)
         return 0.;
       v *= factor;
     }
@@ -1291,14 +1291,14 @@ struct VarRegionList
   {
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) &&
-                 c->check_array (axesZ, axesZ[0].static_size,
-                                 (unsigned int) axisCount * (unsigned int) regionCount));
+                 axesZ.sanitize (c, (unsigned int) axisCount * (unsigned int) regionCount));
   }
 
   protected:
   HBUINT16     axisCount;
   HBUINT16     regionCount;
-  VarRegionAxis        axesZ[VAR];
+  UnsizedArrayOf<VarRegionAxis>
+               axesZ;
   public:
   DEFINE_SIZE_ARRAY (4, axesZ);
 };
@@ -1330,13 +1330,13 @@ struct VarData
    const HBINT16 *scursor = reinterpret_cast<const HBINT16 *> (row);
    for (; i < scount; i++)
    {
-     float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count);
+     float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count);
      delta += scalar * *scursor++;
    }
    const HBINT8 *bcursor = reinterpret_cast<const HBINT8 *> (scursor);
    for (; i < count; i++)
    {
-     float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count);
+     float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count);
      delta += scalar * *bcursor++;
    }
 
@@ -1357,7 +1357,7 @@ struct VarData
   HBUINT16             itemCount;
   HBUINT16             shortCount;
   ArrayOf<HBUINT16>    regionIndices;
-  HBUINT8                      bytesX[VAR];
+  HBUINT8              bytesX[VAR];
   public:
   DEFINE_SIZE_ARRAY2 (6, regionIndices, bytesX);
 };
@@ -1465,7 +1465,7 @@ struct ConditionSet
   {
     unsigned int count = conditions.len;
     for (unsigned int i = 0; i < count; i++)
-      if (!(this+conditions.array[i]).evaluate (coords, coord_len))
+      if (!(this+conditions.arrayZ[i]).evaluate (coords, coord_len))
         return false;
     return true;
   }
@@ -1506,7 +1506,7 @@ struct FeatureTableSubstitution
     unsigned int count = substitutions.len;
     for (unsigned int i = 0; i < count; i++)
     {
-      const FeatureTableSubstitutionRecord &record = substitutions.array[i];
+      const FeatureTableSubstitutionRecord &record = substitutions.arrayZ[i];
       if (record.featureIndex == feature_index)
        return &(this+record.feature);
     }
@@ -1559,7 +1559,7 @@ struct FeatureVariations
     unsigned int count = varRecords.len;
     for (unsigned int i = 0; i < count; i++)
     {
-      const FeatureVariationRecord &record = varRecords.array[i];
+      const FeatureVariationRecord &record = varRecords.arrayZ[i];
       if ((this+record.conditions).evaluate (coords, coord_len))
       {
        *index = i;
index 2d6c66e..60a8d3a 100644 (file)
@@ -333,7 +333,8 @@ struct MarkGlyphSets
 
 
 /*
- * GDEF -- The Glyph Definition Table
+ * GDEF -- Glyph Definition
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/gdef
  */
 
 struct GDEF
index 46ffcc6..bc8a5fd 100644 (file)
@@ -262,7 +262,7 @@ struct AnchorFormat2
     hb_font_t *font = c->font;
     unsigned int x_ppem = font->x_ppem;
     unsigned int y_ppem = font->y_ppem;
-    hb_position_t cx, cy;
+    hb_position_t cx = 0, cy = 0;
     hb_bool_t ret;
 
     ret = (x_ppem || y_ppem) &&
@@ -1497,7 +1497,8 @@ struct PosLookup : Lookup
 typedef OffsetListOf<PosLookup> PosLookupList;
 
 /*
- * GPOS -- The Glyph Positioning Table
+ * GPOS -- Glyph Positioning
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/gpos
  */
 
 struct GPOS : GSUBGPOS
index 5f67aed..bd72fe6 100644 (file)
@@ -269,7 +269,7 @@ struct Sequence
   inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     TRACE_COLLECT_GLYPHS (this);
-    c->output->add_array (substitute.array, substitute.len);
+    c->output->add_array (substitute.arrayZ, substitute.len);
   }
 
   inline bool apply (hb_ot_apply_context_t *c) const
@@ -281,7 +281,7 @@ struct Sequence
      * as a "multiplied" substitution. */
     if (unlikely (count == 1))
     {
-      c->replace_glyph (substitute.array[0]);
+      c->replace_glyph (substitute.arrayZ[0]);
       return_trace (true);
     }
     /* Spec disallows this, but Uniscribe allows it.
@@ -297,7 +297,7 @@ struct Sequence
 
     for (unsigned int i = 0; i < count; i++) {
       _hb_glyph_info_set_lig_props_for_component (&c->buffer->cur(), i);
-      c->output_glyph_for_component (substitute.array[i], klass);
+      c->output_glyph_for_component (substitute.arrayZ[i], klass);
     }
     c->buffer->skip_glyph ();
 
@@ -480,7 +480,7 @@ struct AlternateSubstFormat1
       if (unlikely (iter.get_coverage () >= count))
         break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
       const AlternateSet &alt_set = this+alternateSet[iter.get_coverage ()];
-      c->output->add_array (alt_set.array, alt_set.len);
+      c->output->add_array (alt_set.arrayZ, alt_set.len);
     }
   }
 
@@ -611,7 +611,7 @@ struct Ligature
   inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     TRACE_COLLECT_GLYPHS (this);
-    c->input->add_array (component.array, component.len ? component.len - 1 : 0);
+    c->input->add_array (component.arrayZ, component.len ? component.len - 1 : 0);
     c->output->add (ligGlyph);
   }
 
@@ -979,7 +979,7 @@ struct ReverseChainSingleSubstFormat1
 
     const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
     count = substitute.len;
-    c->output->add_array (substitute.array, substitute.len);
+    c->output->add_array (substitute.arrayZ, substitute.len);
   }
 
   inline const Coverage &get_coverage (void) const
@@ -1007,11 +1007,11 @@ struct ReverseChainSingleSubstFormat1
 
   unsigned int start_index = 0, end_index = 0;
     if (match_backtrack (c,
-                        backtrack.len, (HBUINT16 *) backtrack.array,
+                        backtrack.len, (HBUINT16 *) backtrack.arrayZ,
                         match_coverage, this,
                         &start_index) &&
         match_lookahead (c,
-                        lookahead.len, (HBUINT16 *) lookahead.array,
+                        lookahead.len, (HBUINT16 *) lookahead.arrayZ,
                         match_coverage, this,
                         1, &end_index))
     {
@@ -1156,10 +1156,13 @@ struct SubstLookup : Lookup
     return_trace (dispatch (c));
   }
 
-  inline hb_closure_context_t::return_t closure (hb_closure_context_t *c) const
+  inline hb_closure_context_t::return_t closure (hb_closure_context_t *c, unsigned int this_index) const
   {
     TRACE_CLOSURE (this);
-    c->set_recurse_func (dispatch_recurse_func<hb_closure_context_t>);
+    if (!c->should_visit_lookup (this_index))
+      return_trace (HB_VOID);
+
+    c->set_recurse_func (dispatch_closure_recurse_func);
     return_trace (dispatch (c));
   }
 
@@ -1258,6 +1261,13 @@ struct SubstLookup : Lookup
   template <typename context_t>
   static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
 
+  static inline hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned int lookup_index)
+  {
+    if (!c->should_visit_lookup (lookup_index))
+      return HB_VOID;
+    return dispatch_recurse_func (c, lookup_index);
+  }
+
   template <typename context_t>
   inline typename context_t::return_t dispatch (context_t *c) const
   { return Lookup::dispatch<SubstLookupSubTable> (c); }
@@ -1287,7 +1297,8 @@ struct SubstLookup : Lookup
 typedef OffsetListOf<SubstLookup> SubstLookupList;
 
 /*
- * GSUB -- The Glyph Substitution Table
+ * GSUB -- Glyph Substitution
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/gsub
  */
 
 struct GSUB : GSUBGPOS
index 9054634..661085d 100644 (file)
@@ -32,6 +32,7 @@
 #include "hb-private.hh"
 #include "hb-debug.hh"
 #include "hb-buffer-private.hh"
+#include "hb-map-private.hh"
 #include "hb-ot-layout-gdef-table.hh"
 #include "hb-set-private.hh"
 
@@ -59,6 +60,20 @@ struct hb_closure_context_t :
     return HB_VOID;
   }
 
+  bool should_visit_lookup (unsigned int lookup_index)
+  {
+    if (is_lookup_done (lookup_index))
+      return false;
+    done_lookups->set (lookup_index, glyphs->get_population ());
+    return true;
+  }
+
+  bool is_lookup_done (unsigned int lookup_index)
+  {
+    // Have we visited this lookup with the current set of glyphs?
+    return done_lookups->get (lookup_index) == glyphs->get_population ();
+  }
+
   hb_face_t *face;
   hb_set_t *glyphs;
   recurse_func_t recurse_func;
@@ -67,14 +82,19 @@ struct hb_closure_context_t :
 
   hb_closure_context_t (hb_face_t *face_,
                        hb_set_t *glyphs_,
+                        hb_map_t *done_lookups_,
                        unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) :
                          face (face_),
                          glyphs (glyphs_),
                          recurse_func (nullptr),
                          nesting_level_left (nesting_level_left_),
-                         debug_depth (0) {}
+                         debug_depth (0),
+                          done_lookups (done_lookups_) {}
 
   void set_recurse_func (recurse_func_t func) { recurse_func = func; }
+
+  private:
+  hb_map_t *done_lookups;
 };
 
 
@@ -855,7 +875,7 @@ static inline bool ligate_input (hb_ot_apply_context_t *c,
 
   for (unsigned int i = 1; i < count; i++)
   {
-    while (buffer->idx < match_positions[i] && !buffer->in_error)
+    while (buffer->idx < match_positions[i] && buffer->successful)
     {
       if (!is_mark_ligature) {
         unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
@@ -990,7 +1010,7 @@ static inline bool apply_lookup (hb_ot_apply_context_t *c,
       match_positions[j] += delta;
   }
 
-  for (unsigned int i = 0; i < lookupCount && !buffer->in_error; i++)
+  for (unsigned int i = 0; i < lookupCount && buffer->successful; i++)
   {
     unsigned int idx = lookupRecord[i].sequenceIndex;
     if (idx >= count)
@@ -1713,10 +1733,10 @@ struct ChainRule
     const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
     const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
     chain_context_closure_lookup (c,
-                                 backtrack.len, backtrack.array,
-                                 input.len, input.array,
-                                 lookahead.len, lookahead.array,
-                                 lookup.len, lookup.array,
+                                 backtrack.len, backtrack.arrayZ,
+                                 input.len, input.arrayZ,
+                                 lookahead.len, lookahead.arrayZ,
+                                 lookup.len, lookup.arrayZ,
                                  lookup_context);
   }
 
@@ -1727,10 +1747,10 @@ struct ChainRule
     const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
     const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
     chain_context_collect_glyphs_lookup (c,
-                                        backtrack.len, backtrack.array,
-                                        input.len, input.array,
-                                        lookahead.len, lookahead.array,
-                                        lookup.len, lookup.array,
+                                        backtrack.len, backtrack.arrayZ,
+                                        input.len, input.arrayZ,
+                                        lookahead.len, lookahead.arrayZ,
+                                        lookup.len, lookup.arrayZ,
                                         lookup_context);
   }
 
@@ -1741,10 +1761,10 @@ struct ChainRule
     const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
     const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
     return_trace (chain_context_would_apply_lookup (c,
-                                                   backtrack.len, backtrack.array,
-                                                   input.len, input.array,
-                                                   lookahead.len, lookahead.array, lookup.len,
-                                                   lookup.array, lookup_context));
+                                                   backtrack.len, backtrack.arrayZ,
+                                                   input.len, input.arrayZ,
+                                                   lookahead.len, lookahead.arrayZ, lookup.len,
+                                                   lookup.arrayZ, lookup_context));
   }
 
   inline bool apply (hb_ot_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
@@ -1754,10 +1774,10 @@ struct ChainRule
     const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
     const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
     return_trace (chain_context_apply_lookup (c,
-                                             backtrack.len, backtrack.array,
-                                             input.len, input.array,
-                                             lookahead.len, lookahead.array, lookup.len,
-                                             lookup.array, lookup_context));
+                                             backtrack.len, backtrack.arrayZ,
+                                             input.len, input.arrayZ,
+                                             lookahead.len, lookahead.arrayZ, lookup.len,
+                                             lookup.arrayZ, lookup_context));
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
@@ -2072,10 +2092,10 @@ struct ChainContextFormat3
       {this, this, this}
     };
     chain_context_closure_lookup (c,
-                                 backtrack.len, (const HBUINT16 *) backtrack.array,
-                                 input.len, (const HBUINT16 *) input.array + 1,
-                                 lookahead.len, (const HBUINT16 *) lookahead.array,
-                                 lookup.len, lookup.array,
+                                 backtrack.len, (const HBUINT16 *) backtrack.arrayZ,
+                                 input.len, (const HBUINT16 *) input.arrayZ + 1,
+                                 lookahead.len, (const HBUINT16 *) lookahead.arrayZ,
+                                 lookup.len, lookup.arrayZ,
                                  lookup_context);
   }
 
@@ -2093,10 +2113,10 @@ struct ChainContextFormat3
       {this, this, this}
     };
     chain_context_collect_glyphs_lookup (c,
-                                        backtrack.len, (const HBUINT16 *) backtrack.array,
-                                        input.len, (const HBUINT16 *) input.array + 1,
-                                        lookahead.len, (const HBUINT16 *) lookahead.array,
-                                        lookup.len, lookup.array,
+                                        backtrack.len, (const HBUINT16 *) backtrack.arrayZ,
+                                        input.len, (const HBUINT16 *) input.arrayZ + 1,
+                                        lookahead.len, (const HBUINT16 *) lookahead.arrayZ,
+                                        lookup.len, lookup.arrayZ,
                                         lookup_context);
   }
 
@@ -2112,10 +2132,10 @@ struct ChainContextFormat3
       {this, this, this}
     };
     return_trace (chain_context_would_apply_lookup (c,
-                                                   backtrack.len, (const HBUINT16 *) backtrack.array,
-                                                   input.len, (const HBUINT16 *) input.array + 1,
-                                                   lookahead.len, (const HBUINT16 *) lookahead.array,
-                                                   lookup.len, lookup.array, lookup_context));
+                                                   backtrack.len, (const HBUINT16 *) backtrack.arrayZ,
+                                                   input.len, (const HBUINT16 *) input.arrayZ + 1,
+                                                   lookahead.len, (const HBUINT16 *) lookahead.arrayZ,
+                                                   lookup.len, lookup.arrayZ, lookup_context));
   }
 
   inline const Coverage &get_coverage (void) const
@@ -2139,10 +2159,10 @@ struct ChainContextFormat3
       {this, this, this}
     };
     return_trace (chain_context_apply_lookup (c,
-                                             backtrack.len, (const HBUINT16 *) backtrack.array,
-                                             input.len, (const HBUINT16 *) input.array + 1,
-                                             lookahead.len, (const HBUINT16 *) lookahead.array,
-                                             lookup.len, lookup.array, lookup_context));
+                                             backtrack.len, (const HBUINT16 *) backtrack.arrayZ,
+                                             input.len, (const HBUINT16 *) input.arrayZ + 1,
+                                             lookahead.len, (const HBUINT16 *) lookahead.arrayZ,
+                                             lookup.len, lookup.arrayZ, lookup_context));
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
index adbaad6..7fabdeb 100644 (file)
@@ -189,7 +189,8 @@ struct JstfScript
 
 
 /*
- * JSTF -- The Justification Table
+ * JSTF -- Justification
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/jstf
  */
 
 struct JSTF
index 870ba73..b2f974b 100644 (file)
@@ -105,12 +105,12 @@ HB_INTERNAL void
 hb_ot_layout_position_start (hb_font_t    *font,
                             hb_buffer_t  *buffer);
 
-/* Should be called after all the position_lookup's are done, to finish advances. */
+/* Should be called after all the position_lookup's are done, to fini advances. */
 HB_INTERNAL void
 hb_ot_layout_position_finish_advances (hb_font_t    *font,
                                       hb_buffer_t  *buffer);
 
-/* Should be called after hb_ot_layout_position_finish_advances, to finish offsets. */
+/* Should be called after hb_ot_layout_position_finish_advances, to fini offsets. */
 HB_INTERNAL void
 hb_ot_layout_position_finish_offsets (hb_font_t    *font,
                                      hb_buffer_t  *buffer);
@@ -172,16 +172,10 @@ struct hb_ot_layout_t
   const struct OT::GPOS *gpos;
 
   /* TODO Move the following out of this struct. */
-  OT::hb_lazy_table_loader_t<struct OT::BASE> base;
-  OT::hb_lazy_table_loader_t<struct OT::COLR> colr;
-  OT::hb_lazy_table_loader_t<struct OT::CPAL> cpal;
-  OT::hb_lazy_table_loader_t<struct OT::MATH> math;
-  OT::hb_lazy_table_loader_t<struct OT::fvar> fvar;
-  OT::hb_lazy_table_loader_t<struct OT::avar> avar;
-  OT::hb_lazy_table_loader_t<struct AAT::ankr> ankr;
-  OT::hb_lazy_table_loader_t<struct AAT::kerx> kerx;
-  OT::hb_lazy_table_loader_t<struct AAT::morx> morx;
-  OT::hb_lazy_table_loader_t<struct AAT::trak> trak;
+  OT::hb_table_lazy_loader_t<struct OT::BASE> base;
+  OT::hb_table_lazy_loader_t<struct OT::MATH> math;
+  OT::hb_table_lazy_loader_t<struct OT::fvar> fvar;
+  OT::hb_table_lazy_loader_t<struct OT::avar> avar;
 
   unsigned int gsub_lookup_count;
   unsigned int gpos_lookup_count;
@@ -309,7 +303,7 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer)
        * processing on. */
 
       /* Only Mn and Mc can have non-zero ccc:
-       * http://www.unicode.org/policies/stability_policy.html#Property_Value
+       * https://unicode.org/policies/stability_policy.html#Property_Value
        * """
        * Canonical_Combining_Class, General_Category
        * All characters other than those with General_Category property values
index 1c9e950..655c36c 100644 (file)
 
 #include "hb-open-type-private.hh"
 #include "hb-ot-layout-private.hh"
+#include "hb-ot-map-private.hh"
 
-#include "hb-ot-layout-base-table.hh"
 #include "hb-ot-layout-gdef-table.hh"
 #include "hb-ot-layout-gsub-table.hh"
 #include "hb-ot-layout-gpos-table.hh"
-#include "hb-ot-layout-jstf-table.hh" // Just so we compile it; unused otherwise.
-#include "hb-ot-name-table.hh" // Just so we compile it; unused otherwise.
+
+// Just so we compile them; unused otherwise:
+#include "hb-ot-layout-base-table.hh"
+#include "hb-ot-layout-jstf-table.hh"
 #include "hb-ot-color-colr-table.hh"
 #include "hb-ot-color-cpal-table.hh"
-
-#include "hb-ot-map-private.hh"
-
-
-#ifndef HB_NO_VISIBILITY
-const void * const OT::_hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {};
-#endif
+#include "hb-ot-color-sbix-table.hh"
+#include "hb-ot-color-svg-table.hh"
+#include "hb-ot-name-table.hh"
+#include "hb-map-private.hh"
 
 
 hb_ot_layout_t *
@@ -56,24 +55,17 @@ _hb_ot_layout_create (hb_face_t *face)
     return nullptr;
 
   layout->gdef_blob = OT::Sanitizer<OT::GDEF>().sanitize (face->reference_table (HB_OT_TAG_GDEF));
-  layout->gdef = OT::Sanitizer<OT::GDEF>::lock_instance (layout->gdef_blob);
+  layout->gdef = layout->gdef_blob->as<OT::GDEF> ();
 
   layout->gsub_blob = OT::Sanitizer<OT::GSUB>().sanitize (face->reference_table (HB_OT_TAG_GSUB));
-  layout->gsub = OT::Sanitizer<OT::GSUB>::lock_instance (layout->gsub_blob);
+  layout->gsub = layout->gsub_blob->as<OT::GSUB> ();
 
   layout->gpos_blob = OT::Sanitizer<OT::GPOS>().sanitize (face->reference_table (HB_OT_TAG_GPOS));
-  layout->gpos = OT::Sanitizer<OT::GPOS>::lock_instance (layout->gpos_blob);
+  layout->gpos = layout->gpos_blob->as<OT::GPOS> ();
 
-  layout->base.init (face);
-  layout->colr.init (face);
-  layout->cpal.init (face);
   layout->math.init (face);
   layout->fvar.init (face);
   layout->avar.init (face);
-  layout->ankr.init (face);
-  layout->kerx.init (face);
-  layout->morx.init (face);
-  layout->trak.init (face);
 
   {
     /*
@@ -81,9 +73,9 @@ _hb_ot_layout_create (hb_face_t *face)
      * See this thread for why we finally had to bend in and do this:
      * https://lists.freedesktop.org/archives/harfbuzz/2016-February/005489.html
      */
-    unsigned int gdef_len = hb_blob_get_length (layout->gdef_blob);
-    unsigned int gsub_len = hb_blob_get_length (layout->gsub_blob);
-    unsigned int gpos_len = hb_blob_get_length (layout->gpos_blob);
+    unsigned int gdef_len = layout->gdef_blob->length;
+    unsigned int gsub_len = layout->gsub_blob->length;
+    unsigned int gpos_len = layout->gpos_blob->length;
     if (0
       /* sha1sum:c5ee92f0bca4bfb7d06c4d03e8cf9f9cf75d2e8a Windows 7? timesi.ttf */
       || (442 == gdef_len && 42038 == gpos_len && 2874 == gsub_len)
@@ -106,7 +98,7 @@ _hb_ot_layout_create (hb_face_t *face)
        * https://lists.freedesktop.org/archives/harfbuzz/2016-February/005489.html
        */
      if (3 == layout->gdef->get_glyph_class (5))
-       layout->gdef = &OT::Null(OT::GDEF);
+       layout->gdef = &Null(OT::GDEF);
     }
     else if (0
       /* sha1sum:96eda93f7d33e79962451c6c39a6b51ee893ce8c  tahoma.ttf from Windows 8 */
@@ -178,7 +170,7 @@ _hb_ot_layout_create (hb_face_t *face)
        *     https://bugzilla.mozilla.org/show_bug.cgi?id=1279693
        *     https://bugzilla.mozilla.org/show_bug.cgi?id=1279875
        */
-      layout->gdef = &OT::Null(OT::GDEF);
+      layout->gdef = &Null(OT::GDEF);
     }
   }
 
@@ -220,16 +212,9 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout)
   hb_blob_destroy (layout->gsub_blob);
   hb_blob_destroy (layout->gpos_blob);
 
-  layout->base.fini ();
-  layout->colr.fini ();
-  layout->cpal.fini ();
   layout->math.fini ();
   layout->fvar.fini ();
   layout->avar.fini ();
-  layout->ankr.fini ();
-  layout->kerx.fini ();
-  layout->morx.fini ();
-  layout->trak.fini ();
 
   free (layout);
 }
@@ -237,7 +222,7 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout)
 // static inline const OT::BASE&
 // _get_base (hb_face_t *face)
 // {
-//   if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::BASE);
+//   if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::BASE);
 //   hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
 //   return *(layout->base.get ());
 // }
@@ -245,19 +230,19 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout)
 static inline const OT::GDEF&
 _get_gdef (hb_face_t *face)
 {
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GDEF);
+  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::GDEF);
   return *hb_ot_layout_from_face (face)->gdef;
 }
 static inline const OT::GSUB&
 _get_gsub (hb_face_t *face)
 {
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GSUB);
+  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::GSUB);
   return *hb_ot_layout_from_face (face)->gsub;
 }
 static inline const OT::GPOS&
 _get_gpos (hb_face_t *face)
 {
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GPOS);
+  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::GPOS);
   return *hb_ot_layout_from_face (face)->gpos;
 }
 
@@ -329,7 +314,7 @@ get_gsubgpos_table (hb_face_t *face,
   switch (table_tag) {
     case HB_OT_TAG_GSUB: return _get_gsub (face);
     case HB_OT_TAG_GPOS: return _get_gpos (face);
-    default:             return OT::Null(OT::GSUBGPOS);
+    default:             return Null(OT::GSUBGPOS);
   }
 }
 
@@ -909,7 +894,7 @@ hb_ot_layout_feature_with_variations_get_lookups (hb_face_t    *face,
 hb_bool_t
 hb_ot_layout_has_substitution (hb_face_t *face)
 {
-  return &_get_gsub (face) != &OT::Null(OT::GSUB);
+  return &_get_gsub (face) != &Null(OT::GSUB);
 }
 
 /**
@@ -959,11 +944,46 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t    *face,
                                        unsigned int  lookup_index,
                                        hb_set_t     *glyphs)
 {
-  OT::hb_closure_context_t c (face, glyphs);
+  hb_auto_t<hb_map_t> done_lookups;
+  OT::hb_closure_context_t c (face, glyphs, &done_lookups);
 
   const OT::SubstLookup& l = _get_gsub (face).get_lookup (lookup_index);
 
-  l.closure (&c);
+  l.closure (&c, lookup_index);
+}
+
+/**
+ * hb_ot_layout_lookups_substitute_closure:
+ *
+ * Compute the transitive closure of glyphs needed for all of the
+ * provided lookups.
+ *
+ * Since: 1.8.1
+ **/
+void
+hb_ot_layout_lookups_substitute_closure (hb_face_t      *face,
+                                         const hb_set_t *lookups,
+                                         hb_set_t       *glyphs)
+{
+  hb_auto_t<hb_map_t> done_lookups;
+  OT::hb_closure_context_t c (face, glyphs, &done_lookups);
+  const OT::GSUB& gsub = _get_gsub (face);
+
+  unsigned int glyphs_length;
+  do
+  {
+    glyphs_length = glyphs->get_population ();
+    if (lookups != nullptr)
+    {
+      for (hb_codepoint_t lookup_index = HB_SET_VALUE_INVALID; hb_set_next (lookups, &lookup_index);)
+        gsub.get_lookup (lookup_index).closure (&c, lookup_index);
+    }
+    else
+    {
+      for (unsigned int i = 0; i < gsub.get_lookup_count (); i++)
+        gsub.get_lookup (i).closure (&c, i);
+    }
+  } while (glyphs_length != glyphs->get_population ());
 }
 
 /*
@@ -973,7 +993,7 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t    *face,
 hb_bool_t
 hb_ot_layout_has_positioning (hb_face_t *face)
 {
-  return &_get_gpos (face) != &OT::Null(OT::GPOS);
+  return &_get_gpos (face) != &Null(OT::GPOS);
 }
 
 void
@@ -1107,7 +1127,7 @@ struct hb_get_subtables_context_t :
     hb_apply_func_t apply_func;
   };
 
-  typedef hb_auto_array_t<hb_applicable_t> array_t;
+  typedef hb_auto_t<hb_vector_t<hb_applicable_t> > array_t;
 
   /* Dispatch interface. */
   inline const char *get_name (void) { return "GET_SUBTABLES"; }
@@ -1115,8 +1135,7 @@ struct hb_get_subtables_context_t :
   inline return_t dispatch (const T &obj)
   {
     hb_applicable_t *entry = array.push();
-    if (likely (entry))
-      entry->init (&obj, apply_to<T>);
+    entry->init (&obj, apply_to<T>);
     return HB_VOID;
   }
   static return_t default_return_value (void) { return HB_VOID; }
@@ -1137,7 +1156,7 @@ apply_forward (OT::hb_ot_apply_context_t *c,
 {
   bool ret = false;
   hb_buffer_t *buffer = c->buffer;
-  while (buffer->idx < buffer->len && !buffer->in_error)
+  while (buffer->idx < buffer->len && buffer->successful)
   {
     bool applied = false;
     if (accel.may_have (buffer->cur().codepoint) &&
@@ -1309,5 +1328,5 @@ hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
 // hb_bool_t
 // hb_ot_base_has_data (hb_face_t *face)
 // {
-//   return &_get_base (face) != &OT::Null(OT::BASE);
+//   return &_get_base (face) != &Null(OT::BASE);
 // }
index 85938ba..0278796 100644 (file)
@@ -277,6 +277,12 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t    *face,
                                        hb_set_t     *glyphs
                                        /*TODO , hb_bool_t  inclusive */);
 
+HB_EXTERN void
+hb_ot_layout_lookups_substitute_closure (hb_face_t      *face,
+                                         const hb_set_t *lookups,
+                                         hb_set_t       *glyphs);
+
+
 #ifdef HB_NOT_IMPLEMENTED
 /* Note: You better have GDEF when using this API, or marks won't do much. */
 HB_EXTERN hb_bool_t
@@ -307,7 +313,7 @@ Xhb_ot_layout_lookup_position (hb_font_t            *font,
 #endif
 
 /* Optical 'size' feature info.  Returns true if found.
- * http://www.microsoft.com/typography/otspec/features_pt.htm#size */
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#size */
 HB_EXTERN hb_bool_t
 hb_ot_layout_get_size_params (hb_face_t    *face,
                              unsigned int *design_size,       /* OUT.  May be NULL */
index e6bd8ea..4aaf328 100644 (file)
@@ -78,8 +78,26 @@ struct hb_ot_map_t
     pause_func_t pause_func;
   };
 
+  inline void init (void)
+  {
+    memset (this, 0, sizeof (*this));
 
-  hb_ot_map_t (void) { memset (this, 0, sizeof (*this)); }
+    features.init ();
+    for (unsigned int table_index = 0; table_index < 2; table_index++)
+    {
+      lookups[table_index].init ();
+      stages[table_index].init ();
+    }
+  }
+  inline void fini (void)
+  {
+    features.fini ();
+    for (unsigned int table_index = 0; table_index < 2; table_index++)
+    {
+      lookups[table_index].fini ();
+      stages[table_index].fini ();
+    }
+  }
 
   inline hb_mask_t get_global_mask (void) const { return global_mask; }
 
@@ -130,15 +148,6 @@ struct hb_ot_map_t
   HB_INTERNAL void substitute (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
   HB_INTERNAL void position (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
 
-  inline void finish (void) {
-    features.finish ();
-    for (unsigned int table_index = 0; table_index < 2; table_index++)
-    {
-      lookups[table_index].finish ();
-      stages[table_index].finish ();
-    }
-  }
-
   public:
   hb_tag_t chosen_script[2];
   bool found_script[2];
@@ -147,9 +156,9 @@ struct hb_ot_map_t
 
   hb_mask_t global_mask;
 
-  hb_prealloced_array_t<feature_map_t, 8> features;
-  hb_prealloced_array_t<lookup_map_t, 32> lookups[2]; /* GSUB/GPOS */
-  hb_prealloced_array_t<stage_map_t, 4> stages[2]; /* GSUB/GPOS */
+  hb_vector_t<feature_map_t, 8> features;
+  hb_vector_t<lookup_map_t, 32> lookups[2]; /* GSUB/GPOS */
+  hb_vector_t<stage_map_t, 4> stages[2]; /* GSUB/GPOS */
 };
 
 enum hb_ot_map_feature_flags_t {
@@ -172,6 +181,8 @@ struct hb_ot_map_builder_t
   HB_INTERNAL hb_ot_map_builder_t (hb_face_t *face_,
                                   const hb_segment_properties_t *props_);
 
+  HB_INTERNAL ~hb_ot_map_builder_t (void);
+
   HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value,
                                hb_ot_map_feature_flags_t flags);
 
@@ -187,14 +198,6 @@ struct hb_ot_map_builder_t
                            const int    *coords,
                            unsigned int  num_coords);
 
-  inline void finish (void) {
-    feature_infos.finish ();
-    for (unsigned int table_index = 0; table_index < 2; table_index++)
-    {
-      stages[table_index].finish ();
-    }
-  }
-
   private:
 
   HB_INTERNAL void add_lookups (hb_ot_map_t  &m,
@@ -241,8 +244,8 @@ struct hb_ot_map_builder_t
   private:
 
   unsigned int current_stage[2]; /* GSUB/GPOS */
-  hb_prealloced_array_t<feature_info_t, 32> feature_infos;
-  hb_prealloced_array_t<stage_info_t, 8> stages[2]; /* GSUB/GPOS */
+  hb_vector_t<feature_info_t, 32> feature_infos;
+  hb_vector_t<stage_info_t, 8> stages[2]; /* GSUB/GPOS */
 };
 
 
index 54b0ce3..46bf2db 100644 (file)
@@ -43,6 +43,10 @@ hb_ot_map_builder_t::hb_ot_map_builder_t (hb_face_t *face_,
 {
   memset (this, 0, sizeof (*this));
 
+  feature_infos.init ();
+  for (unsigned int table_index = 0; table_index < 2; table_index++)
+    stages[table_index].init ();
+
   face = face_;
   props = *props_;
 
@@ -63,11 +67,17 @@ hb_ot_map_builder_t::hb_ot_map_builder_t (hb_face_t *face_,
   }
 }
 
+hb_ot_map_builder_t::~hb_ot_map_builder_t (void)
+{
+  feature_infos.fini ();
+  for (unsigned int table_index = 0; table_index < 2; table_index++)
+    stages[table_index].fini ();
+}
+
 void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value,
                                       hb_ot_map_feature_flags_t flags)
 {
   feature_info_t *info = feature_infos.push();
-  if (unlikely (!info)) return;
   if (unlikely (!tag)) return;
   info->tag = tag;
   info->seq = feature_infos.len;
@@ -108,8 +118,6 @@ hb_ot_map_builder_t::add_lookups (hb_ot_map_t  &m,
       if (lookup_indices[i] >= table_lookup_count)
        continue;
       hb_ot_map_t::lookup_map_t *lookup = m.lookups[table_index].push ();
-      if (unlikely (!lookup))
-        return;
       lookup->mask = mask;
       lookup->index = lookup_indices[i];
       lookup->auto_zwnj = auto_zwnj;
@@ -124,10 +132,8 @@ hb_ot_map_builder_t::add_lookups (hb_ot_map_t  &m,
 void hb_ot_map_builder_t::add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func)
 {
   stage_info_t *s = stages[table_index].push ();
-  if (likely (s)) {
-    s->index = current_stage[table_index];
-    s->pause_func = pause_func;
-  }
+  s->index = current_stage[table_index];
+  s->pause_func = pause_func;
 
   current_stage[table_index]++;
 }
@@ -164,9 +170,6 @@ hb_ot_map_builder_t::compile (hb_ot_map_t  &m,
                                                &required_feature_tag[table_index]);
   }
 
-  if (!feature_infos.len)
-    return;
-
   /* Sort features and merge duplicates */
   {
     feature_infos.qsort ();
@@ -241,8 +244,6 @@ hb_ot_map_builder_t::compile (hb_ot_map_t  &m,
 
 
     hb_ot_map_t::feature_map_t *map = m.features.push ();
-    if (unlikely (!map))
-      break;
 
     map->tag = info->tag;
     map->index[0] = feature_index[0];
@@ -324,10 +325,8 @@ hb_ot_map_builder_t::compile (hb_ot_map_t  &m,
 
       if (stage_index < stages[table_index].len && stages[table_index][stage_index].index == stage) {
        hb_ot_map_t::stage_map_t *stage_map = m.stages[table_index].push ();
-       if (likely (stage_map)) {
-         stage_map->last_lookup = last_num_lookups;
-         stage_map->pause_func = stages[table_index][stage_index].pause_func;
-       }
+       stage_map->last_lookup = last_num_lookups;
+       stage_map->pause_func = stages[table_index][stage_index].pause_func;
 
        stage_index++;
       }
index 571ce01..5fef2d2 100644 (file)
@@ -678,7 +678,8 @@ struct MathVariants
 
 
 /*
- * MATH -- The MATH Table
+ * MATH -- Mathematical typesetting
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/math
  */
 
 struct MATH
index f82a073..1667a7d 100644 (file)
@@ -32,7 +32,7 @@
 static inline const OT::MATH&
 _get_math (hb_face_t *face)
 {
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::MATH);
+  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::MATH);
   hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
   return *(layout->math.get ());
 }
@@ -55,7 +55,7 @@ _get_math (hb_face_t *face)
 hb_bool_t
 hb_ot_math_has_data (hb_face_t *face)
 {
-  return &_get_math (face) != &OT::Null(OT::MATH);
+  return &_get_math (face) != &Null(OT::MATH);
 }
 
 /**
index 881deda..390b60d 100644 (file)
@@ -34,7 +34,8 @@ namespace OT {
 
 
 /*
- * maxp -- The Maximum Profile Table
+ * maxp -- Maximum Profile
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/maxp
  */
 
 #define HB_OT_TAG_maxp HB_TAG('m','a','x','p')
@@ -108,11 +109,11 @@ struct maxp
     }
     OT::maxp *maxp_prime = (OT::maxp *) hb_blob_get_data (maxp_prime_blob, nullptr);
 
-    maxp_prime->set_num_glyphs (plan->gids_to_retain_sorted.len);
+    maxp_prime->set_num_glyphs (plan->glyphs.len);
     if (plan->drop_hints)
       drop_hint_fields (plan, maxp_prime);
 
-    bool result = hb_subset_plan_add_table(plan, HB_OT_TAG_maxp, maxp_prime_blob);
+    bool result = plan->add_table (HB_OT_TAG_maxp, maxp_prime_blob);
     hb_blob_destroy (maxp_prime_blob);
     return result;
   }
index eb01333..bff85df 100644 (file)
@@ -34,9 +34,9 @@ namespace OT {
 
 
 /*
- * name -- The Naming Table
+ * name -- Naming
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/name
  */
-
 #define HB_OT_TAG_name HB_TAG('n','a','m','e')
 
 
index 6cb8d49..c52b7eb 100644 (file)
 
 #include "hb-open-type-private.hh"
 #include "hb-ot-os2-unicode-ranges.hh"
+#include "hb-subset-plan.hh"
 
 namespace OT {
 
 /*
  * OS/2 and Windows Metrics
- * http://www.microsoft.com/typography/otspec/os2.htm
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/os2
  */
-
 #define HB_OT_TAG_os2 HB_TAG('O','S','/','2')
 
 struct os2
@@ -63,26 +63,25 @@ struct os2
     }
 
     uint16_t min_cp, max_cp;
-    find_min_and_max_codepoint (plan->codepoints, &min_cp, &max_cp);
+    find_min_and_max_codepoint (plan->unicodes, &min_cp, &max_cp);
     os2_prime->usFirstCharIndex.set (min_cp);
     os2_prime->usLastCharIndex.set (max_cp);
 
-    _update_unicode_ranges (plan->codepoints, os2_prime->ulUnicodeRange);
-    bool result = hb_subset_plan_add_table(plan, HB_OT_TAG_os2, os2_prime_blob);
+    _update_unicode_ranges (plan->unicodes, os2_prime->ulUnicodeRange);
+    bool result = plan->add_table (HB_OT_TAG_os2, os2_prime_blob);
 
     hb_blob_destroy (os2_prime_blob);
     return result;
   }
 
-  inline void _update_unicode_ranges (const hb_prealloced_array_t<hb_codepoint_t> &codepoints,
+  inline void _update_unicode_ranges (const hb_set_t *codepoints,
                                       HBUINT32 ulUnicodeRange[4]) const
   {
     for (unsigned int i = 0; i < 4; i++)
       ulUnicodeRange[i].set (0);
 
-    for (unsigned int i = 0; i < codepoints.len; i++)
-    {
-      hb_codepoint_t cp = codepoints[i];
+    hb_codepoint_t cp = HB_SET_VALUE_INVALID;
+    while (codepoints->next (&cp)) {
       unsigned int bit = hb_get_unicode_range_bit (cp);
       if (bit < 128)
       {
@@ -101,28 +100,30 @@ struct os2
     }
   }
 
-  static inline void find_min_and_max_codepoint (const hb_prealloced_array_t<hb_codepoint_t> &codepoints,
+  static inline void find_min_and_max_codepoint (const hb_set_t *codepoints,
                                                  uint16_t *min_cp, /* OUT */
                                                  uint16_t *max_cp  /* OUT */)
   {
-    hb_codepoint_t min = -1, max = 0;
-
-    for (unsigned int i = 0; i < codepoints.len; i++)
-    {
-      hb_codepoint_t cp = codepoints[i];
-      if (cp < min)
-        min = cp;
-      if (cp > max)
-        max = cp;
-    }
-
-    if (min > 0xFFFF)
-      min = 0xFFFF;
-    if (max > 0xFFFF)
-      max = 0xFFFF;
+    *min_cp = codepoints->get_min ();
+    *max_cp = codepoints->get_max ();
+  }
 
-    *min_cp = min;
-    *max_cp = max;
+  enum font_page_t {
+    HEBREW_FONT_PAGE           = 0xB100, // Hebrew Windows 3.1 font page
+    SIMP_ARABIC_FONT_PAGE      = 0xB200, // Simplified Arabic Windows 3.1 font page
+    TRAD_ARABIC_FONT_PAGE      = 0xB300, // Traditional Arabic Windows 3.1 font page
+    OEM_ARABIC_FONT_PAGE       = 0xB400, // OEM Arabic Windows 3.1 font page
+    SIMP_FARSI_FONT_PAGE       = 0xBA00, // Simplified Farsi Windows 3.1 font page
+    TRAD_FARSI_FONT_PAGE       = 0xBB00, // Traditional Farsi Windows 3.1 font page
+    THAI_FONT_PAGE             = 0xDE00  // Thai Windows 3.1 font page
+  };
+
+  // https://github.com/Microsoft/Font-Validator/blob/520aaae/OTFontFileVal/val_OS2.cs#L644-L681
+  inline font_page_t get_font_page () const
+  {
+    if (version != 0)
+      return (font_page_t) 0;
+    return (font_page_t) (fsSelection & 0xFF00);
   }
 
   public:
index 2cf168f..9b32cfa 100644 (file)
@@ -237,7 +237,7 @@ hb_get_unicode_range_bit (hb_codepoint_t cp)
                                         sizeof (os2UnicodeRangesSorted) / sizeof(Range),
                                         sizeof(Range),
                                         _compare_range, nullptr);
-  if (range != NULL)
+  if (range != nullptr)
     return range->bit;
   return -1;
 }
index 9e47921..5f42751 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "hb-open-type-private.hh"
 #include "hb-dsalgs.hh"
+#include "hb-subset-plan.hh"
 
 #define HB_STRING_ARRAY_NAME format1_names
 #define HB_STRING_ARRAY_LIST "hb-ot-post-macroman.hh"
 
 #define NUM_FORMAT1_NAMES 258
 
-namespace OT {
-
-
 /*
  * post -- PostScript
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/post
  */
-
 #define HB_OT_TAG_post HB_TAG('p','o','s','t')
 
 
+namespace OT {
+
+
 struct postV2Tail
 {
   inline bool sanitize (hb_sanitize_context_t *c) const
@@ -82,16 +83,39 @@ struct post
     return_trace (true);
   }
 
+  inline bool subset (hb_subset_plan_t *plan) const
+  {
+    unsigned int post_prime_length;
+    hb_blob_t *post_blob = OT::Sanitizer<post>().sanitize (hb_face_reference_table (plan->source, HB_OT_TAG_post));
+    hb_blob_t *post_prime_blob = hb_blob_create_sub_blob (post_blob, 0, post::static_size);
+    post *post_prime = (post *) hb_blob_get_data_writable (post_prime_blob, &post_prime_length);
+    hb_blob_destroy (post_blob);
+
+    if (unlikely (!post_prime || post_prime_length != post::static_size))
+    {
+      hb_blob_destroy (post_prime_blob);
+      DEBUG_MSG(SUBSET, nullptr, "Invalid source post table with length %d.", post_prime_length);
+      return false;
+    }
+
+    post_prime->version.major.set (3); // Version 3 does not have any glyph names.
+    bool result = plan->add_table (HB_OT_TAG_post, post_prime_blob);
+    hb_blob_destroy (post_prime_blob);
+
+    return result;
+  }
+
   struct accelerator_t
   {
     inline void init (hb_face_t *face)
     {
+      index_to_offset.init ();
+
       blob = Sanitizer<post>().sanitize (face->reference_table (HB_OT_TAG_post));
-      const post *table = Sanitizer<post>::lock_instance (blob);
-      unsigned int table_length = hb_blob_get_length (blob);
+      const post *table = blob->as<post> ();
+      unsigned int table_length = blob->length;
 
       version = table->version.to_int ();
-      index_to_offset.init ();
       if (version != 0x00020000)
         return;
 
@@ -102,23 +126,18 @@ struct post
 
       const uint8_t *end = (uint8_t *) table + table_length;
       for (const uint8_t *data = pool; data < end && data + *data <= end; data += 1 + *data)
-      {
-       uint32_t *offset = index_to_offset.push ();
-       if (unlikely (!offset))
-         break;
-       *offset = data - pool;
-      }
+       index_to_offset.push (data - pool);
     }
     inline void fini (void)
     {
-      index_to_offset.finish ();
+      index_to_offset.fini ();
       free (gids_sorted_by_name);
     }
 
     inline bool get_glyph_name (hb_codepoint_t glyph,
                                char *buf, unsigned int buf_len) const
     {
-      hb_string_t s = find_glyph_name (glyph);
+      hb_bytes_t s = find_glyph_name (glyph);
       if (!s.len)
         return false;
       if (!buf_len)
@@ -162,7 +181,7 @@ struct post
        }
       }
 
-      hb_string_t st (name, len);
+      hb_bytes_t st (name, len);
       const uint16_t *gid = (const uint16_t *) hb_bsearch_r (&st, gids, count, sizeof (gids[0]), cmp_key, (void *) this);
       if (gid)
       {
@@ -197,45 +216,45 @@ struct post
     static inline int cmp_key (const void *pk, const void *po, void *arg)
     {
       const accelerator_t *thiz = (const accelerator_t *) arg;
-      const hb_string_t *key = (const hb_string_t *) pk;
+      const hb_bytes_t *key = (const hb_bytes_t *) pk;
       uint16_t o = * (const uint16_t *) po;
       return thiz->find_glyph_name (o).cmp (*key);
     }
 
-    inline hb_string_t find_glyph_name (hb_codepoint_t glyph) const
+    inline hb_bytes_t find_glyph_name (hb_codepoint_t glyph) const
     {
       if (version == 0x00010000)
       {
        if (glyph >= NUM_FORMAT1_NAMES)
-         return hb_string_t ();
+         return hb_bytes_t ();
 
        return format1_names (glyph);
       }
 
       if (version != 0x00020000 || glyph >= glyphNameIndex->len)
-       return hb_string_t ();
+       return hb_bytes_t ();
 
-      unsigned int index = glyphNameIndex->array[glyph];
+      unsigned int index = glyphNameIndex->arrayZ[glyph];
       if (index < NUM_FORMAT1_NAMES)
        return format1_names (index);
       index -= NUM_FORMAT1_NAMES;
 
       if (index >= index_to_offset.len)
-       return hb_string_t ();
-      unsigned int offset = index_to_offset.array[index];
+       return hb_bytes_t ();
+      unsigned int offset = index_to_offset.arrayZ[index];
 
       const uint8_t *data = pool + offset;
       unsigned int name_length = *data;
       data++;
 
-      return hb_string_t ((const char *) data, name_length);
+      return hb_bytes_t ((const char *) data, name_length);
     }
 
     private:
     hb_blob_t *blob;
     uint32_t version;
     const ArrayOf<HBUINT16> *glyphNameIndex;
-    hb_prealloced_array_t<uint32_t, 1> index_to_offset;
+    hb_vector_t<uint32_t, 1> index_to_offset;
     const uint8_t *pool;
     mutable uint16_t *gids_sorted_by_name;
   };
index cd6e405..9459aad 100644 (file)
@@ -6,10 +6,10 @@
  *
  * on files with these headers:
  *
- * # ArabicShaping-10.0.0.txt
- * # Date: 2017-02-16, 00:00:00 GMT [RP, KW]
- * # Blocks-10.0.0.txt
- * # Date: 2017-04-12, 17:30:00 GMT [KW]
+ * # ArabicShaping-11.0.0.txt
+ * # Date: 2018-02-21, 14:50:00 GMT [KW, RP]
+ * # Blocks-11.0.0.txt
+ * # Date: 2017-10-16, 24:39:00 GMT [KW]
  * UnicodeData.txt does not have a header.
  */
 
@@ -45,7 +45,7 @@ static const uint8_t joining_table[] =
 
   /* Syriac */
 
-  /* 0700 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,A,X,D,D,D,DR,DR,R,R,R,D,D,D,D,R,D,
+  /* 0700 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,T,A,X,D,D,D,DR,DR,R,R,R,D,D,D,D,R,D,
   /* 0720 */ D,D,D,D,D,D,D,D,R,D,DR,D,R,D,D,DR,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
   /* 0740 */ X,X,X,X,X,X,X,X,X,X,X,X,X,R,D,D,
 
@@ -91,7 +91,7 @@ static const uint8_t joining_table[] =
   /* 1800 */             U,D,X,X,C,X,X,X,U,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
   /* 1820 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,
   /* 1840 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,
-  /* 1860 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,X,X,X,X,X,X,X,X,
+  /* 1860 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,X,X,X,X,X,X,X,
   /* 1880 */ U,U,U,U,U,T,T,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,
   /* 18A0 */ D,D,D,D,D,D,D,D,D,X,D,
 
@@ -125,7 +125,28 @@ static const uint8_t joining_table[] =
   /* 10B80 */ D,R,D,R,R,R,D,D,D,R,D,D,R,D,R,R,D,R,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
   /* 10BA0 */ X,X,X,X,X,X,X,X,X,R,R,R,R,D,D,U,
 
-#define joining_offset_0x1e900u 1146
+#define joining_offset_0x10d00u 1146
+
+  /* Hanifi Rohingya */
+
+  /* 10D00 */ L,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,
+  /* 10D20 */ D,D,R,D,
+
+#define joining_offset_0x10f30u 1182
+
+  /* Sogdian */
+
+  /* 10F20 */                                 D,D,D,R,D,D,D,D,D,D,D,D,D,D,D,D,
+  /* 10F40 */ D,D,D,D,D,U,X,X,X,X,X,X,X,X,X,X,X,D,D,D,R,
+
+#define joining_offset_0x110bdu 1219
+
+  /* Kaithi */
+
+  /* 110A0 */                                                           U,X,X,
+  /* 110C0 */ X,X,X,X,X,X,X,X,X,X,X,X,X,U,
+
+#define joining_offset_0x1e900u 1236
 
   /* Adlam */
 
@@ -133,7 +154,7 @@ static const uint8_t joining_table[] =
   /* 1E920 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,
   /* 1E940 */ D,D,D,D,
 
-}; /* Table items: 1214; occupancy: 55% */
+}; /* Table items: 1304; occupancy: 56% */
 
 
 static unsigned int
@@ -160,6 +181,12 @@ joining_type (hb_codepoint_t u)
     case 0x10u:
       if (hb_in_range<hb_codepoint_t> (u, 0x10AC0u, 0x10AEFu)) return joining_table[u - 0x10AC0u + joining_offset_0x10ac0u];
       if (hb_in_range<hb_codepoint_t> (u, 0x10B80u, 0x10BAFu)) return joining_table[u - 0x10B80u + joining_offset_0x10b80u];
+      if (hb_in_range<hb_codepoint_t> (u, 0x10D00u, 0x10D23u)) return joining_table[u - 0x10D00u + joining_offset_0x10d00u];
+      if (hb_in_range<hb_codepoint_t> (u, 0x10F30u, 0x10F54u)) return joining_table[u - 0x10F30u + joining_offset_0x10f30u];
+      break;
+
+    case 0x11u:
+      if (hb_in_range<hb_codepoint_t> (u, 0x110BDu, 0x110CDu)) return joining_table[u - 0x110BDu + joining_offset_0x110bdu];
       break;
 
     case 0x1Eu:
index 47961bf..124a67f 100644 (file)
@@ -421,7 +421,7 @@ retry:
 /*
  * Stretch feature: "stch".
  * See example here:
- * https://www.microsoft.com/typography/OpenTypeDev/syriac/intro.htm
+ * https://docs.microsoft.com/en-us/typography/script-development/syriac
  * We implement this in a generic way, such that the Arabic subtending
  * marks can use it as well.
  */
@@ -611,7 +611,7 @@ postprocess_glyphs_arabic (const hb_ot_shape_plan_t *plan,
   HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
 }
 
-/* http://www.unicode.org/reports/tr53/tr53-1.pdf */
+/* https://unicode.org/reports/tr53/tr53-1.pdf */
 
 static hb_codepoint_t
 modifier_combining_marks[] =
index 7508c22..7420c5d 100644 (file)
@@ -151,8 +151,8 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan,
    *   - <V>: U+1160..11A7, U+D7B0..D7C7
    *   - <T>: U+11A8..11FF, U+D7CB..D7FB
    *
-   *   - Only the <L,V> sequences for the 11xx ranges combine.
-   *   - Only <LV,T> sequences for T in U+11A8..11C3 combine.
+   *   - Only the <L,V> sequences for some of the U+11xx ranges combine.
+   *   - Only <LV,T> sequences for some of the Ts in U+11xx range combine.
    *
    * Here is what we want to accomplish in this shaper:
    *
@@ -188,7 +188,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan,
                                    */
   unsigned int count = buffer->len;
 
-  for (buffer->idx = 0; buffer->idx < count && !buffer->in_error;)
+  for (buffer->idx = 0; buffer->idx < count && buffer->successful;)
   {
     hb_codepoint_t u = buffer->cur().codepoint;
 
@@ -269,7 +269,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan,
          if (font->has_glyph (s))
          {
            buffer->replace_glyphs (t ? 3 : 2, 1, &s);
-           if (unlikely (buffer->in_error))
+           if (unlikely (!buffer->successful))
              return;
            end = start + 1;
            continue;
@@ -319,7 +319,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan,
        if (font->has_glyph (new_s))
        {
          buffer->replace_glyphs (2, 1, &new_s);
-         if (unlikely (buffer->in_error))
+         if (unlikely (!buffer->successful))
            return;
          end = start + 1;
          continue;
@@ -345,7 +345,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan,
        {
          unsigned int s_len = tindex ? 3 : 2;
          buffer->replace_glyphs (1, s_len, decomposed);
-         if (unlikely (buffer->in_error))
+         if (unlikely (!buffer->successful))
            return;
 
          /* We decomposed S: apply jamo features to the individual glyphs
index f3cea22..73f9d58 100644 (file)
@@ -1129,7 +1129,7 @@ static const int indic_syllable_machine_en_main = 166;
 static void
 find_syllables (hb_buffer_t *buffer)
 {
-  unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
+  unsigned int p, pe, eof, ts HB_UNUSED, te, act;
   int cs;
   hb_glyph_info_t *info = buffer->info;
   
index 0ea91c0..35e7ce9 100644 (file)
@@ -104,7 +104,7 @@ main := |*
 static void
 find_syllables (hb_buffer_t *buffer)
 {
-  unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
+  unsigned int p, pe, eof, ts HB_UNUSED, te, act;
   int cs;
   hb_glyph_info_t *info = buffer->info;
   %%{
index 867b936..9554994 100644 (file)
@@ -42,7 +42,7 @@
 #define INDIC_TABLE_ELEMENT_TYPE uint16_t
 
 /* Cateories used in the OpenType spec:
- * https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx
+ * https://docs.microsoft.com/en-us/typography/script-development/devanagari
  */
 /* Note: This enum is duplicated in the -machine.rl source file.
  * Not sure how to avoid duplication. */
index 867cfb3..54291bc 100644 (file)
@@ -6,62 +6,63 @@
  *
  * on files with these headers:
  *
- * # IndicSyllabicCategory-10.0.0.txt
- * # Date: 2017-05-31, 01:07:00 GMT [KW, RP]
- * # IndicPositionalCategory-10.0.0.txt
- * # Date: 2017-05-31, 01:07:00 GMT [RP]
- * # Blocks-10.0.0.txt
- * # Date: 2017-04-12, 17:30:00 GMT [KW]
+ * # IndicSyllabicCategory-11.0.0.txt
+ * # Date: 2018-05-21, 18:33:00 GMT [KW, RP]
+ * # IndicPositionalCategory-11.0.0.txt
+ * # Date: 2018-02-05, 16:21:00 GMT [KW, RP]
+ * # Blocks-11.0.0.txt
+ * # Date: 2017-10-16, 24:39:00 GMT [KW]
  */
 
 #include "hb-ot-shape-complex-indic-private.hh"
 
 
-#define ISC_A  INDIC_SYLLABIC_CATEGORY_AVAGRAHA                /*  15 chars; Avagraha */
-#define ISC_Bi INDIC_SYLLABIC_CATEGORY_BINDU                   /*  80 chars; Bindu */
+#define ISC_A  INDIC_SYLLABIC_CATEGORY_AVAGRAHA                /*  16 chars; Avagraha */
+#define ISC_Bi INDIC_SYLLABIC_CATEGORY_BINDU                   /*  83 chars; Bindu */
 #define ISC_BJN        INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER   /*  20 chars; Brahmi_Joining_Number */
-#define ISC_Ca INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK       /*  57 chars; Cantillation_Mark */
-#define ISC_C  INDIC_SYLLABIC_CATEGORY_CONSONANT               /* 2024 chars; Consonant */
+#define ISC_Ca INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK       /*  58 chars; Cantillation_Mark */
+#define ISC_C  INDIC_SYLLABIC_CATEGORY_CONSONANT               /* 2110 chars; Consonant */
 #define ISC_CD INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD          /*  10 chars; Consonant_Dead */
-#define ISC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL         /*  68 chars; Consonant_Final */
+#define ISC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL         /*  67 chars; Consonant_Final */
 #define ISC_CHL        INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER   /*   5 chars; Consonant_Head_Letter */
+#define ISC_CIP        INDIC_SYLLABIC_CATEGORY_CONSONANT_INITIAL_POSTFIXED     /*   1 chars; Consonant_Initial_Postfixed */
 #define ISC_CK INDIC_SYLLABIC_CATEGORY_CONSONANT_KILLER        /*   2 chars; Consonant_Killer */
-#define ISC_CM INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL        /*  27 chars; Consonant_Medial */
-#define ISC_CP INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER   /*  18 chars; Consonant_Placeholder */
+#define ISC_CM INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL        /*  28 chars; Consonant_Medial */
+#define ISC_CP INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER   /*  21 chars; Consonant_Placeholder */
 #define ISC_CPR        INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA       /*   2 chars; Consonant_Preceding_Repha */
 #define ISC_CPrf       INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED      /*   7 chars; Consonant_Prefixed */
 #define ISC_CS INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED     /*  95 chars; Consonant_Subjoined */
-#define ISC_CSR        INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA      /*   5 chars; Consonant_Succeeding_Repha */
-#define ISC_CWS        INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER  /*   4 chars; Consonant_With_Stacker */
+#define ISC_CSR        INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA      /*   4 chars; Consonant_Succeeding_Repha */
+#define ISC_CWS        INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER  /*   6 chars; Consonant_With_Stacker */
 #define ISC_GM INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK         /*   3 chars; Gemination_Mark */
-#define ISC_IS INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER       /*  10 chars; Invisible_Stacker */
+#define ISC_IS INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER       /*  11 chars; Invisible_Stacker */
 #define ISC_ZWJ        INDIC_SYLLABIC_CATEGORY_JOINER                  /*   1 chars; Joiner */
 #define ISC_ML INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER        /*   1 chars; Modifying_Letter */
 #define ISC_ZWNJ       INDIC_SYLLABIC_CATEGORY_NON_JOINER              /*   1 chars; Non_Joiner */
-#define ISC_N  INDIC_SYLLABIC_CATEGORY_NUKTA                   /*  28 chars; Nukta */
-#define ISC_Nd INDIC_SYLLABIC_CATEGORY_NUMBER                  /* 469 chars; Number */
+#define ISC_N  INDIC_SYLLABIC_CATEGORY_NUKTA                   /*  30 chars; Nukta */
+#define ISC_Nd INDIC_SYLLABIC_CATEGORY_NUMBER                  /* 480 chars; Number */
 #define ISC_NJ INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER           /*   1 chars; Number_Joiner */
 #define ISC_x  INDIC_SYLLABIC_CATEGORY_OTHER                   /*   1 chars; Other */
 #define ISC_PK INDIC_SYLLABIC_CATEGORY_PURE_KILLER             /*  21 chars; Pure_Killer */
 #define ISC_RS INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER        /*   2 chars; Register_Shifter */
-#define ISC_SM INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER       /*  22 chars; Syllable_Modifier */
+#define ISC_SM INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER       /*  25 chars; Syllable_Modifier */
 #define ISC_TL INDIC_SYLLABIC_CATEGORY_TONE_LETTER             /*   7 chars; Tone_Letter */
 #define ISC_TM INDIC_SYLLABIC_CATEGORY_TONE_MARK               /*  42 chars; Tone_Mark */
-#define ISC_V  INDIC_SYLLABIC_CATEGORY_VIRAMA                  /*  24 chars; Virama */
-#define ISC_Vs INDIC_SYLLABIC_CATEGORY_VISARGA                 /*  34 chars; Visarga */
+#define ISC_V  INDIC_SYLLABIC_CATEGORY_VIRAMA                  /*  25 chars; Virama */
+#define ISC_Vs INDIC_SYLLABIC_CATEGORY_VISARGA                 /*  36 chars; Visarga */
 #define ISC_Vo INDIC_SYLLABIC_CATEGORY_VOWEL                   /*  30 chars; Vowel */
-#define ISC_M  INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT         /* 633 chars; Vowel_Dependent */
-#define ISC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT       /* 443 chars; Vowel_Independent */
+#define ISC_M  INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT         /* 660 chars; Vowel_Dependent */
+#define ISC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT       /* 464 chars; Vowel_Independent */
 
-#define IMC_B  INDIC_MATRA_CATEGORY_BOTTOM                     /* 330 chars; Bottom */
+#define IMC_B  INDIC_MATRA_CATEGORY_BOTTOM                     /* 340 chars; Bottom */
 #define IMC_BL INDIC_MATRA_CATEGORY_BOTTOM_AND_LEFT            /*   1 chars; Bottom_And_Left */
 #define IMC_BR INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT           /*   2 chars; Bottom_And_Right */
-#define IMC_L  INDIC_MATRA_CATEGORY_LEFT                       /*  57 chars; Left */
+#define IMC_L  INDIC_MATRA_CATEGORY_LEFT                       /*  59 chars; Left */
 #define IMC_LR INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT             /*  21 chars; Left_And_Right */
 #define IMC_x  INDIC_MATRA_CATEGORY_NOT_APPLICABLE             /*   1 chars; Not_Applicable */
 #define IMC_O  INDIC_MATRA_CATEGORY_OVERSTRUCK                 /*  10 chars; Overstruck */
-#define IMC_R  INDIC_MATRA_CATEGORY_RIGHT                      /* 262 chars; Right */
-#define IMC_T  INDIC_MATRA_CATEGORY_TOP                        /* 380 chars; Top */
+#define IMC_R  INDIC_MATRA_CATEGORY_RIGHT                      /* 276 chars; Right */
+#define IMC_T  INDIC_MATRA_CATEGORY_TOP                        /* 393 chars; Top */
 #define IMC_TB INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM             /*  10 chars; Top_And_Bottom */
 #define IMC_TBR        INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT   /*   1 chars; Top_And_Bottom_And_Right */
 #define IMC_TL INDIC_MATRA_CATEGORY_TOP_AND_LEFT               /*   6 chars; Top_And_Left */
@@ -119,7 +120,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
 
   /* Bengali */
 
-  /* 0980 */  _(x,x), _(Bi,T), _(Bi,R), _(Vs,R),  _(x,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 0980 */ _(CP,x), _(Bi,T), _(Bi,R), _(Vs,R),  _(x,x), _(VI,x), _(VI,x), _(VI,x),
   /* 0988 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),  _(x,x),  _(x,x), _(VI,x),
   /* 0990 */ _(VI,x),  _(x,x),  _(x,x), _(VI,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),
   /* 0998 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
@@ -134,7 +135,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
   /* 09E0 */ _(VI,x), _(VI,x),  _(M,B),  _(M,B),  _(x,x),  _(x,x), _(Nd,x), _(Nd,x),
   /* 09E8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
   /* 09F0 */  _(C,x),  _(C,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
-  /* 09F8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x), _(Bi,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 09F8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x), _(Bi,x),  _(x,x), _(SM,T),  _(x,x),
 
   /* Gurmukhi */
 
@@ -148,7 +149,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
   /* 0A38 */  _(C,x),  _(C,x),  _(x,x),  _(x,x),  _(N,B),  _(x,x),  _(M,R),  _(M,L),
   /* 0A40 */  _(M,R),  _(M,B),  _(M,B),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(M,T),
   /* 0A48 */  _(M,T),  _(x,x),  _(x,x),  _(M,T),  _(M,T),  _(V,B),  _(x,x),  _(x,x),
-  /* 0A50 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 0A50 */  _(x,x), _(Ca,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
   /* 0A58 */  _(x,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(x,x),  _(C,x),  _(x,x),
   /* 0A60 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x), _(Nd,x), _(Nd,x),
   /* 0A68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
@@ -214,7 +215,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
 
   /* Telugu */
 
-  /* 0C00 */ _(Bi,T), _(Bi,R), _(Bi,R), _(Vs,R),  _(x,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 0C00 */ _(Bi,T), _(Bi,R), _(Bi,R), _(Vs,R), _(Bi,T), _(VI,x), _(VI,x), _(VI,x),
   /* 0C08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),  _(x,x), _(VI,x), _(VI,x),
   /* 0C10 */ _(VI,x),  _(x,x), _(VI,x), _(VI,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),
   /* 0C18 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
@@ -301,7 +302,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
   /* 1030 */  _(M,B),  _(M,L),  _(M,T),  _(M,T),  _(M,T),  _(M,T), _(Bi,T), _(TM,B),
   /* 1038 */ _(Vs,R), _(IS,x), _(PK,T), _(CM,R), _(CM,x), _(CM,B), _(CM,B),  _(C,x),
   /* 1040 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
-  /* 1048 */ _(Nd,x), _(Nd,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x), _(CP,x),  _(x,x),
+  /* 1048 */ _(Nd,x), _(Nd,x),  _(x,x), _(CP,x),  _(x,x),  _(x,x), _(CP,x),  _(x,x),
   /* 1050 */  _(C,x),  _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),  _(M,R),  _(M,R),
   /* 1058 */  _(M,B),  _(M,B),  _(C,x),  _(C,x),  _(C,x),  _(C,x), _(CM,B), _(CM,B),
   /* 1060 */ _(CM,B),  _(C,x),  _(M,R), _(TM,R), _(TM,R),  _(C,x),  _(C,x),  _(M,R),
@@ -342,7 +343,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
   /* 1CD8 */ _(Ca,B), _(Ca,B), _(Ca,T), _(Ca,T), _(Ca,B), _(Ca,B), _(Ca,B), _(Ca,B),
   /* 1CE0 */ _(Ca,T), _(Ca,R),  _(x,O),  _(x,O),  _(x,O),  _(x,O),  _(x,O),  _(x,O),
   /* 1CE8 */  _(x,O),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,B),  _(x,x),  _(x,x),
-  /* 1CF0 */  _(x,x),  _(x,x), _(Vs,x), _(Vs,x), _(Ca,T),  _(x,x),  _(x,x), _(Ca,R),
+  /* 1CF0 */  _(x,x),  _(x,x), _(Vs,x), _(Vs,x), _(Ca,T),_(CWS,x),_(CWS,x), _(Ca,R),
   /* 1CF8 */ _(Ca,x), _(Ca,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
 
 #define indic_offset_0x2008u 1656
@@ -370,8 +371,9 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
   /* A8E0 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T),
   /* A8E8 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T),
   /* A8F0 */ _(Ca,T), _(Ca,T), _(Bi,x), _(Bi,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* A8F8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x), _(VI,x),  _(M,T),
 
-#define indic_offset_0xa9e0u 1720
+#define indic_offset_0xa9e0u 1728
 
 
   /* Myanmar Extended-B */
@@ -381,7 +383,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
   /* A9F0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
   /* A9F8 */ _(Nd,x), _(Nd,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(x,x),
 
-#define indic_offset_0xaa60u 1752
+#define indic_offset_0xaa60u 1760
 
 
   /* Myanmar Extended-A */
@@ -391,7 +393,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
   /* AA70 */  _(x,x),  _(C,x),  _(C,x),  _(C,x), _(CP,x), _(CP,x), _(CP,x),  _(x,x),
   /* AA78 */  _(x,x),  _(x,x),  _(C,x), _(TM,R), _(TM,T), _(TM,R),  _(C,x),  _(C,x),
 
-}; /* Table items: 1784; occupancy: 70% */
+}; /* Table items: 1792; occupancy: 70% */
 
 INDIC_TABLE_ELEMENT_TYPE
 hb_indic_get_categories (hb_codepoint_t u)
@@ -418,7 +420,7 @@ hb_indic_get_categories (hb_codepoint_t u)
       break;
 
     case 0xAu:
-      if (hb_in_range<hb_codepoint_t> (u, 0xA8E0u, 0xA8F7u)) return indic_table[u - 0xA8E0u + indic_offset_0xa8e0u];
+      if (hb_in_range<hb_codepoint_t> (u, 0xA8E0u, 0xA8FFu)) return indic_table[u - 0xA8E0u + indic_offset_0xa8e0u];
       if (hb_in_range<hb_codepoint_t> (u, 0xA9E0u, 0xA9FFu)) return indic_table[u - 0xA9E0u + indic_offset_0xa9e0u];
       if (hb_in_range<hb_codepoint_t> (u, 0xAA60u, 0xAA7Fu)) return indic_table[u - 0xAA60u + indic_offset_0xaa60u];
       break;
@@ -430,7 +432,6 @@ hb_indic_get_categories (hb_codepoint_t u)
 }
 
 #undef _
-
 #undef ISC_A
 #undef ISC_Bi
 #undef ISC_BJN
@@ -439,6 +440,7 @@ hb_indic_get_categories (hb_codepoint_t u)
 #undef ISC_CD
 #undef ISC_CF
 #undef ISC_CHL
+#undef ISC_CIP
 #undef ISC_CK
 #undef ISC_CM
 #undef ISC_CP
@@ -466,7 +468,6 @@ hb_indic_get_categories (hb_codepoint_t u)
 #undef ISC_Vo
 #undef ISC_M
 #undef ISC_VI
-
 #undef IMC_B
 #undef IMC_BL
 #undef IMC_BR
index 32ad86a..447e36c 100644 (file)
@@ -86,7 +86,7 @@ static const indic_config_t indic_configs[] =
   {HB_SCRIPT_KANNADA,  true, 0x0CCDu,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_POST_ONLY},
   {HB_SCRIPT_MALAYALAM,        true, 0x0D4Du,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA,BLWF_MODE_PRE_AND_POST},
   {HB_SCRIPT_SINHALA,  false,0x0DCAu,BASE_POS_LAST_SINHALA,
-                                                    REPH_POS_AFTER_MAIN, REPH_MODE_EXPLICIT, BLWF_MODE_PRE_AND_POST},
+                                                    REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT, BLWF_MODE_PRE_AND_POST},
 };
 
 
@@ -435,7 +435,7 @@ update_consonant_positions (const hb_ot_shape_plan_t *plan,
 
 
 /* Rules from:
- * https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx */
+ * https://docs.microsqoft.com/en-us/typography/script-development/devanagari */
 
 static void
 initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
@@ -974,7 +974,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
 
   buffer->idx = 0;
   unsigned int last_syllable = 0;
-  while (buffer->idx < buffer->len && !buffer->in_error)
+  while (buffer->idx < buffer->len && buffer->successful)
   {
     unsigned int syllable = buffer->cur().syllable();
     syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
@@ -989,7 +989,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
       /* TODO Set glyph_props? */
 
       /* Insert dottedcircle after possible Repha. */
-      while (buffer->idx < buffer->len && !buffer->in_error &&
+      while (buffer->idx < buffer->len && buffer->successful &&
             last_syllable == buffer->cur().syllable() &&
             buffer->cur().indic_category() == OT_Repha)
         buffer->next_glyph ();
@@ -1470,6 +1470,9 @@ decompose_indic (const hb_ot_shape_normalize_context_t *c,
   {
     /* Don't decompose these. */
     case 0x0931u  : return false; /* DEVANAGARI LETTER RRA */
+    // https://github.com/harfbuzz/harfbuzz/issues/779
+    case 0x09DCu  : return false; /* BENGALI LETTER RRA */
+    case 0x09DDu  : return false; /* BENGALI LETTER RHA */
     case 0x0B94u  : return false; /* TAMIL LETTER AU */
 
 
@@ -1512,7 +1515,7 @@ decompose_indic (const hb_ot_shape_normalize_context_t *c,
      * The Uniscribe behavior is now documented in the newly published Sinhala
      * spec in 2012:
      *
-     *   http://www.microsoft.com/typography/OpenTypeDev/sinhala/intro.htm#shaping
+     *   https://docs.microsoft.com/en-us/typography/script-development/sinhala#shaping
      */
 
     const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) c->plan->data;
index 380705a..d001021 100644 (file)
@@ -173,7 +173,7 @@ static const int khmer_syllable_machine_en_main = 10;
 static void
 find_syllables (hb_buffer_t *buffer)
 {
-  unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
+  unsigned int p, pe, eof, ts HB_UNUSED, te, act HB_UNUSED;
   int cs;
   hb_glyph_info_t *info = buffer->info;
   
index 8b00c37..54644d8 100644 (file)
@@ -86,7 +86,7 @@ main := |*
 static void
 find_syllables (hb_buffer_t *buffer)
 {
-  unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
+  unsigned int p, pe, eof, ts HB_UNUSED, te, act HB_UNUSED;
   int cs;
   hb_glyph_info_t *info = buffer->info;
   %%{
index 304879d..18e3c94 100644 (file)
@@ -275,7 +275,7 @@ compare_khmer_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
 
 
 /* Rules from:
- * https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx */
+ * https://docs.microsoft.com/en-us/typography/script-development/devanagari */
 
 static void
 initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
@@ -317,7 +317,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
       if ((FLAG_UNSAFE (info[i].khmer_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | FLAG (OT_Coeng))))
       {
        info[i].khmer_position() = last_pos;
-       if (unlikely (info[i].khmer_category() == OT_H &&
+       if (unlikely (info[i].khmer_category() == OT_Coeng &&
                      info[i].khmer_position() == POS_PRE_M))
        {
          /*
@@ -485,7 +485,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
 
   buffer->idx = 0;
   unsigned int last_syllable = 0;
-  while (buffer->idx < buffer->len && !buffer->in_error)
+  while (buffer->idx < buffer->len && buffer->successful)
   {
     unsigned int syllable = buffer->cur().syllable();
     syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
@@ -500,7 +500,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
       /* TODO Set glyph_props? */
 
       /* Insert dottedcircle after possible Repha. */
-      while (buffer->idx < buffer->len && !buffer->in_error &&
+      while (buffer->idx < buffer->len && buffer->successful &&
             last_syllable == buffer->cur().syllable() &&
             buffer->cur().khmer_category() == OT_Repha)
         buffer->next_glyph ();
@@ -538,7 +538,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
    * and possibly multiple substitutions happened prior to this
    * phase, and that might have messed up our properties.  Recover
    * from a particular case of that where we're fairly sure that a
-   * class of OT_H is desired but has been lost. */
+   * class of OT_Coeng is desired but has been lost. */
   if (khmer_plan->virama_glyph)
   {
     unsigned int virama_glyph = khmer_plan->virama_glyph;
@@ -548,7 +548,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
          _hb_glyph_info_multiplied (&info[i]))
       {
         /* This will make sure that this glyph passes is_coeng() test. */
-       info[i].khmer_category() = OT_H;
+       info[i].khmer_category() = OT_Coeng;
        _hb_glyph_info_clear_ligated_and_multiplied (&info[i]);
       }
   }
index 04f81bd..14d011d 100644 (file)
@@ -68,7 +68,7 @@ set_myanmar_properties (hb_glyph_info_t &info)
   indic_position_t pos = (indic_position_t) (type >> 8);
 
   /* Myanmar
-   * http://www.microsoft.com/typography/OpenTypeDev/myanmar/intro.htm#analyze
+   * https://docs.microsoft.com/en-us/typography/script-development/myanmar#analyze
    */
   if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xFE00u, 0xFE0Fu)))
     cat = (indic_category_t) OT_VS;
index 3c57bc1..e4214b8 100644 (file)
@@ -161,7 +161,7 @@ compare_myanmar_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
 
 
 /* Rules from:
- * http://www.microsoft.com/typography/OpenTypeDev/myanmar/intro.htm */
+ * https://docs.microsoft.com/en-us/typography/script-development/myanmar */
 
 static void
 initial_reordering_consonant_syllable (hb_buffer_t *buffer,
@@ -312,7 +312,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
 
   buffer->idx = 0;
   unsigned int last_syllable = 0;
-  while (buffer->idx < buffer->len && !buffer->in_error)
+  while (buffer->idx < buffer->len && buffer->successful)
   {
     unsigned int syllable = buffer->cur().syllable();
     syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
index 08b6fe9..ed6849b 100644 (file)
@@ -205,6 +205,10 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
     /* Unicode-9.0 additions */
     case HB_SCRIPT_ADLAM:
 
+    /* Unicode-11.0 additions */
+    case HB_SCRIPT_HANIFI_ROHINGYA:
+    case HB_SCRIPT_SOGDIAN:
+
       /* For Arabic script, use the Arabic shaper even if no OT script tag was found.
        * This is because we do fallback shaping for Arabic script (and not others).
        * But note that Arabic shaping is applicable only to horizontal layout; for
@@ -380,6 +384,11 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
     case HB_SCRIPT_SOYOMBO:
     case HB_SCRIPT_ZANABAZAR_SQUARE:
 
+    /* Unicode-11.0 additions */
+    case HB_SCRIPT_DOGRA:
+    case HB_SCRIPT_GUNJALA_GONDI:
+    case HB_SCRIPT_MAKASAR:
+
       /* If the designer designed the font for the 'DFLT' script,
        * (or we ended up arbitrarily pick 'latn'), use the default shaper.
        * Otherwise, use the specific shaper.
index 6ba925c..02d78ac 100644 (file)
@@ -260,7 +260,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan,
 {
   /* This function implements the shaping logic documented here:
    *
-   *   http://linux.thai.net/~thep/th-otf/shaping.html
+   *   https://linux.thai.net/~thep/th-otf/shaping.html
    *
    * The first shaping rule listed there is needed even if the font has Thai
    * OpenType tables.  The rest do fallback positioning based on PUA codepoints.
@@ -315,7 +315,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan,
 
   buffer->clear_output ();
   unsigned int count = buffer->len;
-  for (buffer->idx = 0; buffer->idx < count && !buffer->in_error;)
+  for (buffer->idx = 0; buffer->idx < count && buffer->successful;)
   {
     hb_codepoint_t u = buffer->cur().codepoint;
     if (likely (!IS_SARA_AM (u))) {
@@ -327,7 +327,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan,
     hb_codepoint_t decomposed[2] = {hb_codepoint_t (NIKHAHIT_FROM_SARA_AM (u)),
                                    hb_codepoint_t (SARA_AA_FROM_SARA_AM (u))};
     buffer->replace_glyphs (1, 2, decomposed);
-    if (unlikely (buffer->in_error))
+    if (unlikely (!buffer->successful))
       return;
 
     /* Make Nikhahit be recognized as a ccc=0 mark when zeroing widths. */
index 0bf3ad3..0ec805a 100644 (file)
@@ -331,7 +331,7 @@ static const int use_syllable_machine_en_main = 4;
 static void
 find_syllables (hb_buffer_t *buffer)
 {
-  unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
+  unsigned int p, pe, eof, ts HB_UNUSED, te, act;
   int cs;
   hb_glyph_info_t *info = buffer->info;
   
index 11fb470..7ec8a7f 100644 (file)
@@ -89,7 +89,7 @@ SMBlw = 42; # SYM_MOD_BELOW
 CS     = 43; # CONS_WITH_STACKER
 
 
-# Override: Adjoc ZWJ placement. https://github.com/harfbuzz/harfbuzz/issues/542#issuecomment-353169729
+# Override: Adhoc ZWJ placement. https://github.com/harfbuzz/harfbuzz/issues/542#issuecomment-353169729
 consonant_modifiers = CMAbv* CMBlw* ((ZWJ?.H.ZWJ? B | SUB) VS? CMAbv? CMBlw*)*;
 # Override: Allow two MBlw. https://github.com/harfbuzz/harfbuzz/issues/376
 medial_consonants = MPre? MAbv? MBlw?.MBlw? MPst?;
@@ -153,7 +153,7 @@ main := |*
 static void
 find_syllables (hb_buffer_t *buffer)
 {
-  unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
+  unsigned int p, pe, eof, ts HB_UNUSED, te, act;
   int cs;
   hb_glyph_info_t *info = buffer->info;
   %%{
index f7ded13..b4bda8b 100644 (file)
@@ -38,7 +38,7 @@
 #define USE_TABLE_ELEMENT_TYPE uint8_t
 
 /* Cateories used in the Universal Shaping Engine spec:
- * https://www.microsoft.com/typography/OpenTypeDev/USE/intro.htm
+ * https://docs.microsoft.com/en-us/typography/script-development/use
  */
 /* Note: This enum is duplicated in the -machine.rl source file.
  * Not sure how to avoid duplication. */
index 6823392..1431533 100644 (file)
@@ -6,12 +6,12 @@
  *
  * on files with these headers:
  *
- * # IndicSyllabicCategory-10.0.0.txt
- * # Date: 2017-05-31, 01:07:00 GMT [KW, RP]
- * # IndicPositionalCategory-10.0.0.txt
- * # Date: 2017-05-31, 01:07:00 GMT [RP]
- * # Blocks-10.0.0.txt
- * # Date: 2017-04-12, 17:30:00 GMT [KW]
+ * # IndicSyllabicCategory-11.0.0.txt
+ * # Date: 2018-05-21, 18:33:00 GMT [KW, RP]
+ * # IndicPositionalCategory-11.0.0.txt
+ * # Date: 2018-02-05, 16:21:00 GMT [KW, RP]
+ * # Blocks-11.0.0.txt
+ * # Date: 2017-10-16, 24:39:00 GMT [KW]
  * UnicodeData.txt does not have a header.
  */
 
@@ -97,14 +97,14 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
 
   /* Bengali */
 
-  /* 0980 */     O, VMAbv, VMPst, VMPst,     O,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     B,
+  /* 0980 */    GB, VMAbv, VMPst, VMPst,     O,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     B,
   /* 0990 */     B,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 09A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
   /* 09B0 */     B,     O,     B,     O,     O,     O,     B,     B,     B,     B,     O,     O, CMBlw,     B,  VPst,  VPre,
   /* 09C0 */  VPst,  VBlw,  VBlw,  VBlw,  VBlw,     O,     O,  VPre,  VPre,     O,     O,  VPre,  VPre,     H,   IND,     O,
   /* 09D0 */     O,     O,     O,     O,     O,     O,     O,  VPst,     O,     O,     O,     O,     B,     B,     O,     B,
   /* 09E0 */     B,     B,  VBlw,  VBlw,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 09F0 */     B,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     B,     O,     O,     O,
+  /* 09F0 */     B,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     B,     O,    FM,     O,
 
   /* Gurmukhi */
 
@@ -113,7 +113,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
   /* 0A20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
   /* 0A30 */     B,     O,     B,     B,     O,     B,     B,     O,     B,     B,     O,     O, CMBlw,     O,  VPst,  VPre,
   /* 0A40 */  VPst,  VBlw,  VBlw,     O,     O,     O,     O,  VAbv,  VAbv,     O,     O,  VAbv,  VAbv,     H,     O,     O,
-  /* 0A50 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     B,     B,     B,     B,     O,     B,     O,
+  /* 0A50 */     O, VMBlw,     O,     O,     O,     O,     O,     O,     O,     B,     B,     B,     B,     O,     B,     O,
   /* 0A60 */     O,     O,     O,     O,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 0A70 */ VMAbv, CMAbv,    GB,    GB,     O,  MBlw,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
 
@@ -152,7 +152,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
 
   /* Telugu */
 
-  /* 0C00 */ VMAbv, VMPst, VMPst, VMPst,     O,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,
+  /* 0C00 */ VMAbv, VMPst, VMPst, VMPst, VMAbv,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,
   /* 0C10 */     B,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 0C20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
   /* 0C30 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     B,  VAbv,  VAbv,
@@ -203,7 +203,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
   /* 1010 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1020 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,  VPst,  VPst,  VAbv,  VAbv,  VBlw,
   /* 1030 */  VBlw,  VPre,  VAbv,  VAbv,  VAbv,  VAbv, VMAbv, VMBlw, VMPst,     H,  VAbv,  MPst,  MPre,  MBlw,  MBlw,     B,
-  /* 1040 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,    GB,     O,
+  /* 1040 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,    GB,     O,     O,    GB,     O,
   /* 1050 */     B,     B,     B,     B,     B,     B,  VPst,  VPst,  VBlw,  VBlw,     B,     B,     B,     B,  MBlw,  MBlw,
   /* 1060 */  MBlw,     B,  VPst, VMPst, VMPst,     B,     B,  VPst,  VPst, VMPst, VMPst, VMPst, VMPst, VMPst,     B,     B,
   /* 1070 */     B,  VAbv,  VAbv,  VAbv,  VAbv,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
@@ -330,7 +330,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
 
   /* 1CD0 */ VMAbv, VMAbv, VMAbv,     O, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMAbv, VMAbv, VMBlw, VMBlw, VMBlw, VMBlw,
   /* 1CE0 */ VMAbv, VMPst, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw,     O,     O,     O,     O, VMBlw,     O,     O,
-  /* 1CF0 */     O,     O, VMPst, VMPst, VMAbv,     O,     O, VMPst, VMAbv, VMAbv,     O,     O,     O,     O,     O,     O,
+  /* 1CF0 */     O,     O, VMPst, VMPst, VMAbv,    CS,    CS, VMPst, VMAbv, VMAbv,     O,     O,     O,     O,     O,     O,
 
 #define use_offset_0x1df8u 2560
 
@@ -396,7 +396,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
   /* Devanagari Extended */
 
   /* A8E0 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,
-  /* A8F0 */ VMAbv, VMAbv,     B,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* A8F0 */ VMAbv, VMAbv,     B,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     B,  VAbv,
 
   /* Kayah Li */
 
@@ -479,10 +479,10 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
   /* 10A00 */     B,  VBlw,  VBlw,  VBlw,     O,  VAbv,  VBlw,     O,     O,     O,     O,     O,  VBlw,  VBlw, VMBlw, VMAbv,
   /* 10A10 */     B,     B,     B,     B,     O,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,     B,
   /* 10A20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 10A30 */     B,     B,     B,     B,     O,     O,     O,     O, CMAbv, CMBlw, CMBlw,     O,     O,     O,     O,     H,
-  /* 10A40 */     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 10A30 */     B,     B,     B,     B,     B,     B,     O,     O, CMAbv, CMBlw, CMBlw,     O,     O,     O,     O,     H,
+  /* 10A40 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,     O,
 
-#define use_offset_0x11000u 3552
+#define use_offset_0x11000u 3560
 
 
   /* Brahmi */
@@ -503,7 +503,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
   /* 110A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 110B0 */  VPst,  VPre,  VPst,  VBlw,  VBlw,  VAbv,  VAbv,  VPst,  VPst,     H, CMBlw,     O,     O,     O,     O,     O,
 
-#define use_offset_0x11100u 3744
+#define use_offset_0x11100u 3752
 
 
   /* Chakma */
@@ -512,7 +512,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
   /* 11110 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11120 */     B,     B,     B,     B,     B,     B,     B,  VAbv,  VAbv,  VAbv,  VBlw,  VBlw,  VPre,  VAbv,  VAbv,  VAbv,
   /* 11130 */  VAbv,  VBlw,  VBlw,     H,  VAbv,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 11140 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 11140 */     O,     O,     O,     O,     B,  VPst,  VPst,     O,     O,     O,     O,     O,     O,     O,     O,     O,
 
   /* Mahajani */
 
@@ -526,7 +526,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
   /* 11190 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 111A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 111B0 */     B,     B,     B,  VPst,  VPre,  VPst,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv,
-  /* 111C0 */     H,     B,     R,     R,     O,     O,     O,     O,     O,     O, CMBlw,  VAbv,  VBlw,     O,     O,     O,
+  /* 111C0 */     H,     B,     R,     R,     O,     O,     O,     O,     O,    FM, CMBlw,  VAbv,  VBlw,     O,     O,     O,
   /* 111D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
 
   /* Sinhala Archaic Numbers */
@@ -541,7 +541,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
   /* 11220 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,  VPst,  VPst,  VPst,  VBlw,
   /* 11230 */  VAbv,  VAbv,  VAbv,  VAbv, VMAbv,     H, CMAbv, CMAbv,     O,     O,     O,     O,     O,     O, VMAbv,     O,
 
-#define use_offset_0x11280u 4064
+#define use_offset_0x11280u 4072
 
 
   /* Multani */
@@ -563,13 +563,13 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
   /* 11300 */ VMAbv, VMAbv, VMPst, VMPst,     O,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     B,
   /* 11310 */     B,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11320 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
-  /* 11330 */     B,     O,     B,     B,     O,     B,     B,     B,     B,     B,     O,     O, CMBlw,     B,  VPst,  VPst,
+  /* 11330 */     B,     O,     B,     B,     O,     B,     B,     B,     B,     B,     O, CMBlw, CMBlw,     B,  VPst,  VPst,
   /* 11340 */  VAbv,  VPst,  VPst,  VPst,  VPst,     O,     O,  VPre,  VPre,     O,     O,  VPre,  VPre,     H,     O,     O,
   /* 11350 */     O,     O,     O,     O,     O,     O,     O,  VPst,     O,     O,     O,     O,     O,     O,     B,     B,
   /* 11360 */     B,     B,  VPst,  VPst,     O,     O, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,     O,     O,     O,
   /* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,     O,     O,     O,
 
-#define use_offset_0x11400u 4312
+#define use_offset_0x11400u 4320
 
 
   /* Newa */
@@ -579,7 +579,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
   /* 11420 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11430 */     B,     B,     B,     B,     B,  VPst,  VPre,  VPst,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VAbv,  VAbv,
   /* 11440 */  VPst,  VPst,     H, VMAbv, VMAbv, VMPst, CMBlw,     B,     O,     O,     O,     O,     O,     O,     O,     O,
-  /* 11450 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
+  /* 11450 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,    FM,     O,
   /* 11460 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 11470 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
 
@@ -592,7 +592,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
   /* 114C0 */ VMAbv, VMPst,     H, CMBlw,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 114D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
 
-#define use_offset_0x11580u 4536
+#define use_offset_0x11580u 4544
 
 
   /* Siddham */
@@ -631,11 +631,21 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
   /* Ahom */
 
   /* 11700 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 11710 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,  MBlw,  MPre,  MAbv,
+  /* 11710 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,  MBlw,  MPre,  MAbv,
   /* 11720 */  VPst,  VPst,  VAbv,  VAbv,  VBlw,  VBlw,  VPre,  VAbv,  VBlw,  VAbv,  VAbv,  VAbv,     O,     O,     O,     O,
   /* 11730 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,
 
-#define use_offset_0x11a00u 4984
+#define use_offset_0x11800u 4992
+
+
+  /* Dogra */
+
+  /* 11800 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11810 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11820 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,  VPst,  VPre,  VPst,  VBlw,
+  /* 11830 */  VBlw,  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv, VMAbv, VMPst,     H, CMBlw,     O,     O,     O,     O,     O,
+
+#define use_offset_0x11a00u 5056
 
 
   /* Zanabazar Square */
@@ -652,9 +662,9 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
   /* 11A60 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11A70 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11A80 */     B,     B,     B,     B,     O,     O,     R,     R,     R,     R,  FBlw,  FBlw,  FBlw,  FBlw,  FBlw,  FBlw,
-  /* 11A90 */  FBlw,  FBlw,  FBlw,  FBlw,  FBlw,  FBlw, VMAbv, VMPst, CMAbv,     H,     O,     O,     O,     O,     O,     O,
+  /* 11A90 */  FBlw,  FBlw,  FBlw,  FBlw,  FBlw,  FBlw, VMAbv, VMPst, CMAbv,     H,     O,     O,     O,     B,     O,     O,
 
-#define use_offset_0x11c00u 5144
+#define use_offset_0x11c00u 5216
 
 
   /* Bhaiksuki */
@@ -675,7 +685,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
   /* 11CA0 */   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,     O,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,
   /* 11CB0 */  VBlw,  VPre,  VBlw,  VAbv,  VPst, VMAbv, VMAbv,     O,
 
-#define use_offset_0x11d00u 5328
+#define use_offset_0x11d00u 5400
 
 
   /* Masaram Gondi */
@@ -687,7 +697,23 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
   /* 11D40 */ VMAbv, VMAbv, CMBlw,  VAbv,  VBlw,     H,     R,  MBlw,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 11D50 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
 
-}; /* Table items: 5424; occupancy: 73% */
+  /* Gunjala Gondi */
+
+  /* 11D60 */     B,     B,     B,     B,     B,     B,     O,     B,     B,     O,     B,     B,     B,     B,     B,     B,
+  /* 11D70 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11D80 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,  VPst,  VPst,  VPst,  VPst,  VPst,     O,
+  /* 11D90 */  VAbv,  VAbv,     O,  VPst,  VPst, VMAbv, VMPst,     H,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 11DA0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
+
+#define use_offset_0x11ee0u 5576
+
+
+  /* Makasar */
+
+  /* 11EE0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11EF0 */     B,     B,    GB,  VAbv,  VBlw,  VPre,  VPst,     O,
+
+}; /* Table items: 5600; occupancy: 73% */
 
 USE_TABLE_ELEMENT_TYPE
 hb_use_get_category (hb_codepoint_t u)
@@ -727,7 +753,7 @@ hb_use_get_category (hb_codepoint_t u)
       break;
 
     case 0x10u:
-      if (hb_in_range<hb_codepoint_t> (u, 0x10A00u, 0x10A47u)) return use_table[u - 0x10A00u + use_offset_0x10a00u];
+      if (hb_in_range<hb_codepoint_t> (u, 0x10A00u, 0x10A4Fu)) return use_table[u - 0x10A00u + use_offset_0x10a00u];
       break;
 
     case 0x11u:
@@ -736,9 +762,11 @@ hb_use_get_category (hb_codepoint_t u)
       if (hb_in_range<hb_codepoint_t> (u, 0x11280u, 0x11377u)) return use_table[u - 0x11280u + use_offset_0x11280u];
       if (hb_in_range<hb_codepoint_t> (u, 0x11400u, 0x114DFu)) return use_table[u - 0x11400u + use_offset_0x11400u];
       if (hb_in_range<hb_codepoint_t> (u, 0x11580u, 0x1173Fu)) return use_table[u - 0x11580u + use_offset_0x11580u];
+      if (hb_in_range<hb_codepoint_t> (u, 0x11800u, 0x1183Fu)) return use_table[u - 0x11800u + use_offset_0x11800u];
       if (hb_in_range<hb_codepoint_t> (u, 0x11A00u, 0x11A9Fu)) return use_table[u - 0x11A00u + use_offset_0x11a00u];
       if (hb_in_range<hb_codepoint_t> (u, 0x11C00u, 0x11CB7u)) return use_table[u - 0x11C00u + use_offset_0x11c00u];
-      if (hb_in_range<hb_codepoint_t> (u, 0x11D00u, 0x11D5Fu)) return use_table[u - 0x11D00u + use_offset_0x11d00u];
+      if (hb_in_range<hb_codepoint_t> (u, 0x11D00u, 0x11DAFu)) return use_table[u - 0x11D00u + use_offset_0x11d00u];
+      if (hb_in_range<hb_codepoint_t> (u, 0x11EE0u, 0x11EF7u)) return use_table[u - 0x11EE0u + use_offset_0x11ee0u];
       break;
 
     default:
index ee7653b..66b9571 100644 (file)
@@ -35,7 +35,7 @@
 
 /*
  * Universal Shaping Engine.
- * https://www.microsoft.com/typography/OpenTypeDev/USE/intro.htm
+ * https://docs.microsoft.com/en-us/typography/script-development/use
  */
 
 static const hb_tag_t
@@ -511,7 +511,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
 
   buffer->idx = 0;
   unsigned int last_syllable = 0;
-  while (buffer->idx < buffer->len && !buffer->in_error)
+  while (buffer->idx < buffer->len && buffer->successful)
   {
     unsigned int syllable = buffer->cur().syllable();
     syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
@@ -526,7 +526,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
       /* TODO Set glyph_props? */
 
       /* Insert dottedcircle after possible Repha. */
-      while (buffer->idx < buffer->len && !buffer->in_error &&
+      while (buffer->idx < buffer->len && buffer->successful &&
             last_syllable == buffer->cur().syllable() &&
             buffer->cur().use_category() == USE_R)
         buffer->next_glyph ();
index c7b4605..fbf31ab 100644 (file)
@@ -548,7 +548,7 @@ _hb_ot_shape_fallback_spaces (const hb_ot_shape_plan_t *plan,
 
        case t::SPACE_NARROW:
          /* Half-space?
-          * Unicode doc http://www.unicode.org/charts/PDF/U2000.pdf says ~1/4 or 1/5 of EM.
+          * Unicode doc https://unicode.org/charts/PDF/U2000.pdf says ~1/4 or 1/5 of EM.
           * However, in my testing, many fonts have their regular space being about that
           * size.  To me, a percentage of the space width makes more sense.  Half is as
           * good as any. */
index 62cbb9d..358450e 100644 (file)
@@ -119,7 +119,7 @@ skip_char (hb_buffer_t *buffer)
 static inline unsigned int
 decompose (const hb_ot_shape_normalize_context_t *c, bool shortest, hb_codepoint_t ab)
 {
-  hb_codepoint_t a, b, a_glyph, b_glyph;
+  hb_codepoint_t a = 0, b = 0, a_glyph = 0, b_glyph = 0;
   hb_buffer_t * const buffer = c->buffer;
   hb_font_t * const font = c->font;
 
@@ -164,7 +164,7 @@ decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shor
 {
   hb_buffer_t * const buffer = c->buffer;
   hb_codepoint_t u = buffer->cur().codepoint;
-  hb_codepoint_t glyph;
+  hb_codepoint_t glyph = 0;
 
   if (shortest && c->font->get_nominal_glyph (u, &glyph))
   {
@@ -218,7 +218,7 @@ handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, uns
   /* TODO Currently if there's a variation-selector we give-up, it's just too hard. */
   hb_buffer_t * const buffer = c->buffer;
   hb_font_t * const font = c->font;
-  for (; buffer->idx < end - 1 && !buffer->in_error;) {
+  for (; buffer->idx < end - 1 && buffer->successful;) {
     if (unlikely (buffer->unicode->is_variation_selector (buffer->cur(+1).codepoint))) {
       /* The next two lines are some ugly lines... But work. */
       if (font->get_variation_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index()))
@@ -254,13 +254,13 @@ static inline void
 decompose_multi_char_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end, bool short_circuit)
 {
   hb_buffer_t * const buffer = c->buffer;
-  for (unsigned int i = buffer->idx; i < end && !buffer->in_error; i++)
+  for (unsigned int i = buffer->idx; i < end && buffer->successful; i++)
     if (unlikely (buffer->unicode->is_variation_selector (buffer->info[i].codepoint))) {
       handle_variation_selector_cluster (c, end, short_circuit);
       return;
     }
 
-  while (buffer->idx < end && !buffer->in_error)
+  while (buffer->idx < end && buffer->successful)
     decompose_current_character (c, short_circuit);
 }
 
@@ -320,7 +320,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
 
   buffer->clear_output ();
   count = buffer->len;
-  for (buffer->idx = 0; buffer->idx < count && !buffer->in_error;)
+  for (buffer->idx = 0; buffer->idx < count && buffer->successful;)
   {
     unsigned int end;
     for (end = buffer->idx + 1; end < count; end++)
@@ -373,7 +373,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
   count = buffer->len;
   unsigned int starter = 0;
   buffer->next_glyph ();
-  while (buffer->idx < count && !buffer->in_error)
+  while (buffer->idx < count && buffer->successful)
   {
     hb_codepoint_t composed, glyph;
     if (/* We don't try to compose a non-mark character with it's preceding starter.
@@ -396,7 +396,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
       {
        /* Composes. */
        buffer->next_glyph (); /* Copy to out-buffer. */
-       if (unlikely (buffer->in_error))
+       if (unlikely (!buffer->successful))
          return;
        buffer->merge_out_clusters (starter, buffer->out_len);
        buffer->out_len--; /* Remove the second composable. */
index fe5d2b7..d689826 100644 (file)
@@ -59,7 +59,14 @@ struct hb_ot_shape_plan_t
   inline void substitute (hb_font_t *font, hb_buffer_t *buffer) const { map.substitute (this, font, buffer); }
   inline void position (hb_font_t *font, hb_buffer_t *buffer) const { map.position (this, font, buffer); }
 
-  void finish (void) { map.finish (); }
+  void init (void)
+  {
+    memset (this, 0, sizeof (*this));
+    map.init ();
+  }
+  void fini (void) {
+    map.fini ();
+  }
 };
 
 struct hb_ot_shape_planner_t
@@ -75,7 +82,6 @@ struct hb_ot_shape_planner_t
                         props (master_plan->props),
                         shaper (nullptr),
                         map (face, &props) {}
-  ~hb_ot_shape_planner_t (void) { map.finish (); }
 
   inline void compile (hb_ot_shape_plan_t &plan,
                       const int          *coords,
@@ -99,9 +105,7 @@ struct hb_ot_shape_planner_t
   }
 
   private:
-  /* No copy. */
-  hb_ot_shape_planner_t (const hb_ot_shape_planner_t &);
-  hb_ot_shape_planner_t &operator = (const hb_ot_shape_planner_t &);
+  HB_DISALLOW_COPY_AND_ASSIGN (hb_ot_shape_planner_t);
 };
 
 
index 263d65c..36e0bf9 100644 (file)
@@ -180,6 +180,8 @@ _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t    *shape_plan,
   if (unlikely (!plan))
     return nullptr;
 
+  plan->init ();
+
   hb_ot_shape_planner_t planner (shape_plan);
 
   planner.shaper = hb_ot_shape_complex_categorize (&planner);
@@ -204,7 +206,7 @@ _hb_ot_shaper_shape_plan_data_destroy (hb_ot_shaper_shape_plan_data_t *plan)
   if (plan->shaper->data_destroy)
     plan->shaper->data_destroy (const_cast<void *> (plan->data));
 
-  plan->finish ();
+  plan->fini ();
 
   free (plan);
 }
@@ -268,7 +270,7 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font)
   info.cluster = buffer->cur().cluster;
   info.mask = buffer->cur().mask;
   buffer->output_info (info);
-  while (buffer->idx < buffer->len && !buffer->in_error)
+  while (buffer->idx < buffer->len && buffer->successful)
     buffer->next_glyph ();
 
   buffer->swap_buffers ();
@@ -306,13 +308,16 @@ static void
 hb_ensure_native_direction (hb_buffer_t *buffer)
 {
   hb_direction_t direction = buffer->props.direction;
+  hb_direction_t horiz_dir = hb_script_get_horizontal_direction (buffer->props.script);
 
   /* TODO vertical:
    * The only BTT vertical script is Ogham, but it's not clear to me whether OpenType
    * Ogham fonts are supposed to be implemented BTT or not.  Need to research that
    * first. */
-  if ((HB_DIRECTION_IS_HORIZONTAL (direction) && direction != hb_script_get_horizontal_direction (buffer->props.script)) ||
-      (HB_DIRECTION_IS_VERTICAL   (direction) && direction != HB_DIRECTION_TTB))
+  if ((HB_DIRECTION_IS_HORIZONTAL (direction) &&
+       direction != horiz_dir && horiz_dir != HB_DIRECTION_INVALID) ||
+      (HB_DIRECTION_IS_VERTICAL   (direction) &&
+       direction != HB_DIRECTION_TTB))
   {
     /* Same loop as hb_form_clusters().
      * Since form_clusters() merged clusters already, we don't merge. */
@@ -939,8 +944,6 @@ hb_ot_shape_glyphs_closure (hb_font_t          *font,
                            unsigned int        num_features,
                            hb_set_t           *glyphs)
 {
-  hb_ot_shape_plan_t plan;
-
   const char *shapers[] = {"ot", nullptr};
   hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props,
                                                             features, num_features, shapers);
@@ -954,15 +957,7 @@ hb_ot_shape_glyphs_closure (hb_font_t          *font,
 
   hb_set_t *lookups = hb_set_create ();
   hb_ot_shape_plan_collect_lookups (shape_plan, HB_OT_TAG_GSUB, lookups);
-
-  /* And find transitive closure. */
-  hb_set_t *copy = hb_set_create ();
-  do {
-    copy->set (glyphs);
-    for (hb_codepoint_t lookup_index = HB_SET_VALUE_INVALID; hb_set_next (lookups, &lookup_index);)
-      hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs);
-  } while (!copy->is_equal (glyphs));
-  hb_set_destroy (copy);
+  hb_ot_layout_lookups_substitute_closure (font->face, lookups, glyphs);
 
   hb_set_destroy (lookups);
 
index 1338c31..991d8e7 100644 (file)
@@ -116,8 +116,7 @@ hb_ot_new_tag_to_script (hb_tag_t tag)
 
 /*
  * Complete list at:
- * https://www.microsoft.com/typography/otspec/scripttags.htm
- * https://www.microsoft.com/typography/otspec160/scripttagsProposed.htm
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/scripttags
  *
  * Most of the script tags are the same as the ISO 15924 tag but lowercased.
  * So we just do that, and handle the exceptional cases in a switch.
@@ -159,7 +158,7 @@ typedef struct {
 
 /*
  * Complete list at:
- * http://www.microsoft.com/typography/otspec/languagetags.htm
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/languagetags
  *
  * Generated by intersecting the OpenType language tag list from
  * Draft OpenType 1.5 spec, with with the ISO 639-3 codes from
@@ -176,7 +175,7 @@ typedef struct {
  * Updated as of 2015-05-06: OT1.7 on MS website has some newer
  * items that we don't have here, eg. Zazaki.  This is the new
  * items in OpenType 1.7 (red items), most of which we have:
- * http://www.microsoft.com/typography/otspec170/languagetags.htm
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/languagetags
  */
 
 static const LangTag ot_languages[] = {
@@ -1010,7 +1009,7 @@ hb_ot_tag_from_language (hb_language_t language)
 /**
  * hb_ot_tag_to_language:
  *
- * 
+ *
  *
  * Return value: (transfer none):
  *
index e305a67..ad063d3 100644 (file)
 
 #include "hb-open-type-private.hh"
 
+/*
+ * avar -- Axis Variations
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/avar
+ */
+
+#define HB_OT_TAG_avar HB_TAG('a','v','a','r')
+
+
 namespace OT {
 
 
@@ -62,38 +70,32 @@ struct SegmentMaps : ArrayOf<AxisValueMap>
       if (!len)
        return value;
       else /* len == 1*/
-       return value - array[0].fromCoord + array[0].toCoord;
+       return value - arrayZ[0].fromCoord + arrayZ[0].toCoord;
     }
 
-    if (value <= array[0].fromCoord)
-      return value - array[0].fromCoord + array[0].toCoord;
+    if (value <= arrayZ[0].fromCoord)
+      return value - arrayZ[0].fromCoord + arrayZ[0].toCoord;
 
     unsigned int i;
     unsigned int count = len;
-    for (i = 1; i < count && value > array[i].fromCoord; i++)
+    for (i = 1; i < count && value > arrayZ[i].fromCoord; i++)
       ;
 
-    if (value >= array[i].fromCoord)
-      return value - array[i].fromCoord + array[i].toCoord;
+    if (value >= arrayZ[i].fromCoord)
+      return value - arrayZ[i].fromCoord + arrayZ[i].toCoord;
 
-    if (unlikely (array[i-1].fromCoord == array[i].fromCoord))
-      return array[i-1].toCoord;
+    if (unlikely (arrayZ[i-1].fromCoord == arrayZ[i].fromCoord))
+      return arrayZ[i-1].toCoord;
 
-    int denom = array[i].fromCoord - array[i-1].fromCoord;
-    return array[i-1].toCoord +
-          ((array[i].toCoord - array[i-1].toCoord) *
-           (value - array[i-1].fromCoord) + denom/2) / denom;
+    int denom = arrayZ[i].fromCoord - arrayZ[i-1].fromCoord;
+    return arrayZ[i-1].toCoord +
+          ((arrayZ[i].toCoord - arrayZ[i-1].toCoord) *
+           (value - arrayZ[i-1].fromCoord) + denom/2) / denom;
   }
 
-  DEFINE_SIZE_ARRAY (2, array);
+  DEFINE_SIZE_ARRAY (2, arrayZ);
 };
 
-/*
- * avar — Axis Variations Table
- */
-
-#define HB_OT_TAG_avar HB_TAG('a','v','a','r')
-
 struct avar
 {
   static const hb_tag_t tableTag       = HB_OT_TAG_avar;
@@ -106,7 +108,7 @@ struct avar
                    c->check_struct (this))))
       return_trace (false);
 
-    const SegmentMaps *map = &axisSegmentMapsZ;
+    const SegmentMaps *map = axisSegmentMapsZ;
     unsigned int count = axisCount;
     for (unsigned int i = 0; i < count; i++)
     {
@@ -122,7 +124,7 @@ struct avar
   {
     unsigned int count = MIN<unsigned int> (coords_length, axisCount);
 
-    const SegmentMaps *map = &axisSegmentMapsZ;
+    const SegmentMaps *map = axisSegmentMapsZ;
     for (unsigned int i = 0; i < count; i++)
     {
       coords[i] = map->map (coords[i]);
@@ -137,7 +139,7 @@ struct avar
   HBUINT16     axisCount;      /* The number of variation axes in the font. This
                                 * must be the same number as axisCount in the
                                 * 'fvar' table. */
-  SegmentMaps  axisSegmentMapsZ;
+  SegmentMaps  axisSegmentMapsZ[VAR];
 
   public:
   DEFINE_SIZE_MIN (8);
index 999b723..82d2996 100644 (file)
 
 #include "hb-open-type-private.hh"
 
+/*
+ * fvar -- Font Variations
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/fvar
+ */
+
+#define HB_OT_TAG_fvar HB_TAG('f','v','a','r')
+
+
 namespace OT {
 
 
@@ -42,11 +50,11 @@ struct InstanceRecord
   }
 
   protected:
-  HBUINT16     subfamilyNameID;/* The name ID for entries in the 'name' table
+  NameID       subfamilyNameID;/* The name ID for entries in the 'name' table
                                 * that provide subfamily names for this instance. */
   HBUINT16     reserved;       /* Reserved for future use — set to 0. */
   Fixed                coordinates[VAR];/* The coordinates array for this instance. */
-  //HBUINT16   postScriptNameIDX;/*Optional. The name ID for entries in the 'name'
+  //NameID     postScriptNameIDX;/*Optional. The name ID for entries in the 'name'
   //                             * table that provide PostScript names for this
   //                             * instance. */
 
@@ -68,20 +76,13 @@ struct AxisRecord
   Fixed                defaultValue;   /* The default coordinate value for the axis. */
   Fixed                maxValue;       /* The maximum coordinate value for the axis. */
   HBUINT16     reserved;       /* Reserved for future use — set to 0. */
-  HBUINT16     axisNameID;     /* The name ID for entries in the 'name' table that
+  NameID       axisNameID;     /* The name ID for entries in the 'name' table that
                                 * provide a display name for this axis. */
 
   public:
   DEFINE_SIZE_STATIC (20);
 };
 
-
-/*
- * fvar — Font Variations Table
- */
-
-#define HB_OT_TAG_fvar HB_TAG('f','v','a','r')
-
 struct fvar
 {
   static const hb_tag_t tableTag       = HB_OT_TAG_fvar;
index e20131b..2b384db 100644 (file)
@@ -89,10 +89,11 @@ struct DeltaSetIndexMap
 
 
 /*
- * HVAR -- The Horizontal Metrics Variations Table
- * VVAR -- The Vertical Metrics Variations Table
+ * HVAR -- Horizontal Metrics Variations
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/hvar
+ * VVAR -- Vertical Metrics Variations
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/vvar
  */
-
 #define HB_OT_TAG_HVAR HB_TAG('H','V','A','R')
 #define HB_OT_TAG_VVAR HB_TAG('V','V','A','R')
 
index e835768..dfde782 100644 (file)
@@ -51,9 +51,9 @@ struct VariationValueRecord
 
 
 /*
- * MVAR -- Metrics Variations Table
+ * MVAR -- Metrics Variations
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/mvar
  */
-
 #define HB_OT_TAG_MVAR HB_TAG('M','V','A','R')
 
 struct MVAR
index 90ba0bd..f0612a6 100644 (file)
 static inline const OT::fvar&
 _get_fvar (hb_face_t *face)
 {
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::fvar);
+  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::fvar);
   hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
   return *(layout->fvar.get ());
 }
 static inline const OT::avar&
 _get_avar (hb_face_t *face)
 {
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::avar);
+  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::avar);
   hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
   return *(layout->avar.get ());
 }
@@ -65,7 +65,7 @@ _get_avar (hb_face_t *face)
 hb_bool_t
 hb_ot_var_has_data (hb_face_t *face)
 {
-  return &_get_fvar (face) != &OT::Null(OT::fvar);
+  return &_get_fvar (face) != &Null(OT::fvar);
 }
 
 /**
index daa496e..32e3354 100644 (file)
@@ -51,7 +51,7 @@
 #include <stdio.h>
 #include <stdarg.h>
 
-#if defined(_MSC_VER) || defined(__MINGW32__)
+#if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__)
 #include <intrin.h>
 #endif
 
@@ -90,6 +90,14 @@ extern "C" void  hb_free_impl(void *ptr);
        HB_UNUSED typedef int HB_PASTE(static_assertion_failed_at_line_, __LINE__) [(e) ? 1 : -1]
 #endif // static_assert
 
+#ifdef __GNUC__
+#if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8))
+#define thread_local __thread
+#endif
+#else
+#define thread_local
+#endif
+
 #endif // __cplusplus < 201103L
 
 #if (defined(__GNUC__) || defined(__clang__)) && defined(__OPTIMIZE__)
@@ -139,7 +147,7 @@ extern "C" void  hb_free_impl(void *ptr);
 #define HB_FUNC __func__
 #endif
 
-#ifdef __SUNPRO_CC
+#if defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x5140)
 /* https://github.com/harfbuzz/harfbuzz/issues/630 */
 #define __restrict
 #endif
@@ -221,16 +229,14 @@ static int errno = 0; /* Use something better? */
 #    endif
 #  elif defined(_MSC_VER) || defined(__MINGW32__)
 /* For MSVC:
- * http://msdn.microsoft.com/en-ca/library/tze57ck3.aspx
- * http://msdn.microsoft.com/en-ca/library/zk17ww08.aspx
+ * https://msdn.microsoft.com/en-us/library/tze57ck3.aspx
+ * https://msdn.microsoft.com/en-us/library/zk17ww08.aspx
  * mingw32 headers say atexit is safe to use in shared libraries.
  */
 #    define HB_USE_ATEXIT 1
-#  elif defined(__ANDROID__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
-/* This was fixed in Android NKD r8 or r8b:
- * https://code.google.com/p/android/issues/detail?id=6455
- * which introduced GCC 4.6:
- * https://developer.android.com/tools/sdk/ndk/index.html
+#  elif defined(__ANDROID__)
+/* This is available since Android NKD r8 or r8b:
+ * https://issuetracker.google.com/code/p/android/issues/detail?id=6455
  */
 #    define HB_USE_ATEXIT 1
 #  elif defined(__APPLE__)
@@ -241,6 +247,9 @@ static int errno = 0; /* Use something better? */
 #    define HB_USE_ATEXIT 1
 #  endif
 #endif
+#ifdef HB_NO_ATEXIT
+#  undef HB_USE_ATEXIT
+#endif
 
 /* Basics */
 
@@ -314,7 +323,7 @@ static_assert ((sizeof (hb_var_int_t) == 4), "");
 
 
 
-/* Misc */
+/* Tiny functions */
 
 /*
  * Void!
@@ -360,6 +369,7 @@ _hb_popcount (T v)
   }
 
   assert (0);
+  return 0; /* Shut up stupid compiler. */
 }
 
 /* Returns the number of bits needed to store number */
@@ -380,7 +390,7 @@ _hb_bit_storage (T v)
     return sizeof (unsigned long long) * 8 - __builtin_clzll (v);
 #endif
 
-#if defined(_MSC_VER) || defined(__MINGW32__)
+#if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__)
   if (sizeof (T) <= sizeof (unsigned int))
   {
     unsigned long where;
@@ -414,7 +424,7 @@ _hb_bit_storage (T v)
   if (sizeof (T) <= 8)
   {
     /* "bithacks" */
-    const uint64_t b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000, 0xFFFFFFFF00000000};
+    const uint64_t b[] = {0x2ULL, 0xCULL, 0xF0ULL, 0xFF00ULL, 0xFFFF0000ULL, 0xFFFFFFFF00000000ULL};
     const unsigned int S[] = {1, 2, 4, 8, 16, 32};
     unsigned int r = 0;
     for (int i = 5; i >= 0; i--)
@@ -428,11 +438,12 @@ _hb_bit_storage (T v)
   if (sizeof (T) == 16)
   {
     unsigned int shift = 64;
-    return (v >> shift) ? _hb_bit_storage<uint64_t> ((uint64_t) v >> shift) + shift :
+    return (v >> shift) ? _hb_bit_storage<uint64_t> ((uint64_t) (v >> shift)) + shift :
                          _hb_bit_storage<uint64_t> ((uint64_t) v);
   }
 
   assert (0);
+  return 0; /* Shut up stupid compiler. */
 }
 
 /* Returns the number of zero bits in the least significant side of v */
@@ -453,7 +464,7 @@ _hb_ctz (T v)
     return __builtin_ctzll (v);
 #endif
 
-#if defined(_MSC_VER) || defined(__MINGW32__)
+#if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__)
   if (sizeof (T) <= sizeof (unsigned int))
   {
     unsigned long where;
@@ -489,12 +500,12 @@ _hb_ctz (T v)
     unsigned int c = 64;
     v &= - (int64_t) (v);
     if (v) c--;
-    if (v & 0x00000000FFFFFFFF) c -= 32;
-    if (v & 0x0000FFFF0000FFFF) c -= 16;
-    if (v & 0x00FF00FF00FF00FF) c -= 8;
-    if (v & 0x0F0F0F0F0F0F0F0F) c -= 4;
-    if (v & 0x3333333333333333) c -= 2;
-    if (v & 0x5555555555555555) c -= 1;
+    if (v & 0x00000000FFFFFFFFULL) c -= 32;
+    if (v & 0x0000FFFF0000FFFFULL) c -= 16;
+    if (v & 0x00FF00FF00FF00FFULL) c -= 8;
+    if (v & 0x0F0F0F0F0F0F0F0FULL) c -= 4;
+    if (v & 0x3333333333333333ULL) c -= 2;
+    if (v & 0x5555555555555555ULL) c -= 1;
     return c;
   }
   if (sizeof (T) == 16)
@@ -505,6 +516,7 @@ _hb_ctz (T v)
   }
 
   assert (0);
+  return 0; /* Shut up stupid compiler. */
 }
 
 static inline bool
@@ -521,39 +533,147 @@ _hb_ceil_to_4 (unsigned int v)
 
 
 
+/*
+ *
+ * Utility types
+ *
+ */
+
+#define HB_DISALLOW_COPY_AND_ASSIGN(TypeName) \
+  TypeName(const TypeName&); \
+  void operator=(const TypeName&)
+
+/*
+ * Static pools
+ */
+
+/* Global nul-content Null pool.  Enlarge as necessary. */
+
+#define HB_NULL_POOL_SIZE 264
+static_assert (HB_NULL_POOL_SIZE % sizeof (void *) == 0, "Align HB_NULL_POOL_SIZE.");
+
+#ifdef HB_NO_VISIBILITY
+static
+#else
+extern HB_INTERNAL
+#endif
+void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)]
+#ifdef HB_NO_VISIBILITY
+= {}
+#endif
+;
+/* Generic nul-content Null objects. */
+template <typename Type>
+static inline Type const & Null (void) {
+  static_assert (sizeof (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE.");
+  return *reinterpret_cast<Type const *> (_hb_NullPool);
+}
+#define Null(Type) Null<Type>()
+
+/* Specializaiton for arbitrary-content arbitrary-sized Null objects. */
+#define DEFINE_NULL_DATA(Namespace, Type, data) \
+} /* Close namespace. */ \
+static const char _Null##Type[sizeof (Namespace::Type) + 1] = data; /* +1 is for nul-termination in data */ \
+template <> \
+/*static*/ inline const Namespace::Type& Null<Namespace::Type> (void) { \
+  return *reinterpret_cast<const Namespace::Type *> (_Null##Type); \
+} \
+namespace Namespace { \
+/* The following line really exists such that we end in a place needing semicolon */ \
+static_assert (Namespace::Type::min_size + 1 <= sizeof (_Null##Type), "Null pool too small.  Enlarge.")
+
+
+/* Global writable pool.  Enlarge as necessary. */
+
+/* To be fully correct, CrapPool must be thread_local. However, we do not rely on CrapPool
+ * for correct operation. It only exist to catch and divert program logic bugs instead of
+ * causing bad memory access. So, races there are not actually introducing incorrectness
+ * in the code. Has ~12kb binary size overhead to have it, also clang build fails with it. */
+#ifdef HB_NO_VISIBILITY
+static
+#else
+extern HB_INTERNAL
+#endif
+/*thread_local*/ void * _hb_CrapPool[HB_NULL_POOL_SIZE / sizeof (void *)]
+#ifdef HB_NO_VISIBILITY
+= {}
+#endif
+;
+/* CRAP pool: Common Region for Access Protection. */
+template <typename Type>
+static inline Type& Crap (void) {
+  static_assert (sizeof (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE.");
+  Type *obj = reinterpret_cast<Type *> (_hb_CrapPool);
+  *obj = Null(Type);
+  return *obj;
+}
+#define Crap(Type) Crap<Type>()
+
+template <typename Type>
+struct CrapOrNull {
+  static inline Type & get (void) { return Crap(Type); }
+};
+template <typename Type>
+struct CrapOrNull<const Type> {
+  static inline Type const & get (void) { return Null(Type); }
+};
+#define CrapOrNull(Type) CrapOrNull<Type>::get ()
+
+
+
 /* arrays and maps */
 
 
 #define HB_PREALLOCED_ARRAY_INIT {0, 0, nullptr}
-template <typename Type, unsigned int StaticSize=16>
-struct hb_prealloced_array_t
+template <typename Type, unsigned int StaticSize=8>
+struct hb_vector_t
 {
   unsigned int len;
   unsigned int allocated;
-  Type *array;
+  bool successful;
+  Type *arrayZ;
   Type static_array[StaticSize];
 
   void init (void)
   {
     len = 0;
     allocated = ARRAY_LENGTH (static_array);
-    array = static_array;
+    successful = true;
+    arrayZ = static_array;
   }
 
-  inline Type& operator [] (unsigned int i) { return array[i]; }
-  inline const Type& operator [] (unsigned int i) const { return array[i]; }
+  inline Type& operator [] (unsigned int i)
+  {
+    if (unlikely (i >= len))
+      return Crap (Type);
+    return arrayZ[i];
+  }
+  inline const Type& operator [] (unsigned int i) const
+  {
+    if (unlikely (i >= len))
+      return Null(Type);
+    return arrayZ[i];
+  }
 
   inline Type *push (void)
   {
     if (unlikely (!resize (len + 1)))
-      return nullptr;
-
-    return &array[len - 1];
+      return &Crap(Type);
+    return &arrayZ[len - 1];
+  }
+  inline Type *push (const Type& v)
+  {
+    Type *p = push ();
+    *p = v;
+    return p;
   }
 
   /* Allocate for size but don't adjust len. */
-  inline bool alloc(unsigned int size)
+  inline bool alloc (unsigned int size)
   {
+    if (unlikely (!successful))
+      return false;
+
     if (likely (size <= allocated))
       return true;
 
@@ -565,37 +685,47 @@ struct hb_prealloced_array_t
 
     Type *new_array = nullptr;
 
-    if (array == static_array) {
+    if (arrayZ == static_array)
+    {
       new_array = (Type *) calloc (new_allocated, sizeof (Type));
       if (new_array)
-        memcpy (new_array, array, len * sizeof (Type));
-          } else {
+        memcpy (new_array, arrayZ, len * sizeof (Type));
+    }
+    else
+    {
       bool overflows = (new_allocated < allocated) || _hb_unsigned_int_mul_overflows (new_allocated, sizeof (Type));
-      if (likely (!overflows)) {
-        new_array = (Type *) realloc (array, new_allocated * sizeof (Type));
-      }
+      if (likely (!overflows))
+        new_array = (Type *) realloc (arrayZ, new_allocated * sizeof (Type));
     }
 
     if (unlikely (!new_array))
+    {
+      successful = false;
       return false;
+    }
 
-    array = new_array;
+    arrayZ = new_array;
     allocated = new_allocated;
 
     return true;
   }
 
-  inline bool resize (unsigned int size)
+  inline bool resize (int size_)
   {
+    unsigned int size = size_ < 0 ? 0u : (unsigned int) size_;
     if (!alloc (size))
       return false;
 
+    if (size > len)
+      memset (arrayZ + len, 0, (size - len) * sizeof (*arrayZ));
+
     len = size;
     return true;
   }
 
   inline void pop (void)
   {
+    if (!len) return;
     len--;
   }
 
@@ -603,54 +733,55 @@ struct hb_prealloced_array_t
   {
      if (unlikely (i >= len))
        return;
-     memmove (static_cast<void *> (&array[i]),
-             static_cast<void *> (&array[i + 1]),
+     memmove (static_cast<void *> (&arrayZ[i]),
+             static_cast<void *> (&arrayZ[i + 1]),
              (len - i - 1) * sizeof (Type));
      len--;
   }
 
-  inline void shrink (unsigned int l)
+  inline void shrink (int size_)
   {
-     if (l < len)
-       len = l;
+    unsigned int size = size_ < 0 ? 0u : (unsigned int) size_;
+     if (size < len)
+       len = size;
   }
 
   template <typename T>
   inline Type *find (T v) {
     for (unsigned int i = 0; i < len; i++)
-      if (array[i] == v)
-       return &array[i];
+      if (arrayZ[i] == v)
+       return &arrayZ[i];
     return nullptr;
   }
   template <typename T>
   inline const Type *find (T v) const {
     for (unsigned int i = 0; i < len; i++)
-      if (array[i] == v)
-       return &array[i];
+      if (arrayZ[i] == v)
+       return &arrayZ[i];
     return nullptr;
   }
 
   inline void qsort (int (*cmp)(const void*, const void*))
   {
-    ::qsort (array, len, sizeof (Type), cmp);
+    ::qsort (arrayZ, len, sizeof (Type), cmp);
   }
 
   inline void qsort (void)
   {
-    ::qsort (array, len, sizeof (Type), Type::cmp);
+    ::qsort (arrayZ, len, sizeof (Type), Type::cmp);
   }
 
   inline void qsort (unsigned int start, unsigned int end)
   {
-    ::qsort (array + start, end - start, sizeof (Type), Type::cmp);
+    ::qsort (arrayZ + start, end - start, sizeof (Type), Type::cmp);
   }
 
   template <typename T>
   inline Type *lsearch (const T &x)
   {
     for (unsigned int i = 0; i < len; i++)
-      if (0 == this->array[i].cmp (&x))
-       return &array[i];
+      if (0 == this->arrayZ[i].cmp (&x))
+       return &arrayZ[i];
     return nullptr;
   }
 
@@ -658,13 +789,13 @@ struct hb_prealloced_array_t
   inline Type *bsearch (const T &x)
   {
     unsigned int i;
-    return bfind (x, &i) ? &array[i] : nullptr;
+    return bfind (x, &i) ? &arrayZ[i] : nullptr;
   }
   template <typename T>
   inline const Type *bsearch (const T &x) const
   {
     unsigned int i;
-    return bfind (x, &i) ? &array[i] : nullptr;
+    return bfind (x, &i) ? &arrayZ[i] : nullptr;
   }
   template <typename T>
   inline bool bfind (const T &x, unsigned int *i) const
@@ -673,7 +804,7 @@ struct hb_prealloced_array_t
     while (min <= max)
     {
       int mid = (min + max) / 2;
-      int c = this->array[mid].cmp (&x);
+      int c = this->arrayZ[mid].cmp (&x);
       if (c < 0)
         max = mid - 1;
       else if (c > 0)
@@ -684,34 +815,39 @@ struct hb_prealloced_array_t
        return true;
       }
     }
-    if (max < 0 || (max < (int) this->len && this->array[max].cmp (&x) > 0))
+    if (max < 0 || (max < (int) this->len && this->arrayZ[max].cmp (&x) > 0))
       max++;
     *i = max;
     return false;
   }
 
-  inline void finish (void)
+  inline void fini (void)
   {
-    if (array != static_array)
-      free (array);
-    array = nullptr;
+    if (arrayZ != static_array)
+      free (arrayZ);
+    arrayZ = nullptr;
     allocated = len = 0;
   }
 };
 
 template <typename Type>
-struct hb_auto_array_t : hb_prealloced_array_t <Type>
+struct hb_auto_t : Type
 {
-  hb_auto_array_t (void) { hb_prealloced_array_t<Type>::init (); }
-  ~hb_auto_array_t (void) { hb_prealloced_array_t<Type>::finish (); }
+  hb_auto_t (void) { Type::init (); }
+  ~hb_auto_t (void) { Type::fini (); }
+  private: /* Hide */
+  void init (void) {}
+  void fini (void) {}
 };
+template <typename Type>
+struct hb_auto_array_t : hb_auto_t <hb_vector_t <Type> > {};
 
 
 #define HB_LOCKABLE_SET_INIT {HB_PREALLOCED_ARRAY_INIT}
 template <typename item_t, typename lock_t>
 struct hb_lockable_set_t
 {
-  hb_prealloced_array_t <item_t, 1> items;
+  hb_vector_t <item_t, 1> items;
 
   inline void init (void) { items.init (); }
 
@@ -725,16 +861,14 @@ struct hb_lockable_set_t
        item_t old = *item;
        *item = v;
        l.unlock ();
-       old.finish ();
+       old.fini ();
       }
       else {
         item = nullptr;
        l.unlock ();
       }
     } else {
-      item = items.push ();
-      if (likely (item))
-       *item = v;
+      item = items.push (v);
       l.unlock ();
     }
     return item;
@@ -750,7 +884,7 @@ struct hb_lockable_set_t
       *item = items[items.len - 1];
       items.pop ();
       l.unlock ();
-      old.finish ();
+      old.fini ();
     } else {
       l.unlock ();
     }
@@ -773,19 +907,17 @@ struct hb_lockable_set_t
     l.lock ();
     item_t *item = items.find (v);
     if (!item) {
-      item = items.push ();
-      if (likely (item))
-        *item = v;
+      item = items.push (v);
     }
     l.unlock ();
     return item;
   }
 
-  inline void finish (lock_t &l)
+  inline void fini (lock_t &l)
   {
     if (!items.len) {
       /* No need for locking. */
-      items.finish ();
+      items.fini ();
       return;
     }
     l.lock ();
@@ -793,10 +925,10 @@ struct hb_lockable_set_t
       item_t old = items[items.len - 1];
        items.pop ();
        l.unlock ();
-       old.finish ();
+       old.fini ();
        l.lock ();
     }
-    items.finish ();
+    items.fini ();
     l.unlock ();
   }
 
@@ -823,7 +955,7 @@ static inline unsigned char TOLOWER (unsigned char c)
  * light-weight) to be enabled, then HB_DEBUG can be defined to disable
  * the costlier checks. */
 #ifdef NDEBUG
-#define HB_NDEBUG
+#define HB_NDEBUG 1
 #endif
 
 
@@ -972,19 +1104,35 @@ struct HbOpXor
   template <typename T> static void process (T &o, const T &a, const T &b) { o = a ^ b; }
 };
 
+
+/* Compiler-assisted vectorization. */
+
+/* The `vector_size' attribute was introduced in gcc 3.1. */
+#if defined( __GNUC__ ) && ( __GNUC__ >= 4 )
+#define HB_VECTOR_SIZE 128
+#elif !defined(HB_VECTOR_SIZE)
+#define HB_VECTOR_SIZE 0
+#endif
+
 /* Type behaving similar to vectorized vars defined using __attribute__((vector_size(...))). */
 template <typename elt_t, unsigned int byte_size>
 struct hb_vector_size_t
 {
-  elt_t& operator [] (unsigned int i) { return v[i]; }
-  const elt_t& operator [] (unsigned int i) const { return v[i]; }
+  elt_t& operator [] (unsigned int i) { return u.v[i]; }
+  const elt_t& operator [] (unsigned int i) const { return u.v[i]; }
 
   template <class Op>
   inline hb_vector_size_t process (const hb_vector_size_t &o) const
   {
     hb_vector_size_t r;
-    for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
-      Op::process (r.v[i], v[i], o.v[i]);
+#if HB_VECTOR_SIZE
+    if (HB_VECTOR_SIZE && 0 == (byte_size * 8) % HB_VECTOR_SIZE)
+      for (unsigned int i = 0; i < ARRAY_LENGTH (u.vec); i++)
+       Op::process (r.u.vec[i], u.vec[i], o.u.vec[i]);
+    else
+#endif
+      for (unsigned int i = 0; i < ARRAY_LENGTH (u.v); i++)
+       Op::process (r.u.v[i], u.v[i], o.u.v[i]);
     return r;
   }
   inline hb_vector_size_t operator | (const hb_vector_size_t &o) const
@@ -996,20 +1144,27 @@ struct hb_vector_size_t
   inline hb_vector_size_t operator ~ () const
   {
     hb_vector_size_t r;
-    for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
-      r.v[i] = ~v[i];
+#if HB_VECTOR_SIZE && 0
+    if (HB_VECTOR_SIZE && 0 == (byte_size * 8) % HB_VECTOR_SIZE)
+      for (unsigned int i = 0; i < ARRAY_LENGTH (u.vec); i++)
+       r.u.vec[i] = ~u.vec[i];
+    else
+#endif
+    for (unsigned int i = 0; i < ARRAY_LENGTH (u.v); i++)
+      r.u.v[i] = ~u.v[i];
     return r;
   }
 
   private:
   static_assert (byte_size / sizeof (elt_t) * sizeof (elt_t) == byte_size, "");
-  elt_t v[byte_size / sizeof (elt_t)];
-};
-
-/* The `vector_size' attribute was introduced in gcc 3.1. */
-#if defined( __GNUC__ ) && ( __GNUC__ >= 4 )
-#define HAVE_VECTOR_SIZE 1
+  union {
+    elt_t v[byte_size / sizeof (elt_t)];
+#if HB_VECTOR_SIZE
+    typedef unsigned long vec_t __attribute__((vector_size (HB_VECTOR_SIZE / 8)));
+    vec_t vec[byte_size / sizeof (vec_t)];
 #endif
+  } u;
+};
 
 
 /* Global runtime options. */
@@ -1046,12 +1201,12 @@ hb_options (void)
 
 /* String type. */
 
-struct hb_string_t
+struct hb_bytes_t
 {
-  inline hb_string_t (void) : bytes (nullptr), len (0) {}
-  inline hb_string_t (const char *bytes_, unsigned int len_) : bytes (bytes_), len (len_) {}
+  inline hb_bytes_t (void) : bytes (nullptr), len (0) {}
+  inline hb_bytes_t (const char *bytes_, unsigned int len_) : bytes (bytes_), len (len_) {}
 
-  inline int cmp (const hb_string_t &a) const
+  inline int cmp (const hb_bytes_t &a) const
   {
     if (len != a.len)
       return (int) a.len - (int) len;
@@ -1060,8 +1215,8 @@ struct hb_string_t
   }
   static inline int cmp (const void *pa, const void *pb)
   {
-    hb_string_t *a = (hb_string_t *) pa;
-    hb_string_t *b = (hb_string_t *) pb;
+    hb_bytes_t *a = (hb_bytes_t *) pa;
+    hb_bytes_t *b = (hb_bytes_t *) pb;
     return b->cmp (*a);
   }
 
@@ -1070,4 +1225,17 @@ struct hb_string_t
 };
 
 
+/* fallback for round() */
+#if !defined (HAVE_ROUND) && !defined (HAVE_DECL_ROUND)
+static inline double
+round (double x)
+{
+  if (x >= 0)
+    return floor (x + 0.5);
+  else
+    return ceil (x - 0.5);
+}
+#endif
+
+
 #endif /* HB_PRIVATE_HH */
index 3615c50..ccd4d8d 100644 (file)
@@ -158,21 +158,13 @@ struct hb_set_t
     }
 
     typedef unsigned long long elt_t;
-    static const unsigned int PAGE_BITS = 1024;
+    static const unsigned int PAGE_BITS = 512;
     static_assert ((PAGE_BITS & ((PAGE_BITS) - 1)) == 0, "");
 
     static inline unsigned int elt_get_min (const elt_t &elt) { return _hb_ctz (elt); }
     static inline unsigned int elt_get_max (const elt_t &elt) { return _hb_bit_storage (elt) - 1; }
 
-#if 0 && HAVE_VECTOR_SIZE
-    /* The vectorized version does not work with clang as non-const
-     * elt() errs "non-const reference cannot bind to vector element". */
-    typedef elt_t vector_t __attribute__((vector_size (PAGE_BITS / 8)));
-#else
     typedef hb_vector_size_t<elt_t, PAGE_BITS / 8> vector_t;
-#endif
-
-    vector_t v;
 
     static const unsigned int ELT_BITS = sizeof (elt_t) * 8;
     static const unsigned int ELT_MASK = ELT_BITS - 1;
@@ -183,34 +175,47 @@ struct hb_set_t
     elt_t &elt (hb_codepoint_t g) { return v[(g & MASK) / ELT_BITS]; }
     elt_t const &elt (hb_codepoint_t g) const { return v[(g & MASK) / ELT_BITS]; }
     elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & ELT_MASK); }
+
+    vector_t v;
   };
   static_assert (page_t::PAGE_BITS == sizeof (page_t) * 8, "");
 
   hb_object_header_t header;
-  ASSERT_POD ();
-  bool in_error;
-  hb_prealloced_array_t<page_map_t, 8> page_map;
-  hb_prealloced_array_t<page_t, 1> pages;
+  bool successful; /* Allocations successful */
+  mutable unsigned int population;
+  hb_vector_t<page_map_t, 1> page_map;
+  hb_vector_t<page_t, 1> pages;
 
-  inline void init (void)
+  inline void init_shallow (void)
   {
-    in_error = false;
+    successful = true;
+    population = 0;
     page_map.init ();
     pages.init ();
   }
-  inline void finish (void)
+  inline void init (void)
+  {
+    hb_object_init (this);
+    init_shallow ();
+  }
+  inline void fini_shallow (void)
+  {
+    page_map.fini ();
+    pages.fini ();
+  }
+  inline void fini (void)
   {
-    page_map.finish ();
-    pages.finish ();
+    hb_object_fini (this);
+    fini_shallow ();
   }
 
   inline bool resize (unsigned int count)
   {
-    if (unlikely (in_error)) return false;
+    if (unlikely (!successful)) return false;
     if (!pages.resize (count) || !page_map.resize (count))
     {
       pages.resize (page_map.len);
-      in_error = true;
+      successful = false;
       return false;
     }
     return true;
@@ -219,7 +224,8 @@ struct hb_set_t
   inline void clear (void) {
     if (unlikely (hb_object_is_inert (this)))
       return;
-    in_error = false;
+    successful = true;
+    population = 0;
     page_map.resize (0);
     pages.resize (0);
   }
@@ -231,17 +237,21 @@ struct hb_set_t
     return true;
   }
 
+  inline void dirty (void) { population = (unsigned int) -1; }
+
   inline void add (hb_codepoint_t g)
   {
-    if (unlikely (in_error)) return;
+    if (unlikely (!successful)) return;
     if (unlikely (g == INVALID)) return;
+    dirty ();
     page_t *page = page_for_insert (g); if (unlikely (!page)) return;
     page->add (g);
   }
   inline bool add_range (hb_codepoint_t a, hb_codepoint_t b)
   {
-    if (unlikely (in_error)) return true; /* https://github.com/harfbuzz/harfbuzz/issues/657 */
+    if (unlikely (!successful)) return true; /* https://github.com/harfbuzz/harfbuzz/issues/657 */
     if (unlikely (a > b || a == INVALID || b == INVALID)) return false;
+    dirty ();
     unsigned int ma = get_major (a);
     unsigned int mb = get_major (b);
     if (ma == mb)
@@ -269,8 +279,9 @@ struct hb_set_t
   template <typename T>
   inline void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
   {
-    if (unlikely (in_error)) return;
+    if (unlikely (!successful)) return;
     if (!count) return;
+    dirty ();
     hb_codepoint_t g = *array;
     while (count)
     {
@@ -294,8 +305,9 @@ struct hb_set_t
   template <typename T>
   inline bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
   {
-    if (unlikely (in_error)) return true; /* https://github.com/harfbuzz/harfbuzz/issues/657 */
+    if (unlikely (!successful)) return true; /* https://github.com/harfbuzz/harfbuzz/issues/657 */
     if (!count) return true;
+    dirty ();
     hb_codepoint_t g = *array;
     hb_codepoint_t last_g = g;
     while (count)
@@ -321,16 +333,19 @@ struct hb_set_t
 
   inline void del (hb_codepoint_t g)
   {
-    if (unlikely (in_error)) return;
+    /* TODO perform op even if !successful. */
+    if (unlikely (!successful)) return;
     page_t *p = page_for (g);
     if (!p)
       return;
+    dirty ();
     p->del (g);
   }
   inline void del_range (hb_codepoint_t a, hb_codepoint_t b)
   {
+    /* TODO perform op even if !successful. */
     /* TODO Optimize, like add_range(). */
-    if (unlikely (in_error)) return;
+    if (unlikely (!successful)) return;
     for (unsigned int i = a; i < b + 1; i++)
       del (i);
   }
@@ -349,17 +364,20 @@ struct hb_set_t
   }
   inline void set (const hb_set_t *other)
   {
-    if (unlikely (in_error)) return;
+    if (unlikely (!successful)) return;
     unsigned int count = other->pages.len;
     if (!resize (count))
       return;
-
-    memcpy (pages.array, other->pages.array, count * sizeof (pages.array[0]));
-    memcpy (page_map.array, other->page_map.array, count * sizeof (page_map.array[0]));
+    population = other->population;
+    memcpy (pages.arrayZ, other->pages.arrayZ, count * sizeof (pages.arrayZ[0]));
+    memcpy (page_map.arrayZ, other->page_map.arrayZ, count * sizeof (page_map.arrayZ[0]));
   }
 
   inline bool is_equal (const hb_set_t *other) const
   {
+    if (get_population () != other->get_population ())
+      return false;
+
     unsigned int na = pages.len;
     unsigned int nb = other->pages.len;
 
@@ -382,16 +400,31 @@ struct hb_set_t
     return true;
   }
 
+  inline bool is_subset (const hb_set_t *larger_set) const
+  {
+    if (get_population () > larger_set->get_population ())
+      return false;
+
+    hb_codepoint_t c = INVALID;
+    while (next (&c))
+      if (!larger_set->has (c))
+        return false;
+
+    return true;
+  }
+
   template <class Op>
   inline void process (const hb_set_t *other)
   {
-    if (unlikely (in_error)) return;
+    if (unlikely (!successful)) return;
+
+    dirty ();
 
     unsigned int na = pages.len;
     unsigned int nb = other->pages.len;
     unsigned int next_page = na;
 
-    unsigned int count = 0;
+    unsigned int count = 0, newCount = 0;
     unsigned int a = 0, b = 0;
     for (; a < na && b < nb; )
     {
@@ -419,8 +452,10 @@ struct hb_set_t
     if (Op::passthru_right)
       count += nb - b;
 
-    if (!resize (count))
-      return;
+    if (count > pages.len)
+      if (!resize (count))
+        return;
+    newCount = count;
 
     /* Process in-place backward. */
     a = na;
@@ -473,6 +508,8 @@ struct hb_set_t
        page_at (count).v = other->page_at (b).v;
       }
     assert (!count);
+    if (pages.len > newCount)
+      resize (newCount);
   }
 
   inline void union_ (const hb_set_t *other)
@@ -592,10 +629,15 @@ struct hb_set_t
 
   inline unsigned int get_population (void) const
   {
+    if (population != (unsigned int) -1)
+      return population;
+
     unsigned int pop = 0;
     unsigned int count = pages.len;
     for (unsigned int i = 0; i < count; i++)
       pop += pages[i].get_population ();
+
+    population = pop;
     return pop;
   }
   inline hb_codepoint_t get_min (void) const
index 07cf9d0..25027e6 100644 (file)
@@ -45,18 +45,11 @@ hb_set_create (void)
   if (!(set = hb_object_create<hb_set_t> ()))
     return hb_set_get_empty ();
 
-  set->init ();
+  set->init_shallow ();
 
   return set;
 }
 
-static const hb_set_t _hb_set_nil = {
-  HB_OBJECT_HEADER_STATIC,
-  true, /* in_error */
-
-  {0} /* elts */
-};
-
 /**
  * hb_set_get_empty:
  *
@@ -67,7 +60,7 @@ static const hb_set_t _hb_set_nil = {
 hb_set_t *
 hb_set_get_empty (void)
 {
-  return const_cast<hb_set_t *> (&_hb_set_nil);
+  return const_cast<hb_set_t *> (&Null(hb_set_t));
 }
 
 /**
@@ -95,7 +88,7 @@ hb_set_destroy (hb_set_t *set)
 {
   if (!hb_object_destroy (set)) return;
 
-  set->finish ();
+  set->fini_shallow ();
 
   free (set);
 }
@@ -150,9 +143,9 @@ hb_set_get_user_data (hb_set_t           *set,
  * Since: 0.9.2
  **/
 hb_bool_t
-hb_set_allocation_successful (const hb_set_t  *set HB_UNUSED)
+hb_set_allocation_successful (const hb_set_t  *set)
 {
-  return !set->in_error;
+  return set->successful;
 }
 
 /**
@@ -274,11 +267,11 @@ hb_set_del_range (hb_set_t       *set,
 /**
  * hb_set_is_equal:
  * @set: a set.
- * @other: 
+ * @other: other set.
  *
  * 
  *
- * Return value: 
+ * Return value: %TRUE if the two sets are equal, %FALSE otherwise.
  *
  * Since: 0.9.7
  **/
@@ -290,6 +283,24 @@ hb_set_is_equal (const hb_set_t *set,
 }
 
 /**
+ * hb_set_is_subset:
+ * @set: a set.
+ * @larger_set: other set.
+ *
+ *
+ *
+ * Return value: %TRUE if the @set is a subset of (or equal to) @larger_set, %FALSE otherwise.
+ *
+ * Since: 1.8.1
+ **/
+hb_bool_t
+hb_set_is_subset (const hb_set_t *set,
+                 const hb_set_t *larger_set)
+{
+  return set->is_subset (larger_set);
+}
+
+/**
  * hb_set_set:
  * @set: a set.
  * @other: 
index b0f82f8..ed0e05d 100644 (file)
@@ -82,8 +82,6 @@ HB_EXTERN hb_bool_t
 hb_set_has (const hb_set_t *set,
            hb_codepoint_t  codepoint);
 
-/* Right now limited to 16-bit integers.  Eventually will do full codepoint range, sans -1
- * which we will use as a sentinel. */
 HB_EXTERN void
 hb_set_add (hb_set_t       *set,
            hb_codepoint_t  codepoint);
@@ -106,6 +104,10 @@ HB_EXTERN hb_bool_t
 hb_set_is_equal (const hb_set_t *set,
                 const hb_set_t *other);
 
+HB_EXTERN hb_bool_t
+hb_set_is_subset (const hb_set_t *set,
+                 const hb_set_t *larger_set);
+
 HB_EXTERN void
 hb_set_set (hb_set_t       *set,
            const hb_set_t *other);
index 39355b3..c1e7365 100644 (file)
@@ -51,7 +51,12 @@ static const char **static_shaper_list;
 static
 void free_static_shaper_list (void)
 {
-  free (static_shaper_list);
+retry:
+  const char **shaper_list = (const char **) hb_atomic_ptr_get (&static_shaper_list);
+  if (!hb_atomic_ptr_cmpexch (&static_shaper_list, shaper_list, nullptr))
+    goto retry;
+
+  free (shaper_list);
 }
 #endif
 
index 2c44cf2..d44d8c9 100644 (file)
@@ -44,8 +44,13 @@ static const hb_shaper_pair_t *static_shapers;
 static
 void free_static_shapers (void)
 {
-  if (unlikely (static_shapers != all_shapers))
-    free ((void *) static_shapers);
+retry:
+  hb_shaper_pair_t *shapers = (hb_shaper_pair_t *) hb_atomic_ptr_get (&static_shapers);
+  if (!hb_atomic_ptr_cmpexch (&static_shapers, shapers, nullptr))
+    goto retry;
+
+  if (unlikely (shapers != all_shapers))
+    free ((void *) shapers);
 }
 #endif
 
diff --git a/src/hb-static.cc b/src/hb-static.cc
new file mode 100644 (file)
index 0000000..e26e5c8
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright © 2018  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-private.hh"
+
+#ifndef HB_NO_VISIBILITY
+void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {};
+/*thread_local*/ void * _hb_CrapPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {};
+#endif
index ba829b0..679841c 100644 (file)
@@ -42,7 +42,7 @@ static const union HB_STRING_ARRAY_TYPE_NAME {
   struct {
 /* I like to avoid storing the nul-termination byte since we don't need it,
  * but C++ does not allow that.
- * https://stackoverflow.com/questions/28433862/why-initializer-string-for-array-of-chars-is-too-long-compiles-fine-in-c-not
+ * https://stackoverflow.com/q/28433862
  */
 #define _S(s) char HB_PASTE (str, __LINE__)[sizeof (s)];
 #include HB_STRING_ARRAY_LIST
@@ -66,12 +66,12 @@ static const unsigned int HB_STRING_ARRAY_OFFS_NAME[] =
   sizeof (HB_STRING_ARRAY_TYPE_NAME)
 };
 
-static inline hb_string_t
+static inline hb_bytes_t
 HB_STRING_ARRAY_NAME (unsigned int i)
 {
   assert (i < ARRAY_LENGTH (HB_STRING_ARRAY_OFFS_NAME) - 1);
-  return hb_string_t (HB_STRING_ARRAY_POOL_NAME.str + HB_STRING_ARRAY_OFFS_NAME[i],
-                     HB_STRING_ARRAY_OFFS_NAME[i + 1] - HB_STRING_ARRAY_OFFS_NAME[i] - 1);
+  return hb_bytes_t (HB_STRING_ARRAY_POOL_NAME.str + HB_STRING_ARRAY_OFFS_NAME[i],
+                    HB_STRING_ARRAY_OFFS_NAME[i + 1] - HB_STRING_ARRAY_OFFS_NAME[i] - 1);
 }
 
 #undef HB_STRING_ARRAY_TYPE_NAME
index 0b84c85..c8fa39b 100644 (file)
 
 static bool
 _calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf,
-                                     hb_prealloced_array_t<hb_codepoint_t> &glyph_ids,
+                                     hb_vector_t<hb_codepoint_t> &glyph_ids,
                                      hb_bool_t drop_hints,
                                      bool *use_short_loca /* OUT */,
                                      unsigned int *glyf_size /* OUT */,
                                      unsigned int *loca_size /* OUT */,
-                                     hb_prealloced_array_t<unsigned int> *instruction_ranges /* OUT */)
+                                     hb_vector_t<unsigned int> *instruction_ranges /* OUT */)
 {
   unsigned int total = 0;
   for (unsigned int i = 0; i < glyph_ids.len; i++)
   {
     hb_codepoint_t next_glyph = glyph_ids[i];
-    unsigned int *instruction_start = instruction_ranges->push();
-    unsigned int *instruction_end = instruction_ranges->push();
+    if (!instruction_ranges->resize (instruction_ranges->len + 2))
+    {
+      DEBUG_MSG(SUBSET, nullptr, "Failed to resize instruction_ranges.");
+      return false;
+    }
+    unsigned int *instruction_start = &(*instruction_ranges)[instruction_ranges->len - 2];
     *instruction_start = 0;
+    unsigned int *instruction_end = &(*instruction_ranges)[instruction_ranges->len - 1];
     *instruction_end = 0;
 
     unsigned int start_offset, end_offset;
@@ -116,7 +121,6 @@ static void
 _update_components (hb_subset_plan_t * plan,
                    char * glyph_start,
                    unsigned int length)
-
 {
   OT::glyf::CompositeGlyphHeader::Iterator iterator;
   if (OT::glyf::CompositeGlyphHeader::get_iterator (glyph_start,
@@ -126,9 +130,8 @@ _update_components (hb_subset_plan_t * plan,
     do
     {
       hb_codepoint_t new_gid;
-      if (!hb_subset_plan_new_gid_for_old_id (plan,
-                                             iterator.current->glyphIndex,
-                                             &new_gid))
+      if (!plan->new_gid_for_old_gid (iterator.current->glyphIndex,
+                                      &new_gid))
        continue;
 
       ((OT::glyf::CompositeGlyphHeader *) iterator.current)->glyphIndex.set (new_gid);
@@ -155,13 +158,13 @@ _write_glyf_and_loca_prime (hb_subset_plan_t              *plan,
                            const OT::glyf::accelerator_t &glyf,
                             const char                    *glyf_data,
                             bool                           use_short_loca,
-                            hb_prealloced_array_t<unsigned int> &instruction_ranges,
+                            hb_vector_t<unsigned int> &instruction_ranges,
                             unsigned int                   glyf_prime_size,
                             char                          *glyf_prime_data /* OUT */,
                             unsigned int                   loca_prime_size,
                             char                          *loca_prime_data /* OUT */)
 {
-  hb_prealloced_array_t<hb_codepoint_t> &glyph_ids = plan->gids_to_retain_sorted;
+  hb_vector_t<hb_codepoint_t> &glyph_ids = plan->glyphs;
   char *glyf_prime_data_next = glyf_prime_data;
 
   bool success = true;
@@ -171,11 +174,11 @@ _write_glyf_and_loca_prime (hb_subset_plan_t              *plan,
     if (unlikely (!(glyf.get_offsets (glyph_ids[i], &start_offset, &end_offset)
                     && glyf.remove_padding(start_offset, &end_offset))))
       end_offset = start_offset = 0;
+
     unsigned int instruction_start = instruction_ranges[i * 2];
     unsigned int instruction_end = instruction_ranges[i * 2 + 1];
 
     int length = end_offset - start_offset - (instruction_end - instruction_start);
-    length += length % 2;
 
     if (glyf_prime_data_next + length > glyf_prime_data + glyf_prime_size)
     {
@@ -209,7 +212,8 @@ _write_glyf_and_loca_prime (hb_subset_plan_t              *plan,
                                             loca_prime_size);
     _update_components (plan, glyf_prime_data_next, length);
 
-    glyf_prime_data_next += length;
+    // TODO: don't align to two bytes if using long loca.
+    glyf_prime_data_next += length + (length % 2); // Align to 2 bytes for short loca.
   }
 
   success = success && _write_loca_entry (glyph_ids.len,
@@ -229,11 +233,11 @@ _hb_subset_glyf_and_loca (const OT::glyf::accelerator_t  &glyf,
                           hb_blob_t                     **loca_prime /* OUT */)
 {
   // TODO(grieger): Sanity check allocation size for the new table.
-  hb_prealloced_array_t<hb_codepoint_t> &glyphs_to_retain = plan->gids_to_retain_sorted;
+  hb_vector_t<hb_codepoint_t> &glyphs_to_retain = plan->glyphs;
 
   unsigned int glyf_prime_size;
   unsigned int loca_prime_size;
-  hb_prealloced_array_t<unsigned int> instruction_ranges;
+  hb_vector_t<unsigned int> instruction_ranges;
   instruction_ranges.init();
 
   if (unlikely (!_calculate_glyf_and_loca_prime_size (glyf,
@@ -243,7 +247,7 @@ _hb_subset_glyf_and_loca (const OT::glyf::accelerator_t  &glyf,
                                                       &glyf_prime_size,
                                                       &loca_prime_size,
                                                       &instruction_ranges))) {
-    instruction_ranges.finish();
+    instruction_ranges.fini();
     return false;
   }
 
@@ -256,10 +260,10 @@ _hb_subset_glyf_and_loca (const OT::glyf::accelerator_t  &glyf,
                                              loca_prime_size, loca_prime_data))) {
     free (glyf_prime_data);
     free (loca_prime_data);
-    instruction_ranges.finish();
+    instruction_ranges.fini();
     return false;
   }
-  instruction_ranges.finish();
+  instruction_ranges.fini();
 
   *glyf_prime = hb_blob_create (glyf_prime_data,
                                 glyf_prime_size,
index c4003dd..39c5ac4 100644 (file)
@@ -45,6 +45,7 @@ hb_subset_input_create_or_fail (void)
 
   input->unicodes = hb_set_create ();
   input->glyphs = hb_set_create ();
+  input->drop_ot_layout = true;
 
   return input;
 }
@@ -117,3 +118,19 @@ hb_subset_input_drop_hints (hb_subset_input_t *subset_input)
 {
   return &subset_input->drop_hints;
 }
+
+/**
+ * hb_subset_input_drop_ot_layout:
+ * @subset_input: a subset_input.
+ *
+ * If enabled ot layout tables will be dropped as part of
+ * the subsetting operation. Currently this defaults to
+ * true.
+ *
+ * Since: REPLACEME
+ **/
+HB_EXTERN hb_bool_t *
+hb_subset_input_drop_ot_layout (hb_subset_input_t *subset_input)
+{
+  return &subset_input->drop_ot_layout;
+}
index f8a09ef..55c4e3f 100644 (file)
  * Google Author(s): Garret Rieger, Roderick Sheeter
  */
 
+#include "hb-map-private.hh"
 #include "hb-subset-private.hh"
+#include "hb-set-private.hh"
 
 #include "hb-subset-plan.hh"
 #include "hb-ot-cmap-table.hh"
 #include "hb-ot-glyf-table.hh"
 
-static int
-_hb_codepoint_t_cmp (const void *pa, const void *pb)
-{
-  hb_codepoint_t a = * (hb_codepoint_t *) pa;
-  hb_codepoint_t b = * (hb_codepoint_t *) pb;
-
-  return a < b ? -1 : a > b ? +1 : 0;
-}
-
-hb_bool_t
-hb_subset_plan_new_gid_for_codepoint (hb_subset_plan_t *plan,
-                                      hb_codepoint_t codepoint,
-                                      hb_codepoint_t *new_gid)
-{
-  // TODO actual map, delete this garbage.
-  for (unsigned int i = 0; i < plan->codepoints.len; i++)
-  {
-    if (plan->codepoints[i] != codepoint) continue;
-    if (!hb_subset_plan_new_gid_for_old_id(plan, plan->gids_to_retain[i], new_gid))
-    {
-      return false;
-    }
-    return true;
-  }
-  return false;
-}
-
-hb_bool_t
-hb_subset_plan_new_gid_for_old_id (hb_subset_plan_t *plan,
-                                   hb_codepoint_t old_gid,
-                                   hb_codepoint_t *new_gid)
-{
-  // the index in old_gids is the new gid; only up to codepoints.len are valid
-  for (unsigned int i = 0; i < plan->gids_to_retain_sorted.len; i++)
-  {
-    if (plan->gids_to_retain_sorted[i] == old_gid)
-    {
-      *new_gid = i;
-      return true;
-    }
-  }
-  return false;
-}
-
-hb_bool_t
-hb_subset_plan_add_table (hb_subset_plan_t *plan,
-                          hb_tag_t tag,
-                          hb_blob_t *contents)
-{
-  hb_blob_t *source_blob = plan->source->reference_table (tag);
-  DEBUG_MSG(SUBSET, nullptr, "add table %c%c%c%c, dest %d bytes, source %d bytes", HB_UNTAG(tag), hb_blob_get_length (contents), hb_blob_get_length (source_blob));
-  hb_blob_destroy (source_blob);
-  return hb_subset_face_add_table(plan->dest, tag, contents);
-}
-
-static void
-_populate_codepoints (hb_set_t *input_codepoints,
-                      hb_prealloced_array_t<hb_codepoint_t>& plan_codepoints)
-{
-  plan_codepoints.alloc (hb_set_get_population (input_codepoints));
-  hb_codepoint_t cp = -1;
-  while (hb_set_next (input_codepoints, &cp)) {
-    hb_codepoint_t *wr = plan_codepoints.push();
-    *wr = cp;
-  }
-  plan_codepoints.qsort (_hb_codepoint_t_cmp);
-}
-
 static void
 _add_gid_and_children (const OT::glyf::accelerator_t &glyf,
                       hb_codepoint_t gid,
@@ -120,59 +54,80 @@ _add_gid_and_children (const OT::glyf::accelerator_t &glyf,
 }
 
 static void
+_gsub_closure (hb_face_t *face, hb_set_t *gids_to_retain)
+{
+  // TODO(grieger): This uses all lookups, instead collect
+  //                the set of lookups that are relevant.
+  //                See fontTools implementation.
+  hb_ot_layout_lookups_substitute_closure (face,
+                                           nullptr,
+                                           gids_to_retain);
+}
+
+
+static void
 _populate_gids_to_retain (hb_face_t *face,
-                          hb_prealloced_array_t<hb_codepoint_t>& codepoints,
-                          hb_prealloced_array_t<hb_codepoint_t>& old_gids,
-                          hb_prealloced_array_t<hb_codepoint_t>& old_gids_sorted)
+                          const hb_set_t *unicodes,
+                          bool close_over_gsub,
+                          hb_set_t *unicodes_to_retain,
+                          hb_map_t *codepoint_to_glyph,
+                          hb_vector_t<hb_codepoint_t> *glyphs)
 {
   OT::cmap::accelerator_t cmap;
   OT::glyf::accelerator_t glyf;
   cmap.init (face);
   glyf.init (face);
 
-  hb_auto_array_t<unsigned int> bad_indices;
+  hb_set_t *initial_gids_to_retain = hb_set_create ();
+  initial_gids_to_retain->add (0); // Not-def
 
-  old_gids.alloc (codepoints.len);
-  for (unsigned int i = 0; i < codepoints.len; i++)
+  hb_codepoint_t cp = HB_SET_VALUE_INVALID;
+  while (unicodes->next (&cp))
   {
     hb_codepoint_t gid;
-    if (!cmap.get_nominal_glyph (codepoints[i], &gid))
+    if (!cmap.get_nominal_glyph (cp, &gid))
     {
-      gid = -1;
-      *(bad_indices.push ()) = i;
+      DEBUG_MSG(SUBSET, nullptr, "Drop U+%04X; no gid", cp);
+      continue;
     }
-    *(old_gids.push ()) = gid;
+    unicodes_to_retain->add (cp);
+    codepoint_to_glyph->set (cp, gid);
+    initial_gids_to_retain->add (gid);
   }
 
-  /* Generally there shouldn't be any */
-  while (bad_indices.len > 0)
-  {
-    unsigned int i = bad_indices[bad_indices.len - 1];
-    bad_indices.pop ();
-    DEBUG_MSG(SUBSET, nullptr, "Drop U+%04X; no gid", codepoints[i]);
-    codepoints.remove (i);
-    old_gids.remove (i);
-  }
+  if (close_over_gsub)
+    // Add all glyphs needed for GSUB substitutions.
+    _gsub_closure (face, initial_gids_to_retain);
 
   // Populate a full set of glyphs to retain by adding all referenced
   // composite glyphs.
-  // TODO expand with glyphs reached by G*
-  hb_set_t * all_gids_to_retain = hb_set_create ();
-  _add_gid_and_children (glyf, 0, all_gids_to_retain);
-  for (unsigned int i = 0; i < old_gids.len; i++)
-    _add_gid_and_children (glyf, old_gids[i], all_gids_to_retain);
-
-  // Transfer to a sorted list.
-  old_gids_sorted.alloc (hb_set_get_population (all_gids_to_retain));
   hb_codepoint_t gid = HB_SET_VALUE_INVALID;
-  while (hb_set_next (all_gids_to_retain, &gid))
-    *(old_gids_sorted.push ()) = gid;
+  hb_set_t *all_gids_to_retain = hb_set_create ();
+  while (initial_gids_to_retain->next (&gid))
+  {
+    _add_gid_and_children (glyf, gid, all_gids_to_retain);
+  }
+  hb_set_destroy (initial_gids_to_retain);
+
+  glyphs->alloc (all_gids_to_retain->get_population ());
+  gid = HB_SET_VALUE_INVALID;
+  while (all_gids_to_retain->next (&gid))
+    glyphs->push (gid);
 
   hb_set_destroy (all_gids_to_retain);
   glyf.fini ();
   cmap.fini ();
 }
 
+static void
+_create_old_gid_to_new_gid_map (const hb_vector_t<hb_codepoint_t> &glyphs,
+                                hb_map_t *glyph_map)
+{
+  for (unsigned int i = 0; i < glyphs.len; i++) {
+    glyph_map->set (glyphs[i], i);
+  }
+}
+
 /**
  * hb_subset_plan_create:
  * Computes a plan for subsetting the supplied face according
@@ -190,18 +145,23 @@ hb_subset_plan_create (hb_face_t           *face,
 {
   hb_subset_plan_t *plan = hb_object_create<hb_subset_plan_t> ();
 
-  plan->codepoints.init();
-  plan->gids_to_retain.init();
-  plan->gids_to_retain_sorted.init();
+  plan->drop_hints = input->drop_hints;
+  plan->drop_ot_layout = input->drop_ot_layout;
+  plan->unicodes = hb_set_create();
+  plan->glyphs.init();
   plan->source = hb_face_reference (face);
   plan->dest = hb_subset_face_create ();
-  plan->drop_hints = input->drop_hints;
+  plan->codepoint_to_glyph = hb_map_create();
+  plan->glyph_map = hb_map_create();
 
-  _populate_codepoints (input->unicodes, plan->codepoints);
   _populate_gids_to_retain (face,
-                            plan->codepoints,
-                            plan->gids_to_retain,
-                            plan->gids_to_retain_sorted);
+                            input->unicodes,
+                            !plan->drop_ot_layout,
+                            plan->unicodes,
+                            plan->codepoint_to_glyph,
+                            &plan->glyphs);
+  _create_old_gid_to_new_gid_map (plan->glyphs,
+                                  plan->glyph_map);
 
   return plan;
 }
@@ -216,12 +176,12 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan)
 {
   if (!hb_object_destroy (plan)) return;
 
-  plan->codepoints.finish ();
-  plan->gids_to_retain.finish ();
-  plan->gids_to_retain_sorted.finish ();
-
+  hb_set_destroy (plan->unicodes);
+  plan->glyphs.fini();
   hb_face_destroy (plan->source);
   hb_face_destroy (plan->dest);
+  hb_map_destroy (plan->codepoint_to_glyph);
+  hb_map_destroy (plan->glyph_map);
 
   free (plan);
 }
index d1b66b4..f4b261d 100644 (file)
 #include "hb-private.hh"
 
 #include "hb-subset.h"
+#include "hb-subset-private.hh"
 
 #include "hb-object-private.hh"
+#include "hb-map-private.hh"
 
-struct hb_subset_plan_t {
+struct hb_subset_plan_t
+{
   hb_object_header_t header;
   ASSERT_POD ();
 
   hb_bool_t drop_hints;
+  hb_bool_t drop_ot_layout;
 
-  // TODO(Q1) actual map, drop this crap
-  // Look at me ma, I'm a poor mans map codepoint : new gid
-  // codepoints is sorted and aligned with gids_to_retain.
-
-  // These first two lists provide a mapping from cp -> gid
-  // As a result it does not list the full set of glyphs to retain.
-  hb_prealloced_array_t<hb_codepoint_t> codepoints;
-  hb_prealloced_array_t<hb_codepoint_t> gids_to_retain;
+  // For each cp that we'd like to retain maps to the corresponding gid.
+  hb_set_t *unicodes;
 
   // This list contains the complete set of glyphs to retain and may contain
   // more glyphs then the lists above.
-  hb_prealloced_array_t<hb_codepoint_t> gids_to_retain_sorted;
+  hb_vector_t<hb_codepoint_t> glyphs;
+
+  hb_map_t *codepoint_to_glyph;
+  hb_map_t *glyph_map;
 
   // Plan is only good for a specific source/dest so keep them with it
   hb_face_t *source;
   hb_face_t *dest;
+
+  inline hb_bool_t
+  new_gid_for_codepoint (hb_codepoint_t codepoint,
+                         hb_codepoint_t *new_gid) const
+  {
+    hb_codepoint_t old_gid = codepoint_to_glyph->get (codepoint);
+    if (old_gid == HB_MAP_VALUE_INVALID)
+      return false;
+
+    return new_gid_for_old_gid (old_gid, new_gid);
+  }
+
+  inline hb_bool_t
+  new_gid_for_old_gid (hb_codepoint_t old_gid,
+                      hb_codepoint_t *new_gid) const
+  {
+    hb_codepoint_t gid = glyph_map->get (old_gid);
+    if (gid == HB_MAP_VALUE_INVALID)
+      return false;
+
+    *new_gid = gid;
+    return true;
+  }
+
+  inline hb_bool_t
+  add_table (hb_tag_t tag,
+             hb_blob_t *contents)
+  {
+    hb_blob_t *source_blob = source->reference_table (tag);
+    DEBUG_MSG(SUBSET, nullptr, "add table %c%c%c%c, dest %d bytes, source %d bytes",
+              HB_UNTAG(tag),
+              hb_blob_get_length (contents),
+              hb_blob_get_length (source_blob));
+    hb_blob_destroy (source_blob);
+    return hb_subset_face_add_table(dest, tag, contents);
+  }
 };
 
 typedef struct hb_subset_plan_t hb_subset_plan_t;
@@ -64,21 +101,6 @@ hb_subset_plan_create (hb_face_t           *face,
                        hb_subset_profile_t *profile,
                        hb_subset_input_t   *input);
 
-HB_INTERNAL hb_bool_t
-hb_subset_plan_new_gid_for_old_id(hb_subset_plan_t *plan,
-                                  hb_codepoint_t old_gid,
-                                  hb_codepoint_t *new_gid /* OUT */);
-
-HB_INTERNAL hb_bool_t
-hb_subset_plan_new_gid_for_codepoint(hb_subset_plan_t *plan,
-                                     hb_codepoint_t codepont,
-                                     hb_codepoint_t *new_gid /* OUT */);
-
-HB_INTERNAL hb_bool_t
-hb_subset_plan_add_table(hb_subset_plan_t *plan,
-                         hb_tag_t tag,
-                         hb_blob_t *contents);
-
 HB_INTERNAL void
 hb_subset_plan_destroy (hb_subset_plan_t *plan);
 
index 5fa7252..6b2b207 100644 (file)
@@ -44,6 +44,7 @@ struct hb_subset_input_t {
   hb_set_t *glyphs;
 
   hb_bool_t drop_hints;
+  hb_bool_t drop_ot_layout;
   /* TODO
    *
    * features
index 9ebe5d3..b97c763 100644 (file)
 #include "hb-ot-hmtx-table.hh"
 #include "hb-ot-maxp-table.hh"
 #include "hb-ot-os2-table.hh"
-
-
-#ifndef HB_NO_VISIBILITY
-const void * const OT::_hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {};
-#endif
+#include "hb-ot-post-table.hh"
 
 
 struct hb_subset_profile_t {
@@ -86,14 +82,18 @@ _subset (hb_subset_plan_t *plan)
   OT::Sanitizer<TableType> sanitizer;
 
   hb_blob_t *source_blob = sanitizer.sanitize (plan->source->reference_table (TableType::tableTag));
-  const TableType *table = OT::Sanitizer<TableType>::lock_instance (source_blob);
+  const TableType *table = source_blob->as<TableType> ();
 
+  hb_tag_t tag = TableType::tableTag;
   hb_bool_t result = false;
-  if (table != &OT::Null(TableType))
+  if (table != &Null(TableType))
+  {
     result = table->subset(plan);
+  } else {
+    DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG(tag));
+  }
 
   hb_blob_destroy (source_blob);
-  hb_tag_t tag = TableType::tableTag;
   DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG(tag), result ? "success" : "FAILED!");
   return result;
 }
@@ -118,7 +118,7 @@ struct hb_subset_face_data_t
     hb_blob_t *blob;
   };
 
-  hb_prealloced_array_t<table_entry_t, 32> tables;
+  hb_vector_t<table_entry_t, 32> tables;
 };
 
 static hb_subset_face_data_t *
@@ -128,6 +128,8 @@ _hb_subset_face_data_create (void)
   if (unlikely (!data))
     return nullptr;
 
+  data->tables.init ();
+
   return data;
 }
 
@@ -139,7 +141,7 @@ _hb_subset_face_data_destroy (void *user_data)
   for (unsigned int i = 0; i < data->tables.len; i++)
     hb_blob_destroy (data->tables[i].blob);
 
-  data->tables.finish ();
+  data->tables.fini ();
 
   free (data);
 }
@@ -152,7 +154,7 @@ _hb_subset_face_data_reference_blob (hb_subset_face_data_t *data)
   unsigned int face_length = table_count * 16 + 12;
 
   for (unsigned int i = 0; i < table_count; i++)
-    face_length += _hb_ceil_to_4 (hb_blob_get_length (data->tables.array[i].blob));
+    face_length += _hb_ceil_to_4 (hb_blob_get_length (data->tables.arrayZ[i].blob));
 
   char *buf = (char *) malloc (face_length);
   if (unlikely (!buf))
@@ -214,13 +216,11 @@ hb_subset_face_create (void)
 hb_bool_t
 hb_subset_face_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob)
 {
-  if (unlikely (face->destroy != _hb_subset_face_data_destroy))
+  if (unlikely (face->destroy != (hb_destroy_func_t) _hb_subset_face_data_destroy))
     return false;
 
   hb_subset_face_data_t *data = (hb_subset_face_data_t *) face->user_data;
   hb_subset_face_data_t::table_entry_t *entry = data->tables.push ();
-  if (unlikely (!entry))
-    return false;
 
   entry->tag = tag;
   entry->blob = hb_blob_reference (blob);
@@ -252,6 +252,12 @@ _subset_table (hb_subset_plan_t *plan,
     case HB_OT_TAG_hmtx:
       result = _subset<const OT::hmtx> (plan);
       break;
+    case HB_OT_TAG_vhea:
+      DEBUG_MSG(SUBSET, nullptr, "skip vhea handled by vmtx");
+      return true;
+    case HB_OT_TAG_vmtx:
+      result = _subset<const OT::vmtx> (plan);
+      break;
     case HB_OT_TAG_maxp:
       result = _subset<const OT::maxp> (plan);
       break;
@@ -264,10 +270,13 @@ _subset_table (hb_subset_plan_t *plan,
     case HB_OT_TAG_os2:
       result = _subset<const OT::os2> (plan);
       break;
+    case HB_OT_TAG_post:
+      result = _subset<const OT::post> (plan);
+      break;
     default:
       hb_blob_t *source_table = hb_face_reference_table(plan->source, tag);
       if (likely (source_table))
-        result = hb_subset_plan_add_table(plan, tag, source_table);
+        result = plan->add_table(tag, source_table);
       else
         result = false;
       hb_blob_destroy (source_table);
@@ -280,21 +289,41 @@ _subset_table (hb_subset_plan_t *plan,
 static bool
 _should_drop_table(hb_subset_plan_t *plan, hb_tag_t tag)
 {
-    switch (tag) {
-      case HB_TAG ('c', 'v', 'a', 'r'): /* hint table, fallthrough */
-      case HB_TAG ('c', 'v', 't', ' '): /* hint table, fallthrough */
-      case HB_TAG ('f', 'p', 'g', 'm'): /* hint table, fallthrough */
-      case HB_TAG ('p', 'r', 'e', 'p'): /* hint table, fallthrough */
-      case HB_TAG ('h', 'd', 'm', 'x'): /* hint table, fallthrough */
-      case HB_TAG ('V', 'D', 'M', 'X'): /* hint table, fallthrough */
-        return plan->drop_hints;
-      case HB_TAG ('G', 'D', 'E', 'F'): /* temporary */
-      case HB_TAG ('G', 'P', 'O', 'S'): /* temporary */
-      case HB_TAG ('G', 'S', 'U', 'B'): /* temporary */
-      case HB_TAG ('D', 'S', 'I', 'G'):
-        return true;
-      default:
-        return false;
+  switch (tag) {
+    case HB_TAG ('c', 'v', 'a', 'r'): /* hint table, fallthrough */
+    case HB_TAG ('c', 'v', 't', ' '): /* hint table, fallthrough */
+    case HB_TAG ('f', 'p', 'g', 'm'): /* hint table, fallthrough */
+    case HB_TAG ('p', 'r', 'e', 'p'): /* hint table, fallthrough */
+    case HB_TAG ('h', 'd', 'm', 'x'): /* hint table, fallthrough */
+    case HB_TAG ('V', 'D', 'M', 'X'): /* hint table, fallthrough */
+      return plan->drop_hints;
+    // Drop Layout Tables if requested.
+    case HB_TAG ('G', 'D', 'E', 'F'): /* temporary */
+    case HB_TAG ('G', 'P', 'O', 'S'): /* temporary */
+    case HB_TAG ('G', 'S', 'U', 'B'): /* temporary */
+      return plan->drop_ot_layout;
+    // Drop these tables below by default, list pulled
+    // from fontTools:
+    case HB_TAG ('B', 'A', 'S', 'E'):
+    case HB_TAG ('J', 'S', 'T', 'F'):
+    case HB_TAG ('D', 'S', 'I', 'G'):
+    case HB_TAG ('E', 'B', 'D', 'T'):
+    case HB_TAG ('E', 'B', 'L', 'C'):
+    case HB_TAG ('E', 'B', 'S', 'C'):
+    case HB_TAG ('S', 'V', 'G', ' '):
+    case HB_TAG ('P', 'C', 'L', 'T'):
+    case HB_TAG ('L', 'T', 'S', 'H'):
+    // Graphite tables:
+    case HB_TAG ('F', 'e', 'a', 't'):
+    case HB_TAG ('G', 'l', 'a', 't'):
+    case HB_TAG ('G', 'l', 'o', 'c'):
+    case HB_TAG ('S', 'i', 'l', 'f'):
+    case HB_TAG ('S', 'i', 'l', 'l'):
+    // Colour
+    case HB_TAG ('s', 'b', 'i', 'x'):
+      return true;
+    default:
+      return false;
   }
 }
 
@@ -331,9 +360,24 @@ hb_subset (hb_face_t *source,
       }
       success = success && _subset_table (plan, tag);
     }
+    offset += count;
   } while (count == ARRAY_LENGTH (table_tags));
 
   hb_face_t *result = success ? hb_face_reference(plan->dest) : hb_face_get_empty();
   hb_subset_plan_destroy (plan);
   return result;
 }
+
+/**
+ * hb_subset_get_all_codepoints:
+ * @source: font face data to load.
+ * @out: set to add the all codepoints covered by font face, source.
+ */
+void
+hb_subset_get_all_codepoints (hb_face_t *source, hb_set_t *out)
+{
+  OT::cmap::accelerator_t cmap;
+  cmap.init (source);
+  cmap.get_all_codepoints (out);
+  cmap.fini();
+}
index 55ce25b..f6d2ae0 100644 (file)
@@ -71,13 +71,19 @@ hb_subset_input_glyph_set (hb_subset_input_t *subset_input);
 HB_EXTERN hb_bool_t *
 hb_subset_input_drop_hints (hb_subset_input_t *subset_input);
 
-/* hb_subset() */
+HB_EXTERN hb_bool_t *
+hb_subset_input_drop_ot_layout (hb_subset_input_t *subset_input);
 
+/* hb_subset() */
 HB_EXTERN hb_face_t *
 hb_subset (hb_face_t *source,
           hb_subset_profile_t *profile,
            hb_subset_input_t *input);
 
+/* hb_subset_get_all_codepoints */
+HB_EXTERN void
+hb_subset_get_all_codepoints (hb_face_t *source, hb_set_t *out);
+
 HB_END_DECLS
 
 #endif /* HB_SUBSET_H */
index 9515bda..2c08718 100644 (file)
@@ -164,6 +164,13 @@ static const hb_script_t ucdn_script_translate[] =
     HB_SCRIPT_NUSHU,
     HB_SCRIPT_SOYOMBO,
     HB_SCRIPT_ZANABAZAR_SQUARE,
+    HB_SCRIPT_DOGRA,
+    HB_SCRIPT_GUNJALA_GONDI,
+    HB_SCRIPT_HANIFI_ROHINGYA,
+    HB_SCRIPT_MAKASAR,
+    HB_SCRIPT_MEDEFAIDRIN,
+    HB_SCRIPT_OLD_SOGDIAN,
+    HB_SCRIPT_SOGDIAN,
 };
 
 static hb_unicode_combining_class_t
@@ -237,7 +244,12 @@ static hb_unicode_funcs_t *static_ucdn_funcs = nullptr;
 static
 void free_static_ucdn_funcs (void)
 {
-  hb_unicode_funcs_destroy (static_ucdn_funcs);
+retry:
+  hb_unicode_funcs_t *ucdn_funcs = (hb_unicode_funcs_t *) hb_atomic_ptr_get (&static_ucdn_funcs);
+  if (!hb_atomic_ptr_cmpexch (&static_ucdn_funcs, ucdn_funcs, nullptr))
+    goto retry;
+
+  hb_unicode_funcs_destroy (ucdn_funcs);
 }
 #endif
 
index 22d7d14..59bbf55 100644 (file)
@@ -90,7 +90,8 @@ build_triplet = @build@
 host_triplet = @host@
 subdir = src/hb-ucdn
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
+       $(top_srcdir)/m4/ax_code_coverage.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
index 2d5fc35..9b0f9d4 100644 (file)
@@ -42,6 +42,16 @@ HB_BEGIN_HEADER
 #  include <inttypes.h>
 #elif defined (_AIX)
 #  include <sys/inttypes.h>
+#elif defined (_MSC_VER) && _MSC_VER < 1600
+/* VS 2010 (_MSC_VER 1600) has stdint.h */
+typedef __int8 int8_t;
+typedef unsigned __int8 uint8_t;
+typedef __int16 int16_t;
+typedef unsigned __int16 uint16_t;
+typedef __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
 #else
 #  include <stdint.h>
 #endif
index 8d2d8de..87872b7 100644 (file)
@@ -1,6 +1,6 @@
 /* this file was generated by makeunicodedata.py 3.2 */
 
-#define UNIDATA_VERSION "10.0.0"
+#define UNIDATA_VERSION "11.0.0"
 /* a list of unique database records */
 static const UCDRecord ucd_records[] = {
     {2, 0, 18, 5, 102, 39},
@@ -185,6 +185,7 @@ static const UCDRecord ucd_records[] = {
     {21, 0, 18, 5, 65, 12},
     {21, 0, 18, 5, 65, 8},
     {21, 0, 18, 5, 65, 6},
+    {23, 0, 3, 5, 65, 9},
     {7, 0, 3, 5, 81, 12},
     {12, 230, 13, 5, 81, 21},
     {6, 0, 3, 5, 81, 12},
@@ -217,12 +218,14 @@ static const UCDRecord ucd_records[] = {
     {26, 0, 0, 5, 10, 12},
     {23, 0, 10, 5, 10, 9},
     {21, 0, 0, 5, 10, 12},
+    {12, 230, 13, 5, 10, 21},
     {12, 0, 13, 5, 11, 21},
     {10, 0, 0, 5, 11, 21},
     {7, 0, 0, 5, 11, 12},
     {12, 7, 13, 5, 11, 21},
     {12, 9, 13, 5, 11, 21},
     {13, 0, 0, 5, 11, 11},
+    {21, 0, 0, 5, 11, 12},
     {12, 0, 13, 5, 12, 21},
     {10, 0, 0, 5, 12, 21},
     {7, 0, 0, 5, 12, 12},
@@ -259,6 +262,7 @@ static const UCDRecord ucd_records[] = {
     {7, 0, 0, 5, 16, 12},
     {12, 0, 13, 5, 16, 21},
     {10, 0, 0, 5, 16, 21},
+    {21, 0, 0, 5, 16, 18},
     {12, 7, 13, 5, 16, 21},
     {12, 0, 0, 5, 16, 21},
     {12, 9, 13, 5, 16, 21},
@@ -328,7 +332,7 @@ static const UCDRecord ucd_records[] = {
     {12, 220, 13, 5, 22, 36},
     {26, 0, 0, 5, 22, 36},
     {9, 0, 0, 5, 23, 12},
-    {7, 0, 0, 5, 23, 12},
+    {5, 0, 0, 5, 23, 12},
     {21, 0, 0, 5, 0, 12},
     {6, 0, 0, 5, 23, 12},
     {7, 0, 0, 2, 24, 25},
@@ -547,7 +551,6 @@ static const UCDRecord ucd_records[] = {
     {21, 0, 18, 5, 54, 6},
     {21, 0, 18, 5, 54, 17},
     {15, 0, 18, 5, 54, 12},
-    {5, 0, 0, 5, 23, 12},
     {7, 0, 0, 5, 57, 12},
     {6, 0, 0, 5, 57, 12},
     {21, 0, 0, 5, 57, 17},
@@ -803,7 +806,17 @@ static const UCDRecord ucd_records[] = {
     {9, 0, 3, 5, 130, 12},
     {5, 0, 3, 5, 130, 12},
     {15, 0, 3, 5, 130, 12},
+    {7, 0, 4, 5, 144, 12},
+    {12, 230, 13, 5, 144, 21},
+    {13, 0, 11, 5, 144, 11},
     {15, 0, 11, 5, 6, 12},
+    {7, 0, 3, 5, 147, 12},
+    {15, 0, 3, 5, 147, 12},
+    {7, 0, 4, 5, 148, 12},
+    {12, 220, 13, 5, 148, 21},
+    {12, 230, 13, 5, 148, 21},
+    {15, 0, 4, 5, 148, 12},
+    {21, 0, 4, 5, 148, 12},
     {10, 0, 0, 5, 93, 21},
     {12, 0, 13, 5, 93, 21},
     {7, 0, 0, 5, 93, 12},
@@ -861,6 +874,7 @@ static const UCDRecord ucd_records[] = {
     {12, 0, 13, 5, 107, 21},
     {10, 0, 0, 5, 107, 21},
     {7, 0, 0, 5, 107, 12},
+    {12, 7, 13, 5, 40, 21},
     {12, 7, 13, 5, 107, 21},
     {10, 9, 0, 5, 107, 21},
     {12, 230, 13, 5, 107, 21},
@@ -872,6 +886,7 @@ static const UCDRecord ucd_records[] = {
     {21, 0, 0, 5, 135, 17},
     {21, 0, 0, 5, 135, 12},
     {13, 0, 0, 5, 135, 11},
+    {12, 230, 13, 5, 135, 21},
     {7, 0, 0, 5, 124, 12},
     {10, 0, 0, 5, 124, 21},
     {12, 0, 13, 5, 124, 21},
@@ -910,6 +925,12 @@ static const UCDRecord ucd_records[] = {
     {15, 0, 0, 5, 126, 36},
     {21, 0, 0, 5, 126, 17},
     {26, 0, 0, 5, 126, 36},
+    {7, 0, 0, 5, 142, 12},
+    {10, 0, 0, 5, 142, 21},
+    {12, 0, 13, 5, 142, 21},
+    {12, 9, 13, 5, 142, 21},
+    {12, 7, 13, 5, 142, 21},
+    {21, 0, 0, 5, 142, 12},
     {9, 0, 0, 5, 125, 12},
     {5, 0, 0, 5, 125, 12},
     {13, 0, 0, 5, 125, 11},
@@ -917,8 +938,9 @@ static const UCDRecord ucd_records[] = {
     {7, 0, 0, 5, 125, 12},
     {7, 0, 0, 5, 141, 12},
     {12, 0, 13, 5, 141, 21},
-    {10, 0, 0, 5, 141, 21},
+    {12, 0, 0, 5, 141, 21},
     {12, 9, 13, 5, 141, 21},
+    {10, 0, 0, 5, 141, 21},
     {21, 0, 0, 5, 141, 18},
     {21, 0, 0, 5, 141, 12},
     {21, 0, 0, 5, 141, 17},
@@ -946,6 +968,15 @@ static const UCDRecord ucd_records[] = {
     {12, 7, 13, 5, 138, 21},
     {12, 9, 13, 5, 138, 21},
     {13, 0, 0, 5, 138, 11},
+    {7, 0, 0, 5, 143, 12},
+    {10, 0, 0, 5, 143, 21},
+    {12, 0, 13, 5, 143, 21},
+    {12, 9, 13, 5, 143, 21},
+    {13, 0, 0, 5, 143, 11},
+    {7, 0, 0, 5, 145, 12},
+    {12, 0, 13, 5, 145, 21},
+    {10, 0, 0, 5, 145, 21},
+    {21, 0, 0, 5, 145, 12},
     {7, 0, 0, 5, 62, 12},
     {14, 0, 0, 5, 62, 12},
     {21, 0, 0, 5, 62, 17},
@@ -969,6 +1000,11 @@ static const UCDRecord ucd_records[] = {
     {6, 0, 0, 5, 119, 12},
     {13, 0, 0, 5, 119, 11},
     {15, 0, 0, 5, 119, 12},
+    {9, 0, 0, 5, 146, 12},
+    {5, 0, 0, 5, 146, 12},
+    {15, 0, 0, 5, 146, 12},
+    {21, 0, 0, 5, 146, 17},
+    {21, 0, 0, 5, 146, 12},
     {7, 0, 0, 5, 98, 12},
     {10, 0, 0, 5, 98, 21},
     {12, 0, 13, 5, 98, 21},
@@ -1001,6 +1037,9 @@ static const UCDRecord ucd_records[] = {
     {12, 7, 13, 5, 132, 21},
     {13, 0, 3, 5, 132, 11},
     {21, 0, 3, 5, 132, 0},
+    {15, 0, 4, 5, 0, 12},
+    {26, 0, 4, 5, 0, 10},
+    {23, 0, 4, 5, 0, 10},
     {2, 0, 18, 5, 102, 14},
     {26, 0, 0, 2, 0, 29},
     {26, 0, 0, 5, 0, 28},
@@ -1009,7 +1048,7 @@ static const UCDRecord ucd_records[] = {
     {26, 0, 18, 5, 0, 5},
 };
 
-#define BIDI_MIRROR_LEN 364
+#define BIDI_MIRROR_LEN 420
 static const MirrorPair mirror_pairs[] = {
     {40, 41},
     {41, 40},
@@ -1042,9 +1081,16 @@ static const MirrorPair mirror_pairs[] = {
     {8716, 8713},
     {8717, 8714},
     {8725, 10741},
+    {8735, 11262},
+    {8736, 10659},
+    {8737, 10651},
+    {8738, 10656},
+    {8740, 10990},
     {8764, 8765},
     {8765, 8764},
     {8771, 8909},
+    {8773, 8780},
+    {8780, 8773},
     {8786, 8787},
     {8787, 8786},
     {8788, 8789},
@@ -1106,6 +1152,7 @@ static const MirrorPair mirror_pairs[] = {
     {8885, 8884},
     {8886, 8887},
     {8887, 8886},
+    {8888, 10204},
     {8905, 8906},
     {8906, 8905},
     {8907, 8908},
@@ -1179,6 +1226,7 @@ static const MirrorPair mirror_pairs[] = {
     {10189, 10187},
     {10197, 10198},
     {10198, 10197},
+    {10204, 8888},
     {10205, 10206},
     {10206, 10205},
     {10210, 10211},
@@ -1217,6 +1265,19 @@ static const MirrorPair mirror_pairs[] = {
     {10646, 10645},
     {10647, 10648},
     {10648, 10647},
+    {10651, 8737},
+    {10656, 8738},
+    {10659, 8736},
+    {10660, 10661},
+    {10661, 10660},
+    {10664, 10665},
+    {10665, 10664},
+    {10666, 10667},
+    {10667, 10666},
+    {10668, 10669},
+    {10669, 10668},
+    {10670, 10671},
+    {10671, 10670},
     {10680, 8856},
     {10688, 10689},
     {10689, 10688},
@@ -1232,6 +1293,8 @@ static const MirrorPair mirror_pairs[] = {
     {10713, 10712},
     {10714, 10715},
     {10715, 10714},
+    {10728, 10729},
+    {10729, 10728},
     {10741, 8725},
     {10744, 10745},
     {10745, 10744},
@@ -1249,6 +1312,8 @@ static const MirrorPair mirror_pairs[] = {
     {10853, 10852},
     {10873, 10874},
     {10874, 10873},
+    {10875, 10876},
+    {10876, 10875},
     {10877, 10878},
     {10878, 10877},
     {10879, 10880},
@@ -1257,8 +1322,18 @@ static const MirrorPair mirror_pairs[] = {
     {10882, 10881},
     {10883, 10884},
     {10884, 10883},
+    {10885, 10886},
+    {10886, 10885},
+    {10887, 10888},
+    {10888, 10887},
+    {10889, 10890},
+    {10890, 10889},
     {10891, 10892},
     {10892, 10891},
+    {10893, 10894},
+    {10894, 10893},
+    {10895, 10896},
+    {10896, 10895},
     {10897, 10898},
     {10898, 10897},
     {10899, 10900},
@@ -1271,6 +1346,10 @@ static const MirrorPair mirror_pairs[] = {
     {10906, 10905},
     {10907, 10908},
     {10908, 10907},
+    {10909, 10910},
+    {10910, 10909},
+    {10911, 10912},
+    {10912, 10911},
     {10913, 10914},
     {10914, 10913},
     {10918, 10919},
@@ -1283,8 +1362,16 @@ static const MirrorPair mirror_pairs[] = {
     {10925, 10924},
     {10927, 10928},
     {10928, 10927},
+    {10929, 10930},
+    {10930, 10929},
     {10931, 10932},
     {10932, 10931},
+    {10933, 10934},
+    {10934, 10933},
+    {10935, 10936},
+    {10936, 10935},
+    {10937, 10938},
+    {10938, 10937},
     {10939, 10940},
     {10940, 10939},
     {10941, 10942},
@@ -1297,6 +1384,12 @@ static const MirrorPair mirror_pairs[] = {
     {10948, 10947},
     {10949, 10950},
     {10950, 10949},
+    {10951, 10952},
+    {10952, 10951},
+    {10953, 10954},
+    {10954, 10953},
+    {10955, 10956},
+    {10956, 10955},
     {10957, 10958},
     {10958, 10957},
     {10959, 10960},
@@ -1313,10 +1406,12 @@ static const MirrorPair mirror_pairs[] = {
     {10981, 8875},
     {10988, 10989},
     {10989, 10988},
+    {10990, 8740},
     {10999, 11000},
     {11000, 10999},
     {11001, 11002},
     {11002, 11001},
+    {11262, 8735},
     {11778, 11779},
     {11779, 11778},
     {11780, 11781},
@@ -1910,6 +2005,13 @@ static const Reindex nfc_last[] = {
 #define UCDN_SCRIPT_NUSHU 139
 #define UCDN_SCRIPT_SOYOMBO 140
 #define UCDN_SCRIPT_ZANABAZAR_SQUARE 141
+#define UCDN_SCRIPT_DOGRA 142
+#define UCDN_SCRIPT_GUNJALA_GONDI 143
+#define UCDN_SCRIPT_HANIFI_ROHINGYA 144
+#define UCDN_SCRIPT_MAKASAR 145
+#define UCDN_SCRIPT_MEDEFAIDRIN 146
+#define UCDN_SCRIPT_OLD_SOGDIAN 147
+#define UCDN_SCRIPT_SOGDIAN 148
 
 #define UCDN_GENERAL_CATEGORY_CC 0
 #define UCDN_GENERAL_CATEGORY_CF 1
@@ -1984,22 +2086,24 @@ static const unsigned char index0[] = {
     66, 67, 68, 69, 70, 71, 65, 66, 67, 68, 69, 70, 71, 65, 72, 73, 73, 73, 
     73, 73, 73, 73, 73, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
     74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 52, 75, 76, 77, 78, 79, 
-    80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 94, 96, 
-    97, 98, 99, 100, 101, 102, 103, 104, 94, 105, 94, 106, 107, 94, 94, 108, 
-    108, 108, 109, 110, 111, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 112, 
-    112, 113, 114, 115, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 116, 117, 118, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 119, 119, 120, 121, 94, 94, 94, 122, 123, 123, 123, 123, 123, 
-    123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 
-    123, 123, 123, 123, 124, 123, 123, 125, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 126, 127, 128, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 129, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 130, 131, 132, 133, 134, 135, 136, 137, 
-    138, 138, 139, 94, 94, 94, 94, 94, 140, 94, 94, 94, 94, 94, 94, 94, 141, 
-    142, 94, 94, 94, 94, 143, 94, 144, 145, 146, 147, 148, 149, 150, 151, 
-    152, 153, 154, 154, 154, 154, 154, 155, 52, 52, 52, 52, 52, 52, 52, 52, 
+    80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 
+    98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 106, 108, 109, 110, 106, 
+    111, 111, 111, 112, 113, 114, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 115, 115, 116, 117, 118, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 119, 120, 121, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 122, 122, 123, 124, 106, 106, 125, 126, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 128, 127, 127, 129, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 130, 131, 132, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 133, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 134, 135, 136, 137, 138, 139, 
+    140, 141, 142, 142, 143, 106, 106, 106, 106, 106, 144, 106, 106, 106, 
+    106, 106, 106, 106, 145, 146, 106, 106, 147, 106, 148, 106, 149, 150, 
+    151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 160, 160, 160, 161, 52, 
     52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
     52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
     52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
@@ -2008,187 +2112,232 @@ static const unsigned char index0[] = {
     52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
     52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
     52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
-    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 156, 52, 52, 52, 
-    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 157, 158, 52, 52, 52, 
     52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
-    159, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
-    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 160, 161, 161, 161, 161, 161, 
-    161, 161, 161, 161, 161, 161, 161, 52, 52, 162, 161, 161, 161, 161, 163, 
-    161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 
-    161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 
-    161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 
-    161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 
-    161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 
-    161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 
-    161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 
-    161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 
-    161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 
-    161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 
-    161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 
-    161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 
-    161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 
-    161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 
-    161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 
-    161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 
-    161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 
-    161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 
-    161, 161, 161, 163, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 164, 165, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 74, 74, 74, 74, 74, 
+    52, 52, 52, 162, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
+    52, 52, 163, 164, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
+    52, 52, 52, 52, 52, 52, 52, 165, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
+    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
+    166, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 52, 52, 
+    168, 167, 167, 167, 167, 169, 167, 167, 167, 167, 167, 167, 167, 167, 
+    167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 
+    167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 
+    167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 
+    167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 
+    167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 
+    167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 
+    167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 
+    167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 
+    167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 
+    167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 
+    167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 
+    167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 
+    167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 
+    167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 
+    167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 
+    167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 
+    167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 
+    167, 167, 167, 167, 167, 167, 167, 167, 167, 169, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 170, 171, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
+    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 74, 74, 74, 
     74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
     74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
     74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
@@ -2202,8 +2351,8 @@ static const unsigned char index0[] = {
     74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
     74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
     74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 166, 74, 
     74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
+    172, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
     74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
     74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
     74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
@@ -2217,7 +2366,7 @@ static const unsigned char index0[] = {
     74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
     74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
     74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 166
+    74, 74, 74, 74, 172
 };
 
 static const unsigned short index1[] = {
@@ -2230,391 +2379,405 @@ static const unsigned short index1[] = {
     79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 
     97, 97, 97, 97, 98, 98, 98, 98, 99, 100, 101, 101, 101, 101, 102, 103, 
     101, 101, 101, 101, 101, 101, 104, 105, 101, 101, 101, 101, 101, 101, 
-    101, 101, 101, 101, 101, 101, 106, 107, 107, 107, 108, 109, 110, 111
-    111, 111, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 121
-    121, 122, 123, 120, 124, 125, 126, 127, 128, 128, 128, 128, 129, 130
-    131, 132, 133, 134, 135, 128, 128, 128, 128, 128, 128, 128, 128, 128
-    128, 128, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 145, 145
-    146, 147, 148, 149, 128, 128, 128, 128, 128, 128, 150, 150, 150, 150
-    151, 152, 153, 120, 154, 155, 156, 156, 156, 157, 158, 159, 160, 160
-    161, 162, 163, 164, 165, 166, 167, 167, 167, 168, 145, 169, 120, 120
-    120, 120, 120, 120, 128, 128, 170, 171, 120, 120, 172, 126, 173, 174
-    175, 176, 177, 178, 178, 178, 178, 178, 178, 179, 180, 181, 182, 178
-    183, 184, 185, 178, 186, 187, 188, 189, 189, 190, 191, 192, 193, 194
-    195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 204, 205, 206, 207
-    208, 209, 210, 211, 212, 213, 214, 120, 215, 216, 217, 218, 218, 219
-    220, 221, 222, 223, 224, 120, 225, 226, 227, 228, 229, 230, 231, 232
-    232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 120, 243, 244
-    245, 246, 247, 244, 248, 249, 250, 251, 252, 120, 253, 254, 255, 256
-    257, 258, 259, 260, 260, 259, 260, 261, 262, 263, 264, 265, 266, 267
-    120, 268, 269, 270, 271, 272, 272, 271, 273, 274, 275, 276, 277, 278
-    279, 280, 281, 120, 282, 283, 284, 285, 285, 285, 285, 286, 287, 288
-    289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 296, 296, 299, 300
-    297, 301, 302, 303, 304, 305, 306, 120, 307, 308, 308, 308, 308, 308
-    309, 310, 311, 312, 313, 314, 120, 120, 120, 120, 315, 316, 317, 318
-    319, 320, 321, 322, 323, 324, 325, 326, 120, 120, 120, 120, 327, 328
-    329, 330, 331, 332, 333, 334, 335, 336, 335, 335, 335, 337, 338, 339
-    340, 341, 342, 343, 342, 342, 342, 344, 345, 346, 347, 348, 120, 120
-    120, 120, 349, 349, 349, 349, 349, 350, 351, 352, 353, 354, 355, 356
-    357, 358, 359, 349, 360, 361, 353, 362, 363, 363, 363, 363, 364, 365
-    366, 366, 366, 366, 366, 367, 368, 368, 368, 368, 368, 368, 368, 368
-    368, 368, 368, 368, 369, 369, 369, 369, 369, 369, 369, 369, 369, 370
-    370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 371, 371, 371, 371
-    371, 371, 371, 371, 371, 372, 373, 372, 371, 371, 371, 371, 371, 372
-    371, 371, 371, 371, 372, 373, 372, 371, 373, 371, 371, 371, 371, 371
-    371, 371, 372, 371, 371, 371, 371, 371, 371, 371, 371, 374, 375, 376
-    377, 378, 371, 371, 379, 380, 381, 381, 381, 381, 381, 381, 381, 381
-    381, 381, 382, 383, 384, 385, 385, 385, 385, 385, 385, 385, 385, 385
-    385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385
-    385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385
-    385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385
-    385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385
-    385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 386, 385, 385
-    387, 388, 388, 389, 390, 390, 390, 390, 390, 390, 390, 390, 390, 391
-    392, 393, 394, 395, 396, 120, 397, 397, 398, 120, 399, 399, 400, 120
-    401, 402, 403, 120, 404, 404, 404, 404, 404, 404, 405, 406, 407, 408
-    409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 419, 419, 419
-    420, 419, 419, 419, 419, 419, 419, 120, 421, 419, 419, 419, 419, 422, 
-    385, 385, 385, 385, 385, 385, 385, 385, 423, 120, 424, 424, 424, 425, 
-    426, 427, 428, 429, 430, 431, 432, 432, 432, 433, 434, 120, 435, 435, 
+    101, 101, 101, 101, 101, 101, 106, 107, 107, 107, 108, 109, 110, 110
+    110, 110, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 120
+    120, 121, 122, 119, 123, 124, 125, 126, 127, 127, 127, 127, 128, 129
+    130, 131, 132, 133, 134, 127, 127, 127, 127, 127, 127, 127, 127, 127
+    127, 127, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 144, 144
+    145, 146, 147, 148, 127, 127, 127, 127, 127, 127, 149, 149, 149, 149
+    150, 151, 152, 119, 153, 154, 155, 155, 155, 156, 157, 158, 159, 159
+    160, 161, 162, 163, 164, 165, 166, 166, 166, 167, 144, 168, 119, 119
+    119, 119, 119, 119, 127, 127, 169, 170, 119, 119, 171, 125, 172, 173
+    174, 175, 176, 177, 177, 177, 177, 177, 177, 178, 179, 180, 181, 177
+    182, 183, 184, 177, 185, 186, 187, 188, 188, 189, 190, 191, 192, 193
+    194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 203, 204, 205, 206
+    207, 208, 209, 210, 211, 212, 213, 119, 214, 215, 216, 217, 217, 218
+    219, 220, 221, 222, 223, 119, 224, 225, 226, 227, 228, 229, 230, 231
+    231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 119, 242, 243
+    244, 245, 246, 243, 247, 248, 249, 250, 251, 119, 252, 253, 254, 255
+    256, 257, 258, 259, 259, 258, 259, 260, 261, 262, 263, 264, 265, 266
+    119, 267, 268, 269, 270, 271, 271, 270, 272, 273, 274, 275, 276, 277
+    278, 279, 280, 119, 281, 282, 283, 284, 284, 284, 284, 285, 286, 287
+    288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 295, 295, 298, 299
+    296, 300, 301, 302, 303, 304, 305, 119, 306, 307, 307, 307, 307, 307
+    308, 309, 310, 311, 312, 313, 119, 119, 119, 119, 314, 315, 316, 317
+    318, 319, 320, 321, 322, 323, 324, 325, 119, 119, 119, 119, 326, 327
+    328, 329, 330, 331, 332, 333, 334, 335, 334, 334, 334, 336, 337, 338
+    339, 340, 341, 342, 341, 341, 341, 343, 344, 345, 346, 347, 119, 119
+    119, 119, 348, 348, 348, 348, 348, 349, 350, 351, 352, 353, 354, 355
+    356, 357, 358, 348, 359, 360, 352, 361, 362, 362, 362, 362, 363, 364
+    365, 365, 365, 365, 365, 366, 367, 367, 367, 367, 367, 367, 367, 367
+    367, 367, 367, 367, 368, 368, 368, 368, 368, 368, 368, 368, 368, 369
+    369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 370, 370, 370, 370
+    370, 370, 370, 370, 370, 371, 372, 371, 370, 370, 370, 370, 370, 371
+    370, 370, 370, 370, 371, 372, 371, 370, 372, 370, 370, 370, 370, 370
+    370, 370, 371, 370, 370, 370, 370, 370, 370, 370, 370, 373, 374, 375
+    376, 377, 370, 370, 378, 379, 380, 380, 380, 380, 380, 380, 380, 380
+    380, 380, 381, 382, 383, 384, 384, 384, 384, 384, 384, 384, 384, 384
+    384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384
+    384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384
+    384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384
+    384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384
+    384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 385, 384, 384
+    386, 387, 387, 388, 389, 389, 389, 389, 389, 389, 389, 389, 389, 390
+    391, 392, 393, 394, 395, 119, 396, 396, 397, 119, 398, 398, 399, 119
+    400, 401, 402, 119, 403, 403, 403, 403, 403, 403, 404, 405, 406, 407
+    408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 418, 418, 418
+    419, 418, 418, 418, 418, 418, 418, 420, 421, 418, 418, 418, 418, 422, 
+    384, 384, 384, 384, 384, 384, 384, 384, 423, 119, 424, 424, 424, 425, 
+    426, 427, 428, 429, 430, 431, 432, 432, 432, 433, 434, 119, 435, 435, 
     435, 435, 435, 436, 435, 435, 435, 437, 438, 439, 440, 440, 440, 440, 
     441, 441, 442, 443, 444, 444, 444, 444, 444, 444, 445, 446, 447, 448, 
-    449, 450, 451, 452, 451, 452, 453, 454, 455, 456, 120, 120, 120, 120
-    120, 120, 120, 120, 457, 458, 458, 458, 458, 458, 459, 460, 461, 462, 
+    449, 450, 451, 452, 451, 452, 453, 454, 455, 456, 119, 119, 119, 119
+    119, 119, 119, 119, 457, 458, 458, 458, 458, 458, 459, 460, 461, 462, 
     463, 464, 465, 466, 467, 468, 469, 470, 470, 470, 471, 472, 473, 474, 
     475, 475, 475, 475, 476, 477, 478, 479, 480, 480, 480, 480, 481, 482, 
-    483, 484, 485, 486, 487, 488, 489, 489, 489, 490, 100, 491, 120, 120, 
-    120, 120, 120, 120, 492, 120, 493, 494, 495, 496, 497, 498, 54, 54, 54, 
-    54, 499, 500, 56, 56, 56, 56, 56, 501, 502, 503, 54, 504, 54, 54, 54, 
-    505, 56, 56, 56, 506, 507, 508, 509, 510, 510, 510, 511, 512, 27, 27, 27, 
-    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 513, 514, 27, 
-    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 515, 516, 517, 518, 515, 516, 
-    515, 516, 517, 518, 515, 519, 515, 516, 515, 517, 515, 520, 515, 520, 
-    515, 520, 521, 522, 523, 524, 525, 526, 515, 527, 528, 529, 530, 531, 
-    532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 
-    546, 547, 56, 548, 549, 550, 551, 552, 553, 553, 554, 555, 556, 557, 558, 
-    120, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 
-    572, 571, 573, 574, 575, 576, 577, 578, 579, 580, 581, 580, 582, 583, 
-    580, 584, 580, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 586, 
-    595, 596, 586, 597, 598, 586, 586, 598, 586, 599, 600, 599, 586, 586, 
-    601, 586, 586, 586, 586, 586, 602, 586, 586, 580, 603, 604, 605, 606, 
-    607, 608, 609, 609, 609, 609, 609, 609, 609, 609, 610, 580, 580, 611, 
-    612, 586, 586, 613, 580, 580, 580, 580, 585, 606, 614, 615, 580, 580, 
-    580, 580, 580, 616, 120, 120, 120, 580, 617, 120, 120, 618, 618, 618, 
-    618, 618, 619, 619, 620, 621, 621, 621, 621, 621, 621, 621, 621, 621, 
-    622, 618, 623, 624, 624, 624, 624, 624, 624, 624, 624, 624, 625, 624, 
-    624, 624, 624, 626, 580, 624, 624, 627, 580, 628, 629, 630, 631, 632, 
-    633, 629, 580, 627, 634, 580, 635, 636, 637, 638, 639, 580, 580, 580, 
-    640, 641, 642, 643, 580, 644, 645, 580, 646, 580, 580, 647, 648, 649, 
-    650, 580, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 580, 
-    580, 580, 662, 580, 663, 580, 664, 665, 666, 667, 668, 669, 618, 670, 
-    670, 671, 580, 580, 580, 662, 672, 673, 586, 586, 586, 674, 675, 586, 
-    586, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 
-    676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 
-    676, 676, 676, 676, 676, 586, 586, 586, 586, 586, 586, 586, 586, 586, 
-    586, 586, 586, 586, 586, 586, 586, 677, 678, 678, 679, 586, 586, 586, 
-    586, 586, 586, 586, 680, 586, 586, 586, 681, 586, 586, 586, 586, 586, 
-    586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 
-    586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 580, 
-    580, 580, 682, 580, 580, 586, 586, 683, 684, 685, 629, 580, 580, 686, 
-    580, 580, 580, 687, 580, 580, 580, 580, 688, 580, 689, 617, 120, 120, 
-    690, 120, 120, 691, 691, 691, 691, 691, 692, 693, 693, 693, 693, 693, 
-    694, 695, 696, 697, 698, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 
-    699, 700, 701, 702, 703, 703, 703, 703, 704, 705, 706, 706, 706, 706, 
-    706, 706, 706, 707, 708, 709, 371, 371, 373, 120, 373, 373, 373, 373, 
-    373, 373, 373, 373, 710, 710, 710, 710, 711, 712, 713, 714, 715, 716, 
-    717, 718, 719, 720, 120, 120, 120, 120, 120, 120, 721, 721, 721, 722, 
-    721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 723, 120, 721, 721, 
-    721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 
-    721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 724, 120, 120, 120, 
-    725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 737, 
-    738, 737, 737, 737, 739, 740, 741, 742, 743, 744, 745, 745, 746, 745, 
-    745, 745, 747, 748, 749, 750, 751, 752, 752, 752, 752, 753, 754, 755, 
-    755, 755, 755, 755, 755, 755, 755, 755, 755, 756, 757, 758, 752, 752, 
-    752, 759, 725, 725, 725, 725, 726, 120, 760, 760, 761, 761, 761, 762, 
-    763, 764, 758, 758, 758, 765, 766, 767, 761, 761, 761, 768, 763, 764, 
-    758, 758, 758, 758, 769, 767, 758, 770, 771, 771, 771, 771, 771, 772, 
-    771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 758, 758, 758, 
-    773, 774, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 775, 
-    758, 758, 758, 773, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 
-    776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 
-    776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 
+    483, 484, 485, 486, 487, 488, 489, 489, 489, 490, 100, 491, 362, 362, 
+    362, 362, 362, 492, 493, 119, 494, 495, 496, 497, 498, 499, 54, 54, 54, 
+    54, 500, 501, 56, 56, 56, 56, 56, 502, 503, 504, 54, 505, 54, 54, 54, 
+    506, 56, 56, 56, 507, 508, 509, 510, 511, 511, 511, 512, 513, 27, 27, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 514, 515, 27, 
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 516, 517, 518, 519, 516, 517, 
+    516, 517, 518, 519, 516, 520, 516, 517, 516, 518, 516, 521, 516, 521, 
+    516, 521, 522, 523, 524, 525, 526, 527, 516, 528, 529, 530, 531, 532, 
+    533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 
+    547, 548, 56, 549, 550, 551, 552, 553, 554, 554, 555, 556, 557, 558, 559, 
+    119, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 
+    573, 572, 574, 575, 576, 577, 578, 579, 580, 581, 582, 581, 583, 584, 
+    581, 585, 581, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 587, 
+    596, 597, 587, 598, 599, 587, 587, 599, 587, 600, 601, 600, 587, 587, 
+    602, 587, 587, 587, 587, 587, 603, 587, 587, 581, 604, 605, 606, 607, 
+    608, 609, 610, 610, 610, 610, 610, 610, 610, 610, 611, 581, 581, 612, 
+    613, 587, 587, 614, 581, 581, 581, 581, 586, 607, 615, 616, 581, 581, 
+    581, 581, 581, 617, 119, 119, 119, 581, 618, 119, 119, 619, 619, 619, 
+    619, 619, 620, 620, 621, 622, 622, 622, 622, 622, 622, 622, 622, 622, 
+    623, 619, 624, 625, 625, 625, 625, 625, 625, 625, 625, 625, 626, 625, 
+    625, 625, 625, 627, 581, 625, 625, 628, 581, 629, 630, 631, 632, 633, 
+    634, 630, 581, 628, 635, 581, 636, 637, 638, 639, 640, 581, 581, 581, 
+    641, 642, 643, 644, 581, 645, 646, 581, 647, 581, 581, 648, 649, 650, 
+    651, 581, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 581, 
+    581, 581, 663, 581, 664, 581, 665, 666, 667, 668, 669, 670, 619, 671, 
+    671, 672, 581, 581, 581, 663, 673, 674, 587, 587, 587, 675, 676, 587, 
+    587, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 
+    677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 
+    677, 677, 677, 677, 677, 587, 587, 587, 587, 587, 587, 587, 587, 587, 
+    587, 587, 587, 587, 587, 587, 587, 678, 679, 679, 680, 587, 587, 587, 
+    587, 587, 587, 587, 681, 587, 587, 587, 682, 587, 587, 587, 587, 587, 
+    587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 
+    587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 581, 
+    581, 581, 683, 581, 581, 587, 587, 684, 685, 686, 630, 581, 581, 687, 
+    581, 581, 581, 688, 581, 581, 581, 581, 581, 581, 689, 581, 581, 581, 
+    581, 581, 617, 690, 690, 690, 690, 690, 691, 692, 692, 692, 692, 692, 
+    693, 694, 695, 696, 697, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 
+    698, 699, 700, 701, 365, 365, 365, 365, 702, 703, 704, 704, 704, 704, 
+    704, 704, 704, 705, 706, 707, 370, 370, 372, 119, 372, 372, 372, 372, 
+    372, 372, 372, 372, 708, 708, 708, 708, 709, 710, 711, 712, 713, 714, 
+    715, 716, 717, 718, 119, 119, 119, 119, 119, 119, 719, 719, 719, 720, 
+    719, 719, 719, 719, 719, 719, 719, 719, 719, 719, 721, 119, 719, 719, 
+    719, 719, 719, 719, 719, 719, 719, 719, 719, 719, 719, 719, 719, 719, 
+    719, 719, 719, 719, 719, 719, 719, 719, 719, 719, 722, 119, 119, 119, 
+    723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 735, 
+    736, 735, 735, 735, 737, 738, 739, 740, 741, 742, 743, 743, 744, 743, 
+    743, 743, 745, 746, 747, 748, 749, 750, 750, 750, 750, 750, 751, 752, 
+    752, 752, 752, 752, 752, 752, 752, 752, 752, 753, 754, 755, 750, 750, 
+    750, 756, 723, 723, 723, 723, 724, 119, 757, 757, 758, 758, 758, 759, 
+    760, 761, 755, 755, 755, 762, 763, 764, 758, 758, 758, 765, 760, 761, 
+    755, 755, 755, 755, 766, 764, 755, 767, 768, 768, 768, 768, 768, 769, 
+    768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 755, 755, 755, 
+    770, 771, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 772, 
+    755, 755, 755, 770, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 
+    773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 
+    773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 
+    773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 
+    773, 773, 774, 775, 581, 581, 581, 581, 581, 581, 581, 581, 773, 773, 
+    773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 
+    773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 
+    775, 775, 776, 776, 777, 776, 776, 776, 776, 776, 776, 776, 776, 776, 
     776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 
-    776, 776, 777, 778, 580, 580, 580, 580, 580, 580, 580, 580, 776, 776, 
     776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 
-    776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 779, 
-    778, 778, 780, 780, 781, 780, 780, 780, 780, 780, 780, 780, 780, 780, 
-    780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 
-    780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 
-    780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 
-    780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 
-    780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 782, 
-    783, 783, 783, 783, 783, 783, 784, 120, 785, 785, 785, 785, 785, 786, 
-    787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 
-    787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 
-    787, 787, 787, 787, 787, 788, 787, 787, 789, 790, 120, 120, 101, 101, 
-    101, 101, 101, 791, 792, 793, 101, 101, 101, 794, 795, 795, 795, 795, 
-    795, 795, 795, 795, 796, 797, 798, 120, 64, 64, 799, 800, 801, 27, 802, 
-    27, 27, 27, 27, 27, 27, 27, 803, 804, 27, 805, 806, 27, 27, 807, 808, 
-    120, 120, 120, 120, 120, 120, 120, 809, 810, 811, 812, 813, 813, 814, 
-    815, 816, 817, 818, 818, 818, 818, 818, 818, 819, 120, 820, 821, 821, 
-    821, 821, 821, 822, 823, 824, 825, 826, 827, 828, 828, 829, 830, 831, 
-    832, 833, 833, 834, 835, 836, 836, 837, 838, 839, 840, 368, 368, 368, 
-    841, 842, 843, 843, 843, 843, 843, 844, 845, 846, 847, 848, 849, 850, 
-    349, 353, 851, 852, 852, 852, 852, 852, 853, 854, 120, 855, 856, 857, 
-    858, 349, 349, 859, 860, 861, 861, 861, 861, 861, 861, 862, 863, 864, 
-    120, 120, 865, 866, 867, 868, 120, 869, 869, 869, 120, 373, 373, 54, 54, 
-    54, 54, 54, 870, 871, 120, 872, 872, 872, 872, 872, 872, 872, 872, 872, 
-    872, 866, 866, 866, 866, 873, 874, 875, 876, 877, 878, 878, 879, 878, 
-    878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, 
-    878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, 
-    878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, 
-    878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, 
-    878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, 
-    878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, 
-    878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, 
-    878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, 
-    878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, 
-    878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, 
-    878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, 
-    878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, 
-    878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, 
-    878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, 
-    878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, 
-    878, 878, 877, 878, 878, 879, 878, 878, 878, 878, 878, 878, 877, 878, 
-    878, 879, 878, 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 
-    878, 880, 120, 369, 369, 881, 882, 370, 370, 370, 370, 370, 883, 884, 
-    884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 
-    884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 
-    884, 884, 884, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 
-    885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 
-    885, 885, 885, 885, 885, 885, 885, 776, 776, 776, 776, 776, 776, 776, 
-    776, 776, 776, 776, 776, 776, 777, 776, 776, 776, 776, 776, 776, 776, 
-    776, 776, 776, 776, 776, 776, 886, 778, 778, 778, 778, 887, 120, 888, 
-    889, 121, 890, 891, 892, 893, 121, 128, 128, 128, 128, 128, 128, 128, 
-    128, 128, 128, 128, 128, 894, 895, 896, 120, 897, 128, 128, 128, 128, 
-    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
-    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 
-    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 898, 120, 
-    120, 128, 128, 128, 128, 128, 128, 128, 128, 899, 128, 128, 128, 128, 
-    128, 128, 120, 120, 120, 120, 120, 128, 900, 901, 901, 902, 903, 904, 
-    905, 906, 907, 908, 909, 910, 911, 912, 913, 170, 128, 128, 128, 128, 
-    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 914, 915, 
-    916, 917, 918, 919, 920, 920, 921, 922, 923, 923, 924, 925, 926, 927, 
-    928, 928, 928, 928, 929, 930, 930, 930, 931, 932, 932, 932, 933, 934, 
-    935, 120, 936, 937, 938, 937, 937, 939, 937, 937, 940, 937, 941, 937, 
-    941, 120, 120, 120, 120, 937, 937, 937, 937, 937, 937, 937, 937, 937, 
-    937, 937, 937, 937, 937, 937, 942, 943, 944, 944, 944, 944, 944, 945, 
-    609, 946, 946, 946, 946, 946, 946, 947, 948, 949, 950, 580, 951, 952, 
-    120, 120, 120, 120, 120, 609, 609, 609, 609, 609, 953, 120, 120, 120, 
-    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 954, 
-    954, 954, 955, 956, 956, 956, 956, 956, 956, 957, 120, 958, 959, 959, 
-    960, 961, 961, 961, 961, 962, 963, 964, 964, 965, 966, 967, 967, 967, 
-    967, 968, 969, 970, 970, 970, 971, 972, 972, 972, 972, 973, 972, 974, 
-    120, 120, 120, 120, 120, 975, 975, 975, 975, 975, 976, 976, 976, 976, 
-    976, 977, 977, 977, 977, 977, 977, 978, 978, 978, 979, 980, 981, 982, 
-    982, 982, 982, 983, 984, 984, 984, 984, 985, 986, 986, 986, 986, 986, 
-    120, 987, 987, 987, 987, 987, 987, 988, 989, 120, 120, 120, 120, 120, 
-    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 990, 
-    990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 
-    990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 
-    990, 990, 990, 990, 990, 990, 990, 990, 990, 991, 120, 990, 990, 992, 
-    120, 990, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 
-    120, 120, 120, 120, 120, 120, 120, 993, 994, 995, 995, 995, 995, 996, 
-    997, 998, 998, 999, 1000, 1001, 1001, 1002, 1003, 1004, 1004, 1004, 1005, 
-    1006, 1007, 120, 120, 120, 120, 120, 120, 1008, 1008, 1009, 1010, 1011, 
-    1011, 1012, 1013, 1014, 1014, 1014, 1015, 120, 120, 120, 120, 120, 120, 
-    120, 120, 1016, 1016, 1016, 1016, 1017, 1017, 1017, 1018, 1019, 1019, 
-    1020, 1019, 1019, 1019, 1019, 1019, 1021, 1022, 1023, 1024, 1025, 1025, 
-    1026, 1027, 1028, 120, 1029, 1030, 1031, 1031, 1031, 1032, 1033, 1033, 
-    1033, 1034, 120, 120, 120, 120, 1035, 1036, 1035, 1035, 1037, 1038, 1039, 
-    120, 1040, 1040, 1040, 1040, 1040, 1040, 1041, 1042, 1043, 1043, 1044, 
-    1045, 1046, 1046, 1047, 1048, 1049, 1049, 1050, 1051, 120, 1052, 120, 
-    120, 120, 120, 120, 120, 120, 120, 120, 120, 1053, 1053, 1053, 1053, 
-    1053, 1053, 1053, 1053, 1053, 1054, 120, 120, 120, 120, 120, 120, 1055, 
-    1055, 1055, 1055, 1055, 1055, 1056, 120, 1057, 1057, 1057, 1057, 1057, 
-    1057, 1058, 1059, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 
-    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 
-    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 
-    120, 120, 120, 120, 120, 1060, 1060, 1060, 1061, 120, 120, 120, 120, 120, 
-    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 1062, 1063, 1063, 
-    1063, 1063, 1063, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 120, 
-    1071, 1072, 1073, 1073, 1073, 1073, 1073, 1074, 1075, 1076, 120, 1077, 
-    1077, 1077, 1078, 1079, 1080, 1081, 1082, 1082, 1082, 1083, 1084, 1085, 
-    1086, 1087, 120, 1088, 1088, 1088, 1088, 1089, 120, 1090, 1091, 1091, 
-    1091, 1091, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 
-    120, 1101, 1101, 1102, 1101, 1101, 1103, 1104, 1105, 120, 120, 120, 120, 
-    120, 120, 120, 120, 1106, 1107, 1108, 1109, 1108, 1110, 1111, 1111, 1111, 
-    1111, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1120, 
-    1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1129, 120, 120, 
-    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 
-    120, 1130, 1130, 1130, 1130, 1130, 1130, 1131, 1132, 1133, 1134, 1135, 
-    1136, 120, 120, 120, 120, 1137, 1137, 1137, 1137, 1137, 1137, 1138, 1139, 
-    1140, 120, 1141, 1142, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 
-    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 1143, 1143, 1143, 1143, 
-    1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 120, 120, 120, 120, 1151, 
-    1151, 1151, 1151, 1151, 1151, 1152, 1153, 1154, 120, 1155, 1156, 1157, 
-    1158, 120, 120, 1159, 1159, 1159, 1159, 1159, 1160, 1161, 120, 1162, 
-    1163, 120, 120, 120, 120, 120, 120, 1164, 1164, 1164, 1165, 1166, 1167, 
-    1168, 1169, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 
-    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 
-    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 
-    120, 120, 120, 120, 1170, 1170, 1170, 1170, 1171, 1171, 1171, 1171, 1172, 
-    1173, 1174, 1175, 1176, 1177, 1178, 1178, 1178, 1178, 1179, 1180, 1181, 
-    120, 1182, 1183, 1184, 1184, 1184, 1184, 1185, 1186, 1187, 1188, 1189, 
-    120, 120, 120, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1191, 1192, 
-    1193, 1192, 1192, 1192, 1194, 1195, 1196, 1197, 120, 1198, 1199, 1200, 
-    1201, 1202, 1203, 1203, 1203, 1204, 1205, 1205, 1206, 1207, 120, 120, 
-    120, 120, 120, 120, 120, 120, 120, 1208, 1209, 1210, 1210, 1210, 1210, 
-    1211, 1212, 1213, 120, 1214, 1215, 120, 120, 120, 120, 120, 120, 120, 
-    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 1216, 
-    1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 
-    1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 
-    1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 
-    1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 
-    1216, 1216, 1217, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 
-    120, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 
-    1218, 1218, 1219, 1220, 120, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 
-    1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 
-    1216, 1216, 1216, 1216, 1216, 1221, 120, 120, 120, 120, 120, 120, 120, 
-    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 
-    120, 120, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 
-    1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 
-    1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 
-    1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1223, 1222, 1222, 
-    1222, 1222, 1224, 1225, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 
-    1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 
-    1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1226, 1222, 1222, 
-    1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 
-    1222, 1222, 1222, 1222, 1222, 1222, 1222, 1227, 120, 120, 120, 120, 120, 
-    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 
-    120, 120, 120, 120, 120, 120, 120, 1228, 1228, 1228, 1228, 1228, 1228, 
-    1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 
-    1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 
-    1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 
-    1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 
-    1228, 1228, 1228, 1229, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 
-    1228, 1228, 1228, 1228, 1228, 1228, 1230, 120, 120, 120, 120, 120, 120, 
-    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 
-    120, 120, 120, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 
-    795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 
-    795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 
-    1231, 1232, 1232, 1232, 1233, 1234, 1235, 120, 120, 120, 120, 120, 120, 
-    120, 120, 120, 120, 120, 120, 1236, 1236, 1236, 1237, 1238, 120, 1239, 
-    1239, 1239, 1239, 1239, 1239, 1240, 1241, 1242, 120, 1243, 1244, 1245, 
-    1239, 1239, 1246, 1239, 1239, 120, 120, 120, 120, 120, 120, 120, 120, 
-    120, 120, 120, 120, 120, 120, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 
-    1247, 1248, 120, 1249, 1250, 1250, 1250, 1250, 1251, 120, 1252, 1253, 
-    1254, 120, 120, 120, 120, 120, 120, 120, 120, 1255, 120, 120, 120, 1256, 
-    1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 
-    1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 
-    1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 
-    1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 
-    1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 
-    1257, 120, 120, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 
-    1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 
-    1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1258, 120, 1259, 
-    737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 
-    737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 
-    737, 737, 737, 737, 737, 737, 1260, 120, 120, 120, 120, 120, 120, 120, 
-    120, 120, 120, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 
-    1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 
-    1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 
-    1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 
-    1261, 1261, 1261, 1261, 1262, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 
-    1263, 1263, 1263, 1263, 1263, 1263, 1264, 1263, 1265, 1263, 1266, 1263, 
-    1267, 1268, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 609, 
-    609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 
-    609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 
-    609, 1269, 120, 609, 609, 609, 609, 1270, 1271, 609, 609, 609, 609, 609, 
-    609, 1272, 1273, 1274, 1275, 1276, 1277, 609, 609, 609, 1278, 609, 609, 
-    609, 609, 609, 609, 609, 1279, 120, 120, 949, 949, 949, 949, 949, 949, 
-    949, 949, 1280, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 
-    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 580, 580, 
-    580, 580, 580, 580, 580, 580, 580, 580, 616, 120, 944, 944, 1281, 120, 
-    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 
-    120, 120, 1282, 1282, 1282, 1283, 1284, 1284, 1285, 1282, 1282, 1286, 
-    1287, 1284, 1284, 1282, 1282, 1282, 1283, 1284, 1284, 1288, 1289, 1290, 
-    1286, 1291, 1292, 1284, 1282, 1282, 1282, 1283, 1284, 1284, 1293, 1294, 
-    1295, 1296, 1284, 1284, 1284, 1297, 1298, 1299, 1300, 1284, 1284, 1285, 
-    1282, 1282, 1286, 1284, 1284, 1284, 1282, 1282, 1282, 1283, 1284, 1284, 
-    1285, 1282, 1282, 1286, 1284, 1284, 1284, 1282, 1282, 1282, 1283, 1284, 
-    1284, 1285, 1282, 1282, 1286, 1284, 1284, 1284, 1282, 1282, 1282, 1283, 
-    1284, 1284, 1301, 1282, 1282, 1282, 1302, 1284, 1284, 1303, 1304, 1282, 
-    1282, 1305, 1284, 1284, 1306, 1285, 1282, 1282, 1307, 1284, 1284, 1308, 
-    1309, 1282, 1282, 1310, 1284, 1284, 1284, 1311, 1282, 1282, 1282, 1302, 
-    1284, 1284, 1303, 1312, 1313, 1313, 1313, 1313, 1313, 1313, 1314, 1314, 
-    1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 
-    1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 
-    1314, 1314, 1314, 1314, 1314, 1314, 1315, 1315, 1315, 1315, 1315, 1315, 
-    1316, 1317, 1315, 1315, 1315, 1315, 1315, 1318, 1319, 1314, 1320, 1321, 
-    120, 1322, 1323, 1315, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 
-    1324, 1325, 1325, 1326, 1327, 1328, 120, 120, 120, 120, 120, 120, 120, 
-    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 
-    120, 120, 120, 120, 120, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 
-    1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 
-    1329, 1329, 1329, 1329, 1330, 1331, 1332, 120, 120, 120, 120, 120, 1333, 
-    1333, 1333, 1333, 1334, 1335, 1335, 1335, 1336, 1337, 1338, 1339, 120, 
-    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 
-    120, 120, 120, 120, 120, 1340, 128, 128, 128, 1341, 1342, 1343, 1344, 
-    1345, 1346, 1341, 1347, 1341, 1343, 1343, 1348, 128, 1349, 128, 1350, 
-    1351, 1349, 128, 1350, 120, 120, 120, 120, 120, 120, 1352, 120, 1353, 
-    1354, 1354, 1354, 1354, 1355, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 
-    1354, 1354, 1354, 1354, 1354, 1355, 1356, 1354, 1357, 1358, 1354, 1358, 
-    1359, 1358, 1354, 1354, 1354, 1360, 1356, 619, 1361, 621, 621, 621, 1362, 
-    621, 621, 621, 621, 621, 621, 621, 1363, 621, 621, 621, 1364, 1365, 1366, 
-    621, 1367, 1356, 1356, 1356, 1356, 1356, 1356, 1368, 1369, 1369, 1369, 
-    1370, 1356, 758, 758, 758, 758, 758, 1371, 758, 1372, 1373, 1356, 1374, 
-    1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 
-    1356, 1356, 1356, 1356, 1356, 1356, 1356, 725, 725, 725, 725, 1375, 1376, 
-    1377, 725, 725, 725, 725, 725, 725, 725, 725, 1378, 1379, 725, 1380, 
-    1381, 725, 725, 1382, 1383, 1384, 1385, 1380, 1354, 725, 725, 1386, 1387, 
-    725, 725, 725, 725, 725, 725, 725, 1388, 1389, 1390, 1391, 725, 1392, 
-    1393, 1390, 1394, 1395, 725, 725, 725, 1396, 1397, 1398, 725, 725, 725, 
-    725, 725, 725, 725, 725, 1399, 1400, 725, 1401, 642, 1402, 725, 1403, 
-    1404, 580, 1405, 725, 725, 725, 1354, 1406, 1407, 1354, 1354, 1408, 1354, 
-    1353, 1354, 1354, 1354, 1354, 1354, 1409, 1410, 1354, 1354, 1409, 1411, 
-    725, 725, 725, 725, 725, 725, 725, 725, 1412, 1413, 580, 580, 580, 580, 
-    1414, 1415, 725, 725, 725, 725, 1416, 725, 1417, 725, 1418, 1419, 1420, 
-    1356, 1354, 1421, 1422, 1423, 580, 580, 580, 580, 580, 580, 580, 580, 
-    580, 580, 580, 580, 580, 580, 1424, 1356, 580, 580, 580, 580, 580, 580, 
-    580, 580, 580, 580, 1425, 1356, 1356, 1356, 1356, 1356, 580, 1424, 580, 
-    580, 580, 580, 580, 580, 580, 1356, 580, 1426, 580, 580, 580, 580, 580, 
-    1356, 580, 580, 580, 1427, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 
-    1356, 1356, 1356, 580, 1424, 725, 1428, 1429, 725, 1390, 1430, 725, 1431, 
-    725, 725, 725, 1432, 1356, 1356, 725, 725, 725, 1356, 1356, 1356, 1356, 
-    1356, 1423, 1356, 1433, 1434, 1435, 1356, 1356, 1356, 1356, 1356, 1356, 
-    1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 
-    1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 
-    1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 
-    1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 
-    1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 
-    1436, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 
-    776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 1437, 
-    778, 778, 778, 778, 778, 776, 776, 776, 776, 776, 776, 1438, 778, 776, 
     776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 
-    776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 777, 776, 
     776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 
-    776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 
-    776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 
-    776, 776, 776, 776, 776, 886, 778, 776, 776, 776, 776, 776, 776, 776, 
-    776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 
-    776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 
-    776, 776, 776, 1439, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 
-    778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 
-    778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 776, 776, 776, 
-    777, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 
-    778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 
-    778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 
-    778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 
-    778, 778, 778, 778, 1440, 1441, 120, 120, 120, 1442, 1442, 1442, 1442, 
-    1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 120, 120, 120, 120, 120, 
-    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 901, 901, 901, 
-    901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 
-    901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 120, 
-    120, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 
-    885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 
-    885, 885, 885, 885, 1443, 
+    776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 778, 
+    779, 779, 779, 779, 779, 779, 780, 119, 781, 781, 781, 781, 781, 782, 
+    783, 783, 783, 783, 783, 783, 783, 783, 783, 783, 783, 783, 783, 783, 
+    783, 783, 783, 783, 783, 783, 783, 783, 783, 783, 783, 783, 783, 783, 
+    783, 783, 783, 783, 783, 784, 783, 783, 785, 786, 119, 119, 101, 101, 
+    101, 101, 101, 787, 788, 789, 101, 101, 101, 790, 791, 791, 791, 791, 
+    791, 791, 791, 791, 792, 793, 794, 119, 64, 64, 795, 796, 797, 27, 798, 
+    27, 27, 27, 27, 27, 27, 27, 799, 800, 27, 801, 802, 27, 27, 803, 804, 
+    805, 119, 119, 119, 119, 119, 119, 806, 807, 808, 809, 810, 810, 811, 
+    812, 813, 814, 815, 815, 815, 815, 815, 815, 816, 119, 817, 818, 818, 
+    818, 818, 818, 819, 820, 821, 822, 823, 824, 825, 825, 826, 827, 828, 
+    829, 830, 830, 831, 832, 833, 833, 834, 835, 836, 837, 367, 367, 367, 
+    838, 839, 840, 840, 840, 840, 840, 841, 842, 843, 844, 845, 846, 847, 
+    348, 352, 848, 849, 849, 849, 849, 849, 850, 851, 119, 852, 853, 854, 
+    855, 348, 348, 856, 857, 858, 858, 858, 858, 858, 858, 859, 860, 861, 
+    119, 119, 862, 863, 864, 865, 119, 866, 866, 866, 119, 372, 372, 54, 54, 
+    54, 54, 54, 867, 868, 119, 869, 869, 869, 869, 869, 869, 869, 869, 869, 
+    869, 863, 863, 863, 863, 870, 871, 872, 873, 874, 875, 875, 876, 875, 
+    875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, 
+    875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, 
+    875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, 
+    875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, 
+    875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, 
+    875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, 
+    875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, 
+    875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, 
+    875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, 
+    875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, 
+    875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, 
+    875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, 
+    875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, 
+    875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, 
+    875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 875, 876, 875, 
+    875, 875, 874, 875, 875, 876, 875, 875, 875, 875, 875, 875, 874, 875, 
+    875, 876, 875, 875, 875, 874, 875, 875, 876, 875, 875, 875, 874, 875, 
+    875, 877, 119, 368, 368, 878, 879, 369, 369, 369, 369, 369, 880, 881, 
+    881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 
+    881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, 
+    881, 881, 881, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 
+    882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 
+    882, 882, 882, 882, 882, 882, 882, 773, 773, 773, 773, 773, 773, 773, 
+    773, 773, 773, 773, 773, 773, 774, 773, 773, 773, 773, 773, 773, 773, 
+    773, 773, 773, 773, 773, 773, 883, 775, 775, 775, 775, 884, 119, 885, 
+    886, 120, 887, 888, 889, 890, 120, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 891, 892, 893, 119, 894, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 895, 119, 
+    119, 127, 127, 127, 127, 127, 127, 127, 127, 896, 127, 127, 127, 127, 
+    127, 127, 119, 119, 119, 119, 119, 127, 897, 898, 898, 899, 900, 901, 
+    902, 903, 904, 905, 906, 907, 908, 909, 910, 169, 127, 127, 127, 127, 
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 911, 912, 
+    913, 914, 915, 916, 917, 917, 918, 919, 920, 920, 921, 922, 923, 924, 
+    925, 925, 925, 925, 926, 927, 927, 927, 928, 929, 929, 929, 930, 931, 
+    932, 119, 933, 934, 935, 934, 934, 936, 934, 934, 937, 934, 938, 934, 
+    938, 119, 119, 119, 119, 934, 934, 934, 934, 934, 934, 934, 934, 934, 
+    934, 934, 934, 934, 934, 934, 939, 940, 941, 941, 941, 941, 941, 942, 
+    610, 943, 943, 943, 943, 943, 943, 944, 945, 946, 947, 581, 948, 949, 
+    119, 119, 119, 119, 119, 610, 610, 610, 610, 610, 950, 119, 119, 119, 
+    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 951, 
+    951, 951, 952, 953, 953, 953, 953, 953, 953, 954, 119, 955, 956, 956, 
+    957, 958, 958, 958, 958, 959, 960, 961, 961, 962, 963, 964, 964, 964, 
+    964, 965, 966, 967, 967, 967, 968, 969, 969, 969, 969, 970, 969, 971, 
+    119, 119, 119, 119, 119, 972, 972, 972, 972, 972, 973, 973, 973, 973, 
+    973, 974, 974, 974, 974, 974, 974, 975, 975, 975, 976, 977, 978, 979, 
+    979, 979, 979, 980, 981, 981, 981, 981, 982, 983, 983, 983, 983, 983, 
+    119, 984, 984, 984, 984, 984, 984, 985, 986, 119, 119, 119, 119, 119, 
+    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 987, 
+    987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 
+    987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 987, 
+    987, 987, 987, 987, 987, 987, 987, 987, 987, 988, 119, 987, 987, 989, 
+    119, 987, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
+    119, 119, 119, 119, 119, 119, 119, 990, 991, 992, 992, 992, 992, 993, 
+    994, 995, 995, 996, 997, 998, 998, 999, 1000, 1001, 1001, 1001, 1002, 
+    1003, 1004, 119, 119, 119, 119, 119, 119, 1005, 1005, 1006, 1007, 1008, 
+    1008, 1009, 1010, 1011, 1011, 1011, 1012, 119, 119, 119, 119, 119, 119, 
+    119, 119, 1013, 1013, 1013, 1013, 1014, 1014, 1014, 1015, 1016, 1016, 
+    1017, 1016, 1016, 1016, 1016, 1016, 1018, 1019, 1020, 1021, 1022, 1022, 
+    1023, 1024, 1025, 1026, 1027, 1028, 1029, 1029, 1029, 1030, 1031, 1031, 
+    1031, 1032, 119, 119, 119, 119, 1033, 1034, 1033, 1033, 1035, 1036, 1037, 
+    119, 1038, 1038, 1038, 1038, 1038, 1038, 1039, 1040, 1041, 1041, 1042, 
+    1043, 1044, 1044, 1045, 1046, 1047, 1047, 1048, 1049, 119, 1050, 119, 
+    119, 119, 119, 119, 119, 119, 119, 119, 119, 1051, 1051, 1051, 1051, 
+    1051, 1051, 1051, 1051, 1051, 1052, 119, 119, 119, 119, 119, 119, 1053, 
+    1053, 1053, 1053, 1053, 1053, 1054, 119, 1055, 1055, 1055, 1055, 1055, 
+    1055, 1056, 1057, 1058, 1058, 1058, 1058, 1059, 119, 1060, 1061, 119, 
+    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
+    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
+    119, 119, 119, 119, 119, 119, 119, 1062, 1062, 1062, 1063, 119, 119, 119, 
+    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 1064, 
+    1064, 1064, 1065, 1066, 119, 1067, 1067, 1068, 1069, 1070, 1071, 119, 
+    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
+    119, 119, 119, 119, 119, 1072, 1073, 1073, 1073, 1073, 1073, 1073, 1074, 
+    1075, 1076, 1077, 1078, 1079, 1080, 119, 1081, 1082, 1083, 1083, 1083, 
+    1083, 1083, 1084, 1085, 1086, 1087, 1088, 1088, 1088, 1089, 1090, 1091, 
+    1092, 1093, 1093, 1093, 1094, 1095, 1096, 1097, 1098, 119, 1099, 1099, 
+    1099, 1099, 1100, 119, 1101, 1102, 1102, 1102, 1102, 1102, 1103, 1104, 
+    1105, 1106, 1107, 1108, 1109, 1110, 1111, 119, 1112, 1112, 1113, 1112, 
+    1112, 1114, 1115, 1116, 119, 119, 119, 119, 119, 119, 119, 119, 1117, 
+    1118, 1119, 1120, 1119, 1121, 1122, 1122, 1122, 1122, 1122, 1123, 1124, 
+    1125, 1126, 1127, 1128, 1129, 1130, 1131, 1131, 1132, 1133, 1134, 1135, 
+    1136, 1137, 1138, 1139, 1140, 1140, 119, 119, 119, 119, 119, 119, 119, 
+    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 1141, 1141, 1141, 1141, 
+    1141, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 119, 119, 119, 119, 1148, 
+    1148, 1148, 1148, 1148, 1148, 1149, 1150, 1151, 119, 1152, 1153, 119, 
+    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
+    119, 119, 119, 119, 119, 1154, 1154, 1154, 1154, 1154, 1155, 1156, 1157, 
+    1158, 1159, 1160, 1161, 119, 119, 119, 119, 1162, 1162, 1162, 1162, 1162, 
+    1162, 1163, 1164, 1165, 119, 1166, 1167, 1168, 1169, 119, 119, 1170, 
+    1170, 1170, 1170, 1170, 1171, 1172, 119, 1173, 1174, 119, 119, 119, 119, 
+    119, 119, 1175, 1175, 1175, 1176, 1177, 1178, 1179, 1180, 119, 119, 119, 
+    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
+    119, 119, 119, 119, 119, 119, 119, 1181, 1181, 1181, 1181, 1181, 1182, 
+    1183, 1184, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
+    1185, 1185, 1185, 1185, 1186, 1186, 1186, 1186, 1187, 1188, 1189, 1190, 
+    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
+    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
+    119, 119, 119, 119, 1191, 1192, 1193, 1193, 1193, 1193, 1194, 1195, 1196, 
+    119, 1197, 1198, 1199, 1199, 1199, 1199, 1200, 1201, 1202, 1203, 1204, 
+    119, 119, 119, 1205, 1205, 1205, 1205, 1205, 1205, 1205, 1206, 1207, 
+    1208, 1207, 1207, 1207, 1209, 1210, 1211, 1212, 119, 1213, 1214, 1215, 
+    1216, 1217, 1218, 1218, 1218, 1219, 1220, 1220, 1221, 1222, 119, 119, 
+    119, 119, 119, 119, 119, 119, 119, 1223, 1224, 1225, 1225, 1225, 1225, 
+    1226, 1227, 1228, 119, 1229, 1230, 1231, 1232, 1233, 1233, 1233, 1234, 
+    1235, 1236, 1237, 1238, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
+    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
+    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
+    1239, 1239, 1240, 1241, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 
+    1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 
+    1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 
+    1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 
+    1242, 1242, 1242, 1242, 1242, 1242, 1242, 1243, 119, 119, 119, 119, 119, 
+    119, 119, 119, 119, 119, 119, 119, 1244, 1244, 1244, 1244, 1244, 1244, 
+    1244, 1244, 1244, 1244, 1244, 1244, 1244, 1245, 1246, 119, 1242, 1242, 
+    1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 
+    1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1247, 119, 
+    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
+    119, 119, 119, 119, 119, 119, 119, 119, 1248, 1248, 1248, 1248, 1248, 
+    1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 
+    1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 
+    1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 
+    1248, 1248, 1249, 1248, 1248, 1248, 1248, 1250, 1251, 1248, 1248, 1248, 
+    1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 
+    1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 
+    1248, 1248, 1252, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 
+    1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 
+    1253, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
+    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 1254, 
+    1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 
+    1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 
+    1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 
+    1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 
+    1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1255, 1254, 1254, 1254, 
+    1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1256, 
+    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
+    119, 119, 119, 119, 119, 119, 119, 119, 119, 791, 791, 791, 791, 791, 
+    791, 791, 791, 791, 791, 791, 791, 791, 791, 791, 791, 791, 791, 791, 
+    791, 791, 791, 791, 791, 791, 791, 791, 791, 791, 791, 791, 791, 791, 
+    791, 791, 791, 791, 791, 791, 1257, 1258, 1258, 1258, 1259, 1260, 1261, 
+    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 1262, 1262, 
+    1262, 1263, 1264, 119, 1265, 1265, 1265, 1265, 1265, 1265, 1266, 1267, 
+    1268, 119, 1269, 1270, 1271, 1265, 1265, 1272, 1265, 1265, 119, 119, 119, 
+    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
+    119, 119, 119, 119, 119, 1273, 1273, 1273, 1273, 1274, 1274, 1274, 1274, 
+    1275, 1275, 1276, 1277, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
+    119, 119, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1279, 119, 
+    1280, 1281, 1281, 1281, 1281, 1282, 119, 1283, 1284, 1285, 119, 119, 119, 
+    119, 119, 119, 119, 119, 1286, 119, 119, 119, 1287, 1287, 1287, 1287, 
+    1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 
+    1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 
+    1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 
+    1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 
+    1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1288, 119, 
+    1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 
+    1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 
+    1287, 1287, 1287, 1287, 1287, 1287, 1289, 119, 1290, 735, 735, 735, 735, 
+    735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 
+    735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 
+    735, 735, 1291, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 1292, 
+    1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 
+    1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 
+    1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 
+    1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 1292, 
+    1293, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 
+    1294, 1294, 1295, 1294, 1296, 1294, 1297, 1294, 1298, 1299, 119, 119, 
+    119, 119, 119, 119, 119, 119, 119, 119, 119, 610, 610, 610, 610, 610, 
+    610, 610, 610, 610, 610, 610, 610, 610, 610, 610, 610, 610, 610, 610, 
+    610, 610, 610, 610, 610, 610, 610, 610, 610, 610, 610, 1300, 119, 610, 
+    610, 610, 610, 1301, 1302, 610, 610, 610, 610, 610, 610, 1303, 1304, 
+    1305, 1306, 1307, 1308, 610, 610, 610, 1309, 610, 610, 610, 610, 610, 
+    610, 610, 1310, 119, 119, 946, 946, 946, 946, 946, 946, 946, 946, 1311, 
+    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
+    119, 119, 119, 119, 119, 941, 941, 1312, 119, 581, 581, 581, 581, 581, 
+    581, 581, 581, 581, 581, 617, 119, 941, 941, 941, 1313, 119, 119, 119, 
+    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 1314, 
+    1314, 1314, 1315, 1316, 1316, 1317, 1314, 1314, 1318, 1319, 1316, 1316, 
+    1314, 1314, 1314, 1315, 1316, 1316, 1320, 1321, 1322, 1318, 1323, 1324, 
+    1316, 1314, 1314, 1314, 1315, 1316, 1316, 1325, 1326, 1327, 1328, 1316, 
+    1316, 1316, 1329, 1330, 1331, 1332, 1316, 1316, 1317, 1314, 1314, 1318, 
+    1316, 1316, 1316, 1314, 1314, 1314, 1315, 1316, 1316, 1317, 1314, 1314, 
+    1318, 1316, 1316, 1316, 1314, 1314, 1314, 1315, 1316, 1316, 1317, 1314, 
+    1314, 1318, 1316, 1316, 1316, 1314, 1314, 1314, 1315, 1316, 1316, 1333, 
+    1314, 1314, 1314, 1334, 1316, 1316, 1335, 1336, 1314, 1314, 1337, 1316, 
+    1316, 1338, 1317, 1314, 1314, 1339, 1316, 1316, 1340, 1341, 1314, 1314, 
+    1342, 1316, 1316, 1316, 1343, 1314, 1314, 1314, 1334, 1316, 1316, 1335, 
+    1344, 1345, 1345, 1345, 1345, 1345, 1345, 1346, 1346, 1346, 1346, 1346, 
+    1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 
+    1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 1346, 
+    1346, 1346, 1346, 1347, 1347, 1347, 1347, 1347, 1347, 1348, 1349, 1347, 
+    1347, 1347, 1347, 1347, 1350, 1351, 1346, 1352, 1353, 119, 1354, 1355, 
+    1347, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 1356, 1357, 1357, 
+    1358, 1359, 1360, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
+    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
+    119, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 
+    1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 1361, 
+    1361, 1362, 1363, 1364, 119, 119, 119, 119, 119, 1365, 1365, 1365, 1365, 
+    1366, 1367, 1367, 1367, 1368, 1369, 1370, 1371, 119, 119, 119, 119, 119, 
+    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
+    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
+    119, 1372, 1373, 1373, 1373, 1373, 1373, 1373, 1374, 1375, 119, 119, 119, 
+    119, 119, 119, 119, 119, 119, 1376, 127, 127, 127, 1377, 1378, 1379, 
+    1380, 1381, 1382, 1377, 1383, 1377, 1379, 1379, 1384, 127, 1385, 127, 
+    1386, 1387, 1385, 127, 1386, 119, 119, 119, 119, 119, 119, 1388, 119, 
+    1389, 1390, 1390, 1390, 1390, 1391, 1390, 1390, 1390, 1390, 1390, 1390, 
+    1390, 1390, 1390, 1390, 1390, 1390, 1391, 1392, 1390, 1393, 1394, 1390, 
+    1394, 1395, 1394, 1390, 1390, 1390, 1396, 1392, 620, 1397, 622, 622, 622, 
+    1398, 622, 622, 622, 622, 622, 622, 622, 1399, 622, 622, 622, 1400, 1401, 
+    1402, 622, 1403, 1392, 1392, 1392, 1392, 1392, 1392, 1404, 1405, 1405, 
+    1405, 1406, 1392, 755, 755, 755, 755, 755, 1407, 755, 1408, 1409, 1392, 
+    1410, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 
+    1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 723, 723, 723, 723, 1411, 
+    1412, 1413, 723, 723, 723, 723, 723, 723, 723, 723, 1414, 1415, 723, 
+    1416, 1417, 723, 723, 1418, 1419, 1420, 1421, 1416, 1390, 723, 723, 1422, 
+    1423, 723, 723, 723, 723, 723, 723, 723, 1424, 1425, 1426, 1427, 723, 
+    1428, 1429, 1426, 1430, 1431, 723, 723, 723, 1432, 1433, 1434, 723, 723, 
+    723, 723, 723, 723, 723, 723, 1435, 1436, 723, 1437, 643, 1438, 723, 
+    1439, 1440, 581, 1441, 723, 723, 723, 1390, 1442, 1443, 1390, 1390, 1444, 
+    1390, 1389, 1390, 1390, 1390, 1390, 1390, 1445, 1446, 1390, 1390, 1445, 
+    1447, 723, 723, 723, 723, 723, 723, 723, 723, 1448, 1449, 581, 581, 581, 
+    581, 1450, 1451, 723, 723, 723, 723, 1452, 723, 1453, 723, 1454, 1455, 
+    1456, 1392, 1390, 1457, 1458, 1459, 581, 581, 581, 581, 581, 581, 581, 
+    581, 581, 581, 581, 581, 581, 581, 1460, 1392, 581, 581, 581, 581, 581, 
+    581, 581, 581, 581, 581, 1461, 1462, 1392, 1392, 1392, 1392, 581, 1460, 
+    581, 581, 581, 581, 581, 581, 581, 1392, 581, 1463, 581, 581, 581, 581, 
+    581, 1392, 581, 581, 581, 1464, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 
+    1392, 1392, 1392, 581, 1460, 723, 1465, 1466, 723, 1426, 1467, 723, 723, 
+    723, 723, 723, 723, 1468, 1469, 723, 723, 723, 723, 1470, 1392, 1471, 
+    1472, 1470, 1392, 1473, 1474, 723, 723, 723, 723, 1392, 1392, 1392, 1392, 
+    1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1390, 1396, 1392, 1392, 
+    1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 
+    1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 
+    1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 
+    1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 
+    1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 
+    1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 
+    1392, 1392, 1392, 1392, 1392, 1392, 1392, 1475, 773, 773, 773, 773, 773, 
+    773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 
+    773, 773, 773, 773, 773, 773, 773, 1476, 775, 775, 775, 775, 775, 773, 
+    773, 773, 773, 773, 773, 1477, 775, 773, 773, 773, 773, 773, 773, 773, 
+    773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 
+    773, 773, 773, 773, 773, 773, 774, 773, 773, 773, 773, 773, 773, 773, 
+    773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 
+    773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 
+    773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 883, 
+    775, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 
+    773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 
+    773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 1478, 775, 775, 
+    775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 
+    775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 
+    775, 775, 775, 775, 775, 773, 773, 773, 774, 775, 775, 775, 775, 775, 
+    775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 
+    775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 
+    775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 
+    775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 1479, 1480, 
+    119, 119, 119, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 
+    1481, 1481, 1481, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
+    119, 119, 119, 119, 119, 898, 898, 898, 898, 898, 898, 898, 898, 898, 
+    898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, 
+    898, 898, 898, 898, 898, 898, 898, 119, 119, 882, 882, 882, 882, 882, 
+    882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 
+    882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 1482, 
 };
 
 static const unsigned short index2[] = {
@@ -2666,716 +2829,743 @@ static const unsigned short index2[] = {
     94, 95, 95, 96, 96, 95, 97, 97, 90, 93, 90, 93, 90, 93, 90, 90, 93, 90, 
     93, 90, 93, 90, 93, 90, 93, 90, 93, 90, 93, 93, 81, 98, 98, 98, 98, 98, 
     98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 81, 
-    81, 99, 100, 100, 100, 100, 100, 100, 81, 101, 101, 101, 101, 101, 101, 
-    101, 101, 101, 101, 101, 101, 101, 101, 101, 81, 102, 103, 81, 81, 104, 
-    104, 105, 81, 106, 107, 107, 107, 107, 106, 107, 107, 107, 108, 106, 107, 
-    107, 107, 107, 107, 107, 106, 106, 106, 106, 106, 106, 107, 107, 106, 
-    107, 107, 108, 109, 107, 110, 111, 112, 113, 114, 115, 116, 117, 118, 
-    119, 119, 120, 121, 122, 123, 124, 125, 126, 127, 125, 107, 106, 128, 
-    118, 81, 81, 81, 81, 81, 81, 81, 81, 129, 129, 129, 129, 129, 129, 129, 
-    129, 129, 129, 129, 81, 81, 81, 81, 81, 129, 129, 129, 125, 125, 81, 81, 
-    81, 130, 130, 130, 130, 130, 131, 132, 132, 133, 134, 134, 135, 136, 137, 
-    138, 138, 139, 139, 139, 139, 139, 139, 139, 139, 140, 141, 142, 143, 
-    144, 81, 145, 143, 146, 146, 146, 146, 146, 146, 146, 146, 147, 146, 146, 
-    146, 146, 146, 146, 146, 146, 146, 146, 148, 149, 150, 151, 152, 153, 
-    154, 155, 96, 96, 156, 157, 139, 139, 139, 139, 139, 157, 139, 139, 157, 
-    158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 134, 159, 159, 160, 
-    146, 146, 161, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 
-    145, 146, 139, 139, 139, 139, 139, 139, 139, 131, 138, 139, 139, 139, 
-    139, 157, 139, 162, 162, 139, 139, 138, 157, 139, 139, 157, 146, 146, 
-    163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 146, 146, 146, 164, 
-    164, 146, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 
-    165, 165, 81, 166, 167, 168, 167, 167, 167, 167, 167, 167, 167, 167, 167, 
-    167, 167, 167, 167, 167, 169, 170, 169, 169, 170, 169, 169, 170, 170, 
-    170, 169, 170, 170, 169, 170, 169, 169, 169, 170, 169, 170, 169, 170, 
-    169, 170, 169, 169, 81, 81, 167, 167, 167, 171, 171, 171, 171, 171, 171, 
-    171, 171, 171, 171, 171, 171, 171, 171, 172, 172, 172, 172, 172, 172, 
-    172, 172, 172, 172, 172, 171, 81, 81, 81, 81, 81, 81, 173, 173, 173, 173, 
-    173, 173, 173, 173, 173, 173, 174, 174, 174, 174, 174, 174, 174, 174, 
-    174, 174, 174, 174, 174, 174, 174, 174, 174, 175, 175, 175, 175, 175, 
-    175, 175, 176, 175, 177, 177, 178, 179, 180, 181, 177, 81, 81, 81, 81, 
-    81, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 
-    183, 183, 183, 183, 184, 183, 183, 183, 183, 183, 183, 183, 183, 183, 
-    184, 183, 183, 183, 184, 183, 183, 183, 183, 183, 81, 81, 185, 185, 185, 
-    185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 81, 186, 186, 
-    186, 186, 186, 186, 186, 186, 186, 187, 187, 187, 81, 81, 188, 81, 167, 
-    167, 167, 81, 81, 81, 81, 81, 146, 146, 146, 146, 146, 81, 146, 146, 146, 
-    146, 146, 146, 146, 146, 81, 81, 81, 81, 81, 81, 139, 139, 139, 139, 139, 
-    139, 131, 157, 139, 139, 157, 139, 139, 157, 139, 139, 139, 157, 157, 
-    157, 189, 190, 191, 139, 139, 139, 157, 139, 139, 157, 157, 139, 139, 
-    139, 139, 139, 192, 192, 192, 193, 194, 194, 194, 194, 194, 194, 194, 
-    194, 194, 194, 194, 194, 194, 194, 192, 193, 195, 194, 193, 193, 193, 
-    192, 192, 192, 192, 192, 192, 192, 192, 193, 193, 193, 193, 196, 193, 
-    193, 194, 96, 156, 197, 197, 192, 192, 192, 194, 194, 192, 192, 198, 198, 
-    199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 200, 201, 194, 194, 
-    194, 194, 194, 194, 202, 203, 204, 204, 81, 202, 202, 202, 202, 202, 202, 
-    202, 202, 81, 81, 202, 202, 81, 81, 202, 202, 202, 202, 202, 202, 202, 
-    202, 202, 202, 202, 202, 202, 202, 81, 202, 202, 202, 202, 202, 202, 202, 
-    81, 202, 81, 81, 81, 202, 202, 202, 202, 81, 81, 205, 202, 204, 204, 204, 
-    203, 203, 203, 203, 81, 81, 204, 204, 81, 81, 204, 204, 206, 202, 81, 81, 
-    81, 81, 81, 81, 81, 81, 204, 81, 81, 81, 81, 202, 202, 81, 202, 202, 202, 
-    203, 203, 81, 81, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 202, 
-    202, 208, 208, 209, 209, 209, 209, 209, 210, 211, 212, 202, 213, 81, 81, 
-    81, 214, 214, 215, 81, 216, 216, 216, 216, 216, 216, 81, 81, 81, 81, 216, 
-    216, 81, 81, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 
-    216, 216, 81, 216, 216, 216, 216, 216, 216, 216, 81, 216, 216, 81, 216, 
-    216, 81, 216, 216, 81, 81, 217, 81, 215, 215, 215, 214, 214, 81, 81, 81, 
-    81, 214, 214, 81, 81, 214, 214, 218, 81, 81, 81, 214, 81, 81, 81, 81, 81, 
-    81, 81, 216, 216, 216, 216, 81, 216, 81, 81, 81, 81, 81, 81, 81, 219, 
-    219, 219, 219, 219, 219, 219, 219, 219, 219, 214, 214, 216, 216, 216, 
-    214, 81, 81, 81, 220, 220, 221, 81, 222, 222, 222, 222, 222, 222, 222, 
-    222, 222, 81, 222, 222, 222, 81, 222, 222, 222, 222, 222, 222, 222, 222, 
-    222, 222, 222, 222, 222, 222, 81, 222, 222, 222, 222, 222, 222, 222, 81, 
-    222, 222, 81, 222, 222, 222, 222, 222, 81, 81, 223, 222, 221, 221, 221, 
-    220, 220, 220, 220, 220, 81, 220, 220, 221, 81, 221, 221, 224, 81, 81, 
-    222, 81, 81, 81, 81, 81, 81, 81, 222, 222, 220, 220, 81, 81, 225, 225, 
-    225, 225, 225, 225, 225, 225, 225, 225, 226, 227, 81, 81, 81, 81, 81, 81, 
-    81, 222, 220, 220, 220, 220, 220, 220, 81, 228, 229, 229, 81, 230, 230, 
-    230, 230, 230, 230, 230, 230, 81, 81, 230, 230, 81, 81, 230, 230, 230, 
-    230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 81, 230, 230, 230, 
-    230, 230, 230, 230, 81, 230, 230, 81, 230, 230, 230, 230, 230, 81, 81, 
-    231, 230, 229, 228, 229, 228, 228, 228, 228, 81, 81, 229, 229, 81, 81, 
-    229, 229, 232, 81, 81, 81, 81, 81, 81, 81, 81, 228, 229, 81, 81, 81, 81, 
-    230, 230, 81, 230, 230, 230, 228, 228, 81, 81, 233, 233, 233, 233, 233, 
-    233, 233, 233, 233, 233, 234, 230, 235, 235, 235, 235, 235, 235, 81, 81, 
-    236, 237, 81, 237, 237, 237, 237, 237, 237, 81, 81, 81, 237, 237, 237, 
-    81, 237, 237, 237, 237, 81, 81, 81, 237, 237, 81, 237, 81, 237, 237, 81, 
-    81, 81, 237, 237, 81, 81, 81, 237, 237, 237, 237, 237, 237, 237, 237, 
-    237, 237, 81, 81, 81, 81, 238, 238, 236, 238, 238, 81, 81, 81, 238, 238, 
-    238, 81, 238, 238, 238, 239, 81, 81, 237, 81, 81, 81, 81, 81, 81, 238, 
-    81, 81, 81, 81, 81, 81, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 
-    241, 241, 241, 242, 242, 242, 242, 242, 242, 243, 242, 81, 81, 81, 81, 
-    81, 244, 245, 245, 245, 81, 246, 246, 246, 246, 246, 246, 246, 246, 81, 
-    246, 246, 246, 81, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 
-    246, 246, 246, 246, 246, 81, 81, 81, 246, 244, 244, 244, 245, 245, 245, 
-    245, 81, 244, 244, 244, 81, 244, 244, 244, 247, 81, 81, 81, 81, 81, 81, 
-    81, 248, 249, 81, 246, 246, 246, 81, 81, 81, 81, 81, 246, 246, 244, 244, 
-    81, 81, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 251, 251, 251, 
-    251, 251, 251, 251, 252, 253, 254, 255, 255, 81, 253, 253, 253, 253, 253, 
-    253, 253, 253, 81, 253, 253, 253, 81, 253, 253, 253, 253, 253, 253, 253, 
-    253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 81, 253, 253, 253, 
-    253, 253, 81, 81, 256, 253, 255, 257, 255, 255, 255, 255, 255, 81, 257, 
-    255, 255, 81, 255, 255, 254, 258, 81, 81, 81, 81, 81, 81, 81, 255, 255, 
-    81, 81, 81, 81, 81, 81, 81, 253, 81, 253, 253, 254, 254, 81, 81, 259, 
-    259, 259, 259, 259, 259, 259, 259, 259, 259, 81, 253, 253, 81, 81, 81, 
-    81, 81, 260, 260, 261, 261, 81, 262, 262, 262, 262, 262, 262, 262, 262, 
-    81, 262, 262, 262, 81, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 
-    262, 262, 262, 262, 262, 262, 262, 263, 263, 262, 261, 261, 261, 260, 
-    260, 260, 260, 81, 261, 261, 261, 81, 261, 261, 261, 263, 262, 264, 81, 
-    81, 81, 81, 262, 262, 262, 261, 265, 265, 265, 265, 265, 265, 265, 262, 
-    262, 262, 260, 260, 81, 81, 266, 266, 266, 266, 266, 266, 266, 266, 266, 
-    266, 265, 265, 265, 265, 265, 265, 265, 265, 265, 267, 262, 262, 262, 
-    262, 262, 262, 81, 81, 268, 268, 81, 269, 269, 269, 269, 269, 269, 269, 
-    269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 81, 81, 81, 269, 
-    269, 269, 269, 269, 269, 269, 269, 81, 269, 269, 269, 269, 269, 269, 269, 
-    269, 269, 81, 269, 81, 81, 81, 81, 270, 81, 81, 81, 81, 268, 268, 268, 
-    271, 271, 271, 81, 271, 81, 268, 268, 268, 268, 268, 268, 268, 268, 81, 
-    81, 81, 81, 81, 81, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 81, 
-    81, 268, 268, 273, 81, 81, 81, 81, 274, 274, 274, 274, 274, 274, 274, 
-    274, 274, 274, 274, 274, 274, 274, 274, 274, 275, 274, 274, 275, 275, 
-    275, 275, 276, 276, 277, 81, 81, 81, 81, 278, 274, 274, 274, 274, 274, 
-    274, 279, 275, 280, 280, 280, 280, 275, 275, 275, 281, 282, 282, 282, 
-    282, 282, 282, 282, 282, 282, 282, 283, 283, 81, 81, 81, 81, 81, 284, 
-    284, 81, 284, 81, 81, 284, 284, 81, 284, 81, 81, 284, 81, 81, 81, 81, 81, 
-    81, 284, 284, 284, 284, 81, 284, 284, 284, 284, 284, 284, 284, 81, 284, 
-    284, 284, 81, 284, 81, 284, 81, 81, 284, 284, 81, 284, 284, 284, 284, 
-    285, 284, 284, 285, 285, 285, 285, 286, 286, 81, 285, 285, 284, 81, 81, 
-    284, 284, 284, 284, 284, 81, 287, 81, 288, 288, 288, 288, 285, 285, 81, 
-    81, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 81, 81, 284, 284, 
-    284, 284, 290, 291, 291, 291, 292, 293, 292, 292, 294, 292, 292, 295, 
-    294, 296, 296, 296, 296, 296, 294, 297, 296, 297, 297, 297, 298, 298, 
-    297, 297, 297, 297, 297, 297, 299, 299, 299, 299, 299, 299, 299, 299, 
-    299, 299, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 301, 298, 
-    297, 298, 297, 302, 303, 304, 303, 304, 305, 305, 290, 290, 290, 290, 
-    290, 290, 290, 290, 81, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 
-    290, 290, 81, 81, 81, 81, 306, 307, 308, 309, 308, 308, 308, 308, 308, 
-    307, 307, 307, 307, 308, 310, 307, 308, 311, 311, 312, 295, 311, 311, 
-    290, 290, 290, 290, 290, 308, 308, 308, 308, 308, 308, 308, 308, 308, 
-    308, 308, 81, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 
-    81, 301, 301, 297, 297, 297, 297, 297, 297, 298, 297, 297, 297, 297, 297, 
-    297, 81, 297, 297, 292, 292, 295, 292, 293, 313, 313, 313, 313, 294, 294, 
-    81, 81, 81, 81, 81, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 
-    314, 315, 315, 316, 316, 316, 316, 315, 316, 316, 316, 316, 316, 317, 
-    315, 318, 318, 315, 315, 316, 316, 314, 319, 319, 319, 319, 319, 319, 
-    319, 319, 319, 319, 320, 320, 321, 321, 321, 321, 314, 314, 314, 314, 
-    314, 314, 315, 315, 316, 316, 314, 314, 314, 314, 316, 316, 316, 314, 
-    315, 315, 315, 314, 314, 315, 315, 315, 315, 315, 315, 315, 314, 314, 
-    314, 316, 316, 316, 316, 314, 314, 314, 314, 314, 316, 315, 315, 316, 
-    316, 315, 315, 315, 315, 315, 315, 322, 314, 315, 319, 319, 315, 315, 
-    315, 316, 323, 323, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 
-    324, 324, 324, 324, 81, 324, 81, 81, 81, 81, 81, 324, 81, 81, 325, 325, 
-    325, 325, 325, 325, 325, 325, 325, 325, 325, 326, 327, 325, 325, 325, 
-    328, 328, 328, 328, 328, 328, 328, 328, 329, 329, 329, 329, 329, 329, 
-    329, 329, 330, 330, 330, 330, 330, 330, 330, 330, 331, 331, 331, 331, 
-    331, 331, 331, 331, 331, 81, 331, 331, 331, 331, 81, 81, 331, 331, 331, 
-    331, 331, 331, 331, 81, 331, 331, 331, 81, 81, 332, 332, 332, 333, 334, 
-    333, 333, 333, 333, 333, 333, 333, 335, 335, 335, 335, 335, 335, 335, 
-    335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 81, 81, 
-    81, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 81, 81, 81, 81, 81, 
-    81, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 
-    81, 81, 338, 338, 338, 338, 338, 338, 81, 81, 339, 340, 340, 340, 340, 
-    340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 
-    340, 340, 341, 341, 340, 342, 343, 343, 343, 343, 343, 343, 343, 343, 
-    343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 344, 345, 81, 81, 81, 
-    346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 198, 198, 198, 
-    347, 347, 347, 346, 346, 346, 346, 346, 346, 346, 346, 81, 81, 81, 81, 
-    81, 81, 81, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 
-    348, 81, 348, 348, 348, 348, 349, 349, 350, 81, 81, 81, 351, 351, 351, 
-    351, 351, 351, 351, 351, 351, 351, 352, 352, 353, 198, 198, 81, 354, 354, 
-    354, 354, 354, 354, 354, 354, 354, 354, 355, 355, 81, 81, 81, 81, 356, 
-    356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 81, 356, 356, 
-    356, 81, 357, 357, 81, 81, 81, 81, 358, 358, 358, 358, 358, 358, 358, 
-    358, 358, 358, 358, 358, 359, 359, 360, 359, 359, 359, 359, 359, 359, 
-    359, 360, 360, 360, 360, 360, 360, 360, 360, 359, 360, 360, 359, 359, 
-    359, 359, 359, 359, 359, 359, 359, 361, 359, 362, 362, 363, 364, 362, 
-    365, 362, 366, 358, 367, 81, 81, 368, 368, 368, 368, 368, 368, 368, 368, 
-    368, 368, 81, 81, 81, 81, 81, 81, 369, 369, 369, 369, 369, 369, 369, 369, 
-    369, 369, 81, 81, 81, 81, 81, 81, 370, 370, 371, 371, 372, 373, 374, 370, 
-    375, 375, 370, 376, 376, 376, 377, 81, 378, 378, 378, 378, 378, 378, 378, 
-    378, 378, 378, 81, 81, 81, 81, 81, 81, 379, 379, 379, 379, 379, 379, 379, 
-    379, 379, 379, 379, 380, 379, 379, 379, 379, 379, 379, 379, 379, 379, 
-    376, 376, 379, 379, 381, 379, 81, 81, 81, 81, 81, 340, 340, 340, 340, 
-    340, 340, 81, 81, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 
-    382, 382, 382, 382, 81, 383, 383, 383, 384, 384, 384, 384, 383, 383, 384, 
-    384, 384, 81, 81, 81, 81, 384, 384, 383, 384, 384, 384, 384, 384, 384, 
-    385, 386, 387, 81, 81, 81, 81, 388, 81, 81, 81, 389, 389, 390, 390, 390, 
-    390, 390, 390, 390, 390, 390, 390, 391, 391, 391, 391, 391, 391, 391, 
-    391, 391, 391, 391, 391, 391, 391, 81, 81, 391, 391, 391, 391, 391, 81, 
-    81, 81, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 81, 
-    81, 81, 81, 392, 392, 81, 81, 81, 81, 81, 81, 393, 393, 393, 393, 393, 
-    393, 393, 393, 393, 393, 394, 81, 81, 81, 395, 395, 396, 396, 396, 396, 
-    396, 396, 396, 396, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 
-    397, 397, 397, 397, 397, 398, 399, 400, 400, 401, 81, 81, 402, 402, 403, 
-    403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 404, 405, 
-    404, 405, 405, 405, 405, 405, 405, 405, 81, 406, 404, 405, 404, 404, 405, 
-    405, 405, 405, 405, 405, 405, 405, 404, 404, 404, 404, 404, 404, 405, 
-    405, 407, 407, 407, 407, 407, 407, 407, 407, 81, 81, 408, 409, 409, 409, 
-    409, 409, 409, 409, 409, 409, 409, 81, 81, 81, 81, 81, 81, 410, 410, 410, 
-    410, 410, 410, 410, 411, 410, 410, 410, 410, 410, 410, 81, 81, 96, 96, 
-    96, 96, 96, 156, 156, 156, 156, 156, 156, 96, 96, 156, 412, 81, 413, 413, 
-    413, 413, 414, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 
-    415, 415, 415, 415, 416, 414, 413, 413, 413, 413, 413, 414, 413, 414, 
-    414, 414, 414, 414, 413, 414, 417, 415, 415, 415, 415, 415, 415, 415, 81, 
-    81, 81, 81, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 419, 419, 
-    420, 419, 419, 419, 419, 421, 421, 421, 421, 421, 421, 421, 421, 421, 
-    421, 422, 423, 422, 422, 422, 422, 422, 422, 422, 421, 421, 421, 421, 
-    421, 421, 421, 421, 421, 81, 81, 81, 424, 424, 425, 426, 426, 426, 426, 
-    426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 425, 424, 424, 424, 
-    424, 425, 425, 424, 424, 427, 428, 424, 424, 426, 426, 429, 429, 429, 
-    429, 429, 429, 429, 429, 429, 429, 426, 426, 426, 426, 426, 426, 430, 
-    430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 431, 
-    432, 433, 433, 432, 432, 432, 433, 432, 433, 433, 433, 434, 434, 81, 81, 
-    81, 81, 81, 81, 81, 81, 435, 435, 435, 435, 436, 436, 436, 436, 436, 436, 
-    436, 436, 436, 436, 436, 436, 437, 437, 437, 437, 437, 437, 437, 437, 
-    438, 438, 438, 438, 438, 438, 438, 438, 437, 437, 438, 439, 81, 81, 81, 
-    440, 440, 440, 440, 440, 441, 441, 441, 441, 441, 441, 441, 441, 441, 
-    441, 81, 81, 81, 436, 436, 436, 442, 442, 442, 442, 442, 442, 442, 442, 
-    442, 442, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 
-    443, 443, 444, 444, 444, 444, 444, 444, 445, 445, 93, 81, 81, 81, 81, 81, 
-    81, 81, 446, 446, 446, 446, 446, 446, 446, 446, 96, 96, 96, 326, 447, 
-    156, 156, 156, 156, 156, 96, 96, 156, 156, 156, 156, 96, 448, 447, 447, 
-    447, 447, 447, 447, 447, 449, 449, 449, 449, 156, 449, 449, 449, 449, 
-    448, 448, 96, 449, 449, 448, 96, 96, 81, 81, 81, 81, 81, 81, 56, 56, 56, 
-    56, 56, 56, 79, 79, 79, 79, 79, 93, 59, 59, 59, 59, 59, 59, 59, 59, 59, 
-    82, 82, 82, 82, 82, 59, 59, 59, 59, 82, 82, 82, 82, 82, 56, 56, 56, 56, 
-    56, 450, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 59, 59, 59, 59, 59, 59, 
-    59, 59, 59, 59, 59, 59, 82, 96, 96, 156, 96, 96, 96, 96, 96, 96, 96, 156, 
-    96, 96, 451, 452, 156, 453, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 
-    96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 454, 455, 455, 156, 81, 96, 456, 
-    156, 96, 156, 52, 56, 52, 56, 52, 56, 56, 56, 56, 56, 56, 56, 56, 56, 52, 
-    56, 79, 79, 79, 79, 79, 79, 79, 79, 78, 78, 78, 78, 78, 78, 78, 78, 79, 
-    79, 79, 79, 79, 79, 81, 81, 78, 78, 78, 78, 78, 78, 81, 81, 81, 78, 81, 
-    78, 81, 78, 81, 78, 457, 457, 457, 457, 457, 457, 457, 457, 79, 79, 79, 
-    79, 79, 81, 79, 79, 78, 78, 78, 78, 457, 80, 79, 80, 80, 80, 79, 79, 79, 
-    81, 79, 79, 78, 78, 78, 78, 457, 80, 80, 80, 79, 79, 79, 79, 81, 81, 79, 
-    79, 78, 78, 78, 78, 81, 80, 80, 80, 78, 78, 78, 78, 78, 80, 80, 80, 81, 
-    81, 79, 79, 79, 81, 79, 79, 78, 78, 78, 78, 457, 458, 80, 81, 459, 459, 
-    459, 459, 459, 459, 459, 460, 459, 459, 459, 461, 462, 463, 464, 465, 
-    466, 467, 468, 466, 469, 470, 38, 84, 471, 472, 473, 42, 471, 472, 473, 
-    42, 38, 38, 474, 84, 475, 475, 475, 476, 477, 478, 479, 480, 481, 482, 
-    483, 33, 484, 485, 484, 484, 485, 486, 487, 487, 84, 42, 50, 38, 488, 
-    488, 474, 489, 489, 84, 84, 84, 490, 473, 491, 488, 488, 488, 84, 84, 84, 
-    84, 84, 84, 84, 84, 492, 84, 489, 84, 373, 84, 373, 373, 373, 373, 84, 
-    373, 373, 459, 493, 494, 494, 494, 494, 81, 495, 496, 497, 498, 499, 499, 
-    499, 499, 499, 499, 500, 59, 81, 81, 47, 500, 500, 500, 500, 500, 501, 
-    501, 492, 473, 491, 502, 500, 47, 47, 47, 47, 500, 500, 500, 500, 500, 
-    501, 501, 492, 473, 491, 81, 59, 59, 59, 59, 59, 81, 81, 81, 278, 278, 
-    278, 278, 278, 278, 278, 503, 278, 504, 278, 278, 36, 278, 278, 278, 278, 
-    278, 278, 278, 278, 278, 503, 278, 278, 278, 278, 503, 278, 278, 503, 
-    278, 505, 505, 505, 505, 505, 505, 505, 505, 96, 96, 447, 447, 96, 96, 
-    96, 96, 447, 447, 447, 96, 96, 412, 412, 412, 412, 96, 412, 412, 412, 
-    447, 447, 96, 156, 96, 447, 447, 156, 156, 156, 156, 96, 81, 81, 81, 81, 
-    81, 81, 81, 40, 40, 506, 507, 40, 508, 40, 506, 40, 507, 49, 506, 506, 
-    506, 49, 49, 506, 506, 506, 509, 40, 506, 510, 40, 492, 506, 506, 506, 
-    506, 506, 40, 40, 40, 508, 508, 40, 506, 40, 85, 40, 506, 40, 52, 511, 
-    506, 506, 512, 49, 506, 506, 52, 506, 49, 449, 449, 449, 449, 49, 40, 40, 
-    49, 49, 506, 506, 492, 492, 492, 492, 492, 506, 49, 49, 49, 49, 40, 492, 
-    40, 40, 56, 313, 513, 513, 513, 514, 51, 515, 513, 513, 513, 513, 513, 
-    51, 514, 514, 51, 513, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 
-    516, 516, 517, 517, 517, 517, 516, 516, 517, 517, 517, 517, 517, 517, 
-    517, 517, 517, 52, 56, 517, 517, 517, 517, 51, 40, 40, 81, 81, 81, 81, 
-    54, 54, 54, 54, 54, 508, 508, 508, 508, 508, 492, 492, 40, 40, 40, 40, 
-    492, 40, 40, 492, 40, 40, 492, 40, 40, 40, 40, 40, 40, 40, 492, 40, 40, 
-    40, 40, 40, 40, 40, 40, 40, 44, 44, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
-    40, 40, 40, 492, 492, 40, 40, 54, 40, 54, 40, 40, 40, 40, 40, 40, 40, 40, 
-    40, 40, 44, 40, 40, 40, 40, 492, 492, 492, 492, 492, 492, 492, 492, 492, 
-    492, 492, 492, 54, 492, 54, 54, 492, 492, 492, 54, 54, 492, 492, 54, 492, 
-    492, 492, 54, 492, 54, 518, 519, 492, 54, 492, 492, 492, 492, 54, 492, 
-    492, 54, 54, 54, 54, 492, 492, 54, 492, 54, 492, 54, 54, 54, 54, 54, 54, 
-    492, 54, 492, 492, 492, 492, 492, 54, 54, 54, 54, 492, 492, 492, 492, 54, 
-    54, 492, 492, 54, 492, 492, 492, 54, 492, 492, 492, 492, 492, 54, 492, 
-    492, 492, 492, 492, 54, 54, 492, 492, 54, 54, 54, 54, 492, 492, 54, 54, 
-    492, 492, 54, 54, 492, 492, 492, 492, 492, 54, 492, 492, 492, 54, 492, 
-    492, 492, 492, 492, 492, 492, 492, 492, 492, 492, 492, 492, 54, 492, 492, 
-    492, 492, 492, 492, 492, 520, 473, 491, 473, 491, 40, 40, 40, 40, 40, 40, 
-    508, 40, 40, 40, 40, 40, 40, 40, 521, 521, 40, 40, 40, 40, 492, 492, 40, 
-    40, 40, 40, 40, 40, 40, 522, 523, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
-    40, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 40, 
-    492, 40, 40, 40, 40, 40, 40, 40, 40, 313, 40, 40, 40, 40, 40, 492, 492, 
-    492, 492, 492, 492, 492, 492, 492, 40, 40, 40, 40, 40, 524, 524, 524, 
-    524, 40, 40, 40, 521, 525, 525, 521, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
-    40, 40, 81, 40, 40, 40, 81, 81, 81, 81, 81, 51, 51, 51, 51, 51, 51, 51, 
-    51, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 526, 526, 526, 526, 
-    526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 515, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 514, 508, 508, 508, 508, 508, 508, 508, 
-    508, 508, 508, 508, 508, 40, 40, 40, 40, 508, 508, 508, 508, 527, 40, 40, 
-    40, 40, 40, 508, 508, 508, 508, 40, 40, 508, 508, 40, 508, 508, 508, 508, 
-    508, 508, 508, 40, 40, 40, 40, 40, 40, 40, 40, 508, 508, 40, 40, 508, 54, 
-    40, 40, 40, 40, 508, 508, 40, 40, 508, 54, 40, 40, 40, 40, 508, 508, 508, 
-    40, 40, 508, 40, 40, 508, 508, 40, 40, 40, 40, 40, 40, 40, 508, 492, 492, 
-    492, 492, 492, 528, 528, 492, 525, 525, 525, 525, 40, 508, 508, 40, 40, 
-    508, 40, 40, 40, 40, 508, 508, 40, 40, 40, 40, 521, 521, 527, 527, 525, 
-    40, 525, 525, 529, 530, 529, 525, 40, 525, 525, 525, 40, 40, 40, 40, 508, 
-    40, 508, 40, 40, 40, 40, 40, 524, 524, 524, 524, 524, 524, 524, 524, 524, 
-    524, 524, 524, 40, 40, 40, 40, 508, 508, 40, 508, 508, 508, 40, 508, 529, 
-    508, 508, 40, 508, 508, 40, 54, 40, 40, 40, 40, 40, 40, 40, 521, 40, 40, 
-    40, 524, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 508, 508, 40, 524, 40, 
-    40, 40, 40, 40, 40, 40, 40, 524, 524, 313, 40, 40, 40, 40, 40, 40, 40, 
-    40, 521, 521, 529, 525, 525, 525, 525, 521, 521, 529, 529, 529, 508, 508, 
-    508, 508, 529, 524, 529, 529, 529, 508, 529, 521, 508, 508, 508, 529, 
-    529, 508, 508, 529, 508, 508, 529, 529, 529, 40, 508, 40, 40, 40, 40, 
-    508, 508, 521, 508, 508, 508, 508, 508, 508, 529, 521, 521, 529, 521, 
-    508, 529, 529, 531, 521, 508, 508, 521, 529, 529, 525, 525, 525, 525, 
-    525, 524, 40, 40, 525, 525, 532, 532, 530, 530, 40, 40, 524, 40, 40, 40, 
-    40, 40, 40, 40, 40, 40, 40, 40, 40, 44, 40, 40, 40, 40, 40, 40, 524, 40, 
-    524, 40, 40, 40, 40, 524, 524, 524, 40, 533, 40, 40, 40, 534, 534, 534, 
-    534, 534, 534, 40, 535, 535, 525, 40, 40, 40, 473, 491, 473, 491, 473, 
-    491, 473, 491, 473, 491, 473, 491, 473, 491, 51, 51, 515, 515, 515, 515, 
-    515, 515, 515, 515, 515, 515, 515, 515, 40, 524, 524, 524, 40, 40, 40, 
-    40, 40, 40, 40, 524, 492, 492, 492, 492, 492, 473, 491, 492, 492, 492, 
-    492, 492, 492, 492, 16, 31, 16, 31, 16, 31, 16, 31, 473, 491, 536, 536, 
-    536, 536, 536, 536, 536, 536, 492, 492, 492, 473, 491, 16, 31, 473, 491, 
-    473, 491, 473, 491, 473, 491, 473, 491, 492, 492, 492, 492, 492, 492, 
-    492, 473, 491, 473, 491, 492, 492, 492, 492, 492, 492, 492, 492, 473, 
-    491, 492, 492, 40, 40, 40, 524, 524, 40, 40, 40, 492, 492, 492, 492, 492, 
-    40, 40, 492, 492, 492, 492, 492, 492, 40, 40, 40, 524, 40, 40, 40, 40, 
-    533, 508, 508, 40, 40, 40, 40, 81, 81, 40, 40, 40, 40, 40, 40, 40, 40, 
-    81, 81, 40, 40, 81, 81, 81, 40, 40, 40, 40, 81, 40, 40, 40, 40, 40, 40, 
-    81, 81, 81, 81, 40, 40, 40, 40, 537, 537, 537, 537, 537, 537, 537, 537, 
-    537, 537, 537, 537, 537, 537, 537, 81, 538, 538, 538, 538, 538, 538, 538, 
-    538, 538, 538, 538, 538, 538, 538, 538, 81, 52, 56, 52, 52, 52, 56, 56, 
-    52, 56, 52, 56, 52, 56, 52, 52, 52, 52, 56, 52, 56, 56, 52, 56, 56, 56, 
-    56, 56, 56, 59, 59, 52, 52, 87, 88, 87, 88, 88, 539, 539, 539, 539, 539, 
-    539, 87, 88, 87, 88, 540, 540, 540, 87, 88, 81, 81, 81, 81, 81, 541, 542, 
-    542, 542, 543, 541, 542, 544, 544, 544, 544, 544, 544, 544, 544, 544, 
-    544, 544, 544, 544, 544, 81, 544, 81, 81, 81, 81, 81, 544, 81, 81, 545, 
-    545, 545, 545, 545, 545, 545, 545, 81, 81, 81, 81, 81, 81, 81, 546, 547, 
-    81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 548, 95, 95, 95, 
-    95, 95, 95, 95, 95, 549, 549, 42, 50, 42, 50, 549, 549, 549, 42, 50, 549, 
-    42, 50, 373, 373, 373, 373, 373, 373, 373, 373, 84, 468, 550, 373, 551, 
-    84, 42, 50, 84, 84, 42, 50, 473, 491, 473, 491, 473, 491, 473, 491, 373, 
-    373, 373, 373, 371, 60, 373, 373, 84, 373, 373, 84, 84, 84, 84, 84, 552, 
-    552, 373, 373, 373, 84, 468, 373, 473, 373, 373, 373, 373, 373, 373, 373, 
-    81, 81, 81, 81, 81, 81, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, 
-    81, 553, 553, 553, 553, 553, 553, 553, 553, 553, 81, 81, 81, 81, 553, 
-    553, 553, 553, 553, 553, 81, 81, 521, 521, 521, 521, 521, 521, 521, 521, 
-    521, 521, 521, 521, 81, 81, 81, 81, 554, 555, 555, 556, 521, 557, 558, 
-    559, 522, 523, 522, 523, 522, 523, 522, 523, 522, 523, 521, 521, 522, 
-    523, 522, 523, 522, 523, 522, 523, 560, 522, 523, 523, 521, 559, 559, 
-    559, 559, 559, 559, 559, 559, 559, 561, 562, 563, 564, 565, 565, 566, 
-    567, 567, 567, 567, 568, 521, 521, 559, 559, 559, 557, 569, 556, 521, 
-    525, 81, 570, 571, 570, 571, 570, 571, 570, 571, 570, 571, 571, 571, 571, 
-    571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 570, 
-    571, 571, 571, 571, 571, 571, 571, 570, 571, 570, 571, 570, 571, 571, 
-    571, 571, 571, 571, 570, 571, 571, 571, 571, 571, 571, 570, 570, 81, 81, 
-    572, 572, 573, 573, 574, 574, 571, 560, 575, 576, 575, 576, 575, 576, 
-    575, 576, 575, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 
-    576, 576, 576, 576, 576, 576, 575, 576, 576, 576, 576, 576, 576, 576, 
-    575, 576, 575, 576, 575, 576, 576, 576, 576, 576, 576, 575, 576, 576, 
-    576, 576, 576, 576, 575, 575, 576, 576, 576, 576, 577, 578, 579, 579, 
-    576, 81, 81, 81, 81, 81, 580, 580, 580, 580, 580, 580, 580, 580, 580, 
-    580, 580, 580, 580, 580, 580, 580, 580, 580, 81, 81, 581, 581, 581, 581, 
-    581, 581, 581, 581, 581, 581, 581, 581, 581, 581, 581, 581, 581, 581, 
-    581, 581, 581, 581, 81, 582, 582, 583, 583, 583, 583, 582, 582, 582, 582, 
-    582, 582, 582, 582, 582, 582, 580, 580, 580, 81, 81, 81, 81, 81, 575, 
-    575, 575, 575, 575, 575, 575, 575, 584, 584, 584, 584, 584, 584, 584, 
-    584, 584, 584, 584, 584, 584, 585, 585, 81, 583, 583, 583, 583, 583, 583, 
-    583, 583, 583, 583, 582, 582, 582, 582, 582, 582, 586, 586, 586, 586, 
-    586, 586, 586, 586, 521, 587, 587, 587, 587, 587, 587, 587, 587, 587, 
-    587, 587, 587, 587, 587, 587, 584, 584, 584, 584, 585, 585, 585, 582, 
-    582, 587, 587, 587, 587, 587, 587, 587, 582, 582, 582, 582, 521, 521, 
-    521, 521, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 
-    588, 588, 588, 81, 582, 582, 582, 582, 582, 582, 582, 521, 521, 521, 521, 
-    582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 521, 521, 589, 
-    589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 590, 
-    590, 590, 590, 590, 590, 590, 590, 590, 590, 589, 589, 589, 590, 590, 
-    590, 590, 590, 591, 591, 591, 591, 591, 591, 591, 591, 591, 591, 591, 
-    591, 591, 592, 591, 591, 591, 591, 591, 591, 591, 81, 81, 81, 593, 593, 
-    593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 81, 594, 
-    594, 594, 594, 594, 594, 594, 594, 595, 595, 595, 595, 595, 595, 596, 
-    596, 597, 597, 597, 597, 597, 597, 597, 597, 597, 597, 597, 597, 598, 
-    599, 600, 599, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 597, 
-    597, 81, 81, 81, 81, 90, 93, 90, 93, 90, 93, 602, 95, 97, 97, 97, 603, 
-    95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 603, 604, 90, 93, 90, 93, 450, 
-    450, 95, 95, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 
-    605, 605, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 607, 607, 
-    608, 609, 609, 609, 609, 609, 62, 62, 62, 62, 62, 62, 62, 60, 60, 60, 60, 
-    60, 60, 60, 60, 60, 62, 62, 52, 56, 52, 56, 52, 56, 56, 56, 52, 56, 52, 
-    56, 52, 56, 59, 56, 56, 56, 56, 56, 56, 56, 56, 52, 56, 52, 56, 52, 52, 
-    56, 60, 610, 610, 52, 56, 52, 56, 57, 52, 56, 52, 56, 56, 56, 52, 56, 52, 
-    56, 52, 52, 52, 52, 52, 81, 52, 52, 52, 52, 52, 56, 52, 56, 81, 81, 81, 
-    81, 81, 81, 81, 57, 59, 59, 56, 57, 57, 57, 57, 57, 611, 611, 612, 611, 
-    611, 611, 613, 611, 611, 611, 611, 612, 611, 611, 611, 611, 611, 611, 
-    611, 611, 611, 611, 611, 611, 611, 611, 611, 614, 614, 612, 612, 614, 
-    615, 615, 615, 615, 81, 81, 81, 81, 616, 616, 616, 616, 616, 616, 313, 
-    313, 503, 512, 81, 81, 81, 81, 81, 81, 617, 617, 617, 617, 617, 617, 617, 
-    617, 617, 617, 617, 617, 618, 618, 619, 619, 620, 620, 621, 621, 621, 
-    621, 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, 
-    621, 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, 
-    620, 620, 620, 622, 623, 81, 81, 81, 81, 81, 81, 81, 81, 624, 624, 625, 
-    625, 625, 625, 625, 625, 625, 625, 625, 625, 81, 81, 81, 81, 81, 81, 197, 
-    197, 197, 197, 197, 197, 197, 197, 197, 197, 194, 194, 194, 194, 194, 
-    194, 200, 200, 200, 194, 626, 194, 81, 81, 627, 627, 627, 627, 627, 627, 
-    627, 627, 627, 627, 628, 628, 628, 628, 628, 628, 628, 628, 628, 628, 
-    628, 628, 628, 628, 628, 628, 628, 628, 628, 628, 629, 629, 629, 629, 
-    629, 630, 630, 630, 198, 631, 632, 632, 632, 632, 632, 632, 632, 632, 
-    632, 632, 632, 632, 632, 632, 632, 633, 633, 633, 633, 633, 633, 633, 
-    633, 633, 633, 633, 634, 635, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 
-    636, 328, 328, 328, 328, 328, 81, 81, 81, 637, 637, 637, 638, 639, 639, 
-    639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 640, 
-    638, 638, 637, 637, 637, 637, 638, 638, 637, 638, 638, 638, 641, 642, 
-    642, 642, 642, 642, 642, 643, 643, 643, 642, 642, 642, 642, 81, 61, 644, 
-    644, 644, 644, 644, 644, 644, 644, 644, 644, 81, 81, 81, 81, 642, 642, 
-    314, 314, 314, 314, 314, 316, 645, 314, 319, 319, 314, 314, 314, 314, 
-    314, 81, 646, 646, 646, 646, 646, 646, 646, 646, 646, 647, 647, 647, 647, 
-    647, 647, 648, 648, 647, 647, 648, 648, 647, 647, 81, 646, 646, 646, 647, 
-    646, 646, 646, 646, 646, 646, 646, 646, 647, 648, 81, 81, 649, 649, 649, 
-    649, 649, 649, 649, 649, 649, 649, 81, 81, 650, 651, 651, 651, 645, 314, 
-    314, 314, 314, 314, 314, 323, 323, 323, 314, 315, 316, 315, 314, 314, 
-    652, 652, 652, 652, 652, 652, 652, 652, 653, 652, 653, 653, 654, 652, 
-    652, 653, 653, 652, 652, 652, 652, 652, 653, 653, 652, 653, 652, 81, 81, 
-    81, 81, 81, 81, 81, 81, 652, 652, 655, 656, 656, 657, 657, 657, 657, 657, 
-    657, 657, 657, 657, 657, 657, 658, 659, 659, 658, 658, 660, 660, 657, 
-    661, 661, 658, 662, 81, 81, 331, 331, 331, 331, 331, 331, 81, 56, 56, 56, 
-    610, 59, 59, 59, 59, 56, 56, 56, 56, 56, 79, 81, 81, 338, 338, 338, 338, 
-    338, 338, 338, 338, 657, 657, 657, 658, 658, 659, 658, 658, 659, 658, 
-    658, 660, 658, 662, 81, 81, 663, 663, 663, 663, 663, 663, 663, 663, 663, 
-    663, 81, 81, 81, 81, 81, 81, 664, 665, 665, 665, 665, 665, 665, 665, 665, 
-    665, 665, 665, 665, 665, 665, 665, 665, 665, 665, 665, 664, 665, 665, 
-    665, 665, 665, 665, 665, 81, 81, 81, 81, 329, 329, 329, 329, 329, 329, 
-    329, 81, 81, 81, 81, 330, 330, 330, 330, 330, 330, 330, 330, 330, 81, 81, 
-    81, 81, 666, 666, 666, 666, 666, 666, 666, 666, 667, 667, 667, 667, 667, 
-    667, 667, 667, 589, 589, 590, 590, 590, 590, 590, 590, 56, 56, 56, 56, 
-    56, 56, 56, 81, 81, 81, 81, 101, 101, 101, 101, 101, 81, 81, 81, 81, 81, 
-    129, 668, 129, 129, 669, 129, 129, 129, 129, 129, 129, 129, 129, 129, 
-    129, 129, 129, 129, 81, 129, 129, 129, 129, 129, 81, 129, 81, 129, 129, 
-    81, 129, 129, 81, 129, 129, 146, 146, 670, 670, 670, 670, 670, 670, 670, 
-    670, 670, 670, 670, 670, 670, 670, 670, 670, 81, 81, 81, 81, 81, 81, 81, 
-    81, 81, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 491, 473, 
-    81, 81, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 135, 138, 81, 
-    81, 671, 671, 671, 671, 671, 671, 671, 671, 672, 555, 555, 672, 672, 673, 
-    673, 522, 523, 674, 81, 81, 81, 81, 81, 81, 96, 96, 96, 96, 96, 96, 96, 
-    156, 156, 156, 156, 156, 156, 156, 95, 95, 556, 566, 566, 675, 675, 522, 
-    523, 522, 523, 522, 523, 522, 523, 522, 523, 522, 523, 522, 523, 522, 
-    523, 556, 556, 522, 523, 556, 556, 556, 556, 675, 675, 675, 676, 556, 
-    676, 81, 577, 677, 673, 673, 566, 522, 523, 522, 523, 522, 523, 678, 556, 
-    556, 679, 680, 681, 681, 681, 81, 556, 682, 683, 556, 81, 81, 81, 81, 
-    146, 146, 146, 146, 146, 81, 81, 493, 81, 684, 685, 686, 687, 688, 685, 
-    685, 689, 690, 685, 691, 692, 693, 692, 694, 695, 695, 695, 695, 695, 
-    695, 695, 695, 695, 695, 696, 697, 698, 698, 698, 684, 685, 699, 699, 
-    699, 699, 699, 699, 699, 699, 699, 699, 699, 699, 699, 699, 699, 699, 
-    699, 699, 689, 685, 690, 700, 701, 700, 702, 702, 702, 702, 702, 702, 
-    702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 689, 698, 
-    690, 698, 689, 690, 703, 704, 705, 703, 706, 707, 708, 708, 708, 708, 
-    708, 708, 708, 708, 708, 709, 707, 707, 707, 707, 707, 707, 707, 707, 
-    707, 707, 707, 707, 707, 707, 707, 707, 707, 707, 707, 707, 707, 710, 
-    710, 711, 711, 711, 711, 711, 711, 711, 711, 711, 711, 711, 711, 711, 
-    711, 711, 81, 81, 81, 711, 711, 711, 711, 711, 711, 81, 81, 711, 711, 
-    711, 81, 81, 81, 712, 687, 698, 700, 713, 687, 687, 81, 714, 715, 715, 
-    715, 715, 714, 714, 81, 81, 716, 716, 716, 717, 508, 81, 81, 718, 718, 
-    718, 718, 718, 718, 718, 718, 718, 718, 718, 718, 81, 718, 718, 718, 718, 
-    718, 718, 718, 718, 718, 718, 81, 718, 718, 718, 81, 718, 718, 81, 718, 
-    718, 718, 718, 718, 718, 718, 81, 81, 718, 718, 718, 81, 81, 81, 81, 81, 
-    198, 373, 198, 81, 81, 81, 81, 616, 616, 616, 616, 616, 616, 616, 616, 
-    616, 616, 616, 616, 616, 81, 81, 81, 313, 719, 719, 719, 719, 719, 719, 
-    719, 719, 719, 719, 719, 719, 719, 720, 720, 720, 720, 721, 721, 721, 
-    721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 
-    720, 720, 721, 722, 722, 81, 40, 40, 40, 40, 81, 81, 81, 81, 721, 81, 81, 
-    81, 81, 81, 81, 81, 313, 313, 313, 313, 313, 156, 81, 81, 723, 723, 723, 
-    723, 723, 723, 723, 723, 723, 723, 723, 723, 723, 81, 81, 81, 724, 724, 
-    724, 724, 724, 724, 724, 724, 724, 81, 81, 81, 81, 81, 81, 81, 156, 500, 
-    500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 
-    500, 500, 500, 500, 81, 81, 81, 81, 725, 725, 725, 725, 725, 725, 725, 
-    725, 726, 726, 726, 726, 81, 81, 81, 81, 81, 81, 81, 81, 81, 725, 725, 
-    725, 727, 727, 727, 727, 727, 727, 727, 727, 727, 728, 727, 727, 727, 
-    727, 727, 727, 727, 727, 728, 81, 81, 81, 81, 81, 729, 729, 729, 729, 
-    729, 729, 729, 729, 729, 729, 729, 729, 729, 729, 730, 730, 730, 730, 
-    730, 81, 81, 81, 81, 81, 731, 731, 731, 731, 731, 731, 731, 731, 731, 
-    731, 731, 731, 731, 731, 81, 732, 733, 733, 733, 733, 733, 733, 733, 733, 
-    733, 733, 733, 733, 81, 81, 81, 81, 734, 735, 735, 735, 735, 735, 81, 81, 
-    736, 736, 736, 736, 736, 736, 736, 736, 737, 737, 737, 737, 737, 737, 
-    737, 737, 738, 738, 738, 738, 738, 738, 738, 738, 739, 739, 739, 739, 
-    739, 739, 739, 739, 739, 739, 739, 739, 739, 739, 81, 81, 740, 740, 740, 
-    740, 740, 740, 740, 740, 740, 740, 81, 81, 81, 81, 81, 81, 741, 741, 741, 
-    741, 741, 741, 741, 741, 741, 741, 741, 741, 81, 81, 81, 81, 742, 742, 
-    742, 742, 742, 742, 742, 742, 742, 742, 742, 742, 81, 81, 81, 81, 743, 
-    743, 743, 743, 743, 743, 743, 743, 744, 744, 744, 744, 744, 744, 744, 
-    744, 744, 744, 744, 744, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 745, 
-    746, 746, 746, 746, 746, 746, 746, 746, 746, 746, 746, 746, 746, 746, 
-    746, 81, 746, 746, 746, 746, 746, 746, 81, 81, 747, 747, 747, 747, 747, 
-    747, 81, 81, 747, 81, 747, 747, 747, 747, 747, 747, 747, 747, 747, 747, 
-    747, 747, 747, 747, 747, 747, 747, 747, 747, 747, 81, 747, 747, 81, 81, 
-    81, 747, 81, 81, 747, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 
-    748, 748, 748, 748, 81, 749, 750, 750, 750, 750, 750, 750, 750, 750, 751, 
-    751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 
-    752, 752, 753, 753, 753, 753, 753, 753, 753, 754, 754, 754, 754, 754, 
-    754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 81, 81, 81, 81, 81, 81, 
-    81, 81, 755, 755, 755, 755, 755, 755, 755, 755, 755, 756, 756, 756, 756, 
-    756, 756, 756, 756, 756, 756, 756, 81, 756, 756, 81, 81, 81, 81, 81, 757, 
-    757, 757, 757, 757, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 
-    758, 758, 758, 758, 759, 759, 759, 759, 759, 759, 81, 81, 81, 760, 761, 
-    761, 761, 761, 761, 761, 761, 761, 761, 761, 81, 81, 81, 81, 81, 762, 
-    763, 763, 763, 763, 763, 763, 763, 763, 764, 764, 764, 764, 764, 764, 
-    764, 764, 81, 81, 81, 81, 765, 765, 764, 764, 765, 765, 765, 765, 765, 
-    765, 765, 765, 81, 81, 765, 765, 765, 765, 765, 765, 766, 767, 767, 767, 
-    81, 767, 767, 81, 81, 81, 81, 81, 767, 768, 767, 769, 766, 766, 766, 766, 
-    81, 766, 766, 766, 81, 766, 766, 766, 766, 766, 766, 766, 766, 766, 766, 
-    766, 766, 766, 766, 766, 766, 766, 766, 766, 81, 81, 81, 81, 769, 770, 
-    768, 81, 81, 81, 81, 771, 772, 772, 772, 772, 772, 772, 772, 772, 773, 
-    773, 773, 773, 773, 773, 773, 773, 774, 81, 81, 81, 81, 81, 81, 81, 775, 
-    775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 776, 776, 
-    777, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 
-    779, 779, 779, 780, 780, 780, 780, 780, 780, 780, 780, 781, 780, 780, 
-    780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 782, 783, 81, 81, 81, 
-    81, 784, 784, 784, 784, 784, 785, 785, 785, 785, 785, 785, 786, 81, 787, 
-    787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 81, 81, 
-    81, 788, 788, 788, 788, 788, 788, 788, 789, 789, 789, 789, 789, 789, 789, 
-    789, 789, 789, 789, 789, 789, 789, 81, 81, 790, 790, 790, 790, 790, 790, 
-    790, 790, 791, 791, 791, 791, 791, 791, 791, 791, 791, 791, 791, 81, 81, 
-    81, 81, 81, 792, 792, 792, 792, 792, 792, 792, 792, 793, 793, 793, 793, 
-    793, 793, 793, 793, 793, 793, 81, 81, 81, 81, 81, 81, 81, 794, 794, 794, 
-    794, 81, 81, 81, 81, 795, 795, 795, 795, 795, 795, 795, 796, 796, 796, 
+    81, 99, 100, 100, 100, 100, 100, 100, 101, 101, 101, 101, 101, 101, 101, 
+    101, 101, 102, 103, 81, 81, 104, 104, 105, 81, 106, 107, 107, 107, 107, 
+    106, 107, 107, 107, 108, 106, 107, 107, 107, 107, 107, 107, 106, 106, 
+    106, 106, 106, 106, 107, 107, 106, 107, 107, 108, 109, 107, 110, 111, 
+    112, 113, 114, 115, 116, 117, 118, 119, 119, 120, 121, 122, 123, 124, 
+    125, 126, 127, 125, 107, 106, 128, 118, 81, 81, 81, 81, 81, 81, 81, 81, 
+    129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 81, 81, 81, 81, 
+    129, 129, 129, 129, 125, 125, 81, 81, 81, 130, 130, 130, 130, 130, 131, 
+    132, 132, 133, 134, 134, 135, 136, 137, 138, 138, 139, 139, 139, 139, 
+    139, 139, 139, 139, 140, 141, 142, 143, 144, 81, 145, 143, 146, 146, 146, 
+    146, 146, 146, 146, 146, 147, 146, 146, 146, 146, 146, 146, 146, 146, 
+    146, 146, 148, 149, 150, 151, 152, 153, 154, 155, 96, 96, 156, 157, 139, 
+    139, 139, 139, 139, 157, 139, 139, 157, 158, 158, 158, 158, 158, 158, 
+    158, 158, 158, 158, 134, 159, 159, 160, 146, 146, 161, 146, 146, 146, 
+    146, 146, 146, 146, 146, 146, 146, 146, 145, 146, 139, 139, 139, 139, 
+    139, 139, 139, 131, 138, 139, 139, 139, 139, 157, 139, 162, 162, 139, 
+    139, 138, 157, 139, 139, 157, 146, 146, 163, 163, 163, 163, 163, 163, 
+    163, 163, 163, 163, 146, 146, 146, 164, 164, 146, 165, 165, 165, 165, 
+    165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 81, 166, 167, 168, 167, 
+    167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 169, 
+    170, 169, 169, 170, 169, 169, 170, 170, 170, 169, 170, 170, 169, 170, 
+    169, 169, 169, 170, 169, 170, 169, 170, 169, 170, 169, 169, 81, 81, 167, 
+    167, 167, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 
+    171, 171, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 171, 81, 
+    81, 81, 81, 81, 81, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 
+    174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 
+    174, 174, 174, 175, 175, 175, 175, 175, 175, 175, 176, 175, 177, 177, 
+    178, 179, 180, 181, 177, 81, 81, 176, 182, 182, 183, 183, 183, 183, 183, 
+    183, 183, 183, 183, 183, 183, 183, 183, 183, 184, 184, 184, 184, 185, 
+    184, 184, 184, 184, 184, 184, 184, 184, 184, 185, 184, 184, 184, 185, 
+    184, 184, 184, 184, 184, 81, 81, 186, 186, 186, 186, 186, 186, 186, 186, 
+    186, 186, 186, 186, 186, 186, 186, 81, 187, 187, 187, 187, 187, 187, 187, 
+    187, 187, 188, 188, 188, 81, 81, 189, 81, 167, 167, 167, 81, 81, 81, 81, 
+    81, 146, 146, 146, 146, 146, 81, 146, 146, 146, 146, 146, 146, 146, 146, 
+    81, 81, 81, 81, 81, 157, 139, 139, 139, 139, 139, 139, 131, 157, 139, 
+    139, 157, 139, 139, 157, 139, 139, 139, 157, 157, 157, 190, 191, 192, 
+    139, 139, 139, 157, 139, 139, 157, 157, 139, 139, 139, 139, 139, 193, 
+    193, 193, 194, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 
+    195, 195, 195, 193, 194, 196, 195, 194, 194, 194, 193, 193, 193, 193, 
+    193, 193, 193, 193, 194, 194, 194, 194, 197, 194, 194, 195, 96, 156, 198, 
+    198, 193, 193, 193, 195, 195, 193, 193, 199, 199, 200, 200, 200, 200, 
+    200, 200, 200, 200, 200, 200, 201, 202, 195, 195, 195, 195, 195, 195, 
+    203, 204, 205, 205, 81, 203, 203, 203, 203, 203, 203, 203, 203, 81, 81, 
+    203, 203, 81, 81, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 
+    203, 203, 203, 81, 203, 203, 203, 203, 203, 203, 203, 81, 203, 81, 81, 
+    81, 203, 203, 203, 203, 81, 81, 206, 203, 205, 205, 205, 204, 204, 204, 
+    204, 81, 81, 205, 205, 81, 81, 205, 205, 207, 203, 81, 81, 81, 81, 81, 
+    81, 81, 81, 205, 81, 81, 81, 81, 203, 203, 81, 203, 203, 203, 204, 204, 
+    81, 81, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 203, 203, 209, 
+    209, 210, 210, 210, 210, 210, 211, 212, 213, 203, 214, 215, 81, 81, 216, 
+    216, 217, 81, 218, 218, 218, 218, 218, 218, 81, 81, 81, 81, 218, 218, 81, 
+    81, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 
+    81, 218, 218, 218, 218, 218, 218, 218, 81, 218, 218, 81, 218, 218, 81, 
+    218, 218, 81, 81, 219, 81, 217, 217, 217, 216, 216, 81, 81, 81, 81, 216, 
+    216, 81, 81, 216, 216, 220, 81, 81, 81, 216, 81, 81, 81, 81, 81, 81, 81, 
+    218, 218, 218, 218, 81, 218, 81, 81, 81, 81, 81, 81, 81, 221, 221, 221, 
+    221, 221, 221, 221, 221, 221, 221, 216, 216, 218, 218, 218, 216, 222, 81, 
+    81, 223, 223, 224, 81, 225, 225, 225, 225, 225, 225, 225, 225, 225, 81, 
+    225, 225, 225, 81, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 
+    225, 225, 225, 81, 225, 225, 225, 225, 225, 225, 225, 81, 225, 225, 81, 
+    225, 225, 225, 225, 225, 81, 81, 226, 225, 224, 224, 224, 223, 223, 223, 
+    223, 223, 81, 223, 223, 224, 81, 224, 224, 227, 81, 81, 225, 81, 81, 81, 
+    81, 81, 81, 81, 225, 225, 223, 223, 81, 81, 228, 228, 228, 228, 228, 228, 
+    228, 228, 228, 228, 229, 230, 81, 81, 81, 81, 81, 81, 81, 225, 223, 223, 
+    223, 223, 223, 223, 81, 231, 232, 232, 81, 233, 233, 233, 233, 233, 233, 
+    233, 233, 81, 81, 233, 233, 81, 81, 233, 233, 233, 233, 233, 233, 233, 
+    233, 233, 233, 233, 233, 233, 233, 81, 233, 233, 233, 233, 233, 233, 233, 
+    81, 233, 233, 81, 233, 233, 233, 233, 233, 81, 81, 234, 233, 232, 231, 
+    232, 231, 231, 231, 231, 81, 81, 232, 232, 81, 81, 232, 232, 235, 81, 81, 
+    81, 81, 81, 81, 81, 81, 231, 232, 81, 81, 81, 81, 233, 233, 81, 233, 233, 
+    233, 231, 231, 81, 81, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 
+    237, 233, 238, 238, 238, 238, 238, 238, 81, 81, 239, 240, 81, 240, 240, 
+    240, 240, 240, 240, 81, 81, 81, 240, 240, 240, 81, 240, 240, 240, 240, 
+    81, 81, 81, 240, 240, 81, 240, 81, 240, 240, 81, 81, 81, 240, 240, 81, 
+    81, 81, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 81, 81, 81, 81, 
+    241, 241, 239, 241, 241, 81, 81, 81, 241, 241, 241, 81, 241, 241, 241, 
+    242, 81, 81, 240, 81, 81, 81, 81, 81, 81, 241, 81, 81, 81, 81, 81, 81, 
+    243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 244, 244, 244, 245, 
+    245, 245, 245, 245, 245, 246, 245, 81, 81, 81, 81, 81, 247, 248, 248, 
+    248, 247, 249, 249, 249, 249, 249, 249, 249, 249, 81, 249, 249, 249, 81, 
+    249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 
+    249, 249, 81, 81, 81, 249, 247, 247, 247, 248, 248, 248, 248, 81, 247, 
+    247, 247, 81, 247, 247, 247, 250, 81, 81, 81, 81, 81, 81, 81, 251, 252, 
+    81, 249, 249, 249, 81, 81, 81, 81, 81, 249, 249, 247, 247, 81, 81, 253, 
+    253, 253, 253, 253, 253, 253, 253, 253, 253, 254, 254, 254, 254, 254, 
+    254, 254, 255, 256, 257, 258, 258, 259, 256, 256, 256, 256, 256, 256, 
+    256, 256, 81, 256, 256, 256, 81, 256, 256, 256, 256, 256, 256, 256, 256, 
+    256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 81, 256, 256, 256, 256, 
+    256, 81, 81, 260, 256, 258, 261, 258, 258, 258, 258, 258, 81, 261, 258, 
+    258, 81, 258, 258, 257, 262, 81, 81, 81, 81, 81, 81, 81, 258, 258, 81, 
+    81, 81, 81, 81, 81, 81, 256, 81, 256, 256, 257, 257, 81, 81, 263, 263, 
+    263, 263, 263, 263, 263, 263, 263, 263, 81, 256, 256, 81, 81, 81, 81, 81, 
+    264, 264, 265, 265, 81, 266, 266, 266, 266, 266, 266, 266, 266, 81, 266, 
+    266, 266, 81, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 
+    266, 266, 266, 266, 266, 267, 267, 266, 265, 265, 265, 264, 264, 264, 
+    264, 81, 265, 265, 265, 81, 265, 265, 265, 267, 266, 268, 81, 81, 81, 81, 
+    266, 266, 266, 265, 269, 269, 269, 269, 269, 269, 269, 266, 266, 266, 
+    264, 264, 81, 81, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 269, 
+    269, 269, 269, 269, 269, 269, 269, 269, 271, 266, 266, 266, 266, 266, 
+    266, 81, 81, 272, 272, 81, 273, 273, 273, 273, 273, 273, 273, 273, 273, 
+    273, 273, 273, 273, 273, 273, 273, 273, 273, 81, 81, 81, 273, 273, 273, 
+    273, 273, 273, 273, 273, 81, 273, 273, 273, 273, 273, 273, 273, 273, 273, 
+    81, 273, 81, 81, 81, 81, 274, 81, 81, 81, 81, 272, 272, 272, 275, 275, 
+    275, 81, 275, 81, 272, 272, 272, 272, 272, 272, 272, 272, 81, 81, 81, 81, 
+    81, 81, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 81, 81, 272, 
+    272, 277, 81, 81, 81, 81, 278, 278, 278, 278, 278, 278, 278, 278, 278, 
+    278, 278, 278, 278, 278, 278, 278, 279, 278, 278, 279, 279, 279, 279, 
+    280, 280, 281, 81, 81, 81, 81, 282, 278, 278, 278, 278, 278, 278, 283, 
+    279, 284, 284, 284, 284, 279, 279, 279, 285, 286, 286, 286, 286, 286, 
+    286, 286, 286, 286, 286, 287, 287, 81, 81, 81, 81, 81, 288, 288, 81, 288, 
+    81, 81, 288, 288, 81, 288, 81, 81, 288, 81, 81, 81, 81, 81, 81, 288, 288, 
+    288, 288, 81, 288, 288, 288, 288, 288, 288, 288, 81, 288, 288, 288, 81, 
+    288, 81, 288, 81, 81, 288, 288, 81, 288, 288, 288, 288, 289, 288, 288, 
+    289, 289, 289, 289, 290, 290, 81, 289, 289, 288, 81, 81, 288, 288, 288, 
+    288, 288, 81, 291, 81, 292, 292, 292, 292, 289, 289, 81, 81, 293, 293, 
+    293, 293, 293, 293, 293, 293, 293, 293, 81, 81, 288, 288, 288, 288, 294, 
+    295, 295, 295, 296, 297, 296, 296, 298, 296, 296, 299, 298, 300, 300, 
+    300, 300, 300, 298, 301, 300, 301, 301, 301, 302, 302, 301, 301, 301, 
+    301, 301, 301, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 304, 
+    304, 304, 304, 304, 304, 304, 304, 304, 304, 305, 302, 301, 302, 301, 
+    306, 307, 308, 307, 308, 309, 309, 294, 294, 294, 294, 294, 294, 294, 
+    294, 81, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 81, 
+    81, 81, 81, 310, 311, 312, 313, 312, 312, 312, 312, 312, 311, 311, 311, 
+    311, 312, 314, 311, 312, 315, 315, 316, 299, 315, 315, 294, 294, 294, 
+    294, 294, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 81, 312, 
+    312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 81, 305, 305, 301, 
+    301, 301, 301, 301, 301, 302, 301, 301, 301, 301, 301, 301, 81, 301, 301, 
+    296, 296, 299, 296, 297, 317, 317, 317, 317, 298, 298, 81, 81, 81, 81, 
+    81, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 319, 319, 320, 
+    320, 320, 320, 319, 320, 320, 320, 320, 320, 321, 319, 322, 322, 319, 
+    319, 320, 320, 318, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 
+    324, 324, 325, 325, 325, 325, 318, 318, 318, 318, 318, 318, 319, 319, 
+    320, 320, 318, 318, 318, 318, 320, 320, 320, 318, 319, 319, 319, 318, 
+    318, 319, 319, 319, 319, 319, 319, 319, 318, 318, 318, 320, 320, 320, 
+    320, 318, 318, 318, 318, 318, 320, 319, 319, 320, 320, 319, 319, 319, 
+    319, 319, 319, 326, 318, 319, 323, 323, 319, 319, 319, 320, 327, 327, 
+    328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 81, 
+    328, 81, 81, 81, 81, 81, 328, 81, 81, 329, 329, 329, 329, 329, 329, 329, 
+    329, 329, 329, 329, 330, 331, 329, 329, 329, 332, 332, 332, 332, 332, 
+    332, 332, 332, 333, 333, 333, 333, 333, 333, 333, 333, 334, 334, 334, 
+    334, 334, 334, 334, 334, 335, 335, 335, 335, 335, 335, 335, 335, 335, 81, 
+    335, 335, 335, 335, 81, 81, 335, 335, 335, 335, 335, 335, 335, 81, 335, 
+    335, 335, 81, 81, 336, 336, 336, 337, 338, 337, 337, 337, 337, 337, 337, 
+    337, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 
+    339, 339, 339, 339, 339, 339, 339, 81, 81, 81, 340, 340, 340, 340, 340, 
+    340, 340, 340, 340, 340, 81, 81, 81, 81, 81, 81, 341, 341, 341, 341, 341, 
+    341, 341, 341, 341, 341, 341, 341, 341, 341, 81, 81, 342, 342, 342, 342, 
+    342, 342, 81, 81, 343, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 
+    344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 345, 345, 344, 346, 
+    347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 
+    347, 347, 347, 347, 348, 349, 81, 81, 81, 350, 350, 350, 350, 350, 350, 
+    350, 350, 350, 350, 350, 199, 199, 199, 351, 351, 351, 350, 350, 350, 
+    350, 350, 350, 350, 350, 81, 81, 81, 81, 81, 81, 81, 352, 352, 352, 352, 
+    352, 352, 352, 352, 352, 352, 352, 352, 352, 81, 352, 352, 352, 352, 353, 
+    353, 354, 81, 81, 81, 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, 
+    356, 356, 357, 199, 199, 81, 358, 358, 358, 358, 358, 358, 358, 358, 358, 
+    358, 359, 359, 81, 81, 81, 81, 360, 360, 360, 360, 360, 360, 360, 360, 
+    360, 360, 360, 360, 360, 81, 360, 360, 360, 81, 361, 361, 81, 81, 81, 81, 
+    362, 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, 363, 363, 
+    364, 363, 363, 363, 363, 363, 363, 363, 364, 364, 364, 364, 364, 364, 
+    364, 364, 363, 364, 364, 363, 363, 363, 363, 363, 363, 363, 363, 363, 
+    365, 363, 366, 366, 367, 368, 366, 369, 366, 370, 362, 371, 81, 81, 372, 
+    372, 372, 372, 372, 372, 372, 372, 372, 372, 81, 81, 81, 81, 81, 81, 373, 
+    373, 373, 373, 373, 373, 373, 373, 373, 373, 81, 81, 81, 81, 81, 81, 374, 
+    374, 375, 375, 376, 377, 378, 374, 379, 379, 374, 380, 380, 380, 381, 81, 
+    382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 81, 81, 81, 81, 81, 81, 
+    383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 384, 383, 383, 
+    383, 383, 383, 81, 81, 81, 81, 81, 81, 81, 383, 383, 383, 383, 383, 380, 
+    380, 383, 383, 385, 383, 81, 81, 81, 81, 81, 344, 344, 344, 344, 344, 
+    344, 81, 81, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 
+    386, 386, 386, 81, 387, 387, 387, 388, 388, 388, 388, 387, 387, 388, 388, 
+    388, 81, 81, 81, 81, 388, 388, 387, 388, 388, 388, 388, 388, 388, 389, 
+    390, 391, 81, 81, 81, 81, 392, 81, 81, 81, 393, 393, 394, 394, 394, 394, 
+    394, 394, 394, 394, 394, 394, 395, 395, 395, 395, 395, 395, 395, 395, 
+    395, 395, 395, 395, 395, 395, 81, 81, 395, 395, 395, 395, 395, 81, 81, 
+    81, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 81, 81, 
+    81, 81, 396, 396, 81, 81, 81, 81, 81, 81, 397, 397, 397, 397, 397, 397, 
+    397, 397, 397, 397, 398, 81, 81, 81, 399, 399, 400, 400, 400, 400, 400, 
+    400, 400, 400, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 
+    401, 401, 401, 401, 402, 403, 404, 404, 405, 81, 81, 406, 406, 407, 407, 
+    407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, 408, 409, 408, 
+    409, 409, 409, 409, 409, 409, 409, 81, 410, 408, 409, 408, 408, 409, 409, 
+    409, 409, 409, 409, 409, 409, 408, 408, 408, 408, 408, 408, 409, 409, 
+    411, 411, 411, 411, 411, 411, 411, 411, 81, 81, 412, 413, 413, 413, 413, 
+    413, 413, 413, 413, 413, 413, 81, 81, 81, 81, 81, 81, 414, 414, 414, 414, 
+    414, 414, 414, 415, 414, 414, 414, 414, 414, 414, 81, 81, 96, 96, 96, 96, 
+    96, 156, 156, 156, 156, 156, 156, 96, 96, 156, 416, 81, 417, 417, 417, 
+    417, 418, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 
+    419, 419, 419, 420, 418, 417, 417, 417, 417, 417, 418, 417, 418, 418, 
+    418, 418, 418, 417, 418, 421, 419, 419, 419, 419, 419, 419, 419, 81, 81, 
+    81, 81, 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, 423, 423, 424, 
+    423, 423, 423, 423, 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, 
+    426, 427, 426, 426, 426, 426, 426, 426, 426, 425, 425, 425, 425, 425, 
+    425, 425, 425, 425, 81, 81, 81, 428, 428, 429, 430, 430, 430, 430, 430, 
+    430, 430, 430, 430, 430, 430, 430, 430, 430, 429, 428, 428, 428, 428, 
+    429, 429, 428, 428, 431, 432, 428, 428, 430, 430, 433, 433, 433, 433, 
+    433, 433, 433, 433, 433, 433, 430, 430, 430, 430, 430, 430, 434, 434, 
+    434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 434, 435, 436, 
+    437, 437, 436, 436, 436, 437, 436, 437, 437, 437, 438, 438, 81, 81, 81, 
+    81, 81, 81, 81, 81, 439, 439, 439, 439, 440, 440, 440, 440, 440, 440, 
+    440, 440, 440, 440, 440, 440, 441, 441, 441, 441, 441, 441, 441, 441, 
+    442, 442, 442, 442, 442, 442, 442, 442, 441, 441, 442, 443, 81, 81, 81, 
+    444, 444, 444, 444, 444, 445, 445, 445, 445, 445, 445, 445, 445, 445, 
+    445, 81, 81, 81, 440, 440, 440, 446, 446, 446, 446, 446, 446, 446, 446, 
+    446, 446, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 
+    447, 447, 448, 448, 448, 448, 448, 448, 449, 449, 93, 81, 81, 81, 81, 81, 
+    81, 81, 328, 328, 328, 81, 81, 328, 328, 328, 450, 450, 450, 450, 450, 
+    450, 450, 450, 96, 96, 96, 330, 451, 156, 156, 156, 156, 156, 96, 96, 
+    156, 156, 156, 156, 96, 452, 451, 451, 451, 451, 451, 451, 451, 453, 453, 
+    453, 453, 156, 453, 453, 453, 453, 452, 452, 96, 453, 453, 452, 96, 96, 
+    81, 81, 81, 81, 81, 81, 56, 56, 56, 56, 56, 56, 79, 79, 79, 79, 79, 93, 
+    59, 59, 59, 59, 59, 59, 59, 59, 59, 82, 82, 82, 82, 82, 59, 59, 59, 59, 
+    82, 82, 82, 82, 82, 56, 56, 56, 56, 56, 454, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 82, 96, 96, 
+    156, 96, 96, 96, 96, 96, 96, 96, 156, 96, 96, 455, 456, 156, 457, 96, 96, 
+    96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 
+    96, 458, 459, 459, 156, 81, 96, 460, 156, 96, 156, 52, 56, 52, 56, 52, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 52, 56, 79, 79, 79, 79, 79, 79, 79, 
+    79, 78, 78, 78, 78, 78, 78, 78, 78, 79, 79, 79, 79, 79, 79, 81, 81, 78, 
+    78, 78, 78, 78, 78, 81, 81, 81, 78, 81, 78, 81, 78, 81, 78, 461, 461, 
+    461, 461, 461, 461, 461, 461, 79, 79, 79, 79, 79, 81, 79, 79, 78, 78, 78, 
+    78, 461, 80, 79, 80, 80, 80, 79, 79, 79, 81, 79, 79, 78, 78, 78, 78, 461, 
+    80, 80, 80, 79, 79, 79, 79, 81, 81, 79, 79, 78, 78, 78, 78, 81, 80, 80, 
+    80, 78, 78, 78, 78, 78, 80, 80, 80, 81, 81, 79, 79, 79, 81, 79, 79, 78, 
+    78, 78, 78, 461, 462, 80, 81, 463, 463, 463, 463, 463, 463, 463, 464, 
+    463, 463, 463, 465, 466, 467, 468, 469, 470, 471, 472, 470, 473, 474, 38, 
+    84, 475, 476, 477, 42, 475, 476, 477, 42, 38, 38, 478, 84, 479, 479, 479, 
+    480, 481, 482, 483, 484, 485, 486, 487, 33, 488, 489, 488, 488, 489, 490, 
+    491, 491, 84, 42, 50, 38, 492, 492, 478, 493, 493, 84, 84, 84, 494, 477, 
+    495, 492, 492, 492, 84, 84, 84, 84, 84, 84, 84, 84, 496, 84, 493, 84, 
+    377, 84, 377, 377, 377, 377, 84, 377, 377, 463, 497, 498, 498, 498, 498, 
+    81, 499, 500, 501, 502, 503, 503, 503, 503, 503, 503, 504, 59, 81, 81, 
+    47, 504, 504, 504, 504, 504, 505, 505, 496, 477, 495, 506, 504, 47, 47, 
+    47, 47, 504, 504, 504, 504, 504, 505, 505, 496, 477, 495, 81, 59, 59, 59, 
+    59, 59, 81, 81, 81, 282, 282, 282, 282, 282, 282, 282, 507, 282, 508, 
+    282, 282, 36, 282, 282, 282, 282, 282, 282, 282, 282, 282, 507, 282, 282, 
+    282, 282, 507, 282, 282, 507, 282, 509, 509, 509, 509, 509, 509, 509, 
+    509, 96, 96, 451, 451, 96, 96, 96, 96, 451, 451, 451, 96, 96, 416, 416, 
+    416, 416, 96, 416, 416, 416, 451, 451, 96, 156, 96, 451, 451, 156, 156, 
+    156, 156, 96, 81, 81, 81, 81, 81, 81, 81, 40, 40, 510, 511, 40, 512, 40, 
+    510, 40, 511, 49, 510, 510, 510, 49, 49, 510, 510, 510, 513, 40, 510, 
+    514, 40, 496, 510, 510, 510, 510, 510, 40, 40, 40, 512, 512, 40, 510, 40, 
+    85, 40, 510, 40, 52, 515, 510, 510, 516, 49, 510, 510, 52, 510, 49, 453, 
+    453, 453, 453, 49, 40, 40, 49, 49, 510, 510, 496, 496, 496, 496, 496, 
+    510, 49, 49, 49, 49, 40, 496, 40, 40, 56, 317, 517, 517, 517, 518, 51, 
+    519, 517, 517, 517, 517, 517, 51, 518, 518, 51, 517, 520, 520, 520, 520, 
+    520, 520, 520, 520, 520, 520, 520, 520, 521, 521, 521, 521, 520, 520, 
+    521, 521, 521, 521, 521, 521, 521, 521, 521, 52, 56, 521, 521, 521, 521, 
+    51, 40, 40, 81, 81, 81, 81, 54, 54, 54, 54, 54, 512, 512, 512, 512, 512, 
+    496, 496, 40, 40, 40, 40, 496, 40, 40, 496, 40, 40, 496, 40, 40, 40, 40, 
+    40, 40, 40, 496, 40, 40, 40, 40, 40, 40, 40, 40, 40, 44, 44, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 40, 496, 496, 40, 40, 54, 40, 54, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 40, 44, 40, 40, 40, 40, 496, 496, 496, 496, 
+    496, 496, 496, 496, 496, 496, 496, 496, 54, 496, 54, 54, 496, 496, 496, 
+    54, 54, 496, 496, 54, 496, 496, 496, 54, 496, 54, 522, 523, 496, 54, 496, 
+    496, 496, 496, 54, 496, 496, 54, 54, 54, 54, 496, 496, 54, 496, 54, 496, 
+    54, 54, 54, 54, 54, 54, 496, 54, 496, 496, 496, 496, 496, 54, 54, 54, 54, 
+    496, 496, 496, 496, 54, 54, 496, 496, 54, 496, 496, 496, 54, 496, 496, 
+    496, 496, 496, 54, 496, 496, 496, 496, 496, 54, 54, 496, 496, 54, 54, 54, 
+    54, 496, 496, 54, 54, 496, 496, 54, 54, 496, 496, 496, 496, 496, 54, 496, 
+    496, 496, 54, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 
+    496, 54, 496, 496, 496, 496, 496, 496, 496, 524, 477, 495, 477, 495, 40, 
+    40, 40, 40, 40, 40, 512, 40, 40, 40, 40, 40, 40, 40, 525, 525, 40, 40, 
+    40, 40, 496, 496, 40, 40, 40, 40, 40, 40, 40, 526, 527, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 317, 317, 317, 317, 317, 317, 317, 317, 317, 
+    317, 317, 317, 317, 40, 496, 40, 40, 40, 40, 40, 40, 40, 40, 317, 40, 40, 
+    40, 40, 40, 496, 496, 496, 496, 496, 496, 496, 496, 496, 40, 40, 40, 40, 
+    40, 528, 528, 528, 528, 40, 40, 40, 525, 529, 529, 525, 40, 40, 40, 40, 
+    40, 40, 40, 40, 40, 40, 40, 81, 40, 40, 40, 81, 81, 81, 81, 81, 51, 51, 
+    51, 51, 51, 51, 51, 51, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    530, 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, 
+    519, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 518, 512, 512, 512, 
+    512, 512, 512, 512, 512, 512, 512, 512, 512, 40, 40, 40, 40, 512, 512, 
+    512, 512, 531, 40, 40, 40, 40, 40, 512, 512, 512, 512, 40, 40, 512, 512, 
+    40, 512, 512, 512, 512, 512, 512, 512, 40, 40, 40, 40, 40, 40, 40, 40, 
+    512, 512, 40, 40, 512, 54, 40, 40, 40, 40, 512, 512, 40, 40, 512, 54, 40, 
+    40, 40, 40, 512, 512, 512, 40, 40, 512, 40, 40, 512, 512, 40, 40, 40, 40, 
+    40, 40, 40, 512, 496, 496, 496, 496, 496, 532, 532, 496, 529, 529, 529, 
+    529, 40, 512, 512, 40, 40, 512, 40, 40, 40, 40, 512, 512, 40, 40, 40, 40, 
+    525, 525, 531, 531, 529, 40, 529, 529, 533, 534, 533, 529, 40, 529, 529, 
+    529, 40, 40, 40, 40, 512, 40, 512, 40, 40, 40, 40, 40, 528, 528, 528, 
+    528, 528, 528, 528, 528, 528, 528, 528, 528, 40, 40, 40, 40, 512, 512, 
+    40, 512, 512, 512, 40, 512, 533, 512, 512, 40, 512, 512, 40, 54, 40, 40, 
+    40, 40, 40, 40, 40, 525, 40, 40, 40, 528, 40, 40, 40, 40, 40, 40, 40, 40, 
+    40, 40, 512, 512, 40, 528, 40, 40, 40, 40, 40, 40, 40, 40, 528, 528, 317, 
+    40, 40, 40, 40, 40, 40, 40, 40, 525, 525, 533, 529, 529, 529, 529, 525, 
+    525, 533, 533, 533, 512, 512, 512, 512, 533, 528, 533, 533, 533, 512, 
+    533, 525, 512, 512, 512, 533, 533, 512, 512, 533, 512, 512, 533, 533, 
+    533, 40, 512, 40, 40, 40, 40, 512, 512, 525, 512, 512, 512, 512, 512, 
+    512, 533, 525, 525, 533, 525, 512, 533, 533, 535, 525, 512, 512, 525, 
+    533, 533, 529, 529, 529, 529, 529, 528, 40, 40, 529, 529, 536, 536, 534, 
+    534, 40, 40, 528, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 44, 40, 
+    40, 40, 40, 40, 40, 528, 40, 528, 40, 40, 40, 40, 528, 528, 528, 40, 537, 
+    40, 40, 40, 538, 538, 538, 538, 538, 538, 40, 539, 539, 529, 40, 40, 40, 
+    477, 495, 477, 495, 477, 495, 477, 495, 477, 495, 477, 495, 477, 495, 51, 
+    51, 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, 40, 528, 
+    528, 528, 40, 40, 40, 40, 40, 40, 40, 528, 496, 496, 496, 496, 496, 477, 
+    495, 496, 496, 496, 496, 496, 496, 496, 16, 31, 16, 31, 16, 31, 16, 31, 
+    477, 495, 540, 540, 540, 540, 540, 540, 540, 540, 496, 496, 496, 477, 
+    495, 16, 31, 477, 495, 477, 495, 477, 495, 477, 495, 477, 495, 496, 496, 
+    496, 496, 496, 496, 496, 477, 495, 477, 495, 496, 496, 496, 496, 496, 
+    496, 496, 496, 477, 495, 496, 496, 40, 40, 40, 528, 528, 40, 40, 40, 496, 
+    496, 496, 496, 496, 40, 40, 496, 496, 496, 496, 496, 496, 40, 40, 40, 
+    528, 40, 40, 40, 40, 537, 512, 512, 40, 40, 40, 40, 81, 81, 40, 40, 40, 
+    40, 40, 40, 40, 40, 81, 81, 40, 81, 40, 40, 40, 40, 40, 40, 541, 541, 
+    541, 541, 541, 541, 541, 541, 541, 541, 541, 541, 541, 541, 541, 81, 542, 
+    542, 542, 542, 542, 542, 542, 542, 542, 542, 542, 542, 542, 542, 542, 81, 
+    52, 56, 52, 52, 52, 56, 56, 52, 56, 52, 56, 52, 56, 52, 52, 52, 52, 56, 
+    52, 56, 56, 52, 56, 56, 56, 56, 56, 56, 59, 59, 52, 52, 87, 88, 87, 88, 
+    88, 543, 543, 543, 543, 543, 543, 87, 88, 87, 88, 544, 544, 544, 87, 88, 
+    81, 81, 81, 81, 81, 545, 546, 546, 546, 547, 545, 546, 329, 329, 329, 
+    329, 329, 329, 81, 329, 81, 81, 81, 81, 81, 329, 81, 81, 548, 548, 548, 
+    548, 548, 548, 548, 548, 81, 81, 81, 81, 81, 81, 81, 549, 550, 81, 81, 
+    81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 551, 95, 95, 95, 95, 95, 
+    95, 95, 95, 552, 552, 42, 50, 42, 50, 552, 552, 552, 42, 50, 552, 42, 50, 
+    377, 377, 377, 377, 377, 377, 377, 377, 84, 472, 553, 377, 554, 84, 42, 
+    50, 84, 84, 42, 50, 477, 495, 477, 495, 477, 495, 477, 495, 377, 377, 
+    377, 377, 375, 60, 377, 377, 84, 377, 377, 84, 84, 84, 84, 84, 555, 555, 
+    377, 377, 377, 84, 472, 377, 477, 377, 377, 377, 377, 377, 377, 377, 377, 
+    84, 377, 84, 377, 81, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 
+    81, 556, 556, 556, 556, 556, 556, 556, 556, 556, 81, 81, 81, 81, 556, 
+    556, 556, 556, 556, 556, 81, 81, 525, 525, 525, 525, 525, 525, 525, 525, 
+    525, 525, 525, 525, 81, 81, 81, 81, 557, 558, 558, 559, 525, 560, 561, 
+    562, 526, 527, 526, 527, 526, 527, 526, 527, 526, 527, 525, 525, 526, 
+    527, 526, 527, 526, 527, 526, 527, 563, 526, 527, 527, 525, 562, 562, 
+    562, 562, 562, 562, 562, 562, 562, 564, 565, 566, 567, 568, 568, 569, 
+    570, 570, 570, 570, 571, 525, 525, 562, 562, 562, 560, 572, 559, 525, 
+    529, 81, 573, 574, 573, 574, 573, 574, 573, 574, 573, 574, 574, 574, 574, 
+    574, 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, 573, 
+    574, 574, 574, 574, 574, 574, 574, 573, 574, 573, 574, 573, 574, 574, 
+    574, 574, 574, 574, 573, 574, 574, 574, 574, 574, 574, 573, 573, 81, 81, 
+    575, 575, 576, 576, 577, 577, 574, 563, 578, 579, 578, 579, 578, 579, 
+    578, 579, 578, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 
+    579, 579, 579, 579, 579, 579, 578, 579, 579, 579, 579, 579, 579, 579, 
+    578, 579, 578, 579, 578, 579, 579, 579, 579, 579, 579, 578, 579, 579, 
+    579, 579, 579, 579, 578, 578, 579, 579, 579, 579, 580, 581, 582, 582, 
+    579, 81, 81, 81, 81, 81, 583, 583, 583, 583, 583, 583, 583, 583, 583, 
+    583, 583, 81, 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, 
+    584, 584, 584, 584, 584, 584, 584, 584, 584, 584, 81, 585, 585, 586, 586, 
+    586, 586, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 583, 583, 
+    583, 81, 81, 81, 81, 81, 578, 578, 578, 578, 578, 578, 578, 578, 587, 
+    587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 588, 588, 81, 
+    586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 585, 585, 585, 585, 
+    585, 585, 589, 589, 589, 589, 589, 589, 589, 589, 525, 590, 590, 590, 
+    590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 587, 587, 
+    587, 587, 588, 588, 588, 585, 585, 590, 590, 590, 590, 590, 590, 590, 
+    585, 585, 585, 585, 525, 525, 525, 525, 591, 591, 591, 591, 591, 591, 
+    591, 591, 591, 591, 591, 591, 591, 591, 591, 81, 585, 585, 585, 585, 585, 
+    585, 585, 525, 525, 525, 525, 585, 585, 585, 585, 585, 585, 585, 585, 
+    585, 585, 585, 525, 525, 592, 592, 592, 592, 592, 592, 592, 592, 592, 
+    592, 592, 592, 592, 592, 593, 593, 593, 593, 593, 593, 593, 593, 593, 
+    593, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 
+    595, 594, 594, 594, 594, 594, 594, 594, 81, 81, 81, 596, 596, 596, 596, 
+    596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 81, 597, 597, 597, 
+    597, 597, 597, 597, 597, 598, 598, 598, 598, 598, 598, 599, 599, 600, 
+    600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 601, 602, 603, 
+    602, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 600, 600, 81, 81, 
+    81, 81, 90, 93, 90, 93, 90, 93, 605, 95, 97, 97, 97, 606, 95, 95, 95, 95, 
+    95, 95, 95, 95, 95, 95, 606, 607, 90, 93, 90, 93, 454, 454, 95, 95, 608, 
+    608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, 609, 
+    609, 609, 609, 609, 609, 609, 609, 609, 609, 610, 610, 611, 612, 612, 
+    612, 612, 612, 62, 62, 62, 62, 62, 62, 62, 60, 60, 60, 60, 60, 60, 60, 
+    60, 60, 62, 62, 52, 56, 52, 56, 52, 56, 56, 56, 52, 56, 52, 56, 52, 56, 
+    59, 56, 56, 56, 56, 56, 56, 56, 56, 52, 56, 52, 56, 52, 52, 56, 60, 613, 
+    613, 52, 56, 52, 56, 57, 52, 56, 52, 56, 56, 56, 52, 56, 52, 56, 52, 52, 
+    52, 52, 52, 56, 52, 52, 52, 52, 52, 56, 52, 56, 52, 56, 81, 81, 81, 81, 
+    81, 81, 81, 81, 81, 81, 81, 81, 81, 57, 59, 59, 56, 57, 57, 57, 57, 57, 
+    614, 614, 615, 614, 614, 614, 616, 614, 614, 614, 614, 615, 614, 614, 
+    614, 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, 617, 
+    617, 615, 615, 617, 618, 618, 618, 618, 81, 81, 81, 81, 619, 619, 619, 
+    619, 619, 619, 317, 317, 507, 516, 81, 81, 81, 81, 81, 81, 620, 620, 620, 
+    620, 620, 620, 620, 620, 620, 620, 620, 620, 621, 621, 622, 622, 623, 
+    623, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 
+    624, 624, 624, 624, 624, 623, 623, 623, 623, 623, 623, 623, 623, 623, 
+    623, 623, 623, 623, 623, 623, 623, 625, 626, 81, 81, 81, 81, 81, 81, 81, 
+    81, 627, 627, 628, 628, 628, 628, 628, 628, 628, 628, 628, 628, 81, 81, 
+    81, 81, 81, 81, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 195, 
+    195, 195, 195, 195, 195, 201, 201, 201, 195, 629, 195, 195, 193, 630, 
+    630, 630, 630, 630, 630, 630, 630, 630, 630, 631, 631, 631, 631, 631, 
+    631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 
+    631, 632, 632, 632, 632, 632, 633, 633, 633, 199, 634, 635, 635, 635, 
+    635, 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, 636, 636, 
+    636, 636, 636, 636, 636, 636, 636, 636, 636, 637, 638, 81, 81, 81, 81, 
+    81, 81, 81, 81, 81, 81, 81, 639, 332, 332, 332, 332, 332, 81, 81, 81, 
+    640, 640, 640, 641, 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, 
+    642, 642, 642, 642, 642, 643, 641, 641, 640, 640, 640, 640, 641, 641, 
+    640, 641, 641, 641, 644, 645, 645, 645, 645, 645, 645, 646, 646, 646, 
+    645, 645, 645, 645, 81, 61, 647, 647, 647, 647, 647, 647, 647, 647, 647, 
+    647, 81, 81, 81, 81, 645, 645, 318, 318, 318, 318, 318, 320, 648, 318, 
+    323, 323, 318, 318, 318, 318, 318, 81, 649, 649, 649, 649, 649, 649, 649, 
+    649, 649, 650, 650, 650, 650, 650, 650, 651, 651, 650, 650, 651, 651, 
+    650, 650, 81, 649, 649, 649, 650, 649, 649, 649, 649, 649, 649, 649, 649, 
+    650, 651, 81, 81, 652, 652, 652, 652, 652, 652, 652, 652, 652, 652, 81, 
+    81, 653, 654, 654, 654, 648, 318, 318, 318, 318, 318, 318, 327, 327, 327, 
+    318, 319, 320, 319, 318, 318, 655, 655, 655, 655, 655, 655, 655, 655, 
+    656, 655, 656, 656, 657, 655, 655, 656, 656, 655, 655, 655, 655, 655, 
+    656, 656, 655, 656, 655, 81, 81, 81, 81, 81, 81, 81, 81, 655, 655, 658, 
+    659, 659, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 661, 
+    662, 662, 661, 661, 663, 663, 660, 664, 664, 661, 665, 81, 81, 335, 335, 
+    335, 335, 335, 335, 81, 56, 56, 56, 613, 59, 59, 59, 59, 56, 56, 56, 56, 
+    56, 79, 81, 81, 342, 342, 342, 342, 342, 342, 342, 342, 660, 660, 660, 
+    661, 661, 662, 661, 661, 662, 661, 661, 663, 661, 665, 81, 81, 666, 666, 
+    666, 666, 666, 666, 666, 666, 666, 666, 81, 81, 81, 81, 81, 81, 667, 668, 
+    668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, 
+    668, 668, 668, 668, 667, 668, 668, 668, 668, 668, 668, 668, 81, 81, 81, 
+    81, 333, 333, 333, 333, 333, 333, 333, 81, 81, 81, 81, 334, 334, 334, 
+    334, 334, 334, 334, 334, 334, 81, 81, 81, 81, 669, 669, 669, 669, 669, 
+    669, 669, 669, 670, 670, 670, 670, 670, 670, 670, 670, 592, 592, 593, 
+    593, 593, 593, 593, 593, 56, 56, 56, 56, 56, 56, 56, 81, 81, 81, 81, 101, 
+    101, 101, 101, 101, 81, 81, 81, 81, 81, 129, 671, 129, 129, 672, 129, 
+    129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 81, 129, 129, 
+    129, 129, 129, 81, 129, 81, 129, 129, 81, 129, 129, 81, 129, 129, 146, 
+    146, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, 
+    673, 673, 673, 81, 81, 81, 81, 81, 81, 81, 81, 81, 146, 146, 146, 146, 
+    146, 146, 146, 146, 146, 146, 146, 495, 477, 81, 81, 146, 146, 146, 146, 
+    146, 146, 146, 146, 146, 146, 135, 138, 81, 81, 674, 674, 674, 674, 674, 
+    674, 674, 674, 675, 558, 558, 675, 675, 676, 676, 526, 527, 677, 81, 81, 
+    81, 81, 81, 81, 96, 96, 96, 96, 96, 96, 96, 156, 156, 156, 156, 156, 156, 
+    156, 95, 95, 559, 569, 569, 678, 678, 526, 527, 526, 527, 526, 527, 526, 
+    527, 526, 527, 526, 527, 526, 527, 526, 527, 559, 559, 526, 527, 559, 
+    559, 559, 559, 678, 678, 678, 679, 559, 679, 81, 580, 680, 676, 676, 569, 
+    526, 527, 526, 527, 526, 527, 681, 559, 559, 682, 683, 684, 684, 684, 81, 
+    559, 685, 686, 559, 81, 81, 81, 81, 146, 146, 146, 146, 146, 81, 81, 497, 
+    81, 687, 688, 689, 690, 691, 688, 688, 692, 693, 688, 694, 695, 696, 695, 
+    697, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 699, 700, 701, 
+    701, 701, 687, 688, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 
+    702, 702, 702, 702, 702, 702, 702, 702, 692, 688, 693, 703, 704, 703, 
+    705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 
+    705, 705, 705, 705, 692, 701, 693, 701, 692, 693, 706, 707, 708, 706, 
+    709, 710, 711, 711, 711, 711, 711, 711, 711, 711, 711, 712, 710, 710, 
+    710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 
+    710, 710, 710, 710, 710, 713, 713, 714, 714, 714, 714, 714, 714, 714, 
+    714, 714, 714, 714, 714, 714, 714, 714, 81, 81, 81, 714, 714, 714, 714, 
+    714, 714, 81, 81, 714, 714, 714, 81, 81, 81, 715, 690, 701, 703, 716, 
+    690, 690, 81, 717, 718, 718, 718, 718, 717, 717, 81, 81, 719, 719, 719, 
+    720, 512, 81, 81, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 
+    721, 81, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 81, 721, 721, 
+    721, 81, 721, 721, 81, 721, 721, 721, 721, 721, 721, 721, 81, 81, 721, 
+    721, 721, 81, 81, 81, 81, 81, 199, 377, 199, 81, 81, 81, 81, 619, 619, 
+    619, 619, 619, 619, 619, 619, 619, 619, 619, 619, 619, 81, 81, 81, 317, 
+    722, 722, 722, 722, 722, 722, 722, 722, 722, 722, 722, 722, 722, 723, 
+    723, 723, 723, 724, 724, 724, 724, 724, 724, 724, 724, 724, 724, 724, 
+    724, 724, 724, 724, 724, 724, 723, 723, 724, 725, 725, 81, 40, 40, 40, 
+    40, 81, 81, 81, 81, 724, 81, 81, 81, 81, 81, 81, 81, 317, 317, 317, 317, 
+    317, 156, 81, 81, 726, 726, 726, 726, 726, 726, 726, 726, 726, 726, 726, 
+    726, 726, 81, 81, 81, 727, 727, 727, 727, 727, 727, 727, 727, 727, 81, 
+    81, 81, 81, 81, 81, 81, 156, 504, 504, 504, 504, 504, 504, 504, 504, 504, 
+    504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 81, 81, 81, 81, 728, 
+    728, 728, 728, 728, 728, 728, 728, 729, 729, 729, 729, 81, 81, 81, 81, 
+    81, 81, 81, 81, 81, 728, 728, 728, 730, 730, 730, 730, 730, 730, 730, 
+    730, 730, 731, 730, 730, 730, 730, 730, 730, 730, 730, 731, 81, 81, 81, 
+    81, 81, 732, 732, 732, 732, 732, 732, 732, 732, 732, 732, 732, 732, 732, 
+    732, 733, 733, 733, 733, 733, 81, 81, 81, 81, 81, 734, 734, 734, 734, 
+    734, 734, 734, 734, 734, 734, 734, 734, 734, 734, 81, 735, 736, 736, 736, 
+    736, 736, 736, 736, 736, 736, 736, 736, 736, 81, 81, 81, 81, 737, 738, 
+    738, 738, 738, 738, 81, 81, 739, 739, 739, 739, 739, 739, 739, 739, 740, 
+    740, 740, 740, 740, 740, 740, 740, 741, 741, 741, 741, 741, 741, 741, 
+    741, 742, 742, 742, 742, 742, 742, 742, 742, 742, 742, 742, 742, 742, 
+    742, 81, 81, 743, 743, 743, 743, 743, 743, 743, 743, 743, 743, 81, 81, 
+    81, 81, 81, 81, 744, 744, 744, 744, 744, 744, 744, 744, 744, 744, 744, 
+    744, 81, 81, 81, 81, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 
+    745, 745, 81, 81, 81, 81, 746, 746, 746, 746, 746, 746, 746, 746, 747, 
+    747, 747, 747, 747, 747, 747, 747, 747, 747, 747, 747, 81, 81, 81, 81, 
+    81, 81, 81, 81, 81, 81, 81, 748, 749, 749, 749, 749, 749, 749, 749, 749, 
+    749, 749, 749, 749, 749, 749, 749, 81, 749, 749, 749, 749, 749, 749, 81, 
+    81, 750, 750, 750, 750, 750, 750, 81, 81, 750, 81, 750, 750, 750, 750, 
+    750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 
+    750, 750, 81, 750, 750, 81, 81, 81, 750, 81, 81, 750, 751, 751, 751, 751, 
+    751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 81, 752, 753, 753, 753, 
+    753, 753, 753, 753, 753, 754, 754, 754, 754, 754, 754, 754, 754, 754, 
+    754, 754, 754, 754, 754, 754, 755, 755, 756, 756, 756, 756, 756, 756, 
+    756, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 
+    757, 757, 81, 81, 81, 81, 81, 81, 81, 81, 758, 758, 758, 758, 758, 758, 
+    758, 758, 758, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 81, 
+    759, 759, 81, 81, 81, 81, 81, 760, 760, 760, 760, 760, 761, 761, 761, 
+    761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 762, 762, 762, 
+    762, 762, 762, 81, 81, 81, 763, 764, 764, 764, 764, 764, 764, 764, 764, 
+    764, 764, 81, 81, 81, 81, 81, 765, 766, 766, 766, 766, 766, 766, 766, 
+    766, 767, 767, 767, 767, 767, 767, 767, 767, 81, 81, 81, 81, 768, 768, 
+    767, 767, 768, 768, 768, 768, 768, 768, 768, 768, 81, 81, 768, 768, 768, 
+    768, 768, 768, 769, 770, 770, 770, 81, 770, 770, 81, 81, 81, 81, 81, 770, 
+    771, 770, 772, 769, 769, 769, 769, 81, 769, 769, 769, 81, 769, 769, 769, 
+    769, 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, 
+    769, 769, 769, 769, 81, 81, 772, 773, 771, 81, 81, 81, 81, 774, 775, 775, 
+    775, 775, 775, 775, 775, 775, 775, 81, 81, 81, 81, 81, 81, 81, 776, 776, 
+    776, 776, 776, 776, 776, 776, 777, 81, 81, 81, 81, 81, 81, 81, 778, 778, 
+    778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 779, 779, 780, 
+    781, 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, 782, 
+    782, 782, 783, 783, 783, 783, 783, 783, 783, 783, 784, 783, 783, 783, 
+    783, 783, 783, 783, 783, 783, 783, 783, 783, 785, 786, 81, 81, 81, 81, 
+    787, 787, 787, 787, 787, 788, 788, 788, 788, 788, 788, 789, 81, 790, 790, 
+    790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 81, 81, 81, 
+    791, 791, 791, 791, 791, 791, 791, 792, 792, 792, 792, 792, 792, 792, 
+    792, 792, 792, 792, 792, 792, 792, 81, 81, 793, 793, 793, 793, 793, 793, 
+    793, 793, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, 81, 81, 
+    81, 81, 81, 795, 795, 795, 795, 795, 795, 795, 795, 796, 796, 796, 796, 
     796, 796, 796, 796, 796, 796, 81, 81, 81, 81, 81, 81, 81, 797, 797, 797, 
-    797, 797, 797, 797, 797, 797, 797, 797, 81, 81, 81, 81, 81, 798, 798, 
-    798, 798, 798, 798, 798, 798, 798, 798, 798, 81, 81, 81, 81, 81, 81, 81, 
-    799, 799, 799, 799, 799, 799, 800, 800, 800, 800, 800, 800, 800, 800, 
-    800, 800, 800, 800, 800, 800, 800, 81, 801, 802, 801, 803, 803, 803, 803, 
-    803, 803, 803, 803, 803, 803, 803, 803, 803, 802, 802, 802, 802, 802, 
-    802, 802, 802, 802, 802, 802, 802, 802, 802, 804, 805, 805, 806, 806, 
-    806, 806, 806, 81, 81, 81, 81, 807, 807, 807, 807, 807, 807, 807, 807, 
-    807, 807, 807, 807, 807, 807, 807, 807, 807, 807, 807, 807, 808, 808, 
-    808, 808, 808, 808, 808, 808, 808, 808, 81, 81, 81, 81, 81, 81, 81, 804, 
-    809, 809, 810, 811, 811, 811, 811, 811, 811, 811, 811, 811, 811, 811, 
-    811, 811, 810, 810, 810, 809, 809, 809, 809, 810, 810, 812, 813, 814, 
-    814, 815, 816, 816, 816, 816, 81, 81, 81, 81, 81, 81, 817, 817, 817, 817, 
-    817, 817, 817, 817, 817, 81, 81, 81, 81, 81, 81, 81, 818, 818, 818, 818, 
-    818, 818, 818, 818, 818, 818, 81, 81, 81, 81, 81, 81, 819, 819, 819, 820, 
+    797, 81, 81, 81, 81, 798, 798, 798, 798, 798, 798, 798, 799, 799, 799, 
+    799, 799, 799, 799, 799, 799, 81, 81, 81, 81, 81, 81, 81, 800, 800, 800, 
+    800, 800, 800, 800, 800, 800, 800, 800, 81, 81, 81, 81, 81, 801, 801, 
+    801, 801, 801, 801, 801, 801, 801, 801, 801, 81, 81, 81, 81, 81, 81, 81, 
+    802, 802, 802, 802, 802, 802, 803, 803, 803, 803, 803, 803, 803, 803, 
+    803, 803, 803, 803, 804, 804, 804, 804, 805, 805, 805, 805, 805, 805, 
+    805, 805, 805, 805, 81, 81, 81, 81, 81, 81, 806, 806, 806, 806, 806, 806, 
+    806, 806, 806, 806, 806, 806, 806, 806, 806, 81, 807, 807, 807, 807, 807, 
+    807, 807, 807, 807, 807, 807, 807, 807, 808, 808, 808, 808, 808, 808, 
+    808, 808, 808, 808, 807, 809, 809, 809, 809, 809, 809, 809, 809, 809, 
+    809, 809, 809, 809, 809, 810, 810, 811, 811, 811, 810, 811, 810, 810, 
+    810, 810, 812, 812, 812, 812, 813, 813, 813, 813, 813, 81, 81, 81, 81, 
+    81, 81, 814, 815, 814, 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, 
+    816, 816, 816, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, 
+    815, 815, 815, 817, 818, 818, 819, 819, 819, 819, 819, 81, 81, 81, 81, 
     820, 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, 
-    820, 820, 820, 820, 820, 821, 821, 821, 821, 821, 822, 821, 821, 821, 
-    821, 821, 821, 823, 823, 81, 824, 824, 824, 824, 824, 824, 824, 824, 824, 
-    824, 825, 825, 825, 825, 81, 81, 81, 81, 826, 826, 826, 826, 826, 826, 
-    826, 826, 826, 826, 826, 827, 828, 829, 826, 81, 830, 830, 831, 832, 832, 
-    832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 
-    831, 831, 831, 830, 830, 830, 830, 830, 830, 830, 830, 830, 831, 833, 
-    832, 832, 832, 832, 834, 834, 835, 834, 835, 836, 830, 830, 835, 81, 81, 
-    837, 837, 837, 837, 837, 837, 837, 837, 837, 837, 832, 838, 832, 834, 
-    834, 834, 81, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, 
-    839, 839, 839, 839, 839, 839, 839, 839, 81, 81, 81, 840, 840, 840, 840, 
-    840, 840, 840, 840, 840, 840, 81, 840, 840, 840, 840, 840, 840, 840, 840, 
-    840, 841, 841, 841, 842, 842, 842, 841, 841, 842, 843, 844, 842, 845, 
-    845, 846, 845, 845, 846, 842, 81, 847, 847, 847, 847, 847, 847, 847, 81, 
-    847, 81, 847, 847, 847, 847, 81, 847, 847, 847, 847, 847, 847, 847, 847, 
-    847, 847, 847, 847, 847, 847, 847, 81, 847, 847, 848, 81, 81, 81, 81, 81, 
-    81, 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, 
-    849, 850, 851, 851, 851, 850, 850, 850, 850, 850, 850, 852, 853, 81, 81, 
-    81, 81, 81, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 81, 81, 81, 
-    81, 81, 81, 855, 855, 856, 856, 81, 857, 857, 857, 857, 857, 857, 857, 
-    857, 81, 81, 857, 857, 81, 81, 857, 857, 857, 857, 857, 857, 857, 857, 
-    857, 857, 857, 857, 857, 857, 81, 857, 857, 857, 857, 857, 857, 857, 81, 
-    857, 857, 81, 857, 857, 857, 857, 857, 81, 81, 858, 857, 856, 856, 855, 
-    856, 856, 856, 856, 81, 81, 856, 856, 81, 81, 856, 856, 859, 81, 81, 857, 
-    81, 81, 81, 81, 81, 81, 856, 81, 81, 81, 81, 81, 857, 857, 857, 857, 857, 
-    856, 856, 81, 81, 860, 860, 860, 860, 860, 860, 860, 81, 81, 81, 861, 
-    861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 862, 862, 
-    862, 863, 863, 863, 863, 863, 863, 863, 863, 862, 862, 864, 863, 863, 
-    862, 865, 861, 861, 861, 861, 866, 866, 866, 866, 867, 868, 868, 868, 
-    868, 868, 868, 868, 868, 868, 868, 81, 866, 81, 867, 81, 81, 869, 869, 
-    869, 869, 869, 869, 869, 869, 870, 870, 870, 871, 871, 871, 871, 871, 
-    871, 870, 871, 870, 870, 870, 870, 871, 871, 870, 872, 873, 869, 869, 
-    874, 869, 875, 875, 875, 875, 875, 875, 875, 875, 875, 875, 81, 81, 81, 
-    81, 81, 81, 876, 876, 876, 876, 876, 876, 876, 876, 876, 876, 876, 876, 
-    876, 876, 876, 877, 877, 877, 878, 878, 878, 878, 81, 81, 877, 877, 877, 
-    877, 878, 878, 877, 879, 880, 881, 882, 882, 883, 883, 884, 884, 884, 
-    882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 
-    882, 876, 876, 876, 876, 878, 878, 81, 81, 885, 885, 885, 885, 885, 885, 
-    885, 885, 886, 886, 886, 887, 887, 887, 887, 887, 887, 887, 887, 886, 
-    886, 887, 886, 888, 887, 889, 889, 890, 885, 81, 81, 81, 891, 891, 891, 
-    891, 891, 891, 891, 891, 891, 891, 81, 81, 81, 81, 81, 81, 892, 892, 892, 
-    892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 81, 81, 81, 893, 893, 
-    893, 893, 893, 893, 893, 893, 893, 893, 893, 894, 895, 894, 895, 895, 
-    894, 894, 894, 894, 894, 894, 896, 897, 898, 898, 898, 898, 898, 898, 
-    898, 898, 898, 898, 81, 81, 81, 81, 81, 81, 899, 899, 899, 899, 899, 899, 
-    899, 899, 899, 899, 81, 81, 81, 900, 900, 900, 901, 901, 900, 900, 900, 
-    900, 901, 900, 900, 900, 900, 902, 81, 81, 81, 81, 903, 903, 903, 903, 
-    903, 903, 903, 903, 903, 903, 904, 904, 905, 905, 905, 906, 907, 907, 
-    907, 907, 907, 907, 907, 907, 908, 908, 908, 908, 908, 908, 908, 908, 
-    909, 909, 909, 909, 909, 909, 909, 909, 909, 909, 910, 910, 910, 910, 
-    910, 910, 910, 910, 910, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 
-    911, 912, 913, 913, 913, 913, 913, 913, 914, 914, 913, 913, 912, 912, 
-    912, 912, 912, 912, 912, 912, 912, 912, 912, 912, 912, 912, 912, 912, 
-    913, 915, 913, 913, 913, 913, 914, 912, 913, 913, 913, 913, 916, 917, 
-    918, 918, 918, 918, 916, 917, 915, 919, 920, 920, 920, 920, 920, 920, 
-    921, 921, 920, 920, 920, 919, 919, 919, 919, 919, 919, 919, 919, 919, 
-    919, 919, 919, 919, 919, 919, 919, 81, 81, 919, 919, 919, 919, 920, 920, 
-    920, 920, 920, 920, 920, 920, 920, 920, 920, 920, 920, 921, 920, 922, 
-    923, 923, 923, 81, 924, 924, 924, 923, 923, 81, 81, 81, 81, 81, 925, 925, 
-    925, 925, 925, 925, 925, 925, 925, 81, 81, 81, 81, 81, 81, 81, 926, 926, 
-    926, 926, 926, 926, 926, 926, 926, 81, 926, 926, 926, 926, 926, 926, 926, 
-    926, 926, 926, 926, 926, 926, 927, 928, 928, 928, 928, 928, 928, 928, 81, 
-    928, 928, 928, 928, 928, 928, 927, 929, 926, 930, 930, 930, 930, 930, 81, 
-    81, 931, 931, 931, 931, 931, 931, 931, 931, 931, 931, 932, 932, 932, 932, 
-    932, 932, 932, 932, 932, 932, 932, 932, 932, 932, 932, 932, 932, 932, 
-    932, 81, 81, 81, 933, 934, 935, 935, 935, 935, 935, 935, 935, 935, 935, 
-    935, 935, 935, 935, 935, 81, 81, 936, 936, 936, 936, 936, 936, 936, 936, 
-    936, 936, 936, 936, 936, 936, 81, 937, 936, 936, 936, 936, 936, 936, 936, 
-    937, 936, 936, 937, 936, 936, 81, 938, 938, 938, 938, 938, 938, 938, 81, 
-    938, 938, 81, 938, 938, 938, 938, 938, 938, 938, 938, 938, 938, 938, 938, 
-    938, 938, 939, 939, 939, 939, 939, 939, 81, 81, 81, 939, 81, 939, 939, 
-    81, 939, 939, 939, 940, 939, 941, 941, 938, 939, 942, 942, 942, 942, 942, 
-    942, 942, 942, 942, 942, 81, 81, 81, 81, 81, 81, 943, 943, 943, 943, 943, 
-    943, 943, 943, 943, 943, 81, 81, 81, 81, 81, 81, 944, 944, 944, 944, 944, 
-    944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 81, 945, 945, 945, 945, 
-    945, 81, 81, 81, 943, 943, 943, 943, 81, 81, 81, 81, 946, 946, 946, 946, 
-    946, 946, 946, 946, 947, 947, 947, 948, 948, 948, 946, 946, 946, 946, 
-    948, 946, 946, 946, 947, 948, 947, 948, 946, 946, 946, 946, 946, 946, 
-    946, 947, 948, 948, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, 
-    946, 81, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 
-    949, 950, 951, 949, 949, 949, 949, 949, 949, 949, 81, 605, 81, 81, 81, 
-    81, 81, 81, 81, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 
-    952, 952, 952, 952, 81, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 
-    81, 81, 81, 81, 954, 954, 955, 955, 955, 955, 955, 955, 955, 955, 955, 
-    955, 955, 955, 955, 955, 81, 81, 956, 956, 956, 956, 956, 957, 81, 81, 
-    958, 958, 958, 958, 958, 958, 958, 958, 959, 959, 959, 959, 959, 959, 
-    959, 960, 960, 960, 961, 961, 962, 962, 962, 962, 963, 963, 963, 963, 
-    960, 962, 81, 81, 964, 964, 964, 964, 964, 964, 964, 964, 964, 964, 81, 
-    965, 965, 965, 965, 965, 965, 965, 81, 958, 958, 958, 958, 958, 81, 81, 
-    81, 81, 81, 958, 958, 958, 966, 966, 966, 966, 966, 966, 966, 966, 966, 
-    966, 966, 966, 966, 81, 81, 81, 966, 967, 967, 967, 967, 967, 967, 967, 
-    967, 967, 967, 967, 967, 967, 967, 967, 967, 967, 967, 967, 967, 967, 
-    967, 81, 81, 81, 81, 81, 81, 81, 81, 968, 968, 968, 968, 969, 969, 969, 
-    969, 969, 969, 969, 969, 969, 969, 969, 969, 969, 970, 971, 81, 81, 81, 
-    81, 81, 81, 972, 972, 972, 972, 972, 972, 972, 972, 972, 972, 972, 972, 
-    972, 81, 81, 81, 972, 972, 972, 81, 81, 81, 81, 81, 576, 571, 571, 571, 
-    571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 81, 973, 973, 973, 
-    973, 973, 973, 973, 973, 973, 973, 973, 973, 81, 81, 81, 81, 974, 974, 
-    974, 974, 974, 974, 974, 974, 974, 974, 974, 81, 81, 81, 81, 81, 974, 
-    974, 974, 974, 974, 81, 81, 81, 974, 81, 81, 81, 81, 81, 81, 81, 974, 
-    974, 81, 81, 975, 976, 977, 978, 499, 499, 499, 499, 81, 81, 81, 81, 313, 
-    313, 313, 313, 313, 313, 81, 81, 313, 313, 313, 313, 313, 313, 313, 81, 
-    81, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 979, 979, 
-    447, 447, 447, 313, 313, 313, 980, 979, 979, 979, 979, 979, 499, 499, 
-    499, 499, 499, 499, 499, 499, 156, 156, 156, 156, 156, 156, 156, 156, 
-    313, 313, 96, 96, 96, 96, 96, 156, 156, 313, 313, 313, 313, 313, 313, 96, 
-    96, 96, 96, 313, 313, 313, 81, 81, 81, 81, 81, 81, 81, 721, 721, 981, 
-    981, 981, 721, 81, 81, 616, 616, 81, 81, 81, 81, 81, 81, 506, 506, 506, 
-    506, 506, 506, 506, 506, 506, 506, 49, 49, 49, 49, 49, 49, 49, 49, 49, 
-    49, 49, 49, 49, 49, 49, 49, 49, 49, 506, 506, 506, 506, 506, 506, 506, 
-    506, 506, 506, 49, 49, 49, 49, 49, 49, 49, 81, 49, 49, 49, 49, 49, 49, 
-    506, 81, 506, 506, 81, 81, 506, 81, 81, 506, 506, 81, 81, 506, 506, 506, 
-    506, 81, 506, 506, 49, 49, 81, 49, 81, 49, 49, 49, 49, 49, 49, 49, 81, 
-    49, 49, 49, 49, 49, 49, 49, 506, 506, 81, 506, 506, 506, 506, 81, 81, 
-    506, 506, 506, 506, 506, 506, 506, 506, 81, 506, 506, 506, 506, 506, 506, 
-    506, 81, 49, 49, 506, 506, 81, 506, 506, 506, 506, 81, 506, 506, 506, 
-    506, 506, 81, 506, 81, 81, 81, 506, 506, 506, 506, 506, 506, 506, 81, 49, 
-    49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 81, 81, 506, 982, 49, 49, 49, 
-    49, 49, 49, 49, 49, 49, 492, 49, 49, 49, 49, 49, 49, 506, 506, 506, 506, 
-    506, 506, 506, 506, 506, 982, 49, 49, 49, 49, 49, 49, 49, 49, 49, 492, 
-    49, 49, 506, 506, 506, 506, 506, 982, 49, 49, 49, 49, 49, 49, 49, 49, 49, 
-    492, 49, 49, 49, 49, 49, 49, 506, 506, 506, 506, 506, 506, 506, 506, 506, 
-    982, 49, 492, 49, 49, 49, 49, 49, 49, 49, 49, 506, 49, 81, 81, 983, 983, 
-    983, 983, 983, 983, 983, 983, 983, 983, 984, 984, 984, 984, 984, 984, 
-    984, 984, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 
-    985, 985, 985, 984, 984, 984, 984, 985, 985, 985, 985, 985, 985, 985, 
-    985, 985, 985, 984, 984, 984, 984, 984, 984, 984, 984, 985, 984, 984, 
-    984, 984, 984, 984, 985, 984, 984, 986, 986, 986, 986, 987, 81, 81, 81, 
-    81, 81, 81, 81, 985, 985, 985, 985, 985, 81, 985, 985, 985, 985, 985, 
-    985, 985, 988, 988, 988, 988, 988, 988, 988, 81, 988, 988, 988, 988, 988, 
-    988, 988, 988, 988, 81, 81, 988, 988, 988, 988, 988, 988, 988, 81, 988, 
-    988, 81, 988, 988, 988, 988, 988, 81, 81, 81, 81, 81, 989, 989, 989, 989, 
-    989, 989, 989, 989, 989, 989, 989, 989, 989, 81, 81, 990, 990, 990, 990, 
-    990, 990, 990, 990, 990, 991, 991, 991, 991, 991, 991, 991, 81, 992, 992, 
-    992, 992, 992, 992, 992, 992, 992, 992, 993, 993, 993, 993, 993, 993, 
-    993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 994, 994, 
-    994, 994, 994, 994, 995, 81, 81, 81, 81, 81, 996, 996, 996, 996, 996, 
-    996, 996, 996, 996, 996, 81, 81, 81, 81, 997, 997, 146, 146, 146, 146, 
+    820, 820, 820, 820, 820, 820, 821, 821, 821, 821, 821, 821, 821, 821, 
+    821, 821, 81, 81, 81, 81, 81, 81, 81, 817, 822, 822, 823, 824, 824, 824, 
+    824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 823, 823, 823, 822, 
+    822, 822, 822, 823, 823, 825, 826, 827, 827, 828, 829, 829, 829, 829, 81, 
+    81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 828, 81, 81, 830, 830, 830, 830, 
+    830, 830, 830, 830, 830, 81, 81, 81, 81, 81, 81, 81, 831, 831, 831, 831, 
+    831, 831, 831, 831, 831, 831, 81, 81, 81, 81, 81, 81, 832, 832, 832, 833, 
+    833, 833, 833, 833, 833, 833, 833, 833, 833, 833, 833, 833, 833, 833, 
+    833, 833, 833, 833, 833, 834, 834, 834, 834, 834, 835, 834, 834, 834, 
+    834, 834, 834, 836, 836, 81, 837, 837, 837, 837, 837, 837, 837, 837, 837, 
+    837, 838, 838, 838, 838, 833, 835, 835, 81, 839, 839, 839, 839, 839, 839, 
+    839, 839, 839, 839, 839, 840, 841, 842, 839, 81, 843, 843, 844, 845, 845, 
+    845, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, 
+    844, 844, 844, 843, 843, 843, 843, 843, 843, 843, 843, 843, 844, 846, 
+    845, 845, 845, 845, 847, 847, 848, 847, 843, 849, 843, 843, 848, 81, 81, 
+    850, 850, 850, 850, 850, 850, 850, 850, 850, 850, 845, 851, 845, 847, 
+    847, 847, 81, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 852, 
+    852, 852, 852, 852, 852, 852, 852, 852, 81, 81, 81, 853, 853, 853, 853, 
+    853, 853, 853, 853, 853, 853, 81, 853, 853, 853, 853, 853, 853, 853, 853, 
+    853, 854, 854, 854, 855, 855, 855, 854, 854, 855, 856, 857, 855, 858, 
+    858, 859, 858, 858, 859, 855, 81, 860, 860, 860, 860, 860, 860, 860, 81, 
+    860, 81, 860, 860, 860, 860, 81, 860, 860, 860, 860, 860, 860, 860, 860, 
+    860, 860, 860, 860, 860, 860, 860, 81, 860, 860, 861, 81, 81, 81, 81, 81, 
+    81, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 
+    862, 863, 864, 864, 864, 863, 863, 863, 863, 863, 863, 865, 866, 81, 81, 
+    81, 81, 81, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 81, 81, 81, 
+    81, 81, 81, 868, 868, 869, 869, 81, 870, 870, 870, 870, 870, 870, 870, 
+    870, 81, 81, 870, 870, 81, 81, 870, 870, 870, 870, 870, 870, 870, 870, 
+    870, 870, 870, 870, 870, 870, 81, 870, 870, 870, 870, 870, 870, 870, 81, 
+    870, 870, 81, 870, 870, 870, 870, 870, 81, 871, 872, 870, 869, 869, 868, 
+    869, 869, 869, 869, 81, 81, 869, 869, 81, 81, 869, 869, 873, 81, 81, 870, 
+    81, 81, 81, 81, 81, 81, 869, 81, 81, 81, 81, 81, 870, 870, 870, 870, 870, 
+    869, 869, 81, 81, 874, 874, 874, 874, 874, 874, 874, 81, 81, 81, 875, 
+    875, 875, 875, 875, 875, 875, 875, 875, 875, 875, 875, 875, 876, 876, 
+    876, 877, 877, 877, 877, 877, 877, 877, 877, 876, 876, 878, 877, 877, 
+    876, 879, 875, 875, 875, 875, 880, 880, 880, 880, 881, 882, 882, 882, 
+    882, 882, 882, 882, 882, 882, 882, 81, 880, 81, 881, 883, 81, 884, 884, 
+    884, 884, 884, 884, 884, 884, 885, 885, 885, 886, 886, 886, 886, 886, 
+    886, 885, 886, 885, 885, 885, 885, 886, 886, 885, 887, 888, 884, 884, 
+    889, 884, 890, 890, 890, 890, 890, 890, 890, 890, 890, 890, 81, 81, 81, 
+    81, 81, 81, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, 
+    891, 891, 891, 892, 892, 892, 893, 893, 893, 893, 81, 81, 892, 892, 892, 
+    892, 893, 893, 892, 894, 895, 896, 897, 897, 898, 898, 899, 899, 899, 
+    897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, 
+    897, 891, 891, 891, 891, 893, 893, 81, 81, 900, 900, 900, 900, 900, 900, 
+    900, 900, 901, 901, 901, 902, 902, 902, 902, 902, 902, 902, 902, 901, 
+    901, 902, 901, 903, 902, 904, 904, 905, 900, 81, 81, 81, 906, 906, 906, 
+    906, 906, 906, 906, 906, 906, 906, 81, 81, 81, 81, 81, 81, 907, 907, 907, 
+    907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 81, 81, 81, 908, 908, 
+    908, 908, 908, 908, 908, 908, 908, 908, 908, 909, 910, 909, 910, 910, 
+    909, 909, 909, 909, 909, 909, 911, 912, 913, 913, 913, 913, 913, 913, 
+    913, 913, 913, 913, 81, 81, 81, 81, 81, 81, 914, 914, 914, 914, 914, 914, 
+    914, 914, 914, 914, 914, 81, 81, 915, 915, 915, 916, 916, 915, 915, 915, 
+    915, 916, 915, 915, 915, 915, 917, 81, 81, 81, 81, 918, 918, 918, 918, 
+    918, 918, 918, 918, 918, 918, 919, 919, 920, 920, 920, 921, 922, 922, 
+    922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 923, 923, 923, 924, 
+    924, 924, 924, 924, 924, 924, 924, 924, 923, 925, 926, 927, 81, 81, 81, 
+    81, 928, 928, 928, 928, 928, 928, 928, 928, 929, 929, 929, 929, 929, 929, 
+    929, 929, 930, 930, 930, 930, 930, 930, 930, 930, 930, 930, 931, 931, 
+    931, 931, 931, 931, 931, 931, 931, 81, 81, 81, 81, 81, 81, 81, 81, 81, 
+    81, 81, 81, 932, 933, 934, 934, 934, 934, 934, 934, 935, 935, 934, 934, 
+    933, 933, 933, 933, 933, 933, 933, 933, 933, 933, 933, 933, 933, 933, 
+    933, 933, 934, 936, 934, 934, 934, 934, 937, 933, 934, 934, 934, 934, 
+    938, 939, 940, 940, 940, 940, 938, 939, 936, 941, 942, 942, 942, 942, 
+    942, 942, 943, 943, 942, 942, 942, 941, 941, 941, 941, 941, 941, 941, 
+    941, 941, 941, 941, 941, 941, 941, 941, 941, 81, 81, 941, 941, 941, 941, 
+    942, 942, 942, 942, 942, 942, 942, 942, 942, 942, 942, 942, 942, 943, 
+    942, 944, 945, 945, 945, 941, 946, 946, 946, 945, 945, 81, 81, 81, 81, 
+    81, 947, 947, 947, 947, 947, 947, 947, 947, 947, 81, 81, 81, 81, 81, 81, 
+    81, 948, 948, 948, 948, 948, 948, 948, 948, 948, 81, 948, 948, 948, 948, 
+    948, 948, 948, 948, 948, 948, 948, 948, 948, 949, 950, 950, 950, 950, 
+    950, 950, 950, 81, 950, 950, 950, 950, 950, 950, 949, 951, 948, 952, 952, 
+    952, 952, 952, 81, 81, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, 
+    954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 954, 
+    954, 954, 954, 954, 954, 81, 81, 81, 955, 956, 957, 957, 957, 957, 957, 
+    957, 957, 957, 957, 957, 957, 957, 957, 957, 81, 81, 958, 958, 958, 958, 
+    958, 958, 958, 958, 958, 958, 958, 958, 958, 958, 81, 959, 958, 958, 958, 
+    958, 958, 958, 958, 959, 958, 958, 959, 958, 958, 81, 960, 960, 960, 960, 
+    960, 960, 960, 81, 960, 960, 81, 960, 960, 960, 960, 960, 960, 960, 960, 
+    960, 960, 960, 960, 960, 960, 961, 961, 961, 961, 961, 961, 81, 81, 81, 
+    961, 81, 961, 961, 81, 961, 961, 961, 962, 961, 963, 963, 960, 961, 964, 
+    964, 964, 964, 964, 964, 964, 964, 964, 964, 81, 81, 81, 81, 81, 81, 965, 
+    965, 965, 965, 965, 965, 81, 965, 965, 81, 965, 965, 965, 965, 965, 965, 
+    965, 965, 965, 965, 965, 965, 965, 965, 965, 965, 966, 966, 966, 966, 
+    966, 81, 967, 967, 81, 966, 966, 967, 966, 968, 965, 81, 81, 81, 81, 81, 
+    81, 81, 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, 81, 81, 81, 81, 
+    81, 81, 970, 970, 970, 970, 970, 970, 970, 970, 970, 970, 970, 971, 971, 
+    972, 972, 973, 973, 81, 81, 81, 81, 81, 81, 81, 974, 974, 974, 974, 974, 
+    974, 974, 974, 974, 974, 81, 81, 81, 81, 81, 81, 975, 975, 975, 975, 975, 
+    975, 975, 975, 975, 975, 975, 975, 975, 975, 975, 81, 976, 976, 976, 976, 
+    976, 81, 81, 81, 974, 974, 974, 974, 81, 81, 81, 81, 977, 977, 977, 977, 
+    977, 977, 977, 977, 978, 978, 978, 979, 979, 979, 977, 977, 977, 977, 
+    979, 977, 977, 977, 978, 979, 978, 979, 977, 977, 977, 977, 977, 977, 
+    977, 978, 979, 979, 977, 977, 977, 977, 977, 977, 977, 977, 977, 977, 
+    977, 81, 980, 980, 980, 980, 980, 980, 980, 980, 980, 980, 980, 980, 980, 
+    980, 981, 982, 980, 980, 980, 980, 980, 980, 980, 81, 608, 81, 81, 81, 
+    81, 81, 81, 81, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 
+    983, 983, 983, 983, 81, 984, 984, 984, 984, 984, 984, 984, 984, 984, 984, 
+    81, 81, 81, 81, 985, 985, 986, 986, 986, 986, 986, 986, 986, 986, 986, 
+    986, 986, 986, 986, 986, 81, 81, 987, 987, 987, 987, 987, 988, 81, 81, 
+    989, 989, 989, 989, 989, 989, 989, 989, 990, 990, 990, 990, 990, 990, 
+    990, 991, 991, 991, 992, 992, 993, 993, 993, 993, 994, 994, 994, 994, 
+    991, 993, 81, 81, 995, 995, 995, 995, 995, 995, 995, 995, 995, 995, 81, 
+    996, 996, 996, 996, 996, 996, 996, 81, 989, 989, 989, 989, 989, 81, 81, 
+    81, 81, 81, 989, 989, 989, 997, 997, 997, 997, 997, 997, 997, 997, 998, 
+    998, 998, 998, 998, 998, 998, 998, 999, 999, 999, 999, 999, 999, 999, 
+    999, 999, 999, 999, 999, 999, 999, 999, 1000, 1000, 1001, 1001, 81, 81, 
+    81, 81, 81, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 
+    1002, 1002, 1002, 81, 81, 81, 1002, 1003, 1003, 1003, 1003, 1003, 1003, 
+    1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 
+    1003, 1003, 1003, 1003, 81, 81, 81, 81, 81, 81, 81, 81, 1004, 1004, 1004, 
+    1004, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 
+    1005, 1005, 1006, 1007, 81, 81, 81, 81, 81, 81, 1008, 1008, 1008, 1008, 
+    1008, 1008, 1008, 1008, 1008, 1008, 81, 81, 81, 81, 81, 81, 1008, 1008, 
+    1008, 81, 81, 81, 81, 81, 579, 574, 574, 574, 574, 574, 574, 574, 574, 
+    574, 574, 574, 574, 574, 574, 81, 1009, 1009, 1009, 1009, 1009, 1009, 
+    1009, 1009, 1009, 1009, 1009, 1009, 81, 81, 81, 81, 1010, 1010, 1010, 
+    1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 81, 81, 81, 81, 81, 1010, 
+    1010, 1010, 1010, 1010, 81, 81, 81, 1010, 81, 81, 81, 81, 81, 81, 81, 
+    1010, 1010, 81, 81, 1011, 1012, 1013, 1014, 503, 503, 503, 503, 81, 81, 
+    81, 81, 317, 317, 317, 317, 317, 317, 81, 81, 317, 317, 317, 317, 317, 
+    317, 317, 81, 81, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 
+    317, 1015, 1015, 451, 451, 451, 317, 317, 317, 1016, 1015, 1015, 1015, 
+    1015, 1015, 503, 503, 503, 503, 503, 503, 503, 503, 156, 156, 156, 156, 
+    156, 156, 156, 156, 317, 317, 96, 96, 96, 96, 96, 156, 156, 317, 317, 
+    317, 317, 317, 317, 96, 96, 96, 96, 317, 317, 317, 81, 81, 81, 81, 81, 
+    81, 81, 724, 724, 1017, 1017, 1017, 724, 81, 81, 619, 619, 619, 619, 81, 
+    81, 81, 81, 619, 81, 81, 81, 81, 81, 81, 81, 510, 510, 510, 510, 510, 
+    510, 510, 510, 510, 510, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 
+    49, 49, 49, 49, 49, 49, 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, 
+    49, 49, 49, 49, 49, 49, 49, 81, 49, 49, 49, 49, 49, 49, 510, 81, 510, 
+    510, 81, 81, 510, 81, 81, 510, 510, 81, 81, 510, 510, 510, 510, 81, 510, 
+    510, 49, 49, 81, 49, 81, 49, 49, 49, 49, 49, 49, 49, 81, 49, 49, 49, 49, 
+    49, 49, 49, 510, 510, 81, 510, 510, 510, 510, 81, 81, 510, 510, 510, 510, 
+    510, 510, 510, 510, 81, 510, 510, 510, 510, 510, 510, 510, 81, 49, 49, 
+    510, 510, 81, 510, 510, 510, 510, 81, 510, 510, 510, 510, 510, 81, 510, 
+    81, 81, 81, 510, 510, 510, 510, 510, 510, 510, 81, 49, 49, 49, 49, 49, 
+    49, 49, 49, 49, 49, 49, 49, 81, 81, 510, 1018, 49, 49, 49, 49, 49, 49, 
+    49, 49, 49, 496, 49, 49, 49, 49, 49, 49, 510, 510, 510, 510, 510, 510, 
+    510, 510, 510, 1018, 49, 49, 49, 49, 49, 49, 49, 49, 49, 496, 49, 49, 
+    510, 510, 510, 510, 510, 1018, 49, 49, 49, 49, 49, 49, 49, 49, 49, 496, 
+    49, 49, 49, 49, 49, 49, 510, 510, 510, 510, 510, 510, 510, 510, 510, 
+    1018, 49, 496, 49, 49, 49, 49, 49, 49, 49, 49, 510, 49, 81, 81, 1019, 
+    1019, 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1020, 1020, 1020, 
+    1020, 1020, 1020, 1020, 1020, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 
+    1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1020, 1020, 1020, 1020, 
+    1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1020, 1020, 
+    1020, 1020, 1020, 1020, 1020, 1020, 1021, 1020, 1020, 1020, 1020, 1020, 
+    1020, 1021, 1020, 1020, 1022, 1022, 1022, 1022, 1023, 81, 81, 81, 81, 81, 
+    81, 81, 1021, 1021, 1021, 1021, 1021, 81, 1021, 1021, 1021, 1021, 1021, 
+    1021, 1021, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 81, 1024, 1024, 
+    1024, 1024, 1024, 1024, 1024, 1024, 1024, 81, 81, 1024, 1024, 1024, 1024, 
+    1024, 1024, 1024, 81, 1024, 1024, 81, 1024, 1024, 1024, 1024, 1024, 81, 
+    81, 81, 81, 81, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 
+    1025, 1025, 1025, 1025, 81, 81, 1026, 1026, 1026, 1026, 1026, 1026, 1026, 
+    1026, 1026, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 81, 1028, 1028, 
+    1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1029, 
+    1029, 1029, 1029, 1029, 1029, 1029, 1029, 1029, 1029, 1029, 1029, 1029, 
+    1029, 1029, 1030, 1030, 1030, 1030, 1030, 1030, 1031, 81, 81, 81, 81, 81, 
+    1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, 81, 81, 81, 
+    81, 1033, 1033, 81, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 
+    1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1035, 1034, 
+    1034, 1034, 1036, 1034, 1034, 1034, 1034, 81, 81, 81, 146, 146, 146, 146, 
     81, 146, 146, 146, 81, 146, 146, 81, 146, 81, 81, 146, 81, 146, 146, 146, 
     146, 146, 146, 146, 146, 146, 146, 81, 146, 146, 146, 146, 81, 146, 81, 
     146, 81, 81, 81, 81, 81, 81, 146, 81, 81, 81, 81, 146, 81, 146, 81, 146, 
     81, 146, 146, 146, 81, 146, 81, 146, 81, 146, 81, 146, 81, 146, 146, 146, 
     146, 81, 146, 81, 146, 146, 81, 146, 146, 146, 146, 146, 146, 146, 146, 
     146, 81, 81, 81, 81, 81, 146, 146, 146, 81, 146, 146, 146, 132, 132, 81, 
-    81, 81, 81, 81, 81, 525, 525, 525, 525, 521, 525, 525, 525, 525, 525, 
-    525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 998, 998, 998, 998, 
-    998, 998, 998, 998, 998, 998, 998, 998, 525, 525, 525, 525, 525, 525, 
-    525, 998, 998, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 
-    525, 525, 525, 521, 525, 525, 525, 525, 525, 525, 998, 998, 47, 47, 47, 
-    515, 515, 998, 998, 998, 526, 526, 526, 526, 526, 526, 313, 998, 526, 
-    526, 40, 40, 998, 998, 998, 998, 526, 526, 526, 526, 526, 526, 999, 526, 
-    526, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 526, 526, 526, 
-    526, 526, 526, 526, 526, 526, 526, 998, 998, 998, 998, 998, 998, 998, 
-    998, 998, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 
-    1001, 582, 582, 998, 998, 998, 998, 998, 582, 582, 582, 582, 998, 998, 
-    998, 998, 582, 998, 998, 998, 998, 998, 998, 998, 582, 582, 998, 998, 
-    998, 998, 998, 998, 521, 521, 521, 521, 521, 521, 998, 998, 521, 525, 
-    525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 521, 521, 521, 
-    521, 521, 521, 521, 521, 521, 525, 521, 521, 521, 521, 521, 521, 525, 
-    521, 521, 521, 521, 521, 521, 521, 532, 521, 521, 521, 521, 521, 521, 
-    525, 525, 525, 525, 525, 525, 525, 525, 40, 40, 525, 525, 521, 521, 521, 
-    521, 521, 524, 524, 521, 521, 521, 521, 521, 524, 521, 521, 521, 521, 
-    521, 532, 532, 532, 521, 521, 532, 521, 521, 532, 530, 530, 525, 525, 
-    521, 521, 525, 525, 525, 521, 525, 525, 525, 521, 521, 521, 1002, 1002, 
-    1002, 1002, 1002, 521, 521, 521, 521, 521, 521, 521, 525, 521, 525, 532, 
-    532, 521, 521, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 
-    521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 532, 
-    532, 532, 532, 521, 521, 521, 521, 532, 521, 532, 521, 521, 521, 532, 
-    521, 521, 521, 521, 532, 532, 532, 521, 532, 532, 532, 524, 521, 524, 
-    521, 524, 521, 521, 521, 521, 521, 532, 521, 521, 521, 521, 524, 521, 
-    524, 524, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 525, 525, 
-    521, 524, 524, 524, 524, 524, 524, 524, 521, 521, 521, 521, 521, 521, 
-    521, 521, 524, 524, 524, 524, 524, 524, 521, 521, 521, 521, 521, 524, 
-    524, 524, 524, 524, 524, 524, 524, 524, 524, 524, 524, 40, 40, 40, 40, 
-    525, 521, 521, 521, 521, 525, 525, 525, 525, 525, 530, 530, 525, 525, 
-    525, 525, 532, 525, 525, 525, 525, 525, 530, 525, 525, 525, 525, 532, 
-    532, 525, 525, 525, 525, 525, 40, 40, 40, 40, 40, 40, 40, 40, 525, 525, 
-    525, 525, 40, 40, 525, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 
-    532, 532, 532, 521, 521, 521, 532, 532, 532, 532, 532, 40, 40, 40, 40, 
-    40, 40, 534, 534, 534, 1003, 1003, 1003, 40, 40, 40, 40, 521, 521, 521, 
-    532, 521, 521, 521, 521, 521, 521, 521, 521, 532, 532, 532, 521, 532, 
-    521, 521, 521, 521, 521, 525, 525, 525, 525, 525, 525, 532, 525, 525, 
-    525, 521, 521, 521, 525, 525, 998, 998, 998, 525, 525, 525, 521, 521, 
-    998, 998, 998, 525, 525, 525, 525, 521, 521, 521, 521, 521, 998, 998, 
-    998, 998, 998, 998, 998, 40, 40, 40, 40, 998, 998, 998, 998, 40, 40, 40, 
-    40, 40, 998, 998, 998, 40, 40, 998, 998, 998, 998, 998, 998, 40, 40, 40, 
-    40, 40, 40, 998, 998, 532, 532, 532, 532, 532, 521, 532, 532, 521, 521, 
-    521, 521, 521, 521, 532, 521, 532, 532, 521, 521, 521, 532, 532, 998, 
-    521, 521, 521, 521, 521, 998, 998, 998, 521, 521, 521, 521, 998, 998, 
-    998, 998, 521, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 
-    532, 532, 521, 521, 521, 521, 521, 521, 521, 521, 521, 998, 998, 998, 
-    998, 998, 998, 998, 81, 81, 589, 589, 589, 589, 589, 589, 589, 590, 589, 
-    589, 589, 589, 589, 590, 590, 590, 589, 590, 590, 590, 590, 590, 590, 
-    590, 590, 590, 590, 590, 590, 590, 81, 81, 81, 499, 81, 81, 81, 81, 81, 
-    81, 499, 499, 499, 499, 499, 499, 499, 499, 667, 667, 667, 667, 667, 667, 
-    81, 81, 
+    81, 81, 81, 81, 81, 529, 529, 529, 529, 525, 529, 529, 529, 529, 529, 
+    529, 529, 529, 529, 529, 529, 529, 529, 529, 529, 1037, 1037, 1037, 1037, 
+    1037, 1037, 1037, 1037, 1037, 1037, 1037, 1037, 529, 529, 529, 529, 529, 
+    529, 529, 1037, 1037, 529, 529, 529, 529, 529, 529, 529, 529, 529, 529, 
+    529, 529, 529, 529, 525, 529, 529, 529, 529, 529, 529, 1037, 1037, 47, 
+    47, 47, 519, 519, 1037, 1037, 1037, 530, 530, 530, 530, 530, 530, 317, 
+    40, 530, 530, 40, 40, 1037, 1037, 1037, 1037, 530, 530, 530, 530, 530, 
+    530, 1038, 530, 530, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 
+    1038, 1038, 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, 1037, 1037, 
+    1037, 1037, 1037, 1037, 1037, 1037, 1037, 1039, 1039, 1039, 1039, 1039, 
+    1039, 1039, 1039, 1039, 1039, 1040, 585, 585, 1037, 1037, 1037, 1037, 
+    1037, 585, 585, 585, 585, 1037, 1037, 1037, 1037, 585, 1037, 1037, 1037, 
+    1037, 1037, 1037, 1037, 585, 585, 1037, 1037, 1037, 1037, 1037, 1037, 
+    525, 525, 525, 525, 525, 525, 1037, 1037, 525, 529, 529, 529, 529, 529, 
+    529, 529, 529, 529, 529, 529, 529, 525, 525, 525, 525, 525, 525, 525, 
+    525, 525, 529, 525, 525, 525, 525, 525, 525, 529, 525, 525, 525, 525, 
+    525, 525, 525, 536, 525, 525, 525, 525, 525, 525, 529, 529, 529, 529, 
+    529, 529, 529, 529, 40, 40, 529, 529, 525, 525, 525, 525, 525, 528, 528, 
+    525, 525, 525, 525, 525, 528, 525, 525, 525, 525, 525, 536, 536, 536, 
+    525, 525, 536, 525, 525, 536, 534, 534, 529, 529, 525, 525, 529, 529, 
+    529, 525, 529, 529, 529, 525, 525, 525, 1041, 1041, 1041, 1041, 1041, 
+    525, 525, 525, 525, 525, 525, 525, 529, 525, 529, 536, 536, 525, 525, 
+    536, 536, 536, 536, 536, 536, 536, 536, 536, 536, 536, 525, 525, 525, 
+    525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 536, 536, 536, 536, 
+    525, 525, 525, 525, 536, 525, 536, 525, 525, 525, 536, 525, 525, 525, 
+    525, 536, 536, 536, 525, 536, 536, 536, 528, 525, 528, 525, 528, 525, 
+    525, 525, 525, 525, 536, 525, 525, 525, 525, 528, 525, 528, 528, 525, 
+    525, 525, 525, 525, 525, 525, 525, 525, 525, 529, 529, 525, 528, 528, 
+    528, 528, 528, 528, 528, 525, 525, 525, 525, 525, 525, 525, 525, 528, 
+    528, 528, 528, 528, 528, 525, 525, 525, 525, 525, 528, 528, 528, 528, 
+    528, 528, 528, 528, 528, 528, 528, 528, 40, 40, 40, 40, 529, 525, 525, 
+    525, 525, 529, 529, 529, 529, 529, 534, 534, 529, 529, 529, 529, 536, 
+    529, 529, 529, 529, 529, 534, 529, 529, 529, 529, 536, 536, 529, 529, 
+    529, 529, 529, 40, 40, 40, 40, 40, 40, 40, 40, 529, 529, 529, 529, 40, 
+    40, 529, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 536, 536, 536, 
+    525, 525, 525, 536, 536, 536, 536, 536, 40, 40, 40, 40, 40, 40, 538, 538, 
+    538, 1042, 1042, 1042, 40, 40, 40, 40, 525, 525, 525, 536, 525, 525, 525, 
+    525, 525, 525, 525, 525, 536, 536, 536, 525, 536, 525, 525, 525, 525, 
+    525, 529, 529, 529, 529, 529, 529, 536, 529, 529, 529, 525, 525, 525, 
+    529, 529, 1037, 1037, 1037, 529, 529, 529, 525, 525, 1037, 1037, 1037, 
+    529, 529, 529, 529, 525, 525, 525, 525, 525, 525, 1037, 1037, 1037, 1037, 
+    1037, 1037, 40, 40, 40, 40, 1037, 1037, 1037, 1037, 40, 40, 40, 40, 40, 
+    529, 529, 529, 529, 1037, 1037, 1037, 1037, 1037, 1037, 1037, 40, 40, 
+    1037, 1037, 1037, 1037, 1037, 1037, 40, 40, 40, 40, 40, 40, 1037, 1037, 
+    536, 536, 536, 536, 536, 525, 536, 536, 525, 525, 525, 525, 525, 525, 
+    536, 525, 536, 536, 525, 525, 525, 536, 536, 1037, 525, 1037, 1037, 525, 
+    525, 525, 525, 1037, 1037, 1037, 525, 1037, 525, 525, 525, 525, 525, 525, 
+    525, 1037, 1037, 1037, 1037, 1037, 525, 525, 525, 525, 525, 536, 536, 
+    525, 536, 536, 1037, 1037, 1037, 1037, 1037, 1037, 525, 536, 536, 536, 
+    536, 536, 536, 536, 536, 536, 536, 536, 536, 536, 525, 525, 1037, 1037, 
+    1037, 1037, 1037, 1037, 81, 81, 592, 592, 592, 592, 592, 592, 592, 593, 
+    592, 592, 592, 592, 592, 593, 593, 593, 592, 593, 593, 593, 593, 593, 
+    593, 593, 593, 593, 593, 593, 593, 593, 81, 81, 81, 503, 81, 81, 81, 81, 
+    81, 81, 503, 503, 503, 503, 503, 503, 503, 503, 670, 670, 670, 670, 670, 
+    670, 81, 81, 
 };
 
 /* decomposition data */
index 82bb9a4..5472ece 100644 (file)
@@ -202,8 +202,8 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
   }
 
   /* Space estimates based on:
-   * http://www.unicode.org/charts/PDF/U2000.pdf
-   * https://www.microsoft.com/typography/developers/fdsspec/spaces.aspx
+   * https://unicode.org/charts/PDF/U2000.pdf
+   * https://docs.microsoft.com/en-us/typography/develop/character-design-standards/whitespace
    */
   enum space_t {
     NOT_SPACE = 0,
@@ -276,10 +276,10 @@ extern HB_INTERNAL const hb_unicode_funcs_t _hb_unicode_funcs_nil;
  * We permute the "fixed-position" classes 10-26 into the order
  * described in the SBL Hebrew manual:
  *
- * http://www.sbl-site.org/Fonts/SBLHebrewUserManual1.5x.pdf
+ * https://www.sbl-site.org/Fonts/SBLHebrewUserManual1.5x.pdf
  *
  * (as recommended by:
- *  http://forum.fontlab.com/archive-old-microsoft-volt-group/vista-and-diacritic-ordering-t6751.0.html)
+ *  https://forum.fontlab.com/archive-old-microsoft-volt-group/vista-and-diacritic-ordering/msg22823/)
  *
  * More details here:
  * https://bugzilla.mozilla.org/show_bug.cgi?id=662055
@@ -306,8 +306,8 @@ extern HB_INTERNAL const hb_unicode_funcs_t _hb_unicode_funcs_nil;
  * Arabic
  *
  * Modify to move Shadda (ccc=33) before other marks.  See:
- * http://unicode.org/faq/normalization.html#8
- * http://unicode.org/faq/normalization.html#9
+ * https://unicode.org/faq/normalization.html#8
+ * https://unicode.org/faq/normalization.html#9
  */
 #define HB_MODIFIED_COMBINING_CLASS_CCC27 28 /* fathatan */
 #define HB_MODIFIED_COMBINING_CLASS_CCC28 29 /* dammatan */
@@ -346,9 +346,9 @@ extern HB_INTERNAL const hb_unicode_funcs_t _hb_unicode_funcs_nil;
 #define HB_MODIFIED_COMBINING_CLASS_CCC122 122 /* mai * */
 
 /* Tibetan
- * 
- * In case of multiple vowel-signs, use u first (but after achung) 
- * this allows Dzongkha multi-vowel shortcuts to render correctly 
+ *
+ * In case of multiple vowel-signs, use u first (but after achung)
+ * this allows Dzongkha multi-vowel shortcuts to render correctly
  */
 #define HB_MODIFIED_COMBINING_CLASS_CCC129 129 /* sign aa */
 #define HB_MODIFIED_COMBINING_CLASS_CCC130 132 /* sign i */
index 726baeb..2d16c2e 100644 (file)
@@ -64,7 +64,7 @@ hb_unicode_general_category_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
 
 static hb_codepoint_t
 hb_unicode_mirroring_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
-                         hb_codepoint_t      unicode   HB_UNUSED,
+                         hb_codepoint_t      unicode,
                          void               *user_data HB_UNUSED)
 {
   return unicode;
index cd25769..6d6afe8 100644 (file)
@@ -223,11 +223,19 @@ struct hb_uniscribe_shaper_funcs_t {
 };
 static hb_uniscribe_shaper_funcs_t *uniscribe_funcs;
 
+#ifdef HB_USE_ATEXIT
 static inline void
 free_uniscribe_funcs (void)
 {
+retry:
+  hb_uniscribe_shaper_funcs_t *local_uniscribe_funcs =
+    (hb_uniscribe_shaper_funcs_t *) hb_atomic_ptr_get (&uniscribe_funcs);
+  if (!hb_atomic_ptr_cmpexch (&uniscribe_funcs, local_uniscribe_funcs, nullptr))
+    goto retry;
+
   free (uniscribe_funcs);
 }
+#endif
 
 static hb_uniscribe_shaper_funcs_t *
 hb_uniscribe_shaper_get_funcs (void)
@@ -363,9 +371,10 @@ _hb_rename_font (hb_blob_t *blob, wchar_t *new_name)
   unsigned int name_table_length = OT::name::min_size +
                                    ARRAY_LENGTH (name_IDs) * OT::NameRecord::static_size +
                                    name_str_len * 2; /* for name data in UTF16BE form */
+  unsigned int padded_name_table_length = ((name_table_length + 3) & ~3);
   unsigned int name_table_offset = (length + 3) & ~3;
 
-  new_length = name_table_offset + ((name_table_length + 3) & ~3);
+  new_length = name_table_offset + padded_name_table_length;
   void *new_sfnt_data = calloc (1, new_length);
   if (!new_sfnt_data)
   {
@@ -410,7 +419,7 @@ _hb_rename_font (hb_blob_t *blob, wchar_t *new_name)
     if (face.find_table_index (HB_OT_TAG_name, &index))
     {
       OT::TableRecord &record = const_cast<OT::TableRecord &> (face.get_table (index));
-      record.checkSum.set_for_data (&name, name_table_length);
+      record.checkSum.set_for_data (&name, padded_name_table_length);
       record.offset.set (name_table_offset);
       record.length.set (name_table_length);
     }
@@ -621,12 +630,12 @@ _hb_uniscribe_shape (hb_shape_plan_t    *shape_plan,
   /*
    * Set up features.
    */
-  hb_auto_array_t<OPENTYPE_FEATURE_RECORD> feature_records;
-  hb_auto_array_t<range_record_t> range_records;
+  hb_auto_t<hb_vector_t<OPENTYPE_FEATURE_RECORD> > feature_records;
+  hb_auto_t<hb_vector_t<range_record_t> > range_records;
   if (num_features)
   {
     /* Sort features by start/end events. */
-    hb_auto_array_t<feature_event_t> feature_events;
+    hb_auto_t<hb_vector_t<feature_event_t> > feature_events;
     for (unsigned int i = 0; i < num_features; i++)
     {
       active_feature_t feature;
@@ -637,15 +646,11 @@ _hb_uniscribe_shape (hb_shape_plan_t    *shape_plan,
       feature_event_t *event;
 
       event = feature_events.push ();
-      if (unlikely (!event))
-       goto fail_features;
       event->index = features[i].start;
       event->start = true;
       event->feature = feature;
 
       event = feature_events.push ();
-      if (unlikely (!event))
-       goto fail_features;
       event->index = features[i].end;
       event->start = false;
       event->feature = feature;
@@ -659,15 +664,13 @@ _hb_uniscribe_shape (hb_shape_plan_t    *shape_plan,
       feature.order = num_features + 1;
 
       feature_event_t *event = feature_events.push ();
-      if (unlikely (!event))
-       goto fail_features;
       event->index = 0; /* This value does magic. */
       event->start = false;
       event->feature = feature;
     }
 
     /* Scan events and save features for each range. */
-    hb_auto_array_t<active_feature_t> active_features;
+    hb_auto_t<hb_vector_t<active_feature_t> > active_features;
     unsigned int last_index = 0;
     for (unsigned int i = 0; i < feature_events.len; i++)
     {
@@ -677,8 +680,6 @@ _hb_uniscribe_shape (hb_shape_plan_t    *shape_plan,
       {
         /* Save a snapshot of active features and the range. */
        range_record_t *range = range_records.push ();
-       if (unlikely (!range))
-         goto fail_features;
 
        unsigned int offset = feature_records.len;
 
@@ -687,10 +688,7 @@ _hb_uniscribe_shape (hb_shape_plan_t    *shape_plan,
        {
          if (!j || active_features[j].rec.tagFeature != feature_records[feature_records.len - 1].tagFeature)
          {
-           OPENTYPE_FEATURE_RECORD *feature = feature_records.push ();
-           if (unlikely (!feature))
-             goto fail_features;
-           *feature = active_features[j].rec;
+           feature_records.push (active_features[j].rec);
          }
          else
          {
@@ -709,33 +707,28 @@ _hb_uniscribe_shape (hb_shape_plan_t    *shape_plan,
        last_index = event->index;
       }
 
-      if (event->start) {
-        active_feature_t *feature = active_features.push ();
-       if (unlikely (!feature))
-         goto fail_features;
-       *feature = event->feature;
-      } else {
+      if (event->start)
+      {
+       active_features.push (event->feature);
+      }
+      else
+      {
         active_feature_t *feature = active_features.find (&event->feature);
        if (feature)
-         active_features.remove (feature - active_features.array);
+         active_features.remove (feature - active_features.arrayZ);
       }
     }
 
     if (!range_records.len) /* No active feature found. */
-      goto fail_features;
+      num_features = 0;
 
     /* Fixup the pointers. */
     for (unsigned int i = 0; i < range_records.len; i++)
     {
       range_record_t *range = &range_records[i];
-      range->props.potfRecords = feature_records.array + reinterpret_cast<uintptr_t> (range->props.potfRecords);
+      range->props.potfRecords = feature_records.arrayZ + reinterpret_cast<uintptr_t> (range->props.potfRecords);
     }
   }
-  else
-  {
-  fail_features:
-    num_features = 0;
-  }
 
 #define FAIL(...) \
   HB_STMT_START { \
@@ -849,8 +842,8 @@ retry:
 #undef MAX_ITEMS
 
   OPENTYPE_TAG language_tag = hb_uint32_swap (hb_ot_tag_from_language (buffer->props.language));
-  hb_auto_array_t<TEXTRANGE_PROPERTIES*> range_properties;
-  hb_auto_array_t<int> range_char_counts;
+  hb_auto_t<hb_vector_t<TEXTRANGE_PROPERTIES*> > range_properties;
+  hb_auto_t<hb_vector_t<int> > range_char_counts;
 
   unsigned int glyphs_offset = 0;
   unsigned int glyphs_len;
@@ -907,8 +900,8 @@ retry:
                                     &items[i].a,
                                     script_tags[i],
                                     language_tag,
-                                    range_char_counts.array,
-                                    range_properties.array,
+                                    range_char_counts.arrayZ,
+                                    range_properties.arrayZ,
                                     range_properties.len,
                                     pchars + chars_offset,
                                     item_chars_len,
@@ -948,8 +941,8 @@ retry:
                                     &items[i].a,
                                     script_tags[i],
                                     language_tag,
-                                    range_char_counts.array,
-                                    range_properties.array,
+                                    range_char_counts.arrayZ,
+                                    range_properties.arrayZ,
                                     range_properties.len,
                                     pchars + chars_offset,
                                     log_clusters + chars_offset,
index 2750932..2180d84 100644 (file)
@@ -37,10 +37,10 @@ HB_BEGIN_DECLS
 
 
 #define HB_VERSION_MAJOR 1
-#define HB_VERSION_MINOR 7
-#define HB_VERSION_MICRO 6
+#define HB_VERSION_MINOR 8
+#define HB_VERSION_MICRO 1
 
-#define HB_VERSION_STRING "1.7.6"
+#define HB_VERSION_STRING "1.8.1"
 
 #define HB_VERSION_ATLEAST(major,minor,micro) \
        ((major)*10000+(minor)*100+(micro) <= \
index 7402034..fc75a69 100644 (file)
--- a/src/hb.h
+++ b/src/hb.h
@@ -38,6 +38,7 @@
 #include "hb-deprecated.h"
 #include "hb-face.h"
 #include "hb-font.h"
+#include "hb-map.h"
 #include "hb-set.h"
 #include "hb-shape.h"
 #include "hb-shape-plan.h"
index d221e9d..ca0fcc5 100644 (file)
@@ -24,6 +24,7 @@
  * Red Hat Author(s): Behdad Esfahbod
  */
 
+#include "hb-static.cc"
 #include "hb-open-file-private.hh"
 #include "hb-ot-layout-gdef-table.hh"
 #include "hb-ot-layout-gsubgpos-private.hh"
 
 using namespace OT;
 
-#ifndef HB_NO_VISIBILITY
-const void * const OT::_hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {};
-#endif
-
 int
 main (int argc, char **argv)
 {
@@ -49,25 +46,21 @@ main (int argc, char **argv)
     exit (1);
   }
 
-  const char *font_data = nullptr;
-  int len = 0;
-
-#ifdef HAVE_GLIB
-  GMappedFile *mf = g_mapped_file_new (argv[1], false, nullptr);
-  font_data = g_mapped_file_get_contents (mf);
-  len = g_mapped_file_get_length (mf);
-#else
-  FILE *f = fopen (argv[1], "rb");
-  fseek (f, 0, SEEK_END);
-  len = ftell (f);
-  fseek (f, 0, SEEK_SET);
-  font_data = (const char *) malloc (len);
-  len = fread ((char *) font_data, 1, len, f);
-#endif
-
+  hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
+  unsigned int len;
+  const char *font_data = hb_blob_get_data (blob, &len);
   printf ("Opened font file %s: %d bytes long\n", argv[1], len);
 
-  const OpenTypeFontFile &ot = *CastP<OpenTypeFontFile> (font_data);
+  Sanitizer<OpenTypeFontFile> sanitizer;
+  hb_blob_t *font_blob = sanitizer.sanitize (blob);
+  const OpenTypeFontFile* sanitized = font_blob->as<OpenTypeFontFile> ();
+  if (sanitized == &Null(OpenTypeFontFile))
+  {
+    printf ("Sanitization of the file wasn't successful. Exit");
+    return 1;
+  }
+  const OpenTypeFontFile& ot = *sanitized;
+
 
   switch (ot.get_tag ()) {
   case OpenTypeFontFile::TrueTypeTag:
@@ -101,7 +94,7 @@ main (int argc, char **argv)
     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,
+             (const char *) table.tag,
              (unsigned int) table.offset,
              (unsigned int) table.length);
 
@@ -197,5 +190,3 @@ main (int argc, char **argv)
 
   return 0;
 }
-
-
index 636b003..39eb13d 100644 (file)
 #include "hb-ft.h"
 #endif
 
-#ifdef HAVE_GLIB
-# include <glib.h>
-# if !GLIB_CHECK_VERSION (2, 22, 0)
-#  define g_mapped_file_unref g_mapped_file_free
-# endif
-#endif
-#include <stdlib.h>
 #include <stdio.h>
 
 int
 main (int argc, char **argv)
 {
-  hb_blob_t *blob = nullptr;
-
   if (argc != 2) {
     fprintf (stderr, "usage: %s font-file\n", argv[0]);
     exit (1);
   }
 
-  /* Create the blob */
-  {
-    const char *font_data;
-    unsigned int len;
-    hb_destroy_func_t destroy;
-    void *user_data;
-    hb_memory_mode_t mm;
-
-#ifdef HAVE_GLIB
-    GMappedFile *mf = g_mapped_file_new (argv[1], false, nullptr);
-    font_data = g_mapped_file_get_contents (mf);
-    len = g_mapped_file_get_length (mf);
-    destroy = (hb_destroy_func_t) g_mapped_file_unref;
-    user_data = (void *) mf;
-    mm = HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE;
-#else
-    FILE *f = fopen (argv[1], "rb");
-    fseek (f, 0, SEEK_END);
-    len = ftell (f);
-    fseek (f, 0, SEEK_SET);
-    font_data = (const char *) malloc (len);
-    if (!font_data) len = 0;
-    len = fread ((char *) font_data, 1, len, f);
-    destroy = free;
-    user_data = (void *) font_data;
-    fclose (f);
-    mm = HB_MEMORY_MODE_WRITABLE;
-#endif
-
-    blob = hb_blob_create (font_data, len, mm, user_data, destroy);
-  }
-
+  hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
   hb_face_t *face = hb_face_create (blob, 0 /* first face */);
   hb_blob_destroy (blob);
   blob = nullptr;
index 9741b87..3c43852 100644 (file)
 #include "hb.h"
 #include "hb-ot.h"
 
-#ifdef HAVE_GLIB
-# include <glib.h>
-# if !GLIB_CHECK_VERSION (2, 22, 0)
-#  define g_mapped_file_unref g_mapped_file_free
-# endif
-#endif
-#include <stdlib.h>
 #include <stdio.h>
 
 int
 main (int argc, char **argv)
 {
-  hb_blob_t *blob = nullptr;
-
   if (argc != 2) {
     fprintf (stderr, "usage: %s font-file\n", argv[0]);
     exit (1);
   }
 
-  /* Create the blob */
-  {
-    const char *font_data;
-    unsigned int len;
-    hb_destroy_func_t destroy;
-    void *user_data;
-    hb_memory_mode_t mm;
-
-#ifdef HAVE_GLIB
-    GMappedFile *mf = g_mapped_file_new (argv[1], false, nullptr);
-    font_data = g_mapped_file_get_contents (mf);
-    len = g_mapped_file_get_length (mf);
-    destroy = (hb_destroy_func_t) g_mapped_file_unref;
-    user_data = (void *) mf;
-    mm = HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE;
-#else
-    FILE *f = fopen (argv[1], "rb");
-    fseek (f, 0, SEEK_END);
-    len = ftell (f);
-    fseek (f, 0, SEEK_SET);
-    font_data = (const char *) malloc (len);
-    if (!font_data) len = 0;
-    len = fread ((char *) font_data, 1, len, f);
-    destroy = free;
-    user_data = (void *) font_data;
-    fclose (f);
-    mm = HB_MEMORY_MODE_WRITABLE;
-#endif
-
-    blob = hb_blob_create (font_data, len, mm, user_data, destroy);
-  }
-
   /* Create the face */
+  hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
   hb_face_t *face = hb_face_create (blob, 0 /* first face */);
   hb_blob_destroy (blob);
   blob = nullptr;
index efebf2d..1836d72 100644 (file)
 #include "hb.h"
 #include "hb-ot.h"
 
-#ifdef HAVE_GLIB
-# include <glib.h>
-# if !GLIB_CHECK_VERSION (2, 22, 0)
-#  define g_mapped_file_unref g_mapped_file_free
-# endif
-#endif
-#include <stdlib.h>
 #include <stdio.h>
 
 #ifdef HAVE_FREETYPE
 int
 main (int argc, char **argv)
 {
-  hb_blob_t *blob = nullptr;
-
   if (argc != 4 && argc != 5) {
     fprintf (stderr, "usage: %s font-file lookup-index first-glyph [second-glyph]\n", argv[0]);
     exit (1);
   }
 
-  /* Create the blob */
-  {
-    const char *font_data;
-    unsigned int len;
-    hb_destroy_func_t destroy;
-    void *user_data;
-    hb_memory_mode_t mm;
-
-#ifdef HAVE_GLIB
-    GMappedFile *mf = g_mapped_file_new (argv[1], false, nullptr);
-    font_data = g_mapped_file_get_contents (mf);
-    len = g_mapped_file_get_length (mf);
-    destroy = (hb_destroy_func_t) g_mapped_file_unref;
-    user_data = (void *) mf;
-    mm = HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE;
-#else
-    FILE *f = fopen (argv[1], "rb");
-    fseek (f, 0, SEEK_END);
-    len = ftell (f);
-    fseek (f, 0, SEEK_SET);
-    font_data = (const char *) malloc (len);
-    if (!font_data) len = 0;
-    len = fread ((char *) font_data, 1, len, f);
-    destroy = free;
-    user_data = (void *) font_data;
-    fclose (f);
-    mm = HB_MEMORY_MODE_WRITABLE;
-#endif
-
-    blob = hb_blob_create (font_data, len, mm, user_data, destroy);
-  }
-
   /* Create the face */
+  hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
   hb_face_t *face = hb_face_create (blob, 0 /* first face */);
   hb_blob_destroy (blob);
   blob = nullptr;
index 9592b37..cf59e00 100644 (file)
 
 #include "hb.h"
 
-#ifdef HAVE_GLIB
-# include <glib.h>
-# if !GLIB_CHECK_VERSION (2, 22, 0)
-#  define g_mapped_file_unref g_mapped_file_free
-# endif
-#endif
-#include <stdlib.h>
 #include <stdio.h>
 
 #ifdef HAVE_FREETYPE
 int
 main (int argc, char **argv)
 {
-  hb_blob_t *blob = nullptr;
-
   if (argc != 2) {
     fprintf (stderr, "usage: %s font-file.ttf\n", argv[0]);
     exit (1);
   }
 
-  /* Create the blob */
-  {
-    const char *font_data;
-    unsigned int len;
-    hb_destroy_func_t destroy;
-    void *user_data;
-    hb_memory_mode_t mm;
-
-#ifdef HAVE_GLIB
-    GMappedFile *mf = g_mapped_file_new (argv[1], false, nullptr);
-    font_data = g_mapped_file_get_contents (mf);
-    len = g_mapped_file_get_length (mf);
-    destroy = (hb_destroy_func_t) g_mapped_file_unref;
-    user_data = (void *) mf;
-    mm = HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE;
-#else
-    FILE *f = fopen (argv[1], "rb");
-    fseek (f, 0, SEEK_END);
-    len = ftell (f);
-    fseek (f, 0, SEEK_SET);
-    font_data = (const char *) malloc (len);
-    if (!font_data) len = 0;
-    len = fread ((char *) font_data, 1, len, f);
-    destroy = free;
-    user_data = (void *) font_data;
-    fclose (f);
-    mm = HB_MEMORY_MODE_WRITABLE;
-#endif
-
-    blob = hb_blob_create (font_data, len, mm, user_data, destroy);
-  }
-
+  hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
   printf ("Opened font file %s: %u bytes long\n", argv[1], hb_blob_get_length (blob));
 
   /* Create the face */
index 27cc25e..5a7e405 100644 (file)
@@ -91,7 +91,8 @@ build_triplet = @build@
 host_triplet = @host@
 subdir = test
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
+       $(top_srcdir)/m4/ax_code_coverage.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
index f1a2300..b540eb5 100644 (file)
@@ -21,7 +21,12 @@ if (HB_HAVE_GLIB)
       message (FATAL_ERROR "No source file found for test ${test_name}")
     endif ()
     target_link_libraries (${test_name} harfbuzz harfbuzz-subset)
-    add_test (${test_name} ${test_name})
+    if (WIN32)
+      set_property (TARGET ${test_name} PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
+      add_test (NAME ${test_name} COMMAND ${test_name})
+    else (WIN32)
+      add_test (${test_name} ${test_name})
+    endif (WIN32)
   endforeach ()
   set_tests_properties (${TEST_PROGS} PROPERTIES ENVIRONMENT
     "G_TEST_SRCDIR=${CMAKE_CURRENT_SOURCE_DIR};G_TEST_BUILDDIR=${CMAKE_CURRENT_BINARY_DIR}"
index a6ebc57..65ceeda 100644 (file)
@@ -31,21 +31,28 @@ TEST_PROGS = \
        test-object \
        test-set \
        test-shape \
+       test-subset \
+       test-subset-codepoints \
        test-subset-cmap \
        test-subset-glyf \
        test-subset-hdmx \
        test-subset-hmtx \
        test-subset-os2 \
+       test-subset-post \
+       test-subset-vmtx \
        test-unicode \
        test-version \
        $(NULL)
 
 test_subset_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
+test_subset_codepoints_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
 test_subset_cmap_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
 test_subset_glyf_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
 test_subset_hdmx_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
 test_subset_hmtx_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
-test_subset_os2_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
+test_subset_os2_LDADD  = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
+test_subset_post_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
+test_subset_vmtx_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
 
 test_unicode_CPPFLAGS = \
        $(AM_CPPFLAGS) \
index ea43eb8..c08ad51 100644 (file)
@@ -114,7 +114,8 @@ host_triplet = @host@
 @HAVE_GLIB_TRUE@       symbols-exported.txt symbols-untested.txt
 subdir = test/api
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
+       $(top_srcdir)/m4/ax_code_coverage.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
@@ -136,15 +137,19 @@ am__EXEEXT_1 =
 @HAVE_GLIB_TRUE@am__EXEEXT_4 = test-blob$(EXEEXT) test-buffer$(EXEEXT) \
 @HAVE_GLIB_TRUE@       test-common$(EXEEXT) test-font$(EXEEXT) \
 @HAVE_GLIB_TRUE@       test-object$(EXEEXT) test-set$(EXEEXT) \
-@HAVE_GLIB_TRUE@       test-shape$(EXEEXT) test-subset-cmap$(EXEEXT) \
+@HAVE_GLIB_TRUE@       test-shape$(EXEEXT) test-subset$(EXEEXT) \
+@HAVE_GLIB_TRUE@       test-subset-codepoints$(EXEEXT) \
+@HAVE_GLIB_TRUE@       test-subset-cmap$(EXEEXT) \
 @HAVE_GLIB_TRUE@       test-subset-glyf$(EXEEXT) \
 @HAVE_GLIB_TRUE@       test-subset-hdmx$(EXEEXT) \
 @HAVE_GLIB_TRUE@       test-subset-hmtx$(EXEEXT) \
-@HAVE_GLIB_TRUE@       test-subset-os2$(EXEEXT) test-unicode$(EXEEXT) \
-@HAVE_GLIB_TRUE@       test-version$(EXEEXT) $(am__EXEEXT_1) \
-@HAVE_GLIB_TRUE@       $(am__EXEEXT_2) $(am__EXEEXT_3) \
-@HAVE_GLIB_TRUE@       test-c$(EXEEXT) test-cplusplus$(EXEEXT) \
-@HAVE_GLIB_TRUE@       $(am__EXEEXT_1)
+@HAVE_GLIB_TRUE@       test-subset-os2$(EXEEXT) \
+@HAVE_GLIB_TRUE@       test-subset-post$(EXEEXT) \
+@HAVE_GLIB_TRUE@       test-subset-vmtx$(EXEEXT) \
+@HAVE_GLIB_TRUE@       test-unicode$(EXEEXT) test-version$(EXEEXT) \
+@HAVE_GLIB_TRUE@       $(am__EXEEXT_1) $(am__EXEEXT_2) \
+@HAVE_GLIB_TRUE@       $(am__EXEEXT_3) test-c$(EXEEXT) \
+@HAVE_GLIB_TRUE@       test-cplusplus$(EXEEXT) $(am__EXEEXT_1)
 PROGRAMS = $(noinst_PROGRAMS)
 test_blob_SOURCES = test-blob.c
 test_blob_OBJECTS = test-blob.$(OBJEXT)
@@ -226,10 +231,19 @@ test_shape_LDADD = $(LDADD)
 @HAVE_GLIB_TRUE@test_shape_DEPENDENCIES =  \
 @HAVE_GLIB_TRUE@       $(top_builddir)/src/libharfbuzz.la \
 @HAVE_GLIB_TRUE@       $(am__DEPENDENCIES_1)
+test_subset_SOURCES = test-subset.c
+test_subset_OBJECTS = test-subset.$(OBJEXT)
+@HAVE_GLIB_TRUE@test_subset_DEPENDENCIES = $(am__DEPENDENCIES_2) \
+@HAVE_GLIB_TRUE@       $(top_builddir)/src/libharfbuzz-subset.la
 test_subset_cmap_SOURCES = test-subset-cmap.c
 test_subset_cmap_OBJECTS = test-subset-cmap.$(OBJEXT)
 @HAVE_GLIB_TRUE@test_subset_cmap_DEPENDENCIES = $(am__DEPENDENCIES_2) \
 @HAVE_GLIB_TRUE@       $(top_builddir)/src/libharfbuzz-subset.la
+test_subset_codepoints_SOURCES = test-subset-codepoints.c
+test_subset_codepoints_OBJECTS = test-subset-codepoints.$(OBJEXT)
+@HAVE_GLIB_TRUE@test_subset_codepoints_DEPENDENCIES =  \
+@HAVE_GLIB_TRUE@       $(am__DEPENDENCIES_2) \
+@HAVE_GLIB_TRUE@       $(top_builddir)/src/libharfbuzz-subset.la
 test_subset_glyf_SOURCES = test-subset-glyf.c
 test_subset_glyf_OBJECTS = test-subset-glyf.$(OBJEXT)
 @HAVE_GLIB_TRUE@test_subset_glyf_DEPENDENCIES = $(am__DEPENDENCIES_2) \
@@ -246,6 +260,14 @@ test_subset_os2_SOURCES = test-subset-os2.c
 test_subset_os2_OBJECTS = test-subset-os2.$(OBJEXT)
 @HAVE_GLIB_TRUE@test_subset_os2_DEPENDENCIES = $(am__DEPENDENCIES_2) \
 @HAVE_GLIB_TRUE@       $(top_builddir)/src/libharfbuzz-subset.la
+test_subset_post_SOURCES = test-subset-post.c
+test_subset_post_OBJECTS = test-subset-post.$(OBJEXT)
+@HAVE_GLIB_TRUE@test_subset_post_DEPENDENCIES = $(am__DEPENDENCIES_2) \
+@HAVE_GLIB_TRUE@       $(top_builddir)/src/libharfbuzz-subset.la
+test_subset_vmtx_SOURCES = test-subset-vmtx.c
+test_subset_vmtx_OBJECTS = test-subset-vmtx.$(OBJEXT)
+@HAVE_GLIB_TRUE@test_subset_vmtx_DEPENDENCIES = $(am__DEPENDENCIES_2) \
+@HAVE_GLIB_TRUE@       $(top_builddir)/src/libharfbuzz-subset.la
 test_unicode_SOURCES = test-unicode.c
 test_unicode_OBJECTS = test_unicode-test-unicode.$(OBJEXT)
 @HAVE_GLIB_TRUE@@HAVE_ICU_TRUE@am__DEPENDENCIES_3 = $(top_builddir)/src/libharfbuzz-icu.la \
@@ -313,15 +335,17 @@ am__v_CXXLD_1 =
 SOURCES = test-blob.c test-buffer.c test-c.c test-common.c \
        $(test_cplusplus_SOURCES) test-font.c test-object.c \
        test-ot-color.c test-ot-math.c test-ot-tag.c test-set.c \
-       test-shape.c test-subset-cmap.c test-subset-glyf.c \
-       test-subset-hdmx.c test-subset-hmtx.c test-subset-os2.c \
-       test-unicode.c test-version.c
+       test-shape.c test-subset.c test-subset-cmap.c \
+       test-subset-codepoints.c test-subset-glyf.c test-subset-hdmx.c \
+       test-subset-hmtx.c test-subset-os2.c test-subset-post.c \
+       test-subset-vmtx.c test-unicode.c test-version.c
 DIST_SOURCES = test-blob.c test-buffer.c test-c.c test-common.c \
        $(am__test_cplusplus_SOURCES_DIST) test-font.c test-object.c \
        test-ot-color.c test-ot-math.c test-ot-tag.c test-set.c \
-       test-shape.c test-subset-cmap.c test-subset-glyf.c \
-       test-subset-hdmx.c test-subset-hmtx.c test-subset-os2.c \
-       test-unicode.c test-version.c
+       test-shape.c test-subset.c test-subset-cmap.c \
+       test-subset-codepoints.c test-subset-glyf.c test-subset-hdmx.c \
+       test-subset-hmtx.c test-subset-os2.c test-subset-post.c \
+       test-subset-vmtx.c test-unicode.c test-version.c
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -749,17 +773,22 @@ MAINTAINERCLEANFILES =
 # Tests for header compilation
 @HAVE_GLIB_TRUE@TEST_PROGS = test-blob test-buffer test-common \
 @HAVE_GLIB_TRUE@       test-font test-object test-set test-shape \
+@HAVE_GLIB_TRUE@       test-subset test-subset-codepoints \
 @HAVE_GLIB_TRUE@       test-subset-cmap test-subset-glyf \
 @HAVE_GLIB_TRUE@       test-subset-hdmx test-subset-hmtx \
-@HAVE_GLIB_TRUE@       test-subset-os2 test-unicode test-version \
+@HAVE_GLIB_TRUE@       test-subset-os2 test-subset-post \
+@HAVE_GLIB_TRUE@       test-subset-vmtx test-unicode test-version \
 @HAVE_GLIB_TRUE@       $(NULL) $(am__append_4) $(am__append_5) test-c \
 @HAVE_GLIB_TRUE@       test-cplusplus $(NULL)
 @HAVE_GLIB_TRUE@test_subset_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
+@HAVE_GLIB_TRUE@test_subset_codepoints_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
 @HAVE_GLIB_TRUE@test_subset_cmap_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
 @HAVE_GLIB_TRUE@test_subset_glyf_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
 @HAVE_GLIB_TRUE@test_subset_hdmx_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
 @HAVE_GLIB_TRUE@test_subset_hmtx_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
 @HAVE_GLIB_TRUE@test_subset_os2_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
+@HAVE_GLIB_TRUE@test_subset_post_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
+@HAVE_GLIB_TRUE@test_subset_vmtx_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
 @HAVE_GLIB_TRUE@test_unicode_CPPFLAGS = $(AM_CPPFLAGS) $(GLIB_CFLAGS) \
 @HAVE_GLIB_TRUE@       $(NULL) $(am__append_2)
 @HAVE_GLIB_TRUE@test_unicode_LDADD = $(LDADD) $(am__append_3)
@@ -895,10 +924,18 @@ test-shape$(EXEEXT): $(test_shape_OBJECTS) $(test_shape_DEPENDENCIES) $(EXTRA_te
        @rm -f test-shape$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(test_shape_OBJECTS) $(test_shape_LDADD) $(LIBS)
 
+test-subset$(EXEEXT): $(test_subset_OBJECTS) $(test_subset_DEPENDENCIES) $(EXTRA_test_subset_DEPENDENCIES) 
+       @rm -f test-subset$(EXEEXT)
+       $(AM_V_CCLD)$(LINK) $(test_subset_OBJECTS) $(test_subset_LDADD) $(LIBS)
+
 test-subset-cmap$(EXEEXT): $(test_subset_cmap_OBJECTS) $(test_subset_cmap_DEPENDENCIES) $(EXTRA_test_subset_cmap_DEPENDENCIES) 
        @rm -f test-subset-cmap$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(test_subset_cmap_OBJECTS) $(test_subset_cmap_LDADD) $(LIBS)
 
+test-subset-codepoints$(EXEEXT): $(test_subset_codepoints_OBJECTS) $(test_subset_codepoints_DEPENDENCIES) $(EXTRA_test_subset_codepoints_DEPENDENCIES) 
+       @rm -f test-subset-codepoints$(EXEEXT)
+       $(AM_V_CCLD)$(LINK) $(test_subset_codepoints_OBJECTS) $(test_subset_codepoints_LDADD) $(LIBS)
+
 test-subset-glyf$(EXEEXT): $(test_subset_glyf_OBJECTS) $(test_subset_glyf_DEPENDENCIES) $(EXTRA_test_subset_glyf_DEPENDENCIES) 
        @rm -f test-subset-glyf$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(test_subset_glyf_OBJECTS) $(test_subset_glyf_LDADD) $(LIBS)
@@ -915,6 +952,14 @@ test-subset-os2$(EXEEXT): $(test_subset_os2_OBJECTS) $(test_subset_os2_DEPENDENC
        @rm -f test-subset-os2$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(test_subset_os2_OBJECTS) $(test_subset_os2_LDADD) $(LIBS)
 
+test-subset-post$(EXEEXT): $(test_subset_post_OBJECTS) $(test_subset_post_DEPENDENCIES) $(EXTRA_test_subset_post_DEPENDENCIES) 
+       @rm -f test-subset-post$(EXEEXT)
+       $(AM_V_CCLD)$(LINK) $(test_subset_post_OBJECTS) $(test_subset_post_LDADD) $(LIBS)
+
+test-subset-vmtx$(EXEEXT): $(test_subset_vmtx_OBJECTS) $(test_subset_vmtx_DEPENDENCIES) $(EXTRA_test_subset_vmtx_DEPENDENCIES) 
+       @rm -f test-subset-vmtx$(EXEEXT)
+       $(AM_V_CCLD)$(LINK) $(test_subset_vmtx_OBJECTS) $(test_subset_vmtx_LDADD) $(LIBS)
+
 test-unicode$(EXEEXT): $(test_unicode_OBJECTS) $(test_unicode_DEPENDENCIES) $(EXTRA_test_unicode_DEPENDENCIES) 
        @rm -f test-unicode$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(test_unicode_OBJECTS) $(test_unicode_LDADD) $(LIBS)
@@ -939,10 +984,14 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-set.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-shape.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-subset-cmap.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-subset-codepoints.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-subset-glyf.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-subset-hdmx.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-subset-hmtx.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-subset-os2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-subset-post.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-subset-vmtx.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-subset.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-version.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_c-test-c.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cplusplus-test-cplusplus.Po@am__quote@
@@ -1295,6 +1344,20 @@ test-shape.log: test-shape$(EXEEXT)
        --log-file $$b.log --trs-file $$b.trs \
        $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
        "$$tst" $(AM_TESTS_FD_REDIRECT)
+test-subset.log: test-subset$(EXEEXT)
+       @p='test-subset$(EXEEXT)'; \
+       b='test-subset'; \
+       $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+       --log-file $$b.log --trs-file $$b.trs \
+       $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+       "$$tst" $(AM_TESTS_FD_REDIRECT)
+test-subset-codepoints.log: test-subset-codepoints$(EXEEXT)
+       @p='test-subset-codepoints$(EXEEXT)'; \
+       b='test-subset-codepoints'; \
+       $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+       --log-file $$b.log --trs-file $$b.trs \
+       $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+       "$$tst" $(AM_TESTS_FD_REDIRECT)
 test-subset-cmap.log: test-subset-cmap$(EXEEXT)
        @p='test-subset-cmap$(EXEEXT)'; \
        b='test-subset-cmap'; \
@@ -1330,6 +1393,20 @@ test-subset-os2.log: test-subset-os2$(EXEEXT)
        --log-file $$b.log --trs-file $$b.trs \
        $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
        "$$tst" $(AM_TESTS_FD_REDIRECT)
+test-subset-post.log: test-subset-post$(EXEEXT)
+       @p='test-subset-post$(EXEEXT)'; \
+       b='test-subset-post'; \
+       $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+       --log-file $$b.log --trs-file $$b.trs \
+       $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+       "$$tst" $(AM_TESTS_FD_REDIRECT)
+test-subset-vmtx.log: test-subset-vmtx$(EXEEXT)
+       @p='test-subset-vmtx$(EXEEXT)'; \
+       b='test-subset-vmtx'; \
+       $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+       --log-file $$b.log --trs-file $$b.trs \
+       $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+       "$$tst" $(AM_TESTS_FD_REDIRECT)
 test-unicode.log: test-unicode$(EXEEXT)
        @p='test-unicode$(EXEEXT)'; \
        b='test-unicode'; \
diff --git a/test/api/fonts/Mplus1p-Regular.660E,6975,73E0,5EA6,8F38,6E05.ttf b/test/api/fonts/Mplus1p-Regular.660E,6975,73E0,5EA6,8F38,6E05.ttf
new file mode 100644 (file)
index 0000000..2a978fb
Binary files /dev/null and b/test/api/fonts/Mplus1p-Regular.660E,6975,73E0,5EA6,8F38,6E05.ttf differ
diff --git a/test/api/fonts/Mplus1p-Regular.660E.ttf b/test/api/fonts/Mplus1p-Regular.660E.ttf
new file mode 100644 (file)
index 0000000..3e32c89
Binary files /dev/null and b/test/api/fonts/Mplus1p-Regular.660E.ttf differ
diff --git a/test/api/fonts/Roboto-Regular.D7,D8,D9,DA,DE.ttf b/test/api/fonts/Roboto-Regular.D7,D8,D9,DA,DE.ttf
new file mode 100644 (file)
index 0000000..3a71f53
Binary files /dev/null and b/test/api/fonts/Roboto-Regular.D7,D8,D9,DA,DE.ttf differ
diff --git a/test/api/fonts/Roboto-Regular.abc.format12.ttf b/test/api/fonts/Roboto-Regular.abc.format12.ttf
new file mode 100644 (file)
index 0000000..5aa6334
Binary files /dev/null and b/test/api/fonts/Roboto-Regular.abc.format12.ttf differ
diff --git a/test/api/fonts/Roboto-Regular.abc.format4.ttf b/test/api/fonts/Roboto-Regular.abc.format4.ttf
new file mode 100644 (file)
index 0000000..ccb074a
Binary files /dev/null and b/test/api/fonts/Roboto-Regular.abc.format4.ttf differ
diff --git a/test/api/fonts/Roboto-Regular.gsub.fi.ttf b/test/api/fonts/Roboto-Regular.gsub.fi.ttf
new file mode 100644 (file)
index 0000000..f41953b
Binary files /dev/null and b/test/api/fonts/Roboto-Regular.gsub.fi.ttf differ
diff --git a/test/api/fonts/Roboto-Regular.gsub.fil.ttf b/test/api/fonts/Roboto-Regular.gsub.fil.ttf
new file mode 100644 (file)
index 0000000..03e0be1
Binary files /dev/null and b/test/api/fonts/Roboto-Regular.gsub.fil.ttf differ
diff --git a/test/api/fonts/Roboto-Regular.nogsub.fi.ttf b/test/api/fonts/Roboto-Regular.nogsub.fi.ttf
new file mode 100644 (file)
index 0000000..6a08aa9
Binary files /dev/null and b/test/api/fonts/Roboto-Regular.nogsub.fi.ttf differ
diff --git a/test/api/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5521982557782016 b/test/api/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5521982557782016
new file mode 100644 (file)
index 0000000..55541f7
Binary files /dev/null and b/test/api/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5521982557782016 differ
diff --git a/test/api/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5609911946838016 b/test/api/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5609911946838016
new file mode 100644 (file)
index 0000000..8c647a8
Binary files /dev/null and b/test/api/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5609911946838016 differ
diff --git a/test/api/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-6651660668502016 b/test/api/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-6651660668502016
new file mode 100644 (file)
index 0000000..6206f07
Binary files /dev/null and b/test/api/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-6651660668502016 differ
diff --git a/test/api/fonts/crash-4b60576767ee4d9fe1cc10959d89baf73d4e8249 b/test/api/fonts/crash-4b60576767ee4d9fe1cc10959d89baf73d4e8249
new file mode 100644 (file)
index 0000000..b6b47ff
Binary files /dev/null and b/test/api/fonts/crash-4b60576767ee4d9fe1cc10959d89baf73d4e8249 differ
diff --git a/test/api/fonts/crash-b577db318b30f2851828a4c9ef97cb30678b1b54 b/test/api/fonts/crash-b577db318b30f2851828a4c9ef97cb30678b1b54
new file mode 100644 (file)
index 0000000..00be056
Binary files /dev/null and b/test/api/fonts/crash-b577db318b30f2851828a4c9ef97cb30678b1b54 differ
diff --git a/test/api/fonts/crash-ccc61c92d589f895174cdef6ff2e3b20e9999a1a b/test/api/fonts/crash-ccc61c92d589f895174cdef6ff2e3b20e9999a1a
new file mode 100644 (file)
index 0000000..1af243e
Binary files /dev/null and b/test/api/fonts/crash-ccc61c92d589f895174cdef6ff2e3b20e9999a1a differ
diff --git a/test/api/fonts/crash-e4e0bb1458a91b692eba492c907ae1f94e635480 b/test/api/fonts/crash-e4e0bb1458a91b692eba492c907ae1f94e635480
new file mode 100644 (file)
index 0000000..890c449
Binary files /dev/null and b/test/api/fonts/crash-e4e0bb1458a91b692eba492c907ae1f94e635480 differ
diff --git a/test/api/fonts/oom-6ef8c96d3710262511bcc730dce9c00e722cb653 b/test/api/fonts/oom-6ef8c96d3710262511bcc730dce9c00e722cb653
new file mode 100644 (file)
index 0000000..0bb0f0f
Binary files /dev/null and b/test/api/fonts/oom-6ef8c96d3710262511bcc730dce9c00e722cb653 differ
diff --git a/test/api/fonts/oom-ccc61c92d589f895174cdef6ff2e3b20e9999a1a b/test/api/fonts/oom-ccc61c92d589f895174cdef6ff2e3b20e9999a1a
new file mode 100644 (file)
index 0000000..1af243e
Binary files /dev/null and b/test/api/fonts/oom-ccc61c92d589f895174cdef6ff2e3b20e9999a1a differ
index 8e579a6..c34f394 100644 (file)
 #include "hb-test.h"
 #include "hb-subset.h"
 
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+typedef short bool;
+# ifndef true
+#  define true 1
+# endif
+# ifndef false
+#  define false 0
+# endif
+#endif
 
-HB_BEGIN_DECLS
-
-static inline char *
-hb_subset_test_read_file (const char *path,
-                          size_t     *length /* OUT */)
-{
-  FILE *fp = fopen (path, "rb");
-
-  long file_length = 0;
-  char *buffer = NULL;
-  if (fp && fseek (fp, 0, SEEK_END) == 0)
-  {
-    file_length = ftell(fp);
-    rewind (fp);
-  }
-
-  if (file_length > 0)
-  {
-    buffer = (char *) calloc (file_length + 1, sizeof (char));
-    if (buffer && fread (buffer, 1, file_length, fp) == (size_t) file_length)
-    {
-      *length = file_length;
-    }
-    else
-    {
-      free (buffer);
-      buffer = NULL;
-    }
-  }
-
-  if (fp)
-    fclose(fp);
 
-  return buffer;
-}
+HB_BEGIN_DECLS
 
 static inline hb_face_t *
 hb_subset_test_open_font (const char *font_path)
 {
 #if GLIB_CHECK_VERSION(2,37,2)
-  gchar* path = g_test_build_filename(G_TEST_DIST, font_path, NULL);
+  char* path = g_test_build_filename(G_TEST_DIST, font_path, NULL);
 #else
-  gchar* path = g_strdup(fontFile);
+  char* path = g_strdup(font_path);
 #endif
 
-  size_t length;
-  char *font_data = hb_subset_test_read_file(path, &length);
-
-  if (font_data != NULL) {
-    hb_blob_t *blob = hb_blob_create (font_data,
-                                      length,
-                                      HB_MEMORY_MODE_READONLY,
-                                      font_data,
-                                      free);
-    hb_face_t *face = hb_face_create (blob, 0);
-    hb_blob_destroy (blob);
-    return face;
-  }
-  g_assert (false);
-  return NULL; /* Shut up, compiler! */
+  return hb_face_create (hb_blob_create_from_file (path), 0);
 }
 
 static inline hb_subset_input_t *
@@ -122,9 +86,10 @@ hb_subset_test_check (hb_face_t *expected,
                       hb_face_t *actual,
                       hb_tag_t   table)
 {
+  hb_blob_t *expected_blob, *actual_blob;
   fprintf(stderr, "compare %c%c%c%c\n", HB_UNTAG(table));
-  hb_blob_t *expected_blob = hb_face_reference_table (expected, table);
-  hb_blob_t *actual_blob = hb_face_reference_table (actual, table);
+  expected_blob = hb_face_reference_table (expected, table);
+  actual_blob = hb_face_reference_table (actual, table);
   hb_test_assert_blobs_equal (expected_blob, actual_blob);
   hb_blob_destroy (expected_blob);
   hb_blob_destroy (actual_blob);
index c851f80..307845f 100644 (file)
@@ -87,39 +87,6 @@ hb_test_run (void)
   return g_test_run ();
 }
 
-
-#if 0
-/* Helpers for loading test fonts */
-static inline hb_face_t *
-hb_test_load_face (const char *path)
-{
-  const char *font_data = NULL;
-  unsigned int len = 0;
-  hb_blob_t *blob = NULL;
-  hb_face_t *face = NULL;
-
-  FILE *f = fopen (path, "rb");
-  if (!f) {
-    perror (path);
-    exit (1);
-  }
-
-  fseek (f, 0, SEEK_END);
-  len = ftell (f);
-  fseek (f, 0, SEEK_SET);
-  font_data = (const char *) malloc (len);
-  if (!font_data) len = 0;
-  len = fread ((char *) font_data, 1, len, f);
-  fclose (f);
-
-  blob = hb_blob_create (font_data, len, HB_MEMORY_MODE_READONLY, 0, free);
-  face = hb_face_create (blob, 0 /* first face */);
-  hb_blob_destroy (blob);
-  return face;
-}
-#endif
-
-
 /* Bugzilla helpers */
 
 static inline void
index b9a0268..5c98a9a 100644 (file)
@@ -445,7 +445,7 @@ static const utf8_validity_test_t utf8_validity_tests[] = {
   { "\xe2\x89\xa0\xe2\x89\xa0",  5, 3, FALSE },
   { "\xe2\x89\xa0\xe2\x89\xa0",  6, 6, TRUE },
 
-  /* examples from http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt */
+  /* examples from https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt */
   /* greek 'kosme' */
   { "\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce\xb5", -1, 11, TRUE },
   /* first sequence of each length */
index 74b50be..f6f0d48 100644 (file)
@@ -173,6 +173,7 @@ test_types_script (void)
 
   g_assert_cmpint (hb_script_get_horizontal_direction (HB_SCRIPT_LATIN), ==, HB_DIRECTION_LTR);
   g_assert_cmpint (hb_script_get_horizontal_direction (HB_SCRIPT_ARABIC), ==, HB_DIRECTION_RTL);
+  g_assert_cmpint (hb_script_get_horizontal_direction (HB_SCRIPT_OLD_ITALIC), ==, HB_DIRECTION_INVALID);
   g_assert_cmpint (hb_script_get_horizontal_direction (hb_script_from_iso15924_tag (wWyZ)), ==, HB_DIRECTION_LTR);
 }
 
index 6fe79b4..e821b36 100644 (file)
@@ -31,7 +31,7 @@
 /* Unit tests for hb-ot-tag.h */
 
 
-/* https://www.microsoft.com/typography/otspec/scripttags.htm */
+/* https://docs.microsoft.com/en-us/typography/opentype/spec/scripttags */
 
 static void
 test_simple_tags (const char *s, hb_script_t script)
@@ -112,7 +112,7 @@ test_ot_tag_script_simple (void)
   /* Unicode-5.1 additions */
   test_simple_tags ("vai ", HB_SCRIPT_VAI);
 
-  /* https://www.microsoft.com/typography/otspec160/scripttagsProposed.htm */
+  /* https://docs.microsoft.com/en-us/typography/opentype/spec/scripttags */
 
   /* Unicode-5.2 additions */
   test_simple_tags ("mtei", HB_SCRIPT_MEETEI_MAYEK);
@@ -137,7 +137,7 @@ test_ot_tag_script_indic (void)
 
 
 
-/* https://www.microsoft.com/typography/otspec/languagetags.htm */
+/* https://docs.microsoft.com/en-us/typography/opentype/spec/languagetags */
 
 static void
 test_language_two_way (const char *tag_s, const char *lang_s)
index 15958c5..338a610 100644 (file)
@@ -146,8 +146,12 @@ test_set_algebra (void)
 
   test_empty (s);
   g_assert (!hb_set_is_equal (s, o));
+  g_assert (hb_set_is_subset (s, o));
+  g_assert (!hb_set_is_subset (o, s));
   hb_set_set (s, o);
   g_assert (hb_set_is_equal (s, o));
+  g_assert (hb_set_is_subset (s, o));
+  g_assert (hb_set_is_subset (o, s));
   test_not_empty (s);
   g_assert_cmpint (hb_set_get_population (s), ==, 2);
 
@@ -250,6 +254,12 @@ test_set_algebra (void)
   g_assert_cmpint (hb_set_get_population (o), ==, 1);
   g_assert (hb_set_has (o, 889));
 
+  hb_set_add (o, 511);
+  g_assert_cmpint (hb_set_get_population (o), ==, 2);
+  hb_set_intersect (o, s);
+  g_assert_cmpint (hb_set_get_population (o), ==, 1);
+  g_assert (hb_set_has (o, 889));
+
   hb_set_destroy (s);
   hb_set_destroy (o);
 }
index c274f0f..6232e73 100644 (file)
@@ -154,7 +154,7 @@ test_shape_clusters (void)
   buffer =  hb_buffer_create ();
   hb_buffer_set_direction (buffer, HB_DIRECTION_LTR);
   {
-    /* https://code.google.com/p/chromium/issues/detail?id=497578 */
+    /* https://crbug.com/497578 */
     hb_codepoint_t test[] = {0xFFF1, 0xF0B6};
     hb_buffer_add_utf32 (buffer, test, 2, 0, 2);
   }
index 0771579..84d34bc 100644 (file)
@@ -24,8 +24,6 @@
  * Google Author(s): Roderick Sheeter
  */
 
-#include <stdbool.h>
-
 #include "hb-test.h"
 #include "hb-subset-test.h"
 
@@ -35,12 +33,13 @@ static void
 test_subset_cmap (void)
 {
   hb_face_t *face_abc = hb_subset_test_open_font ("fonts/Roboto-Regular.abc.ttf");
-  hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Roboto-Regular.ac.cmap-format12-only.ttf");
+  hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Roboto-Regular.ac.ttf");
 
   hb_set_t *codepoints = hb_set_create ();
+  hb_face_t *face_abc_subset;
   hb_set_add (codepoints, 97);
   hb_set_add (codepoints, 99);
-  hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
+  face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
   hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('c','m','a','p'));
@@ -51,15 +50,38 @@ test_subset_cmap (void)
 }
 
 static void
+test_subset_cmap_non_consecutive_glyphs (void)
+{
+  hb_face_t *face = hb_subset_test_open_font ("fonts/Roboto-Regular.D7,D8,D9,DA,DE.ttf");
+
+  hb_set_t *codepoints = hb_set_create ();
+  hb_face_t *face_subset;
+  hb_set_add (codepoints, 0xD7);
+  hb_set_add (codepoints, 0xD8);
+  hb_set_add (codepoints, 0xD9);
+  hb_set_add (codepoints, 0xDA);
+  hb_set_add (codepoints, 0xDE);
+
+  face_subset = hb_subset_test_create_subset (face, hb_subset_test_create_input (codepoints));
+  hb_set_destroy (codepoints);
+
+  hb_subset_test_check (face, face_subset, HB_TAG ('c','m','a','p'));
+
+  hb_face_destroy (face_subset);
+  hb_face_destroy (face);
+}
+
+static void
 test_subset_cmap_noop (void)
 {
-  hb_face_t *face_abc = hb_subset_test_open_font("fonts/Roboto-Regular.abc.cmap-format12-only.ttf");
+  hb_face_t *face_abc = hb_subset_test_open_font("fonts/Roboto-Regular.abc.ttf");
 
   hb_set_t *codepoints = hb_set_create();
+  hb_face_t *face_abc_subset;
   hb_set_add (codepoints, 97);
   hb_set_add (codepoints, 98);
   hb_set_add (codepoints, 99);
-  hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
+  face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
   hb_subset_test_check (face_abc, face_abc_subset, HB_TAG ('c','m','a','p'));
@@ -77,6 +99,7 @@ main (int argc, char **argv)
 
   hb_test_add (test_subset_cmap);
   hb_test_add (test_subset_cmap_noop);
+  hb_test_add (test_subset_cmap_non_consecutive_glyphs);
 
   return hb_test_run();
 }
diff --git a/test/api/test-subset-codepoints.c b/test/api/test-subset-codepoints.c
new file mode 100644 (file)
index 0000000..3bd1fe0
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright © 2018  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Garret Rieger
+ */
+
+#include "hb-test.h"
+#include "hb-subset-test.h"
+
+static void
+test_get_all_codepoints_format4 (void)
+{
+  hb_face_t *face = hb_subset_test_open_font("fonts/Roboto-Regular.abc.format4.ttf");
+  hb_set_t *codepoints = hb_set_create();
+
+  hb_subset_get_all_codepoints (face, codepoints);
+
+  hb_codepoint_t cp = HB_SET_VALUE_INVALID;
+  g_assert (hb_set_next (codepoints, &cp));
+  g_assert_cmpuint (0x61, ==, cp);
+  g_assert (hb_set_next (codepoints, &cp));
+  g_assert_cmpuint (0x62, ==, cp);
+  g_assert (hb_set_next (codepoints, &cp));
+  g_assert_cmpuint (0x63, ==, cp);
+  g_assert (!hb_set_next (codepoints, &cp));
+
+  hb_set_destroy (codepoints);
+  hb_face_destroy (face);
+}
+
+static void
+test_get_all_codepoints_format12 (void)
+{
+  hb_face_t *face = hb_subset_test_open_font("fonts/Roboto-Regular.abc.format12.ttf");
+  hb_set_t *codepoints = hb_set_create();
+
+  hb_subset_get_all_codepoints (face, codepoints);
+
+  hb_codepoint_t cp = HB_SET_VALUE_INVALID;
+  g_assert (hb_set_next (codepoints, &cp));
+  g_assert_cmpuint (0x61, ==, cp);
+  g_assert (hb_set_next (codepoints, &cp));
+  g_assert_cmpuint (0x62, ==, cp);
+  g_assert (hb_set_next (codepoints, &cp));
+  g_assert_cmpuint (0x63, ==, cp);
+  g_assert (!hb_set_next (codepoints, &cp));
+
+  hb_set_destroy (codepoints);
+  hb_face_destroy (face);
+}
+
+static void
+test_get_all_codepoints (void)
+{
+  hb_face_t *face = hb_subset_test_open_font("fonts/Roboto-Regular.abc.ttf");
+  hb_set_t *codepoints = hb_set_create();
+
+  hb_subset_get_all_codepoints (face, codepoints);
+
+  hb_codepoint_t cp = HB_SET_VALUE_INVALID;
+  g_assert (hb_set_next (codepoints, &cp));
+  g_assert_cmpuint (0x61, ==, cp);
+  g_assert (hb_set_next (codepoints, &cp));
+  g_assert_cmpuint (0x62, ==, cp);
+  g_assert (hb_set_next (codepoints, &cp));
+  g_assert_cmpuint (0x63, ==, cp);
+  g_assert (!hb_set_next (codepoints, &cp));
+
+  hb_set_destroy (codepoints);
+  hb_face_destroy (face);
+}
+
+int
+main (int argc, char **argv)
+{
+  hb_test_init (&argc, &argv);
+
+  hb_test_add (test_get_all_codepoints);
+  hb_test_add (test_get_all_codepoints_format4);
+  hb_test_add (test_get_all_codepoints_format12);
+
+  return hb_test_run();
+}
index 8e17e8d..e4440e0 100644 (file)
@@ -24,8 +24,6 @@
  * Google Author(s): Garret Rieger
  */
 
-#include <stdbool.h>
-
 #include "hb-test.h"
 #include "hb-subset-test.h"
 
@@ -66,9 +64,10 @@ test_subset_glyf (void)
   hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Roboto-Regular.ac.ttf");
 
   hb_set_t *codepoints = hb_set_create();
+  hb_face_t *face_abc_subset;
   hb_set_add (codepoints, 97);
   hb_set_add (codepoints, 99);
-  hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
+  face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
   hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('g','l','y','f'));
@@ -87,8 +86,9 @@ test_subset_glyf_with_components (void)
   hb_face_t *face_subset = hb_subset_test_open_font ("fonts/Roboto-Regular.components.subset.ttf");
 
   hb_set_t *codepoints = hb_set_create();
+  hb_face_t *face_generated_subset;
   hb_set_add (codepoints, 0x1fc);
-  hb_face_t *face_generated_subset = hb_subset_test_create_subset (face_components, hb_subset_test_create_input (codepoints));
+  face_generated_subset = hb_subset_test_create_subset (face_components, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
   hb_subset_test_check (face_subset, face_generated_subset, HB_TAG ('g','l','y','f'));
@@ -101,15 +101,66 @@ test_subset_glyf_with_components (void)
 }
 
 static void
+test_subset_glyf_with_gsub (void)
+{
+  hb_face_t *face_fil = hb_subset_test_open_font ("fonts/Roboto-Regular.gsub.fil.ttf");
+  hb_face_t *face_fi = hb_subset_test_open_font ("fonts/Roboto-Regular.gsub.fi.ttf");
+
+  hb_set_t *codepoints = hb_set_create();
+  hb_set_add (codepoints, 102); // f
+  hb_set_add (codepoints, 105); // i
+
+  hb_subset_input_t *input = hb_subset_test_create_input (codepoints);
+  hb_set_destroy (codepoints);
+  *hb_subset_input_drop_ot_layout (input) = false;
+
+  hb_face_t *face_subset = hb_subset_test_create_subset (face_fil, input);
+
+  hb_subset_test_check (face_fi, face_subset, HB_TAG ('g','l','y','f'));
+  hb_subset_test_check (face_fi, face_subset, HB_TAG ('l','o','c', 'a'));
+  check_maxp_num_glyphs(face_subset, 5, true);
+
+  hb_face_destroy (face_subset);
+  hb_face_destroy (face_fi);
+  hb_face_destroy (face_fil);
+}
+
+static void
+test_subset_glyf_without_gsub (void)
+{
+  hb_face_t *face_fil = hb_subset_test_open_font ("fonts/Roboto-Regular.gsub.fil.ttf");
+  hb_face_t *face_fi = hb_subset_test_open_font ("fonts/Roboto-Regular.nogsub.fi.ttf");
+
+  hb_set_t *codepoints = hb_set_create();
+  hb_set_add (codepoints, 102); // f
+  hb_set_add (codepoints, 105); // i
+
+  hb_subset_input_t *input = hb_subset_test_create_input (codepoints);
+  hb_set_destroy (codepoints);
+  *hb_subset_input_drop_ot_layout (input) = true;
+
+  hb_face_t *face_subset = hb_subset_test_create_subset (face_fil, input);
+
+  hb_subset_test_check (face_fi, face_subset, HB_TAG ('g','l','y','f'));
+  hb_subset_test_check (face_fi, face_subset, HB_TAG ('l','o','c', 'a'));
+  check_maxp_num_glyphs(face_subset, 3, true);
+
+  hb_face_destroy (face_subset);
+  hb_face_destroy (face_fi);
+  hb_face_destroy (face_fil);
+}
+
+static void
 test_subset_glyf_noop (void)
 {
   hb_face_t *face_abc = hb_subset_test_open_font("fonts/Roboto-Regular.abc.ttf");
 
   hb_set_t *codepoints = hb_set_create();
+  hb_face_t *face_abc_subset;
   hb_set_add (codepoints, 97);
   hb_set_add (codepoints, 98);
   hb_set_add (codepoints, 99);
-  hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
+  face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
   hb_subset_test_check (face_abc, face_abc_subset, HB_TAG ('g','l','y','f'));
@@ -127,11 +178,13 @@ test_subset_glyf_strip_hints_simple (void)
   hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Roboto-Regular.ac.nohints.ttf");
 
   hb_set_t *codepoints = hb_set_create();
+  hb_subset_input_t *input;
+  hb_face_t *face_abc_subset;
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'c');
-  hb_subset_input_t *input = hb_subset_test_create_input (codepoints);
+  input = hb_subset_test_create_input (codepoints);
   *hb_subset_input_drop_hints(input) = true;
-  hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, input);
+  face_abc_subset = hb_subset_test_create_subset (face_abc, input);
   hb_set_destroy (codepoints);
 
   hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('l','o','c', 'a'));
@@ -150,11 +203,13 @@ test_subset_glyf_strip_hints_composite (void)
   hb_face_t *face_subset = hb_subset_test_open_font ("fonts/Roboto-Regular.components.1fc.nohints.ttf");
 
   hb_set_t *codepoints = hb_set_create();
+  hb_subset_input_t *input;
+  hb_face_t *face_generated_subset;
   hb_set_add (codepoints, 0x1fc);
-  hb_subset_input_t *input = hb_subset_test_create_input (codepoints);
+  input = hb_subset_test_create_input (codepoints);
   *hb_subset_input_drop_hints(input) = true;
 
-  hb_face_t *face_generated_subset = hb_subset_test_create_subset (face_components, input);
+  face_generated_subset = hb_subset_test_create_subset (face_components, input);
   hb_set_destroy (codepoints);
 
   hb_subset_test_check (face_subset, face_generated_subset, HB_TAG ('g','l','y','f'));
@@ -166,6 +221,35 @@ test_subset_glyf_strip_hints_composite (void)
   hb_face_destroy (face_components);
 }
 
+static void
+test_subset_glyf_strip_hints_invalid (void)
+{
+  hb_face_t *face = hb_subset_test_open_font ("fonts/oom-ccc61c92d589f895174cdef6ff2e3b20e9999a1a");
+
+  hb_set_t *codepoints = hb_set_create();
+  const hb_codepoint_t text[] =
+  {
+    'A', 'B', 'C', 'D', 'E', 'X', 'Y', 'Z', '1', '2',
+    '3', '@', '_', '%', '&', ')', '*', '$', '!'
+  };
+  unsigned int i;
+  for (i = 0; i < sizeof (text) / sizeof (hb_codepoint_t); i++)
+  {
+    hb_set_add (codepoints, text[i]);
+  }
+
+  hb_subset_input_t *input = hb_subset_test_create_input (codepoints);
+  *hb_subset_input_drop_hints(input) = true;
+  hb_set_destroy (codepoints);
+
+  hb_face_t *face_subset = hb_subset_test_create_subset (face, input);
+  g_assert (face_subset);
+  g_assert (face_subset == hb_face_get_empty ());
+
+  hb_face_destroy (face_subset);
+  hb_face_destroy (face);
+}
+
 // TODO(grieger): test for long loca generation.
 
 int
@@ -177,7 +261,10 @@ main (int argc, char **argv)
   hb_test_add (test_subset_glyf);
   hb_test_add (test_subset_glyf_strip_hints_simple);
   hb_test_add (test_subset_glyf_strip_hints_composite);
+  hb_test_add (test_subset_glyf_strip_hints_invalid);
   hb_test_add (test_subset_glyf_with_components);
+  hb_test_add (test_subset_glyf_with_gsub);
+  hb_test_add (test_subset_glyf_without_gsub);
 
   return hb_test_run();
 }
index 5211dbc..c78009b 100644 (file)
@@ -24,8 +24,6 @@
  * Google Author(s): Garret Rieger
  */
 
-#include <stdbool.h>
-
 #include "hb-test.h"
 #include "hb-subset-test.h"
 
@@ -39,9 +37,10 @@ test_subset_hdmx_simple_subset (void)
   hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Roboto-Regular.ac.ttf");
 
   hb_set_t *codepoints = hb_set_create ();
+  hb_face_t *face_abc_subset;
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'c');
-  hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
+  face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
   hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('h','d','m','x'));
@@ -52,15 +51,60 @@ test_subset_hdmx_simple_subset (void)
 }
 
 static void
+test_subset_hdmx_invalid (void)
+{
+  hb_face_t *face = hb_subset_test_open_font("fonts/crash-ccc61c92d589f895174cdef6ff2e3b20e9999a1a");
+
+  hb_subset_input_t *input = hb_subset_input_create_or_fail ();
+  hb_set_t *codepoints = hb_subset_input_unicode_set (input);
+  hb_set_add (codepoints, 'a');
+  hb_set_add (codepoints, 'b');
+  hb_set_add (codepoints, 'c');
+
+  hb_subset_profile_t *profile = hb_subset_profile_create();
+  hb_face_t *subset = hb_subset (face, profile, input);
+  g_assert (subset);
+  g_assert (subset == hb_face_get_empty ());
+
+  hb_subset_input_destroy (input);
+  hb_subset_profile_destroy (profile);
+  hb_face_destroy (subset);
+  hb_face_destroy (face);
+}
+
+static void
+test_subset_hdmx_fails_sanitize (void)
+{
+  hb_face_t *face = hb_subset_test_open_font("fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5609911946838016");
+
+  hb_subset_input_t *input = hb_subset_input_create_or_fail ();
+  hb_set_t *codepoints = hb_subset_input_unicode_set (input);
+  hb_set_add (codepoints, 'a');
+  hb_set_add (codepoints, 'b');
+  hb_set_add (codepoints, 'c');
+
+  hb_subset_profile_t *profile = hb_subset_profile_create();
+  hb_face_t *subset = hb_subset (face, profile, input);
+  g_assert (subset);
+  g_assert (subset == hb_face_get_empty ());
+
+  hb_subset_input_destroy (input);
+  hb_subset_profile_destroy (profile);
+  hb_face_destroy (subset);
+  hb_face_destroy (face);
+}
+
+static void
 test_subset_hdmx_noop (void)
 {
   hb_face_t *face_abc = hb_subset_test_open_font("fonts/Roboto-Regular.abc.ttf");
 
   hb_set_t *codepoints = hb_set_create();
+  hb_face_t *face_abc_subset;
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'b');
   hb_set_add (codepoints, 'c');
-  hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
+  face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
   hb_subset_test_check (face_abc, face_abc_subset, HB_TAG ('h','d','m','x'));
@@ -75,6 +119,8 @@ main (int argc, char **argv)
   hb_test_init (&argc, &argv);
 
   hb_test_add (test_subset_hdmx_simple_subset);
+  hb_test_add (test_subset_hdmx_invalid);
+  hb_test_add (test_subset_hdmx_fails_sanitize);
   hb_test_add (test_subset_hdmx_noop);
 
   return hb_test_run();
index 2b76452..0ed6256 100644 (file)
@@ -24,8 +24,6 @@
  * Google Author(s): Roderick Sheeter
  */
 
-#include <stdbool.h>
-
 #include "hb-test.h"
 #include "hb-subset-test.h"
 
@@ -53,9 +51,10 @@ test_subset_hmtx_simple_subset (void)
   hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Roboto-Regular.ac.ttf");
 
   hb_set_t *codepoints = hb_set_create ();
+  hb_face_t *face_abc_subset;
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'c');
-  hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
+  face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
   check_num_hmetrics(face_abc_subset, 3); /* nothing has same width */
@@ -74,9 +73,10 @@ test_subset_hmtx_monospace (void)
   hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Inconsolata-Regular.ac.ttf");
 
   hb_set_t *codepoints = hb_set_create ();
+  hb_face_t *face_abc_subset;
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'c');
-  hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
+  face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
   check_num_hmetrics(face_abc_subset, 1); /* everything has same width */
@@ -95,9 +95,10 @@ test_subset_hmtx_keep_num_metrics (void)
   hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Inconsolata-Regular.ac.widerc.ttf");
 
   hb_set_t *codepoints = hb_set_create ();
+  hb_face_t *face_abc_subset;
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'c');
-  hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
+  face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
   check_num_hmetrics(face_abc_subset, 3); /* c is wider */
@@ -115,9 +116,10 @@ test_subset_hmtx_decrease_num_metrics (void)
   hb_face_t *face_ab = hb_subset_test_open_font ("fonts/Inconsolata-Regular.ab.ttf");
 
   hb_set_t *codepoints = hb_set_create ();
+  hb_face_t *face_abc_subset;
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'b');
-  hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
+  face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
   check_num_hmetrics(face_abc_subset, 1); /* everything left has same width */
@@ -134,10 +136,11 @@ test_subset_hmtx_noop (void)
   hb_face_t *face_abc = hb_subset_test_open_font("fonts/Roboto-Regular.abc.ttf");
 
   hb_set_t *codepoints = hb_set_create();
+  hb_face_t *face_abc_subset;
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'b');
   hb_set_add (codepoints, 'c');
-  hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
+  face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
   check_num_hmetrics(face_abc_subset, 4); /* nothing has same width */
@@ -147,6 +150,28 @@ test_subset_hmtx_noop (void)
   hb_face_destroy (face_abc);
 }
 
+static void
+test_subset_invalid_hmtx (void)
+{
+  hb_face_t *face = hb_subset_test_open_font("fonts/crash-e4e0bb1458a91b692eba492c907ae1f94e635480");
+
+  hb_subset_input_t *input = hb_subset_input_create_or_fail ();
+  hb_set_t *codepoints = hb_subset_input_unicode_set (input);
+  hb_set_add (codepoints, 'a');
+  hb_set_add (codepoints, 'b');
+  hb_set_add (codepoints, 'c');
+
+  hb_subset_profile_t *profile = hb_subset_profile_create();
+  hb_face_t *subset = hb_subset (face, profile, input);
+  g_assert (subset);
+  g_assert (subset == hb_face_get_empty ());
+
+  hb_subset_input_destroy (input);
+  hb_subset_profile_destroy (profile);
+  hb_face_destroy (subset);
+  hb_face_destroy (face);
+}
+
 int
 main (int argc, char **argv)
 {
@@ -157,6 +182,7 @@ main (int argc, char **argv)
   hb_test_add (test_subset_hmtx_keep_num_metrics);
   hb_test_add (test_subset_hmtx_decrease_num_metrics);
   hb_test_add (test_subset_hmtx_noop);
+  hb_test_add (test_subset_invalid_hmtx);
 
   return hb_test_run();
 }
index e9db9be..de63a3f 100644 (file)
@@ -24,7 +24,6 @@
  * Google Author(s): Garret Rieger
  */
 
-#include <stdbool.h>
 
 #include "hb-test.h"
 #include "hb-subset-test.h"
@@ -36,8 +35,9 @@ test_subset_os2 (void)
   hb_face_t *face_b = hb_subset_test_open_font("fonts/Roboto-Regular.b.ttf");
 
   hb_set_t *codepoints = hb_set_create();
+  hb_face_t *face_abc_subset;
   hb_set_add (codepoints, 98);
-  hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
+  face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
   hb_subset_test_check (face_b, face_abc_subset, HB_TAG ('O','S','/','2'));
diff --git a/test/api/test-subset-post.c b/test/api/test-subset-post.c
new file mode 100644 (file)
index 0000000..948b18a
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2018  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Garret Rieger
+ */
+
+#include "hb-test.h"
+#include "hb-subset-test.h"
+
+/* Unit tests for hmtx subsetting */
+
+static void
+test_post_drops_glyph_names (void)
+{
+  hb_face_t *face_full = hb_subset_test_open_font ("fonts/Mplus1p-Regular.660E,6975,73E0,5EA6,8F38,6E05.ttf");
+  hb_face_t *face_subset = hb_subset_test_open_font ("fonts/Mplus1p-Regular.660E.ttf");
+
+  hb_set_t *codepoints = hb_set_create ();
+  hb_set_add (codepoints, 0x660E);
+
+  hb_face_t *face_full_subset = hb_subset_test_create_subset (face_full, hb_subset_test_create_input (codepoints));
+  hb_set_destroy (codepoints);
+
+  hb_subset_test_check (face_subset, face_full_subset, HB_TAG ('p','o','s','t'));
+
+  hb_face_destroy (face_full_subset);
+  hb_face_destroy (face_full);
+  hb_face_destroy (face_subset);
+}
+
+int
+main (int argc, char **argv)
+{
+  hb_test_init (&argc, &argv);
+
+  hb_test_add (test_post_drops_glyph_names);
+
+  return hb_test_run();
+}
diff --git a/test/api/test-subset-vmtx.c b/test/api/test-subset-vmtx.c
new file mode 100644 (file)
index 0000000..437f0c2
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright © 2018  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Garret Rieger
+ */
+
+#include "hb-test.h"
+#include "hb-subset-test.h"
+
+/* Unit tests for hmtx subsetting */
+
+static void check_num_vmetrics(hb_face_t *face, uint16_t expected_num_vmetrics)
+{
+  hb_blob_t *vhea_blob = hb_face_reference_table (face, HB_TAG ('v','h','e','a'));
+  hb_blob_t *vmtx_blob = hb_face_reference_table (face, HB_TAG ('v','m','t','x'));
+
+  unsigned int vhea_len;
+  uint8_t *raw_vhea = (uint8_t *) hb_blob_get_data(vhea_blob, &vhea_len);
+  uint16_t num_vmetrics = (raw_vhea[vhea_len - 2] << 8) + raw_vhea[vhea_len - 1];
+  g_assert_cmpuint(expected_num_vmetrics, ==, num_vmetrics);
+
+  hb_blob_destroy (vhea_blob);
+  hb_blob_destroy (vmtx_blob);
+}
+
+static void
+test_subset_vmtx_simple_subset (void)
+{
+  hb_face_t *face_full = hb_subset_test_open_font ("fonts/Mplus1p-Regular.660E,6975,73E0,5EA6,8F38,6E05.ttf");
+  hb_face_t *face_subset = hb_subset_test_open_font ("fonts/Mplus1p-Regular.660E.ttf");
+
+  hb_set_t *codepoints = hb_set_create ();
+  hb_set_add (codepoints, 0x660E);
+
+  hb_face_t *face_full_subset = hb_subset_test_create_subset (face_full, hb_subset_test_create_input (codepoints));
+  hb_set_destroy (codepoints);
+
+  check_num_vmetrics(face_full_subset, 1); /* nothing has same width */
+  hb_subset_test_check (face_subset, face_full_subset, HB_TAG ('v','m','t','x'));
+
+  hb_face_destroy (face_full_subset);
+  hb_face_destroy (face_full);
+  hb_face_destroy (face_subset);
+}
+
+static void
+test_subset_vmtx_noop (void)
+{
+  hb_face_t *face_full = hb_subset_test_open_font ("fonts/Mplus1p-Regular.660E,6975,73E0,5EA6,8F38,6E05.ttf");
+
+  hb_set_t *codepoints = hb_set_create();
+  hb_set_add (codepoints, 0x660E);
+  hb_set_add (codepoints, 0x6975);
+  hb_set_add (codepoints, 0x73E0);
+  hb_set_add (codepoints, 0x5EA6);
+  hb_set_add (codepoints, 0x8F38);
+  hb_set_add (codepoints, 0x6E05);
+  hb_face_t *face_full_subset = hb_subset_test_create_subset (face_full, hb_subset_test_create_input (codepoints));
+  hb_set_destroy (codepoints);
+
+  check_num_vmetrics(face_full_subset, 1); /* all have the same width */
+  hb_subset_test_check (face_full, face_full_subset, HB_TAG ('v','m','t','x'));
+
+  hb_face_destroy (face_full_subset);
+  hb_face_destroy (face_full);
+}
+
+int
+main (int argc, char **argv)
+{
+  hb_test_init (&argc, &argv);
+
+  hb_test_add (test_subset_vmtx_simple_subset);
+  hb_test_add (test_subset_vmtx_noop);
+
+  return hb_test_run();
+}
diff --git a/test/api/test-subset.c b/test/api/test-subset.c
new file mode 100644 (file)
index 0000000..6d2bf06
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright © 2018  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Garret Rieger
+ */
+
+#include "hb-test.h"
+#include "hb-subset-test.h"
+
+/* Unit tests for hb-subset-glyf.h */
+
+static void
+test_subset_32_tables (void)
+{
+  hb_face_t *face = hb_subset_test_open_font("fonts/oom-6ef8c96d3710262511bcc730dce9c00e722cb653");
+
+  hb_subset_input_t *input = hb_subset_input_create_or_fail ();
+  hb_set_t *codepoints = hb_subset_input_unicode_set (input);
+  hb_set_add (codepoints, 'a');
+  hb_set_add (codepoints, 'b');
+  hb_set_add (codepoints, 'c');
+
+  hb_subset_profile_t *profile = hb_subset_profile_create();
+  hb_face_t *subset = hb_subset (face, profile, input);
+  g_assert (subset);
+  g_assert (subset != hb_face_get_empty ());
+
+  hb_subset_input_destroy (input);
+  hb_subset_profile_destroy (profile);
+  hb_face_destroy (subset);
+  hb_face_destroy (face);
+}
+
+static void
+test_subset_no_inf_loop (void)
+{
+  hb_face_t *face = hb_subset_test_open_font("fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5521982557782016");
+
+  hb_subset_input_t *input = hb_subset_input_create_or_fail ();
+  hb_set_t *codepoints = hb_subset_input_unicode_set (input);
+  hb_set_add (codepoints, 'a');
+  hb_set_add (codepoints, 'b');
+  hb_set_add (codepoints, 'c');
+
+  hb_subset_profile_t *profile = hb_subset_profile_create();
+  hb_face_t *subset = hb_subset (face, profile, input);
+  g_assert (subset);
+  g_assert (subset == hb_face_get_empty ());
+
+  hb_subset_input_destroy (input);
+  hb_subset_profile_destroy (profile);
+  hb_face_destroy (subset);
+  hb_face_destroy (face);
+}
+
+static void
+test_subset_crash (void)
+{
+  hb_face_t *face = hb_subset_test_open_font("fonts/crash-4b60576767ee4d9fe1cc10959d89baf73d4e8249");
+
+  hb_subset_input_t *input = hb_subset_input_create_or_fail ();
+  hb_set_t *codepoints = hb_subset_input_unicode_set (input);
+  hb_set_add (codepoints, 'a');
+  hb_set_add (codepoints, 'b');
+  hb_set_add (codepoints, 'c');
+
+  hb_subset_profile_t *profile = hb_subset_profile_create();
+  hb_face_t *subset = hb_subset (face, profile, input);
+  g_assert (subset);
+  g_assert (subset == hb_face_get_empty ());
+
+  hb_subset_input_destroy (input);
+  hb_subset_profile_destroy (profile);
+  hb_face_destroy (subset);
+  hb_face_destroy (face);
+}
+
+int
+main (int argc, char **argv)
+{
+  hb_test_init (&argc, &argv);
+
+  hb_test_add (test_subset_32_tables);
+  hb_test_add (test_subset_no_inf_loop);
+  hb_test_add (test_subset_crash);
+
+  return hb_test_run();
+}
index e31c744..2a45ef6 100644 (file)
@@ -1,18 +1,32 @@
 if (HB_CHECK)
   file (READ "${CMAKE_CURRENT_SOURCE_DIR}/Makefile.am" MAKEFILEAM)
-  extract_make_variable (hb_fuzzer_SOURCES ${MAKEFILEAM})
+  extract_make_variable (hb_shape_fuzzer_SOURCES ${MAKEFILEAM})
+  extract_make_variable (hb_subset_fuzzer_SOURCES ${MAKEFILEAM})
+  extract_make_variable (hb_subset_get_codepoints_fuzzer_SOURCES ${MAKEFILEAM})
 
   # TODO: enable these two
   #extract_make_variable (FUZZING_CPPFLAGS ${MAKEFILEAM}) # extracting regex fail
-  #add_executable (hb-fuzzer # it should be run only after ragel execution
+  #add_executable (hb-shape-fuzzer # it should be run only after ragel execution
   #  ${project_sources} ${project_extra_sources} ${project_headers}
-  #  ${hb_fuzzer_SOURCES})
+  #  ${hb_shape_fuzzer_SOURCES})
 
-  add_executable (hb-fuzzer ${hb_fuzzer_SOURCES})
-  target_link_libraries (hb-fuzzer harfbuzz)
+  add_executable (hb-shape-fuzzer ${hb_shape_fuzzer_SOURCES})
+  target_link_libraries (hb-shape-fuzzer harfbuzz)
 
-  target_compile_definitions(hb-fuzzer PUBLIC ${FUZZING_CPPFLAGS})
-  add_test (NAME hb-fuzzer
-    COMMAND python run-fuzzer-tests.py $<TARGET_FILE:hb-fuzzer>
+  add_executable (hb-subset-fuzzer ${hb_subset_fuzzer_SOURCES})
+  target_link_libraries (hb-subset-fuzzer harfbuzz-subset)
+
+  add_executable (hb-subset-get-codepoints-fuzzer ${hb_subset_get_codepoints_fuzzer_SOURCES})
+  target_link_libraries (hb-subset-get-codepoints-fuzzer harfbuzz-subset)
+
+  target_compile_definitions(hb-shape-fuzzer PUBLIC ${FUZZING_CPPFLAGS})
+  target_compile_definitions(hb-subset-fuzzer PUBLIC ${FUZZING_CPPFLAGS})
+  target_compile_definitions(hb-subset-get-codepoints-fuzzer PUBLIC ${FUZZING_CPPFLAGS})
+
+  add_test (NAME hb-shape-fuzzer
+    COMMAND "${PYTHON_EXECUTABLE}" run-shape-fuzzer-tests.py $<TARGET_FILE:hb-shape-fuzzer>
+    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+  add_test (NAME hb-subset-fuzzer
+    COMMAND "${PYTHON_EXECUTABLE}" run-subset-fuzzer-tests.py $<TARGET_FILE:hb-subset-fuzzer> $<TARGET_FILE:hb-subset-get-codepoints-fuzzer>
     WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
 endif ()
index a7f7362..5af5a73 100644 (file)
@@ -11,15 +11,19 @@ lib:
        @$(MAKE) $(AM_MAKEFLAGS) -C $(top_builddir)/src fuzzing
 
 $(top_builddir)/src/libharfbuzz-fuzzing.la: lib
+$(top_builddir)/src/libharfbuzz-subset-fuzzing.la: lib
 
 EXTRA_DIST += \
        README \
-       run-fuzzer-tests.py \
+       run-shape-fuzzer-tests.py \
+       run-subset-fuzzer-tests.py \
        CMakeLists.txt \
        $(NULL)
 
 check_PROGRAMS = \
-       hb-fuzzer \
+       hb-shape-fuzzer \
+       hb-subset-fuzzer \
+       hb-subset-get-codepoints-fuzzer \
        $(NULL)
 
 AM_CPPFLAGS = \
@@ -31,22 +35,53 @@ LDADD = \
        $(top_builddir)/src/libharfbuzz-fuzzing.la \
        $(NULL)
 
-hb_fuzzer_SOURCES = \
+hb_shape_fuzzer_SOURCES = \
        hb-fuzzer.hh \
-       hb-fuzzer.cc \
+       hb-shape-fuzzer.cc \
        main.cc \
        $(NULL)
-hb_fuzzer_LDADD = \
+hb_shape_fuzzer_LDADD = \
        $(LDADD) \
        $(NULL)
-hb_fuzzer_CPPFLAGS = \
+hb_shape_fuzzer_CPPFLAGS = \
        $(AM_CPPFLAGS) \
        $(NULL)
-hb_fuzzer_DEPENDENCIES = \
+hb_shape_fuzzer_DEPENDENCIES = \
+       lib \
+       $(NULL)
+
+hb_subset_fuzzer_SOURCES = \
+       hb-fuzzer.hh \
+       hb-subset-fuzzer.cc \
+       main.cc \
+       $(NULL)
+hb_subset_fuzzer_LDADD = \
+       $(top_builddir)/src/libharfbuzz-subset-fuzzing.la \
+       $(NULL)
+hb_subset_fuzzer_CPPFLAGS = \
+       $(AM_CPPFLAGS) \
+       $(NULL)
+hb_subset_fuzzer_DEPENDENCIES = \
+       lib \
+       $(NULL)
+
+hb_subset_get_codepoints_fuzzer_SOURCES = \
+       hb-fuzzer.hh \
+       hb-subset-get-codepoints-fuzzer.cc \
+       main.cc \
+       $(NULL)
+hb_subset_get_codepoints_fuzzer_LDADD = \
+       $(top_builddir)/src/libharfbuzz-subset-fuzzing.la \
+       $(NULL)
+hb_subset_get_codepoints_fuzzer_CPPFLAGS = \
+       $(AM_CPPFLAGS) \
+       $(NULL)
+hb_subset_get_codepoints_fuzzer_DEPENDENCIES = \
        lib \
        $(NULL)
 
 check:
-       EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" $(srcdir)/run-fuzzer-tests.py
+       EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" $(srcdir)/run-shape-fuzzer-tests.py
+       EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" $(srcdir)/run-subset-fuzzer-tests.py
 
 -include $(top_srcdir)/git.mk
index 7e9d952..dcbe021 100644 (file)
@@ -89,10 +89,12 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
-check_PROGRAMS = hb-fuzzer$(EXEEXT) $(am__EXEEXT_1)
+check_PROGRAMS = hb-shape-fuzzer$(EXEEXT) hb-subset-fuzzer$(EXEEXT) \
+       hb-subset-get-codepoints-fuzzer$(EXEEXT) $(am__EXEEXT_1)
 subdir = test/fuzzing
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
+       $(top_srcdir)/m4/ax_code_coverage.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
@@ -107,9 +109,10 @@ CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 am__EXEEXT_1 =
 am__objects_1 =
-am_hb_fuzzer_OBJECTS = hb_fuzzer-hb-fuzzer.$(OBJEXT) \
-       hb_fuzzer-main.$(OBJEXT) $(am__objects_1)
-hb_fuzzer_OBJECTS = $(am_hb_fuzzer_OBJECTS)
+am_hb_shape_fuzzer_OBJECTS =  \
+       hb_shape_fuzzer-hb-shape-fuzzer.$(OBJEXT) \
+       hb_shape_fuzzer-main.$(OBJEXT) $(am__objects_1)
+hb_shape_fuzzer_OBJECTS = $(am_hb_shape_fuzzer_OBJECTS)
 am__DEPENDENCIES_1 =
 am__DEPENDENCIES_2 = $(top_builddir)/src/libharfbuzz-fuzzing.la \
        $(am__DEPENDENCIES_1)
@@ -117,6 +120,15 @@ AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
 am__v_lt_0 = --silent
 am__v_lt_1 = 
+am_hb_subset_fuzzer_OBJECTS =  \
+       hb_subset_fuzzer-hb-subset-fuzzer.$(OBJEXT) \
+       hb_subset_fuzzer-main.$(OBJEXT) $(am__objects_1)
+hb_subset_fuzzer_OBJECTS = $(am_hb_subset_fuzzer_OBJECTS)
+am_hb_subset_get_codepoints_fuzzer_OBJECTS = hb_subset_get_codepoints_fuzzer-hb-subset-get-codepoints-fuzzer.$(OBJEXT) \
+       hb_subset_get_codepoints_fuzzer-main.$(OBJEXT) \
+       $(am__objects_1)
+hb_subset_get_codepoints_fuzzer_OBJECTS =  \
+       $(am_hb_subset_get_codepoints_fuzzer_OBJECTS)
 AM_V_P = $(am__v_P_@AM_V@)
 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
 am__v_P_0 = false
@@ -169,8 +181,10 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@)
 am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
 am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
-SOURCES = $(hb_fuzzer_SOURCES)
-DIST_SOURCES = $(hb_fuzzer_SOURCES)
+SOURCES = $(hb_shape_fuzzer_SOURCES) $(hb_subset_fuzzer_SOURCES) \
+       $(hb_subset_get_codepoints_fuzzer_SOURCES)
+DIST_SOURCES = $(hb_shape_fuzzer_SOURCES) $(hb_subset_fuzzer_SOURCES) \
+       $(hb_subset_get_codepoints_fuzzer_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -383,7 +397,8 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 NULL = 
-EXTRA_DIST = README run-fuzzer-tests.py CMakeLists.txt $(NULL)
+EXTRA_DIST = README run-shape-fuzzer-tests.py \
+       run-subset-fuzzer-tests.py CMakeLists.txt $(NULL)
 CLEANFILES = 
 DISTCLEANFILES = 
 MAINTAINERCLEANFILES = 
@@ -397,21 +412,57 @@ LDADD = \
        $(top_builddir)/src/libharfbuzz-fuzzing.la \
        $(NULL)
 
-hb_fuzzer_SOURCES = \
+hb_shape_fuzzer_SOURCES = \
        hb-fuzzer.hh \
-       hb-fuzzer.cc \
+       hb-shape-fuzzer.cc \
        main.cc \
        $(NULL)
 
-hb_fuzzer_LDADD = \
+hb_shape_fuzzer_LDADD = \
        $(LDADD) \
        $(NULL)
 
-hb_fuzzer_CPPFLAGS = \
+hb_shape_fuzzer_CPPFLAGS = \
        $(AM_CPPFLAGS) \
        $(NULL)
 
-hb_fuzzer_DEPENDENCIES = \
+hb_shape_fuzzer_DEPENDENCIES = \
+       lib \
+       $(NULL)
+
+hb_subset_fuzzer_SOURCES = \
+       hb-fuzzer.hh \
+       hb-subset-fuzzer.cc \
+       main.cc \
+       $(NULL)
+
+hb_subset_fuzzer_LDADD = \
+       $(top_builddir)/src/libharfbuzz-subset-fuzzing.la \
+       $(NULL)
+
+hb_subset_fuzzer_CPPFLAGS = \
+       $(AM_CPPFLAGS) \
+       $(NULL)
+
+hb_subset_fuzzer_DEPENDENCIES = \
+       lib \
+       $(NULL)
+
+hb_subset_get_codepoints_fuzzer_SOURCES = \
+       hb-fuzzer.hh \
+       hb-subset-get-codepoints-fuzzer.cc \
+       main.cc \
+       $(NULL)
+
+hb_subset_get_codepoints_fuzzer_LDADD = \
+       $(top_builddir)/src/libharfbuzz-subset-fuzzing.la \
+       $(NULL)
+
+hb_subset_get_codepoints_fuzzer_CPPFLAGS = \
+       $(AM_CPPFLAGS) \
+       $(NULL)
+
+hb_subset_get_codepoints_fuzzer_DEPENDENCIES = \
        lib \
        $(NULL)
 
@@ -458,9 +509,17 @@ clean-checkPROGRAMS:
        echo " rm -f" $$list; \
        rm -f $$list
 
-hb-fuzzer$(EXEEXT): $(hb_fuzzer_OBJECTS) $(hb_fuzzer_DEPENDENCIES) $(EXTRA_hb_fuzzer_DEPENDENCIES) 
-       @rm -f hb-fuzzer$(EXEEXT)
-       $(AM_V_CXXLD)$(CXXLINK) $(hb_fuzzer_OBJECTS) $(hb_fuzzer_LDADD) $(LIBS)
+hb-shape-fuzzer$(EXEEXT): $(hb_shape_fuzzer_OBJECTS) $(hb_shape_fuzzer_DEPENDENCIES) $(EXTRA_hb_shape_fuzzer_DEPENDENCIES) 
+       @rm -f hb-shape-fuzzer$(EXEEXT)
+       $(AM_V_CXXLD)$(CXXLINK) $(hb_shape_fuzzer_OBJECTS) $(hb_shape_fuzzer_LDADD) $(LIBS)
+
+hb-subset-fuzzer$(EXEEXT): $(hb_subset_fuzzer_OBJECTS) $(hb_subset_fuzzer_DEPENDENCIES) $(EXTRA_hb_subset_fuzzer_DEPENDENCIES) 
+       @rm -f hb-subset-fuzzer$(EXEEXT)
+       $(AM_V_CXXLD)$(CXXLINK) $(hb_subset_fuzzer_OBJECTS) $(hb_subset_fuzzer_LDADD) $(LIBS)
+
+hb-subset-get-codepoints-fuzzer$(EXEEXT): $(hb_subset_get_codepoints_fuzzer_OBJECTS) $(hb_subset_get_codepoints_fuzzer_DEPENDENCIES) $(EXTRA_hb_subset_get_codepoints_fuzzer_DEPENDENCIES) 
+       @rm -f hb-subset-get-codepoints-fuzzer$(EXEEXT)
+       $(AM_V_CXXLD)$(CXXLINK) $(hb_subset_get_codepoints_fuzzer_OBJECTS) $(hb_subset_get_codepoints_fuzzer_LDADD) $(LIBS)
 
 mostlyclean-compile:
        -rm -f *.$(OBJEXT)
@@ -468,8 +527,12 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hb_fuzzer-hb-fuzzer.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hb_fuzzer-main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hb_shape_fuzzer-hb-shape-fuzzer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hb_shape_fuzzer-main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hb_subset_fuzzer-hb-subset-fuzzer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hb_subset_fuzzer-main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hb_subset_get_codepoints_fuzzer-hb-subset-get-codepoints-fuzzer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hb_subset_get_codepoints_fuzzer-main.Po@am__quote@
 
 .cc.o:
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -492,33 +555,89 @@ distclean-compile:
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
 
-hb_fuzzer-hb-fuzzer.o: hb-fuzzer.cc
-@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT hb_fuzzer-hb-fuzzer.o -MD -MP -MF $(DEPDIR)/hb_fuzzer-hb-fuzzer.Tpo -c -o hb_fuzzer-hb-fuzzer.o `test -f 'hb-fuzzer.cc' || echo '$(srcdir)/'`hb-fuzzer.cc
-@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/hb_fuzzer-hb-fuzzer.Tpo $(DEPDIR)/hb_fuzzer-hb-fuzzer.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-fuzzer.cc' object='hb_fuzzer-hb-fuzzer.o' libtool=no @AMDEPBACKSLASH@
+hb_shape_fuzzer-hb-shape-fuzzer.o: hb-shape-fuzzer.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_shape_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT hb_shape_fuzzer-hb-shape-fuzzer.o -MD -MP -MF $(DEPDIR)/hb_shape_fuzzer-hb-shape-fuzzer.Tpo -c -o hb_shape_fuzzer-hb-shape-fuzzer.o `test -f 'hb-shape-fuzzer.cc' || echo '$(srcdir)/'`hb-shape-fuzzer.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/hb_shape_fuzzer-hb-shape-fuzzer.Tpo $(DEPDIR)/hb_shape_fuzzer-hb-shape-fuzzer.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-shape-fuzzer.cc' object='hb_shape_fuzzer-hb-shape-fuzzer.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_shape_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o hb_shape_fuzzer-hb-shape-fuzzer.o `test -f 'hb-shape-fuzzer.cc' || echo '$(srcdir)/'`hb-shape-fuzzer.cc
+
+hb_shape_fuzzer-hb-shape-fuzzer.obj: hb-shape-fuzzer.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_shape_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT hb_shape_fuzzer-hb-shape-fuzzer.obj -MD -MP -MF $(DEPDIR)/hb_shape_fuzzer-hb-shape-fuzzer.Tpo -c -o hb_shape_fuzzer-hb-shape-fuzzer.obj `if test -f 'hb-shape-fuzzer.cc'; then $(CYGPATH_W) 'hb-shape-fuzzer.cc'; else $(CYGPATH_W) '$(srcdir)/hb-shape-fuzzer.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/hb_shape_fuzzer-hb-shape-fuzzer.Tpo $(DEPDIR)/hb_shape_fuzzer-hb-shape-fuzzer.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-shape-fuzzer.cc' object='hb_shape_fuzzer-hb-shape-fuzzer.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_shape_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o hb_shape_fuzzer-hb-shape-fuzzer.obj `if test -f 'hb-shape-fuzzer.cc'; then $(CYGPATH_W) 'hb-shape-fuzzer.cc'; else $(CYGPATH_W) '$(srcdir)/hb-shape-fuzzer.cc'; fi`
+
+hb_shape_fuzzer-main.o: main.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_shape_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT hb_shape_fuzzer-main.o -MD -MP -MF $(DEPDIR)/hb_shape_fuzzer-main.Tpo -c -o hb_shape_fuzzer-main.o `test -f 'main.cc' || echo '$(srcdir)/'`main.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/hb_shape_fuzzer-main.Tpo $(DEPDIR)/hb_shape_fuzzer-main.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='main.cc' object='hb_shape_fuzzer-main.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_shape_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o hb_shape_fuzzer-main.o `test -f 'main.cc' || echo '$(srcdir)/'`main.cc
+
+hb_shape_fuzzer-main.obj: main.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_shape_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT hb_shape_fuzzer-main.obj -MD -MP -MF $(DEPDIR)/hb_shape_fuzzer-main.Tpo -c -o hb_shape_fuzzer-main.obj `if test -f 'main.cc'; then $(CYGPATH_W) 'main.cc'; else $(CYGPATH_W) '$(srcdir)/main.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/hb_shape_fuzzer-main.Tpo $(DEPDIR)/hb_shape_fuzzer-main.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='main.cc' object='hb_shape_fuzzer-main.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_shape_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o hb_shape_fuzzer-main.obj `if test -f 'main.cc'; then $(CYGPATH_W) 'main.cc'; else $(CYGPATH_W) '$(srcdir)/main.cc'; fi`
+
+hb_subset_fuzzer-hb-subset-fuzzer.o: hb-subset-fuzzer.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_subset_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT hb_subset_fuzzer-hb-subset-fuzzer.o -MD -MP -MF $(DEPDIR)/hb_subset_fuzzer-hb-subset-fuzzer.Tpo -c -o hb_subset_fuzzer-hb-subset-fuzzer.o `test -f 'hb-subset-fuzzer.cc' || echo '$(srcdir)/'`hb-subset-fuzzer.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/hb_subset_fuzzer-hb-subset-fuzzer.Tpo $(DEPDIR)/hb_subset_fuzzer-hb-subset-fuzzer.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-subset-fuzzer.cc' object='hb_subset_fuzzer-hb-subset-fuzzer.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_subset_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o hb_subset_fuzzer-hb-subset-fuzzer.o `test -f 'hb-subset-fuzzer.cc' || echo '$(srcdir)/'`hb-subset-fuzzer.cc
+
+hb_subset_fuzzer-hb-subset-fuzzer.obj: hb-subset-fuzzer.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_subset_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT hb_subset_fuzzer-hb-subset-fuzzer.obj -MD -MP -MF $(DEPDIR)/hb_subset_fuzzer-hb-subset-fuzzer.Tpo -c -o hb_subset_fuzzer-hb-subset-fuzzer.obj `if test -f 'hb-subset-fuzzer.cc'; then $(CYGPATH_W) 'hb-subset-fuzzer.cc'; else $(CYGPATH_W) '$(srcdir)/hb-subset-fuzzer.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/hb_subset_fuzzer-hb-subset-fuzzer.Tpo $(DEPDIR)/hb_subset_fuzzer-hb-subset-fuzzer.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-subset-fuzzer.cc' object='hb_subset_fuzzer-hb-subset-fuzzer.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_subset_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o hb_subset_fuzzer-hb-subset-fuzzer.obj `if test -f 'hb-subset-fuzzer.cc'; then $(CYGPATH_W) 'hb-subset-fuzzer.cc'; else $(CYGPATH_W) '$(srcdir)/hb-subset-fuzzer.cc'; fi`
+
+hb_subset_fuzzer-main.o: main.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_subset_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT hb_subset_fuzzer-main.o -MD -MP -MF $(DEPDIR)/hb_subset_fuzzer-main.Tpo -c -o hb_subset_fuzzer-main.o `test -f 'main.cc' || echo '$(srcdir)/'`main.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/hb_subset_fuzzer-main.Tpo $(DEPDIR)/hb_subset_fuzzer-main.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='main.cc' object='hb_subset_fuzzer-main.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_subset_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o hb_subset_fuzzer-main.o `test -f 'main.cc' || echo '$(srcdir)/'`main.cc
+
+hb_subset_fuzzer-main.obj: main.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_subset_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT hb_subset_fuzzer-main.obj -MD -MP -MF $(DEPDIR)/hb_subset_fuzzer-main.Tpo -c -o hb_subset_fuzzer-main.obj `if test -f 'main.cc'; then $(CYGPATH_W) 'main.cc'; else $(CYGPATH_W) '$(srcdir)/main.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/hb_subset_fuzzer-main.Tpo $(DEPDIR)/hb_subset_fuzzer-main.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='main.cc' object='hb_subset_fuzzer-main.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_subset_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o hb_subset_fuzzer-main.obj `if test -f 'main.cc'; then $(CYGPATH_W) 'main.cc'; else $(CYGPATH_W) '$(srcdir)/main.cc'; fi`
+
+hb_subset_get_codepoints_fuzzer-hb-subset-get-codepoints-fuzzer.o: hb-subset-get-codepoints-fuzzer.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_subset_get_codepoints_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT hb_subset_get_codepoints_fuzzer-hb-subset-get-codepoints-fuzzer.o -MD -MP -MF $(DEPDIR)/hb_subset_get_codepoints_fuzzer-hb-subset-get-codepoints-fuzzer.Tpo -c -o hb_subset_get_codepoints_fuzzer-hb-subset-get-codepoints-fuzzer.o `test -f 'hb-subset-get-codepoints-fuzzer.cc' || echo '$(srcdir)/'`hb-subset-get-codepoints-fuzzer.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/hb_subset_get_codepoints_fuzzer-hb-subset-get-codepoints-fuzzer.Tpo $(DEPDIR)/hb_subset_get_codepoints_fuzzer-hb-subset-get-codepoints-fuzzer.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-subset-get-codepoints-fuzzer.cc' object='hb_subset_get_codepoints_fuzzer-hb-subset-get-codepoints-fuzzer.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o hb_fuzzer-hb-fuzzer.o `test -f 'hb-fuzzer.cc' || echo '$(srcdir)/'`hb-fuzzer.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_subset_get_codepoints_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o hb_subset_get_codepoints_fuzzer-hb-subset-get-codepoints-fuzzer.o `test -f 'hb-subset-get-codepoints-fuzzer.cc' || echo '$(srcdir)/'`hb-subset-get-codepoints-fuzzer.cc
 
-hb_fuzzer-hb-fuzzer.obj: hb-fuzzer.cc
-@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT hb_fuzzer-hb-fuzzer.obj -MD -MP -MF $(DEPDIR)/hb_fuzzer-hb-fuzzer.Tpo -c -o hb_fuzzer-hb-fuzzer.obj `if test -f 'hb-fuzzer.cc'; then $(CYGPATH_W) 'hb-fuzzer.cc'; else $(CYGPATH_W) '$(srcdir)/hb-fuzzer.cc'; fi`
-@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/hb_fuzzer-hb-fuzzer.Tpo $(DEPDIR)/hb_fuzzer-hb-fuzzer.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-fuzzer.cc' object='hb_fuzzer-hb-fuzzer.obj' libtool=no @AMDEPBACKSLASH@
+hb_subset_get_codepoints_fuzzer-hb-subset-get-codepoints-fuzzer.obj: hb-subset-get-codepoints-fuzzer.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_subset_get_codepoints_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT hb_subset_get_codepoints_fuzzer-hb-subset-get-codepoints-fuzzer.obj -MD -MP -MF $(DEPDIR)/hb_subset_get_codepoints_fuzzer-hb-subset-get-codepoints-fuzzer.Tpo -c -o hb_subset_get_codepoints_fuzzer-hb-subset-get-codepoints-fuzzer.obj `if test -f 'hb-subset-get-codepoints-fuzzer.cc'; then $(CYGPATH_W) 'hb-subset-get-codepoints-fuzzer.cc'; else $(CYGPATH_W) '$(srcdir)/hb-subset-get-codepoints-fuzzer.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/hb_subset_get_codepoints_fuzzer-hb-subset-get-codepoints-fuzzer.Tpo $(DEPDIR)/hb_subset_get_codepoints_fuzzer-hb-subset-get-codepoints-fuzzer.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-subset-get-codepoints-fuzzer.cc' object='hb_subset_get_codepoints_fuzzer-hb-subset-get-codepoints-fuzzer.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o hb_fuzzer-hb-fuzzer.obj `if test -f 'hb-fuzzer.cc'; then $(CYGPATH_W) 'hb-fuzzer.cc'; else $(CYGPATH_W) '$(srcdir)/hb-fuzzer.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_subset_get_codepoints_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o hb_subset_get_codepoints_fuzzer-hb-subset-get-codepoints-fuzzer.obj `if test -f 'hb-subset-get-codepoints-fuzzer.cc'; then $(CYGPATH_W) 'hb-subset-get-codepoints-fuzzer.cc'; else $(CYGPATH_W) '$(srcdir)/hb-subset-get-codepoints-fuzzer.cc'; fi`
 
-hb_fuzzer-main.o: main.cc
-@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT hb_fuzzer-main.o -MD -MP -MF $(DEPDIR)/hb_fuzzer-main.Tpo -c -o hb_fuzzer-main.o `test -f 'main.cc' || echo '$(srcdir)/'`main.cc
-@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/hb_fuzzer-main.Tpo $(DEPDIR)/hb_fuzzer-main.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='main.cc' object='hb_fuzzer-main.o' libtool=no @AMDEPBACKSLASH@
+hb_subset_get_codepoints_fuzzer-main.o: main.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_subset_get_codepoints_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT hb_subset_get_codepoints_fuzzer-main.o -MD -MP -MF $(DEPDIR)/hb_subset_get_codepoints_fuzzer-main.Tpo -c -o hb_subset_get_codepoints_fuzzer-main.o `test -f 'main.cc' || echo '$(srcdir)/'`main.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/hb_subset_get_codepoints_fuzzer-main.Tpo $(DEPDIR)/hb_subset_get_codepoints_fuzzer-main.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='main.cc' object='hb_subset_get_codepoints_fuzzer-main.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o hb_fuzzer-main.o `test -f 'main.cc' || echo '$(srcdir)/'`main.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_subset_get_codepoints_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o hb_subset_get_codepoints_fuzzer-main.o `test -f 'main.cc' || echo '$(srcdir)/'`main.cc
 
-hb_fuzzer-main.obj: main.cc
-@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT hb_fuzzer-main.obj -MD -MP -MF $(DEPDIR)/hb_fuzzer-main.Tpo -c -o hb_fuzzer-main.obj `if test -f 'main.cc'; then $(CYGPATH_W) 'main.cc'; else $(CYGPATH_W) '$(srcdir)/main.cc'; fi`
-@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/hb_fuzzer-main.Tpo $(DEPDIR)/hb_fuzzer-main.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='main.cc' object='hb_fuzzer-main.obj' libtool=no @AMDEPBACKSLASH@
+hb_subset_get_codepoints_fuzzer-main.obj: main.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_subset_get_codepoints_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT hb_subset_get_codepoints_fuzzer-main.obj -MD -MP -MF $(DEPDIR)/hb_subset_get_codepoints_fuzzer-main.Tpo -c -o hb_subset_get_codepoints_fuzzer-main.obj `if test -f 'main.cc'; then $(CYGPATH_W) 'main.cc'; else $(CYGPATH_W) '$(srcdir)/main.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/hb_subset_get_codepoints_fuzzer-main.Tpo $(DEPDIR)/hb_subset_get_codepoints_fuzzer-main.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='main.cc' object='hb_subset_get_codepoints_fuzzer-main.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o hb_fuzzer-main.obj `if test -f 'main.cc'; then $(CYGPATH_W) 'main.cc'; else $(CYGPATH_W) '$(srcdir)/main.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hb_subset_get_codepoints_fuzzer_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o hb_subset_get_codepoints_fuzzer-main.obj `if test -f 'main.cc'; then $(CYGPATH_W) 'main.cc'; else $(CYGPATH_W) '$(srcdir)/main.cc'; fi`
 
 mostlyclean-libtool:
        -rm -f *.lo
@@ -741,9 +860,11 @@ lib:
        @$(MAKE) $(AM_MAKEFLAGS) -C $(top_builddir)/src fuzzing
 
 $(top_builddir)/src/libharfbuzz-fuzzing.la: lib
+$(top_builddir)/src/libharfbuzz-subset-fuzzing.la: lib
 
 check:
-       EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" $(srcdir)/run-fuzzer-tests.py
+       EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" $(srcdir)/run-shape-fuzzer-tests.py
+       EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" $(srcdir)/run-subset-fuzzer-tests.py
 
 -include $(top_srcdir)/git.mk
 
diff --git a/test/fuzzing/hb-subset-fuzzer.cc b/test/fuzzing/hb-subset-fuzzer.cc
new file mode 100644 (file)
index 0000000..28ce921
--- /dev/null
@@ -0,0 +1,75 @@
+#include "hb-fuzzer.hh"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "hb-subset.h"
+
+void trySubset (hb_face_t *face,
+                const hb_codepoint_t text[],
+                int text_length,
+                bool drop_hints,
+                bool drop_ot_layout)
+{
+  hb_subset_profile_t *profile = hb_subset_profile_create ();
+
+  hb_subset_input_t *input = hb_subset_input_create_or_fail ();
+  *hb_subset_input_drop_hints (input) = drop_hints;
+  *hb_subset_input_drop_ot_layout (input) = drop_ot_layout;
+  hb_set_t *codepoints = hb_subset_input_unicode_set (input);
+
+  for (int i = 0; i < text_length; i++)
+  {
+    hb_set_add (codepoints, text[i]);
+  }
+
+  hb_face_t *result = hb_subset (face, profile, input);
+  hb_face_destroy (result);
+
+  hb_subset_input_destroy (input);
+  hb_subset_profile_destroy (profile);
+}
+
+void trySubset (hb_face_t *face,
+                const hb_codepoint_t text[],
+                int text_length)
+{
+  for (unsigned int drop_hints = 0; drop_hints < 2; drop_hints++)
+  {
+    for (unsigned int drop_ot_layout = 0; drop_ot_layout < 2; drop_ot_layout++)
+    {
+      trySubset (face, text, text_length,
+                 (bool) drop_hints, (bool) drop_ot_layout);
+    }
+  }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+  hb_blob_t *blob = hb_blob_create ((const char *)data, size,
+                                    HB_MEMORY_MODE_READONLY, NULL, NULL);
+  hb_face_t *face = hb_face_create (blob, 0);
+
+  const hb_codepoint_t text[] =
+      {
+        'A', 'B', 'C', 'D', 'E', 'X', 'Y', 'Z', '1', '2',
+        '3', '@', '_', '%', '&', ')', '*', '$', '!'
+      };
+
+  trySubset (face, text, sizeof (text) / sizeof (hb_codepoint_t));
+
+  hb_codepoint_t text_from_data[16];
+  if (size > sizeof(text_from_data)) {
+    memcpy(text_from_data,
+           data + size - sizeof(text_from_data),
+           sizeof(text_from_data));
+    unsigned int text_size = sizeof (text_from_data) / sizeof (hb_codepoint_t);
+    trySubset (face, text_from_data, text_size);
+  }
+
+  hb_face_destroy (face);
+  hb_blob_destroy (blob);
+
+  return 0;
+}
diff --git a/test/fuzzing/hb-subset-get-codepoints-fuzzer.cc b/test/fuzzing/hb-subset-get-codepoints-fuzzer.cc
new file mode 100644 (file)
index 0000000..38f338b
--- /dev/null
@@ -0,0 +1,23 @@
+#include "hb-fuzzer.hh"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "hb-subset.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+  hb_blob_t *blob = hb_blob_create ((const char *)data, size,
+                                    HB_MEMORY_MODE_READONLY, NULL, NULL);
+  hb_face_t *face = hb_face_create (blob, 0);
+
+  hb_set_t *output = hb_set_create();
+  hb_subset_get_all_codepoints (face, output);
+
+  hb_set_destroy (output);
+  hb_face_destroy (face);
+  hb_blob_destroy (blob);
+
+  return 0;
+}
diff --git a/test/fuzzing/run-fuzzer-tests.py b/test/fuzzing/run-fuzzer-tests.py
deleted file mode 100755 (executable)
index 9455a4b..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/env python
-
-from __future__ import print_function
-import sys, os, subprocess
-
-srcdir = os.environ.get ("srcdir", ".")
-EXEEXT = os.environ.get ("EXEEXT", "")
-top_builddir = os.environ.get ("top_builddir", ".")
-hb_fuzzer = os.path.join (top_builddir, "hb-fuzzer" + EXEEXT)
-
-if not os.path.exists (hb_fuzzer):
-       if len (sys.argv) == 1 or not os.path.exists (sys.argv[1]):
-               print ("""Failed to find hb-fuzzer binary automatically,
-please provide it as the first argument to the tool""")
-               sys.exit (1)
-
-       hb_fuzzer = sys.argv[1]
-
-print ('hb_fuzzer:', hb_fuzzer)
-fails = 0
-
-for line in open (os.path.join (srcdir, "..", "shaping", "data", "in-house", "tests", "fuzzed.tests")):
-       font = line.split (":")[0]
-
-       p = subprocess.Popen ([hb_fuzzer, os.path.join (srcdir, "..", "shaping", font)])
-
-       if p.wait () != 0:
-               fails = fails + 1
-
-if fails:
-       print ("%i fuzzer related tests failed." % fails)
-       sys.exit (1)
diff --git a/test/fuzzing/run-shape-fuzzer-tests.py b/test/fuzzing/run-shape-fuzzer-tests.py
new file mode 100755 (executable)
index 0000000..fea0b01
--- /dev/null
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+
+from __future__ import print_function, division, absolute_import
+
+import sys, os, subprocess
+
+srcdir = os.environ.get ("srcdir", ".")
+EXEEXT = os.environ.get ("EXEEXT", "")
+top_builddir = os.environ.get ("top_builddir", ".")
+hb_shape_fuzzer = os.path.join (top_builddir, "hb-shape-fuzzer" + EXEEXT)
+
+if not os.path.exists (hb_shape_fuzzer):
+       if len (sys.argv) == 1 or not os.path.exists (sys.argv[1]):
+               print ("""Failed to find hb-shape-fuzzer binary automatically,
+please provide it as the first argument to the tool""")
+               sys.exit (1)
+
+       hb_shape_fuzzer = sys.argv[1]
+
+print ('hb_shape_fuzzer:', hb_shape_fuzzer)
+fails = 0
+
+parent_path = os.path.join (srcdir, "..", "shaping", "data", "in-house", "tests")
+for line in open (os.path.join (parent_path, "fuzzed.tests")):
+       font = line.split (":")[0]
+       font_path = os.path.join (parent_path, font)
+
+       p = subprocess.Popen ([hb_shape_fuzzer, font_path])
+
+       if p.wait () != 0:
+               fails = fails + 1
+
+if fails:
+       print ("%i shape fuzzer related tests failed." % fails)
+       sys.exit (1)
diff --git a/test/fuzzing/run-subset-fuzzer-tests.py b/test/fuzzing/run-subset-fuzzer-tests.py
new file mode 100755 (executable)
index 0000000..0136288
--- /dev/null
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+
+from __future__ import print_function, division, absolute_import
+
+import sys, os, subprocess
+
+srcdir = os.environ.get ("srcdir", ".")
+EXEEXT = os.environ.get ("EXEEXT", "")
+top_builddir = os.environ.get ("top_builddir", ".")
+hb_subset_fuzzer = os.path.join (top_builddir, "hb-subset-fuzzer" + EXEEXT)
+hb_subset_get_codepoints_fuzzer = os.path.join (top_builddir, "hb-subset-get-codepoints-fuzzer" + EXEEXT)
+
+if not os.path.exists (hb_subset_fuzzer):
+        if len (sys.argv) < 2 or not os.path.exists (sys.argv[1]):
+                print ("""Failed to find hb-subset-fuzzer binary automatically,
+please provide it as the first argument to the tool""")
+                sys.exit (1)
+
+        hb_subset_fuzzer = sys.argv[1]
+
+if not os.path.exists (hb_subset_get_codepoints_fuzzer):
+        if len (sys.argv) < 3 or not os.path.exists (sys.argv[2]):
+                print ("""Failed to find hb-subset-get-codepoints-fuzzer binary automatically,
+please provide it as the second argument to the tool""")
+                sys.exit (1)
+
+        hb_subset_get_codepoints_fuzzer = sys.argv[2]
+
+print ('hb_subset_fuzzer:', hb_subset_fuzzer)
+fails = 0
+
+parent_path = os.path.join (srcdir, "..", "subset", "data", "fonts")
+print ("running subset fuzzer against fonts in %s" % parent_path)
+for file in os.listdir (parent_path):
+        path = os.path.join(parent_path, file)
+
+        print ("running subset fuzzer against %s" % path)
+        p = subprocess.Popen ([hb_subset_fuzzer, path])
+
+        if p.wait () != 0:
+                print ("failed for %s" % path)
+                fails = fails + 1
+
+        print ("running subset get codepoints fuzzer against %s" % path)
+        p = subprocess.Popen ([hb_subset_get_codepoints_fuzzer, path])
+
+        if p.wait () != 0:
+                print ("failed for %s" % path)
+                fails = fails + 1
+
+if fails:
+        print ("%i subset fuzzer related tests failed." % fails)
+        sys.exit (1)
index 4bdc5c9..7c2c999 100644 (file)
@@ -3,7 +3,7 @@ if (HB_BUILD_UTILS)
   extract_make_variable (TESTS ${INHOUSE})
   foreach (test IN ITEMS ${TESTS})
     add_test (NAME ${test}
-      COMMAND python run-tests.py $<TARGET_FILE:hb-shape> "data/in-house/${test}"
+      COMMAND "${PYTHON_EXECUTABLE}" run-tests.py $<TARGET_FILE:hb-shape> "data/in-house/${test}"
       WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
   endforeach ()
 
@@ -11,7 +11,7 @@ if (HB_BUILD_UTILS)
   extract_make_variable (TESTS ${TEXTRENDERING})
   foreach (test IN ITEMS ${TESTS})
     add_test (NAME ${test}
-      COMMAND python run-tests.py $<TARGET_FILE:hb-shape> "data/text-rendering-tests/${test}"
+      COMMAND "${PYTHON_EXECUTABLE}" run-tests.py $<TARGET_FILE:hb-shape> "data/text-rendering-tests/${test}"
       WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
   endforeach ()
 endif ()
index ce11b9e..0ddfa3c 100644 (file)
@@ -91,7 +91,8 @@ build_triplet = @build@
 host_triplet = @host@
 subdir = test/shaping
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
+       $(top_srcdir)/m4/ax_code_coverage.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
index 091056c..5839d8c 100644 (file)
@@ -91,7 +91,8 @@ build_triplet = @build@
 host_triplet = @host@
 subdir = test/shaping/data
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
+       $(top_srcdir)/m4/ax_code_coverage.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
index 14a07ae..b9e702a 100644 (file)
@@ -99,16 +99,17 @@ TESTS = tests/arabic-fallback-shaping.tests \
        tests/fallback-positioning.tests tests/fuzzed.tests \
        tests/hangul-jamo.tests tests/hyphens.tests \
        tests/indic-consonant-with-stacker.tests \
-       tests/indic-init.tests tests/indic-joiner-candrabindu.tests \
-       tests/indic-joiners.tests tests/indic-old-spec.tests \
-       tests/indic-pref-blocking.tests \
+       tests/indic-decompose.tests tests/indic-init.tests \
+       tests/indic-joiner-candrabindu.tests tests/indic-joiners.tests \
+       tests/indic-old-spec.tests tests/indic-pref-blocking.tests \
        tests/indic-script-extensions.tests \
        tests/indic-special-cases.tests tests/indic-syllable.tests \
        tests/language-tags.tests tests/ligature-id.tests \
        tests/mark-attachment.tests tests/mark-filtering-sets.tests \
        tests/mongolian-variation-selector.tests \
-       tests/myanmar-syllable.tests tests/spaces.tests \
-       tests/simple.tests tests/tibetan-contractions-1.tests \
+       tests/myanmar-syllable.tests tests/none-directional.tests \
+       tests/spaces.tests tests/simple.tests tests/sinhala.tests \
+       tests/tibetan-contractions-1.tests \
        tests/tibetan-contractions-2.tests tests/tibetan-vowels.tests \
        tests/use.tests tests/use-marchen.tests \
        tests/use-syllable.tests tests/variations-rvrn.tests \
@@ -116,7 +117,8 @@ TESTS = tests/arabic-fallback-shaping.tests \
        $(am__EXEEXT_1)
 subdir = test/shaping/data/in-house
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
+       $(top_srcdir)/m4/ax_code_coverage.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
index 1922fd4..ef16fae 100644 (file)
@@ -16,6 +16,7 @@ TESTS = \
        tests/hangul-jamo.tests \
        tests/hyphens.tests \
        tests/indic-consonant-with-stacker.tests \
+       tests/indic-decompose.tests \
        tests/indic-init.tests \
        tests/indic-joiner-candrabindu.tests \
        tests/indic-joiners.tests \
@@ -30,8 +31,10 @@ TESTS = \
        tests/mark-filtering-sets.tests \
        tests/mongolian-variation-selector.tests \
        tests/myanmar-syllable.tests \
+       tests/none-directional.tests \
        tests/spaces.tests \
        tests/simple.tests \
+       tests/sinhala.tests \
        tests/tibetan-contractions-1.tests \
        tests/tibetan-contractions-2.tests \
        tests/tibetan-vowels.tests \
diff --git a/test/shaping/data/in-house/fonts/5af5361ed4d1e8305780b100e1730cb09132f8d1.ttf b/test/shaping/data/in-house/fonts/5af5361ed4d1e8305780b100e1730cb09132f8d1.ttf
new file mode 100644 (file)
index 0000000..72c5244
Binary files /dev/null and b/test/shaping/data/in-house/fonts/5af5361ed4d1e8305780b100e1730cb09132f8d1.ttf differ
diff --git a/test/shaping/data/in-house/fonts/73e84dac2fc6a2d1bc9250d1414353661088937d.ttf b/test/shaping/data/in-house/fonts/73e84dac2fc6a2d1bc9250d1414353661088937d.ttf
new file mode 100644 (file)
index 0000000..46e7c1d
Binary files /dev/null and b/test/shaping/data/in-house/fonts/73e84dac2fc6a2d1bc9250d1414353661088937d.ttf differ
diff --git a/test/shaping/data/in-house/fonts/932ad5132c2761297c74e9976fe25b08e5ffa10b.ttf b/test/shaping/data/in-house/fonts/932ad5132c2761297c74e9976fe25b08e5ffa10b.ttf
new file mode 100644 (file)
index 0000000..ef20bf8
Binary files /dev/null and b/test/shaping/data/in-house/fonts/932ad5132c2761297c74e9976fe25b08e5ffa10b.ttf differ
diff --git a/test/shaping/data/in-house/tests/indic-decompose.tests b/test/shaping/data/in-house/tests/indic-decompose.tests
new file mode 100644 (file)
index 0000000..ca887be
--- /dev/null
@@ -0,0 +1 @@
+../fonts/932ad5132c2761297c74e9976fe25b08e5ffa10b.ttf:--font-funcs=ot:U+09DC,U+0020,U+09DD,U+0020,U+09A1,U+09BC,U+0020,U+09A2,U+09BC:[bn_rha=0+1024|space=1+1024|bn_yya=2+1024|space=3+1024|bn_dda=4+1024|bn_nukta=4+1024|space=6+1024|bn_ddha=7+1024|bn_nukta=7+1024]
diff --git a/test/shaping/data/in-house/tests/none-directional.tests b/test/shaping/data/in-house/tests/none-directional.tests
new file mode 100644 (file)
index 0000000..e59946d
--- /dev/null
@@ -0,0 +1,3 @@
+../fonts/73e84dac2fc6a2d1bc9250d1414353661088937d.ttf::U+10300,U+10301:[u10300=0+1470|u10301=1+1284]
+../fonts/73e84dac2fc6a2d1bc9250d1414353661088937d.ttf:--direction=ltr:U+10300,U+10301:[u10300=0+1470|u10301=1+1284]
+../fonts/73e84dac2fc6a2d1bc9250d1414353661088937d.ttf:--direction=rtl:U+10300,U+10301:[u10301_r=1+1284|u10300_r=0+1470]
diff --git a/test/shaping/data/in-house/tests/sinhala.tests b/test/shaping/data/in-house/tests/sinhala.tests
new file mode 100644 (file)
index 0000000..9541754
--- /dev/null
@@ -0,0 +1 @@
+../fonts/5af5361ed4d1e8305780b100e1730cb09132f8d1.ttf::U+0DBB,U+0DCA,U+200D,U+0DBA,U+0DCA,U+200D,U+0DBA:[gid8=0+1343|gid4=0+1130]
index 8e95f3f..c164de2 100644 (file)
@@ -102,7 +102,8 @@ TESTS = tests/AVAR-1.tests tests/CFF-1.tests tests/CFF2-1.tests \
        tests/SHKNDA-1.tests $(am__EXEEXT_1)
 subdir = test/shaping/data/text-rendering-tests
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
+       $(top_srcdir)/m4/ax_code_coverage.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
@@ -555,6 +556,8 @@ DISBALED_TESTS = \
        tests/MORX-23.tests \
        tests/MORX-25.tests \
        tests/MORX-26.tests \
+       tests/MORX-27.tests \
+       tests/MORX-28.tests \
        tests/MORX-2.tests \
        tests/MORX-3.tests \
        tests/MORX-4.tests \
index f77c1bc..4be9d05 100644 (file)
@@ -50,6 +50,8 @@ DISBALED_TESTS = \
        tests/MORX-23.tests \
        tests/MORX-25.tests \
        tests/MORX-26.tests \
+       tests/MORX-27.tests \
+       tests/MORX-28.tests \
        tests/MORX-2.tests \
        tests/MORX-3.tests \
        tests/MORX-4.tests \
index 8e5909f..36963e5 100755 (executable)
@@ -1,6 +1,7 @@
 #!/usr/bin/env python
 
-from __future__ import print_function
+from __future__ import print_function, division, absolute_import
+
 import sys
 import xml.etree.ElementTree as ET
 
diff --git a/test/shaping/data/text-rendering-tests/fonts/TestMORXTwentyeight.ttf b/test/shaping/data/text-rendering-tests/fonts/TestMORXTwentyeight.ttf
new file mode 100644 (file)
index 0000000..edabb43
Binary files /dev/null and b/test/shaping/data/text-rendering-tests/fonts/TestMORXTwentyeight.ttf differ
diff --git a/test/shaping/data/text-rendering-tests/fonts/TestMORXTwentyseven.ttf b/test/shaping/data/text-rendering-tests/fonts/TestMORXTwentyseven.ttf
new file mode 100644 (file)
index 0000000..960b4cf
Binary files /dev/null and b/test/shaping/data/text-rendering-tests/fonts/TestMORXTwentyseven.ttf differ
diff --git a/test/shaping/data/text-rendering-tests/fonts/TestShapeKndaV3.ttf b/test/shaping/data/text-rendering-tests/fonts/TestShapeKndaV3.ttf
new file mode 100644 (file)
index 0000000..9f632c3
Binary files /dev/null and b/test/shaping/data/text-rendering-tests/fonts/TestShapeKndaV3.ttf differ
index f7e5943..8348dc2 100644 (file)
@@ -1,6 +1,7 @@
 #!/usr/bin/env python
 
-from __future__ import print_function
+from __future__ import print_function, division, absolute_import
+
 import sys, os, re, difflib, unicodedata, errno, cgi
 from itertools import *
 
@@ -513,7 +514,7 @@ class FileHelpers:
        def open_file_or_stdin (f):
                if f == '-':
                        return sys.stdin
-               return file (f)
+               return open (f)
 
 
 class Manifest:
@@ -532,7 +533,7 @@ class Manifest:
                if os.path.isdir (s):
 
                        try:
-                               m = file (os.path.join (s, "MANIFEST"))
+                               m = open (os.path.join (s, "MANIFEST"))
                                items = [x.strip () for x in m.readlines ()]
                                for f in items:
                                        for p in Manifest.read (os.path.join (s, f)):
index f31d30b..93ebcfc 100755 (executable)
@@ -46,15 +46,22 @@ if test $? != 0; then
        echo "hb-shape failed." >&2
        exit 2
 fi
-glyph_names=`echo "$text" | $hb_shape $options --no-clusters --no-positions "$fontfile" | sed 's/[][]//g; s/|/,/g'`
+glyph_ids=`echo "$text" | $hb_shape $options --no-glyph-names --no-clusters --no-positions "$fontfile" | sed 's/[][]//g; s/|/,/g'`
 
 cp "$fontfile" "$dir/font.ttf"
+echo fonttools subset \
+       --glyph-names \
+       --no-hinting \
+       --layout-features='*' \
+       "$dir/font.ttf" \
+       --gids="$glyph_ids" \
+       --text="$text"
 fonttools subset \
        --glyph-names \
        --no-hinting \
        --layout-features='*' \
        "$dir/font.ttf" \
-       --glyphs="$glyph_names" \
+       --gids="$glyph_ids" \
        --text="$text"
 if ! test -s "$dir/font.subset.ttf"; then
        echo "Subsetter didn't produce nonempty subset font in $dir/font.subset.ttf" >&2
index c65e714..73b61c2 100755 (executable)
@@ -1,6 +1,7 @@
 #!/usr/bin/env python
 
-from __future__ import print_function
+from __future__ import print_function, division, absolute_import
+
 import sys, os, subprocess
 
 
index ea04105..af2b41a 100644 (file)
@@ -3,7 +3,7 @@ if (HB_BUILD_UTILS)
   extract_make_variable (TESTS ${SOURCES})
   foreach (test IN ITEMS ${TESTS})
     add_test (NAME ${test}
-      COMMAND python run-tests.py $<TARGET_FILE:hb-subset> "data/${test}"
+      COMMAND "${PYTHON_EXECUTABLE}" run-tests.py $<TARGET_FILE:hb-subset> "data/${test}"
       WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
     set_property(TEST ${test} PROPERTY SKIP_RETURN_CODE 77)
   endforeach ()
index 76487ce..95ab828 100644 (file)
@@ -91,7 +91,8 @@ build_triplet = @build@
 host_triplet = @host@
 subdir = test/subset
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
+       $(top_srcdir)/m4/ax_code_coverage.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
index 0b00134..0d1b2f0 100644 (file)
@@ -9,6 +9,7 @@ EXTRA_DIST = \
        $(TESTS) \
        expected/basics \
        expected/full-font \
+       expected/japanese \
        fonts \
        profiles \
        $(NULL)
index 1fd8753..0988d97 100644 (file)
@@ -89,11 +89,13 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
-TESTS = tests/basics.tests tests/full-font.tests $(am__EXEEXT_1)
+TESTS = tests/basics.tests tests/full-font.tests tests/japanese.tests \
+       $(am__EXEEXT_1)
 XFAIL_TESTS = $(am__EXEEXT_1)
 subdir = test/subset/data
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
+       $(top_srcdir)/m4/ax_code_coverage.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
@@ -580,6 +582,7 @@ EXTRA_DIST = \
        $(TESTS) \
        expected/basics \
        expected/full-font \
+       expected/japanese \
        fonts \
        profiles \
        $(NULL)
index bc81393..dd1bcfe 100644 (file)
@@ -1,6 +1,7 @@
 TESTS = \
        tests/basics.tests \
        tests/full-font.tests \
+       tests/japanese.tests \
        $(NULL)
 
 XFAIL_TESTS = \
index 02cd7ef..12d9208 100644 (file)
Binary files a/test/subset/data/expected/basics/Roboto-Regular.abc.default.61,62,63.ttf and b/test/subset/data/expected/basics/Roboto-Regular.abc.default.61,62,63.ttf differ
index 4942ad0..1af233f 100644 (file)
Binary files a/test/subset/data/expected/basics/Roboto-Regular.abc.default.61,63.ttf and b/test/subset/data/expected/basics/Roboto-Regular.abc.default.61,63.ttf differ
index 08fe771..a699eea 100644 (file)
Binary files a/test/subset/data/expected/basics/Roboto-Regular.abc.default.61.ttf and b/test/subset/data/expected/basics/Roboto-Regular.abc.default.61.ttf differ
index 8d7e6b2..52706dc 100644 (file)
Binary files a/test/subset/data/expected/basics/Roboto-Regular.abc.default.62.ttf and b/test/subset/data/expected/basics/Roboto-Regular.abc.default.62.ttf differ
index 0f3a934..3de7c77 100644 (file)
Binary files a/test/subset/data/expected/basics/Roboto-Regular.abc.default.63.ttf and b/test/subset/data/expected/basics/Roboto-Regular.abc.default.63.ttf differ
index 70206ad..52dc474 100644 (file)
Binary files a/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61,62,63.ttf and b/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61,62,63.ttf differ
index c74c029..1873672 100644 (file)
Binary files a/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61,63.ttf and b/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61,63.ttf differ
index 8ba816d..128eae0 100644 (file)
Binary files a/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61.ttf and b/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61.ttf differ
index 837438a..122b109 100644 (file)
Binary files a/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.62.ttf and b/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.62.ttf differ
index 311737a..381e97e 100644 (file)
Binary files a/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.63.ttf and b/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.63.ttf differ
index 60e361d..93efe65 100644 (file)
Binary files a/test/subset/data/expected/full-font/Roboto-Regular.default.1FC,21,41,20,62,63.ttf and b/test/subset/data/expected/full-font/Roboto-Regular.default.1FC,21,41,20,62,63.ttf differ
index 1fc430a..d4d26d7 100644 (file)
Binary files a/test/subset/data/expected/full-font/Roboto-Regular.default.61,62,63.ttf and b/test/subset/data/expected/full-font/Roboto-Regular.default.61,62,63.ttf differ
diff --git a/test/subset/data/expected/full-font/Roboto-Regular.default.D7,D8,D9,DA,DE.ttf b/test/subset/data/expected/full-font/Roboto-Regular.default.D7,D8,D9,DA,DE.ttf
new file mode 100644 (file)
index 0000000..7e271f2
Binary files /dev/null and b/test/subset/data/expected/full-font/Roboto-Regular.default.D7,D8,D9,DA,DE.ttf differ
index 98f01e1..99b91bd 100644 (file)
Binary files a/test/subset/data/expected/full-font/Roboto-Regular.drop-hints.1FC,21,41,20,62,63.ttf and b/test/subset/data/expected/full-font/Roboto-Regular.drop-hints.1FC,21,41,20,62,63.ttf differ
index ea212f0..eb94906 100644 (file)
Binary files a/test/subset/data/expected/full-font/Roboto-Regular.drop-hints.61,62,63.ttf and b/test/subset/data/expected/full-font/Roboto-Regular.drop-hints.61,62,63.ttf differ
diff --git a/test/subset/data/expected/full-font/Roboto-Regular.drop-hints.D7,D8,D9,DA,DE.ttf b/test/subset/data/expected/full-font/Roboto-Regular.drop-hints.D7,D8,D9,DA,DE.ttf
new file mode 100644 (file)
index 0000000..ff361ba
Binary files /dev/null and b/test/subset/data/expected/full-font/Roboto-Regular.drop-hints.D7,D8,D9,DA,DE.ttf differ
diff --git a/test/subset/data/expected/japanese/Mplus1p-Regular.default.3042,3044,3046,3048,304A,304B.ttf b/test/subset/data/expected/japanese/Mplus1p-Regular.default.3042,3044,3046,3048,304A,304B.ttf
new file mode 100644 (file)
index 0000000..3398999
Binary files /dev/null and b/test/subset/data/expected/japanese/Mplus1p-Regular.default.3042,3044,3046,3048,304A,304B.ttf differ
diff --git a/test/subset/data/expected/japanese/Mplus1p-Regular.default.3042,3044,3046,73E0,5EA6,8F38.ttf b/test/subset/data/expected/japanese/Mplus1p-Regular.default.3042,3044,3046,73E0,5EA6,8F38.ttf
new file mode 100644 (file)
index 0000000..66b98a6
Binary files /dev/null and b/test/subset/data/expected/japanese/Mplus1p-Regular.default.3042,3044,3046,73E0,5EA6,8F38.ttf differ
diff --git a/test/subset/data/expected/japanese/Mplus1p-Regular.default.61,63,65,6B.ttf b/test/subset/data/expected/japanese/Mplus1p-Regular.default.61,63,65,6B.ttf
new file mode 100644 (file)
index 0000000..22d1bb3
Binary files /dev/null and b/test/subset/data/expected/japanese/Mplus1p-Regular.default.61,63,65,6B.ttf differ
diff --git a/test/subset/data/expected/japanese/Mplus1p-Regular.default.660E,6975,73E0,5EA6,8F38,6E05.ttf b/test/subset/data/expected/japanese/Mplus1p-Regular.default.660E,6975,73E0,5EA6,8F38,6E05.ttf
new file mode 100644 (file)
index 0000000..2804359
Binary files /dev/null and b/test/subset/data/expected/japanese/Mplus1p-Regular.default.660E,6975,73E0,5EA6,8F38,6E05.ttf differ
diff --git a/test/subset/data/expected/japanese/Mplus1p-Regular.default.660E.ttf b/test/subset/data/expected/japanese/Mplus1p-Regular.default.660E.ttf
new file mode 100644 (file)
index 0000000..333ca51
Binary files /dev/null and b/test/subset/data/expected/japanese/Mplus1p-Regular.default.660E.ttf differ
diff --git a/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.3042,3044,3046,3048,304A,304B.ttf b/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.3042,3044,3046,3048,304A,304B.ttf
new file mode 100644 (file)
index 0000000..c84b20c
Binary files /dev/null and b/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.3042,3044,3046,3048,304A,304B.ttf differ
diff --git a/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.3042,3044,3046,73E0,5EA6,8F38.ttf b/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.3042,3044,3046,73E0,5EA6,8F38.ttf
new file mode 100644 (file)
index 0000000..e757b9e
Binary files /dev/null and b/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.3042,3044,3046,73E0,5EA6,8F38.ttf differ
diff --git a/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.61,63,65,6B.ttf b/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.61,63,65,6B.ttf
new file mode 100644 (file)
index 0000000..e869ff1
Binary files /dev/null and b/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.61,63,65,6B.ttf differ
diff --git a/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.ttf b/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.ttf
new file mode 100644 (file)
index 0000000..ed4ed4c
Binary files /dev/null and b/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.ttf differ
diff --git a/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.660E.ttf b/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.660E.ttf
new file mode 100644 (file)
index 0000000..cb50238
Binary files /dev/null and b/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.660E.ttf differ
diff --git a/test/subset/data/fonts/Mplus1p-Regular.ttf b/test/subset/data/fonts/Mplus1p-Regular.ttf
new file mode 100644 (file)
index 0000000..f89a28e
Binary files /dev/null and b/test/subset/data/fonts/Mplus1p-Regular.ttf differ
diff --git a/test/subset/data/tests/japanese.tests b/test/subset/data/tests/japanese.tests
new file mode 100644 (file)
index 0000000..5a04380
--- /dev/null
@@ -0,0 +1,16 @@
+FONTS:
+Mplus1p-Regular.ttf
+
+PROFILES:
+default.txt
+drop-hints.txt
+
+SUBSETS:
+明
+acek
+明極珠度輸清
+あいうえおか
+あいう珠度輸
+
+
+
index 56cd7b4..1cd1a19 100755 (executable)
@@ -3,7 +3,7 @@
 # Runs a subsetting test suite. Compares the results of subsetting via harfbuz
 # to subsetting via fonttools.
 
-from __future__ import print_function
+from __future__ import print_function, division, absolute_import
 
 import io
 from difflib import unified_diff
@@ -19,9 +19,9 @@ from subset_test_suite import SubsetTestSuite
 def cmd(command):
        p = subprocess.Popen (
                command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-       p.wait ()
-       print (p.stderr.read (), end="") # file=sys.stderr
-       return p.stdout.read (), p.returncode
+       (stdoutdata, stderrdata) = p.communicate()
+       print (stderrdata, end="") # file=sys.stderr
+       return stdoutdata, p.returncode
 
 def read_binary(file_path):
        with open(file_path, 'rb') as f:
@@ -60,6 +60,7 @@ def run_test(test, should_check_ots):
        if return_code:
                return fail_test(test, cli_args, "ttx (actual) returned %d" % (return_code))
 
+       print ("stripping checksums.")
        expected_ttx = strip_check_sum (expected_ttx)
        actual_ttx = strip_check_sum (actual_ttx)
 
@@ -77,7 +78,9 @@ def run_test(test, should_check_ots):
        return 0
 
 def run_ttx(file):
+       print ("ttx %s" % file)
        cli_args = ["ttx",
+                   "-q",
                    "-o-",
                    file]
        return cmd(cli_args)
@@ -85,9 +88,9 @@ def run_ttx(file):
 def strip_check_sum (ttx_string):
        return re.sub ('checkSumAdjustment value=["]0x([0-9a-fA-F])+["]',
                       'checkSumAdjustment value="0x00000000"',
-                      ttx_string, count=1)
+                      ttx_string.decode (), count=1)
 
-def has_ots():
+def has_ots ():
        _, returncode = cmd(["which", "ots-sanitize"])
        if returncode:
                print("OTS is not present, skipping all ots checks.")
index 21092cf..86678cf 100644 (file)
@@ -96,7 +96,8 @@ bin_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3)
 @HAVE_GLIB_TRUE@@HAVE_OT_TRUE@am__append_3 = hb-ot-shape-closure
 subdir = util
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
+       $(top_srcdir)/m4/ax_code_coverage.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
index db7115c..24dc41f 100644 (file)
@@ -65,8 +65,6 @@ fail (hb_bool_t suggest_help, const char *format, ...)
 }
 
 
-hb_bool_t debug = false;
-
 static gchar *
 shapers_to_string (void)
 {
@@ -107,7 +105,6 @@ option_parser_t::add_main_options (void)
   {
     {"version",                0, G_OPTION_FLAG_NO_ARG,
                              G_OPTION_ARG_CALLBACK,    (gpointer) &show_version,       "Show version numbers",                 nullptr},
-    {"debug",          0, 0, G_OPTION_ARG_NONE,        &debug,                         "Free all resources before exit",       nullptr},
     {nullptr}
   };
   g_option_context_add_main_entries (context, entries, nullptr);
@@ -192,11 +189,29 @@ static gboolean
 parse_shapers (const char *name G_GNUC_UNUSED,
               const char *arg,
               gpointer    data,
-              GError    **error G_GNUC_UNUSED)
+              GError    **error)
 {
   shape_options_t *shape_opts = (shape_options_t *) data;
+  char **shapers = g_strsplit (arg, ",", 0);
+
+  for (char **shaper = shapers; *shaper; shaper++) {
+    bool found = false;
+    for (const char **hb_shaper = hb_shape_list_shapers (); *hb_shaper; hb_shaper++) {
+      if (strcmp (*shaper, *hb_shaper) == 0) {
+        found = true;
+        break;
+      }
+    }
+    if (!found) {
+      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+                  "Unknown or unsupported shaper: %s", *shaper);
+      g_strfreev (shapers);
+      return false;
+    }
+  }
+
   g_strfreev (shape_opts->shapers);
-  shape_opts->shapers = g_strsplit (arg, ",", 0);
+  shape_opts->shapers = shapers;
   return true;
 }
 
@@ -340,8 +355,10 @@ parse_unicodes (const char *name G_GNUC_UNUSED,
 
   while (s && *s)
   {
-    while (*s && strchr ("<+>{},;&#\\xXuUnNiI\n\t", *s))
+    while (*s && strchr ("<+>{},;&#\\xXuUnNiI\n\t\v\f\r ", *s))
       s++;
+    if (!*s)
+      break;
 
     errno = 0;
     hb_codepoint_t u = strtoul (s, &p, 16);
@@ -629,74 +646,29 @@ font_options_t::get_font (void) const
   hb_blob_t *blob = nullptr;
 
   /* Create the blob */
-  {
-    char *font_data;
-    unsigned int len = 0;
-    hb_destroy_func_t destroy;
-    void *user_data;
-    hb_memory_mode_t mm;
-
-    /* This is a hell of a lot of code for just reading a file! */
-    if (!font_file)
-      fail (true, "No font file set");
-
-    if (0 == strcmp (font_file, "-")) {
-      /* read it */
-      GString *gs = g_string_new (nullptr);
-      char buf[BUFSIZ];
+  if (!font_file)
+    fail (true, "No font file set");
+
+  if (0 == strcmp (font_file, "-")) {
+    /* read it */
+    GString *gs = g_string_new (nullptr);
+    char buf[BUFSIZ];
 #if defined(_WIN32) || defined(__CYGWIN__)
-      setmode (fileno (stdin), O_BINARY);
+    setmode (fileno (stdin), O_BINARY);
 #endif
-      while (!feof (stdin)) {
-       size_t ret = fread (buf, 1, sizeof (buf), stdin);
-       if (ferror (stdin))
-         fail (false, "Failed reading font from standard input: %s",
-               strerror (errno));
-       g_string_append_len (gs, buf, ret);
-      }
-      len = gs->len;
-      font_data = g_string_free (gs, false);
-      user_data = font_data;
-      destroy = (hb_destroy_func_t) g_free;
-      mm = HB_MEMORY_MODE_WRITABLE;
-    } else {
-      GError *error = nullptr;
-      GMappedFile *mf = g_mapped_file_new (font_file, false, &error);
-      if (mf) {
-       font_data = g_mapped_file_get_contents (mf);
-       len = g_mapped_file_get_length (mf);
-       if (len) {
-         destroy = (hb_destroy_func_t) g_mapped_file_unref;
-         user_data = (void *) mf;
-         mm = HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE;
-       } else
-         g_mapped_file_unref (mf);
-      } else {
-       fail (false, "%s", error->message);
-       //g_error_free (error);
-      }
-      if (!len) {
-       /* GMappedFile is buggy, it doesn't fail if file isn't regular.
-        * Try reading.
-        * https://bugzilla.gnome.org/show_bug.cgi?id=659212 */
-        GError *error = nullptr;
-       gsize l;
-       if (g_file_get_contents (font_file, &font_data, &l, &error)) {
-         len = l;
-         destroy = (hb_destroy_func_t) g_free;
-         user_data = (void *) font_data;
-         mm = HB_MEMORY_MODE_WRITABLE;
-       } else {
-         fail (false, "%s", error->message);
-         //g_error_free (error);
-       }
-      }
+    while (!feof (stdin)) {
+      size_t ret = fread (buf, 1, sizeof (buf), stdin);
+      if (ferror (stdin))
+       fail (false, "Failed reading font from standard input: %s",
+             strerror (errno));
+      g_string_append_len (gs, buf, ret);
     }
-
-    if (debug)
-      mm = HB_MEMORY_MODE_DUPLICATE;
-
-    blob = hb_blob_create (font_data, len, mm, user_data, destroy);
+    char *font_data = g_string_free (gs, false);
+    blob = hb_blob_create (font_data, gs->len,
+                          HB_MEMORY_MODE_WRITABLE, font_data,
+                          (hb_destroy_func_t) g_free);
+  } else {
+    blob = hb_blob_create_from_file (font_file);
   }
 
   /* Create the face */
@@ -803,12 +775,6 @@ text_options_t::get_line (unsigned int *len)
     gs = g_string_new (nullptr);
   }
 
-#ifdef HAVE_SETLINEBUF
-  setlinebuf (fp);
-#else
-  setvbuf(fp, NULL, _IOLBF, BUFSIZ);
-#endif
-
   g_string_set_size (gs, 0);
   char buf[BUFSIZ];
   while (fgets (buf, sizeof (buf), fp)) {
@@ -846,12 +812,6 @@ output_options_t::get_file_handle (void)
     fail (false, "Cannot open output file `%s': %s",
          g_filename_display_name (output_file), strerror (errno));
 
-#ifdef HAVE_SETLINEBUF
-  setlinebuf (fp);
-#else
-  setvbuf(fp, NULL, _IOLBF, BUFSIZ);
-#endif
-
   return fp;
 }
 
index 467350a..8dfc842 100644 (file)
 #include <glib.h>
 #include <glib/gprintf.h>
 
-#if !GLIB_CHECK_VERSION (2, 22, 0)
-# define g_mapped_file_unref g_mapped_file_free
-#endif
-
 void fail (hb_bool_t suggest_help, const char *format, ...) G_GNUC_NORETURN G_GNUC_PRINTF (2, 3);
 
-extern hb_bool_t debug;
-
 struct option_group_t
 {
   virtual void add_options (struct option_parser_t *parser) = 0;
index f4f2bc5..e8e334b 100644 (file)
@@ -49,7 +49,7 @@ view_cairo_t::render (const font_options_t *font_opts)
   double leading = font_height + view_options.line_space;
 
   /* Calculate surface size. */
-  double w, h;
+  double w = 0, h = 0;
   (vertical ? w : h) = (int) lines->len * leading - view_options.line_space;
   (vertical ? h : w) = 0;
   for (unsigned int i = 0; i < lines->len; i++) {
index d28c3cd..00df68c 100644 (file)
@@ -40,8 +40,7 @@ struct view_cairo_t
                 direction (HB_DIRECTION_INVALID),
                 lines (0), scale_bits (0) {}
   ~view_cairo_t (void) {
-    if (debug)
-      cairo_debug_reset_static_data ();
+    cairo_debug_reset_static_data ();
   }
 
   void init (hb_buffer_t *buffer, const font_options_t *font_opts)