diff options
Diffstat (limited to 'Build')
144 files changed, 17075 insertions, 5083 deletions
diff --git a/Build/source/libs/README b/Build/source/libs/README index 24ae054bda6..60bbe4980cd 100644 --- a/Build/source/libs/README +++ b/Build/source/libs/README @@ -25,7 +25,7 @@ graphite2 1.3.12 - checked 16aug18 http://sourceforge.net/projects/silgraphite/files/graphite2/ (requires C++11) -harfbuzz 1.8.8 - checked 15aug18 +harfbuzz 2.0.0 - checked 20oct18 http://www.freedesktop.org/software/harfbuzz/release/ icu 61.1 - checked 29mar18 diff --git a/Build/source/libs/harfbuzz/ChangeLog b/Build/source/libs/harfbuzz/ChangeLog index fd5a6cfd927..83bb0c0ce43 100644 --- a/Build/source/libs/harfbuzz/ChangeLog +++ b/Build/source/libs/harfbuzz/ChangeLog @@ -1,3 +1,8 @@ +2018-10-20 Akira Kakuto <kakuto@fuk.kindai.ac.jp> + + Import harfbuzz-2.0.0. + * version.ac, Makefile.am, include/Makefile.am: Adjusted. + 2018-10-20 Khaled Hosny <khaledhosny@eglug.org> * configure.ac: Set HAVE_ICU_BUILTIN. diff --git a/Build/source/libs/harfbuzz/Makefile.am b/Build/source/libs/harfbuzz/Makefile.am index 2242e91b854..a8d719efc14 100644 --- a/Build/source/libs/harfbuzz/Makefile.am +++ b/Build/source/libs/harfbuzz/Makefile.am @@ -37,6 +37,7 @@ libharfbuzz_a_SOURCES = \ @HARFBUZZ_TREE@/src/hb-buffer.hh \ @HARFBUZZ_TREE@/src/hb-buffer-serialize.cc \ @HARFBUZZ_TREE@/src/hb-buffer.cc \ + @HARFBUZZ_TREE@/src/hb-cache.hh \ @HARFBUZZ_TREE@/src/hb-common.cc \ @HARFBUZZ_TREE@/src/hb-debug.hh \ @HARFBUZZ_TREE@/src/hb-dsalgs.hh \ @@ -70,6 +71,7 @@ libharfbuzz_a_SOURCES = \ @HARFBUZZ_TREE@/src/hb-ot-post-macroman.hh \ @HARFBUZZ_TREE@/src/hb-ot-post-table.hh \ @HARFBUZZ_TREE@/src/hb-ot-tag.cc \ + @HARFBUZZ_TREE@/src/hb-ot-tag-table.hh \ @HARFBUZZ_TREE@/src/hb-set-digest.hh \ @HARFBUZZ_TREE@/src/hb-set.hh \ @HARFBUZZ_TREE@/src/hb-set.cc \ @@ -86,6 +88,7 @@ libharfbuzz_a_SOURCES = \ @HARFBUZZ_TREE@/src/hb-subset.hh \ @HARFBUZZ_TREE@/src/hb-unicode.hh \ @HARFBUZZ_TREE@/src/hb-unicode.cc \ + @HARFBUZZ_TREE@/src/hb-unicode-emoji-table.hh \ @HARFBUZZ_TREE@/src/hb-vector.hh \ @HARFBUZZ_TREE@/src/hb-utf.hh \ @HARFBUZZ_TREE@/src/hb-warning.cc \ @@ -142,7 +145,6 @@ libharfbuzz_a_SOURCES += \ @HARFBUZZ_TREE@/src/hb-ot-shape-complex-myanmar.hh \ @HARFBUZZ_TREE@/src/hb-ot-shape-complex-myanmar.cc \ @HARFBUZZ_TREE@/src/hb-ot-shape-complex-thai.cc \ - @HARFBUZZ_TREE@/src/hb-ot-shape-complex-tibetan.cc \ @HARFBUZZ_TREE@/src/hb-ot-shape-complex-use.cc \ @HARFBUZZ_TREE@/src/hb-ot-shape-complex.hh \ @HARFBUZZ_TREE@/src/hb-ot-shape-complex-use-table.cc \ diff --git a/Build/source/libs/harfbuzz/Makefile.in b/Build/source/libs/harfbuzz/Makefile.in index 287c4eddabf..3d61110b9fe 100644 --- a/Build/source/libs/harfbuzz/Makefile.in +++ b/Build/source/libs/harfbuzz/Makefile.in @@ -153,7 +153,6 @@ am_libharfbuzz_a_OBJECTS = @HARFBUZZ_TREE@/src/hb-blob.$(OBJEXT) \ @HARFBUZZ_TREE@/src/hb-ot-shape-complex-khmer.$(OBJEXT) \ @HARFBUZZ_TREE@/src/hb-ot-shape-complex-myanmar.$(OBJEXT) \ @HARFBUZZ_TREE@/src/hb-ot-shape-complex-thai.$(OBJEXT) \ - @HARFBUZZ_TREE@/src/hb-ot-shape-complex-tibetan.$(OBJEXT) \ @HARFBUZZ_TREE@/src/hb-ot-shape-complex-use.$(OBJEXT) \ @HARFBUZZ_TREE@/src/hb-ot-shape-complex-use-table.$(OBJEXT) \ @HARFBUZZ_TREE@/src/hb-ot-shape-normalize.$(OBJEXT) \ @@ -212,7 +211,6 @@ am__depfiles_remade = ./$(DEPDIR)/hbtest-dummy.Po \ @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-khmer.Po \ @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-myanmar.Po \ @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-thai.Po \ - @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-tibetan.Po \ @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-use-table.Po \ @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-use.Po \ @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-fallback.Po \ @@ -703,6 +701,7 @@ libharfbuzz_a_SOURCES = @HARFBUZZ_TREE@/src/hb-atomic.hh \ @HARFBUZZ_TREE@/src/hb-buffer.hh \ @HARFBUZZ_TREE@/src/hb-buffer-serialize.cc \ @HARFBUZZ_TREE@/src/hb-buffer.cc \ + @HARFBUZZ_TREE@/src/hb-cache.hh \ @HARFBUZZ_TREE@/src/hb-common.cc \ @HARFBUZZ_TREE@/src/hb-debug.hh \ @HARFBUZZ_TREE@/src/hb-dsalgs.hh \ @@ -732,6 +731,7 @@ libharfbuzz_a_SOURCES = @HARFBUZZ_TREE@/src/hb-atomic.hh \ @HARFBUZZ_TREE@/src/hb-ot-post-macroman.hh \ @HARFBUZZ_TREE@/src/hb-ot-post-table.hh \ @HARFBUZZ_TREE@/src/hb-ot-tag.cc \ + @HARFBUZZ_TREE@/src/hb-ot-tag-table.hh \ @HARFBUZZ_TREE@/src/hb-set-digest.hh \ @HARFBUZZ_TREE@/src/hb-set.hh @HARFBUZZ_TREE@/src/hb-set.cc \ @HARFBUZZ_TREE@/src/hb-shape.cc \ @@ -747,6 +747,7 @@ libharfbuzz_a_SOURCES = @HARFBUZZ_TREE@/src/hb-atomic.hh \ @HARFBUZZ_TREE@/src/hb-subset.hh \ @HARFBUZZ_TREE@/src/hb-unicode.hh \ @HARFBUZZ_TREE@/src/hb-unicode.cc \ + @HARFBUZZ_TREE@/src/hb-unicode-emoji-table.hh \ @HARFBUZZ_TREE@/src/hb-vector.hh @HARFBUZZ_TREE@/src/hb-utf.hh \ @HARFBUZZ_TREE@/src/hb-warning.cc \ @HARFBUZZ_TREE@/src/hb-buffer-deserialize-json.hh \ @@ -798,7 +799,6 @@ libharfbuzz_a_SOURCES = @HARFBUZZ_TREE@/src/hb-atomic.hh \ @HARFBUZZ_TREE@/src/hb-ot-shape-complex-myanmar.hh \ @HARFBUZZ_TREE@/src/hb-ot-shape-complex-myanmar.cc \ @HARFBUZZ_TREE@/src/hb-ot-shape-complex-thai.cc \ - @HARFBUZZ_TREE@/src/hb-ot-shape-complex-tibetan.cc \ @HARFBUZZ_TREE@/src/hb-ot-shape-complex-use.cc \ @HARFBUZZ_TREE@/src/hb-ot-shape-complex.hh \ @HARFBUZZ_TREE@/src/hb-ot-shape-complex-use-table.cc \ @@ -1003,9 +1003,6 @@ clean-noinstLIBRARIES: @HARFBUZZ_TREE@/src/hb-ot-shape-complex-thai.$(OBJEXT): \ @HARFBUZZ_TREE@/src/$(am__dirstamp) \ @HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@HARFBUZZ_TREE@/src/hb-ot-shape-complex-tibetan.$(OBJEXT): \ - @HARFBUZZ_TREE@/src/$(am__dirstamp) \ - @HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp) @HARFBUZZ_TREE@/src/hb-ot-shape-complex-use.$(OBJEXT): \ @HARFBUZZ_TREE@/src/$(am__dirstamp) \ @HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp) @@ -1072,7 +1069,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-khmer.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-myanmar.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-thai.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-tibetan.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-use-table.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-use.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-fallback.Po@am__quote@ # am--include-marker @@ -1706,7 +1702,6 @@ distclean: distclean-recursive -rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-khmer.Po -rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-myanmar.Po -rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-thai.Po - -rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-tibetan.Po -rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-use-table.Po -rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-use.Po -rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-fallback.Po @@ -1796,7 +1791,6 @@ maintainer-clean: maintainer-clean-recursive -rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-khmer.Po -rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-myanmar.Po -rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-thai.Po - -rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-tibetan.Po -rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-use-table.Po -rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-use.Po -rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-fallback.Po diff --git a/Build/source/libs/harfbuzz/TLpatches/ChangeLog b/Build/source/libs/harfbuzz/TLpatches/ChangeLog index 488f19d7882..9878ab40ff1 100644 --- a/Build/source/libs/harfbuzz/TLpatches/ChangeLog +++ b/Build/source/libs/harfbuzz/TLpatches/ChangeLog @@ -1,3 +1,8 @@ +2018-10-20 Akira Kakuto <kakuto@fuk.kindai.ac.jp> + + Imported harfbuzz-2.0.0 source tree from: + http://www.freedesktop.org/software/harfbuzz/release/ + 2018-09-11 Akira Kakuto <kakuto@fuk.kindai.ac.jp> Imported harfbuzz-1.9.0 source tree from: diff --git a/Build/source/libs/harfbuzz/TLpatches/TL-Changes b/Build/source/libs/harfbuzz/TLpatches/TL-Changes index dae72960cfe..e4a2d8d755b 100644 --- a/Build/source/libs/harfbuzz/TLpatches/TL-Changes +++ b/Build/source/libs/harfbuzz/TLpatches/TL-Changes @@ -1,4 +1,4 @@ -Changes applied to the harfbuzz-1.9.0/ tree as obtained from: +Changes applied to the harfbuzz-2.0.0/ tree as obtained from: http://www.freedesktop.org/software/harfbuzz/release/ Removed: diff --git a/Build/source/libs/harfbuzz/configure b/Build/source/libs/harfbuzz/configure index 75485dc763b..b81652fc50b 100755 --- a/Build/source/libs/harfbuzz/configure +++ b/Build/source/libs/harfbuzz/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for harfbuzz (TeX Live) 1.9.0. +# Generated by GNU Autoconf 2.69 for harfbuzz (TeX Live) 2.0.0. # # Report bugs to <tex-k@tug.org>. # @@ -580,8 +580,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='harfbuzz (TeX Live)' PACKAGE_TARNAME='harfbuzz--tex-live-' -PACKAGE_VERSION='1.9.0' -PACKAGE_STRING='harfbuzz (TeX Live) 1.9.0' +PACKAGE_VERSION='2.0.0' +PACKAGE_STRING='harfbuzz (TeX Live) 2.0.0' PACKAGE_BUGREPORT='tex-k@tug.org' PACKAGE_URL='' @@ -1317,7 +1317,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures harfbuzz (TeX Live) 1.9.0 to adapt to many kinds of systems. +\`configure' configures harfbuzz (TeX Live) 2.0.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1388,7 +1388,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of harfbuzz (TeX Live) 1.9.0:";; + short | recursive ) echo "Configuration of harfbuzz (TeX Live) 2.0.0:";; esac cat <<\_ACEOF @@ -1495,7 +1495,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -harfbuzz (TeX Live) configure 1.9.0 +harfbuzz (TeX Live) configure 2.0.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2131,7 +2131,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by harfbuzz (TeX Live) $as_me 1.9.0, which was +It was created by harfbuzz (TeX Live) $as_me 2.0.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -4054,7 +4054,7 @@ fi # Define the identity of the package. PACKAGE='harfbuzz--tex-live-' - VERSION='1.9.0' + VERSION='2.0.0' # Some tools Automake needs. @@ -4246,10 +4246,10 @@ WARNING_CFLAGS=$kpse_cv_warning_cflags -HB_VERSION_MAJOR=1 -HB_VERSION_MINOR=9 +HB_VERSION_MAJOR=2 +HB_VERSION_MINOR=0 HB_VERSION_MICRO=0 -HB_VERSION=1.9.0 +HB_VERSION=2.0.0 ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -8143,7 +8143,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by harfbuzz (TeX Live) $as_me 1.9.0, which was +This file was extended by harfbuzz (TeX Live) $as_me 2.0.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -8209,7 +8209,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -harfbuzz (TeX Live) config.status 1.9.0 +harfbuzz (TeX Live) config.status 2.0.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/AUTHORS b/Build/source/libs/harfbuzz/harfbuzz-src/AUTHORS index 81cdc4cf37f..0763761bbf8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/AUTHORS +++ b/Build/source/libs/harfbuzz/harfbuzz-src/AUTHORS @@ -1,9 +1,11 @@ Behdad Esfahbod -Simon Hausmann -Martin Hosken +David Turner +Ebrahim Byagowi Jonathan Kew +Khaled Hosny Lars Knoll -Werner Lemberg -Roozbeh Pournader +Martin Hosken Owen Taylor -David Turner +Roozbeh Pournader +Simon Hausmann +Werner Lemberg diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt b/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt index e881dbd1a4d..760883fdae8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt +++ b/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt @@ -82,12 +82,21 @@ if (HB_CHECK) endif () endif () +set (HB_DISABLE_SUBSET OFF) +set (HB_DISABLE_TESTS OFF) +option(HB_IOS "Apply iOS specific build flags" OFF) +if (HB_IOS) + # We should fix their issue and enable them + set (HB_DISABLE_SUBSET ON) + set (HB_DISABLE_TESTS ON) + set (HB_HAVE_CORETEXT OFF) +endif () + include_directories(AFTER ${PROJECT_SOURCE_DIR}/src ${PROJECT_BINARY_DIR}/src ) -add_definitions(-DHAVE_OT) add_definitions(-DHAVE_FALLBACK) # We need PYTHON_EXECUTABLE to be set for running the tests... @@ -359,12 +368,32 @@ if (APPLE AND HB_HAVE_CORETEXT) list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-coretext.cc) list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-coretext.h) - find_library(APPLICATION_SERVICES_FRAMEWORK ApplicationServices) - if (APPLICATION_SERVICES_FRAMEWORK) - list(APPEND THIRD_PARTY_LIBS ${APPLICATION_SERVICES_FRAMEWORK}) - endif (APPLICATION_SERVICES_FRAMEWORK) + if (HB_IOS) + find_library(COREFOUNDATION CoreFoundation) + if (COREFOUNDATION) + list(APPEND THIRD_PARTY_LIBS ${COREFOUNDATION}) + endif () + mark_as_advanced(COREFOUNDATION) - mark_as_advanced(APPLICATION_SERVICES_FRAMEWORK) + find_library(CORETEXT CoreText) + if (CORETEXT) + list(APPEND THIRD_PARTY_LIBS ${CORETEXT}) + endif () + mark_as_advanced(CORETEXT) + + find_library(COREGRAPHICS CoreGraphics) + if (COREGRAPHICS) + list(APPEND THIRD_PARTY_LIBS ${COREGRAPHICS}) + endif () + mark_as_advanced(COREGRAPHICS) + else () + find_library(APPLICATION_SERVICES_FRAMEWORK ApplicationServices) + if (APPLICATION_SERVICES_FRAMEWORK) + list(APPEND THIRD_PARTY_LIBS ${APPLICATION_SERVICES_FRAMEWORK}) + endif () + + mark_as_advanced(APPLICATION_SERVICES_FRAMEWORK) + endif () endif () if (WIN32 AND HB_HAVE_UNISCRIBE) @@ -527,12 +556,14 @@ add_library(harfbuzz ${project_sources} ${project_extra_sources} ${project_heade target_link_libraries(harfbuzz ${THIRD_PARTY_LIBS}) ## Define harfbuzz-subset library -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 (NOT HB_DISABLE_SUBSET) + add_library(harfbuzz-subset ${subset_project_sources} ${subset_project_headers}) + add_dependencies(harfbuzz-subset harfbuzz) + target_link_libraries(harfbuzz-subset harfbuzz ${THIRD_PARTY_LIBS}) -if (BUILD_SHARED_LIBS) - set_target_properties(harfbuzz harfbuzz-subset PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE) + if (BUILD_SHARED_LIBS) + set_target_properties(harfbuzz harfbuzz-subset PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE) + endif () endif () if (UNIX OR MINGW) @@ -549,7 +580,9 @@ if (UNIX OR MINGW) set (CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "m") # libm set (CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "") set_target_properties(harfbuzz PROPERTIES LINKER_LANGUAGE C) - set_target_properties(harfbuzz-subset PROPERTIES LINKER_LANGUAGE C) + if (NOT HB_DISABLE_SUBSET) + set_target_properties(harfbuzz-subset PROPERTIES LINKER_LANGUAGE C) + endif () # No threadsafe statics as we do it ourselves set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-threadsafe-statics") @@ -574,7 +607,7 @@ if (HB_HAVE_GOBJECT) endif () if (BUILD_SHARED_LIBS AND WIN32 AND NOT MINGW) - add_definitions("-DHB_EXTERN=__declspec(dllexport) extern") + add_definitions("-DHB_DLL_EXPORT") endif () # On Windows, g-ir-scanner requires a DLL build in order for it to work @@ -761,12 +794,22 @@ endif () if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL) install(TARGETS harfbuzz + EXPORT harfbuzzConfig ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} FRAMEWORK DESTINATION Library/Frameworks ) + install(EXPORT harfbuzzConfig + NAMESPACE harfbuzz:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/harfbuzz + ) if (HB_BUILD_UTILS) + if (WIN32 AND BUILD_SHARED_LIBS) + install(TARGETS harfbuzz-subset + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ) + endif () install(TARGETS hb-view RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) @@ -818,51 +861,53 @@ if (UNIX AND CMAKE_GENERATOR STREQUAL "Ninja") endif () -## src/ executables -foreach (prog main test test-would-substitute test-size-params test-buffer-serialize hb-ot-tag test-unicode-ranges) - set (prog_name ${prog}) - if (${prog_name} STREQUAL "test") - # test can not be used as a valid executable name on cmake, lets special case it - set (prog_name test-test) - endif () - add_executable(${prog_name} ${PROJECT_SOURCE_DIR}/src/${prog}.cc) - target_link_libraries(${prog_name} harfbuzz ${THIRD_PARTY_LIBS}) -endforeach () -set_target_properties(hb-ot-tag PROPERTIES COMPILE_FLAGS "-DMAIN") - -## Tests -if (UNIX OR MINGW) - if (BUILD_SHARED_LIBS) - # generate harfbuzz.def after build completion - add_custom_command(TARGET harfbuzz POST_BUILD - COMMAND "${PYTHON_EXECUTABLE}" ${PROJECT_SOURCE_DIR}/src/gen-def.py ${PROJECT_BINARY_DIR}/harfbuzz.def ${project_headers} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src) - - add_test(NAME check-static-inits.sh - COMMAND ${PROJECT_SOURCE_DIR}/src/check-static-inits.sh - WORKING_DIRECTORY ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/harfbuzz.dir/src # ugly hack - ) - add_test(NAME check-libstdc++.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-libstdc++.sh) - add_test(NAME check-symbols.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-symbols.sh) +if (NOT HB_DISABLE_TESTS) + ## src/ executables + foreach (prog main test test-would-substitute test-size-params test-buffer-serialize hb-ot-tag test-unicode-ranges) + set (prog_name ${prog}) + if (${prog_name} STREQUAL "test") + # test can not be used as a valid executable name on cmake, lets special case it + set (prog_name test-test) + endif () + add_executable(${prog_name} ${PROJECT_SOURCE_DIR}/src/${prog}.cc) + target_link_libraries(${prog_name} harfbuzz ${THIRD_PARTY_LIBS}) + endforeach () + set_target_properties(hb-ot-tag PROPERTIES COMPILE_FLAGS "-DMAIN") + + ## Tests + if (UNIX OR MINGW) + if (BUILD_SHARED_LIBS) + # generate harfbuzz.def after build completion + add_custom_command(TARGET harfbuzz POST_BUILD + COMMAND "${PYTHON_EXECUTABLE}" ${PROJECT_SOURCE_DIR}/src/gen-def.py ${PROJECT_BINARY_DIR}/harfbuzz.def ${project_headers} + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src) + + add_test(NAME check-static-inits.sh + COMMAND ${PROJECT_SOURCE_DIR}/src/check-static-inits.sh + WORKING_DIRECTORY ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/harfbuzz.dir/src # ugly hack + ) + add_test(NAME check-libstdc++.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-libstdc++.sh) + add_test(NAME check-symbols.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-symbols.sh) + + set_tests_properties( + check-static-inits.sh check-libstdc++.sh check-symbols.sh + PROPERTIES + ENVIRONMENT "libs=.;srcdir=${PROJECT_SOURCE_DIR}/src" + SKIP_RETURN_CODE 77) + endif () + add_test(NAME check-c-linkage-decls.sh COMMAND ./check-c-linkage-decls.sh) + add_test(NAME check-header-guards.sh COMMAND ./check-header-guards.sh) + add_test(NAME check-externs.sh COMMAND ./check-externs.sh) + add_test(NAME check-includes.sh COMMAND ./check-includes.sh) set_tests_properties( - check-static-inits.sh check-libstdc++.sh check-symbols.sh + check-c-linkage-decls.sh check-header-guards.sh check-externs.sh check-includes.sh PROPERTIES - ENVIRONMENT "libs=.;srcdir=${PROJECT_SOURCE_DIR}/src" + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src SKIP_RETURN_CODE 77) endif () - add_test(NAME check-c-linkage-decls.sh COMMAND ./check-c-linkage-decls.sh) - add_test(NAME check-header-guards.sh COMMAND ./check-header-guards.sh) - add_test(NAME check-externs.sh COMMAND ./check-externs.sh) - add_test(NAME check-includes.sh COMMAND ./check-includes.sh) - set_tests_properties( - check-c-linkage-decls.sh check-header-guards.sh check-externs.sh check-includes.sh - PROPERTIES - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src - SKIP_RETURN_CODE 77) + # Needs to come last so that variables defined above are passed to + # subdirectories. + add_subdirectory(test) endif () - -# Needs to come last so that variables defined above are passed to -# subdirectories. -add_subdirectory(test) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog b/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog index e0f47e8af90..d8f413c5386 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog +++ b/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog @@ -1,3 +1,6680 @@ +commit 3d9a0306ebb48706778fd2c487c3cacc7d508d6c +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 18 05:58:17 2018 -0700 + + 2.0.0 + + NEWS | 68 + +++++++++++++++++++++++++++++++++++++++++++++++++++++ + configure.ac | 2 +- + src/hb-buffer.cc | 4 ++-- + src/hb-common.h | 4 ++-- + src/hb-deprecated.h | 18 +++++++------- + src/hb-font.cc | 6 ++--- + src/hb-font.h | 2 +- + src/hb-ot-layout.cc | 8 +++---- + src/hb-ot-name.h | 4 ++-- + src/hb-ot-tag.cc | 4 ++-- + src/hb-ot-tag.h | 4 ++-- + src/hb-version.h | 6 ++--- + 12 files changed, 99 insertions(+), 31 deletions(-) + +commit 535ca678bf9c8ab470ebf5ad84a090328d79d42b +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 18 05:58:04 2018 -0700 + + [test] Don't use newer glib API + + test/api/test-ot-tag.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 03e144135b5c691e3942d1aef917fe2246665fb6 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Thu Oct 18 11:06:37 2018 +0330 + + [ubsan] Use unsigned int instead enum where needed (#1270) + + Actually the check is right, + + On -myanmar.hh, on that particular switch, OT_C is indic_category_t + but OT_D is myanmar_category_t so we are mixing the types in one + variable. + + And on -arabic.cc, step can goes one number higher than step_t enum + in the + loop so we are actually using it as an unsinged int. + + .circleci/config.yml | 2 +- + src/hb-ot-shape-complex-arabic.cc | 4 ++-- + src/hb-ot-shape-complex-myanmar.hh | 48 + +++++++++++++++++++------------------- + 3 files changed, 27 insertions(+), 27 deletions(-) + +commit 64df6b0b0f9d221e14811084f2412a01cf4deb46 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 18 00:35:01 2018 -0700 + + [AUTHORS] Add Ebrahim and Khaled + + AUTHORS | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +commit f1ced9be378d7c7ad3ea35a1cee6f9aff7a44a13 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 17 23:06:53 2018 -0700 + + More warning fix + + Okay, let's see if the gods are happy now... + + src/hb-static.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 40606abd0cd40faf3973d0a8c30af90d36ae8231 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 17 23:06:37 2018 -0700 + + Fix build + + src/hb-static.cc | 1 + + 1 file changed, 1 insertion(+) + +commit c406aca19303e61fa5ba15d215386cfc6d920124 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 17 22:58:43 2018 -0700 + + Fix warning + + src/hb-machinery.hh | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 270a37c3244b32dd839a99eb379be241613ee895 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 17 22:42:47 2018 -0700 + + Kick bots + + src/hb-aat-layout-common.hh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 6da8ef3f9f4706fe88715fabdba7904ff279539b +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 17 22:37:34 2018 -0700 + + Fix some wierdness... + + src/hb-static.cc | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +commit 83780308b41b029513ac2568b6688d3eaad77338 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 17 22:34:16 2018 -0700 + + [aat] Fix sanitize slowdown + + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11034 + + src/hb-aat-layout-common.hh | 4 ++++ + src/hb-machinery.hh | 2 +- + 2 files changed, 5 insertions(+), 1 deletion(-) + +commit b9478e28ac4361353e4920d749cc5d29e5bfef67 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 17 21:52:14 2018 -0700 + + Revert "[test] Remove not-fixed yet testcases (#1268)" + + This reverts commit 191eef823fe95355425621f8e002dfe7fe632383. + + ...rfuzz-testcase-minimized-hb-fuzzer-4548492505645056 | Bin 0 -> + 122 bytes + ...rfuzz-testcase-minimized-hb-fuzzer-6210176798425088 | Bin 0 -> + 1420 bytes + ...testcase-minimized-hb-shape-fuzzer-5738888765636608 | Bin 0 -> + 267731 bytes + 3 files changed, 0 insertions(+), 0 deletions(-) + +commit af99b20dfddbca75e68f84c5aa465a54728990a6 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Thu Oct 18 08:35:20 2018 +0330 + + [ci/ubsan] Disable enum sanitization + + Behdad apparently not interested on them + + .circleci/config.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 9e8a9b846ec24e9124d61706272a0e5fa58d7a24 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 17 21:41:25 2018 -0700 + + [aat] Another try at fixing Lookup null objects... + + Ugly as hell, and don't even understand why some bits are needed. + But the logic is sound. + + src/hb-aat-layout-common.hh | 23 ++++++++++++++++++++--- + src/hb-static.cc | 4 ++++ + 2 files changed, 24 insertions(+), 3 deletions(-) + +commit 191eef823fe95355425621f8e002dfe7fe632383 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Thu Oct 18 08:04:18 2018 +0330 + + [test] Remove not-fixed yet testcases (#1268) + + I added them but now that I think, it is a bad idea to have them as + fuzzing bots will find good seeds to tweak in order to find easy new + testcases which causes duplicated issues. + + ...rfuzz-testcase-minimized-hb-fuzzer-4548492505645056 | Bin 122 -> + 0 bytes + ...rfuzz-testcase-minimized-hb-fuzzer-6210176798425088 | Bin 1420 -> + 0 bytes + ...testcase-minimized-hb-shape-fuzzer-5738888765636608 | Bin 267731 -> + 0 bytes + 3 files changed, 0 insertions(+), 0 deletions(-) + +commit 392e1f4ddd7eb649e1a71755b9bcf6431739f98f +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Thu Oct 18 07:42:20 2018 +0330 + + [test/shape-fuzzer] fail on timeout and ubsan errors (#1267) + + test/fuzzing/run-shape-fuzzer-tests.py | 38 + ++++++++++++++++++++++++++++++---- + 1 file changed, 34 insertions(+), 4 deletions(-) + +commit eeddda3ec6c28b411d33c74938ec6198c7f6888d +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Thu Oct 18 07:38:47 2018 +0330 + + [util] Better file-not-found error from hb-shape / hb-view + + fixes #1266 + + util/options.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 751c10e55e43e2266a5bba024d560c5127fae4b8 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Thu Oct 18 06:36:48 2018 +0330 + + [fuzz] Add more new testcases + + ...testcase-minimized-hb-shape-fuzzer-5718464350650368 | Bin 0 -> + 41 bytes + ...testcase-minimized-hb-shape-fuzzer-5738888765636608 | Bin 0 -> + 267731 bytes + 2 files changed, 0 insertions(+), 0 deletions(-) + +commit fd282eb3285e6d20f77e8a3a7237b677433ccbb4 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Thu Oct 18 06:33:39 2018 +0330 + + [fuzz] Add a new testcase + + .../clusterfuzz-testcase-hb-shape-fuzzer-5634395566768128 | Bin 0 -> + 106 bytes + 1 file changed, 0 insertions(+), 0 deletions(-) + +commit 9d42d70269b879e67f3c7724beab8e4cdbfc877a +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 17 17:55:47 2018 -0700 + + [trak] Fix calc + + We were getting the first track record always. Ie. this line: + + if (trackTable[i].get_track_value () == 0.f) + { + - trackTableEntry = &trackTable[0]; + + trackTableEntry = &trackTable[i]; + break; + } + + The rest is cleanup. + + Fixes https://github.com/harfbuzz/harfbuzz/issues/1263 for the + most part. + + src/hb-aat-layout-trak-table.hh | 17 ++++++++--------- + 1 file changed, 8 insertions(+), 9 deletions(-) + +commit 3341c7fbfb9bc8e137afd9f16da8cf18eb67b25b +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 17 15:04:35 2018 -0700 + + [fuzzing] Move fuzzing fonts from api/ here + + ...estcase-minimized-hb-subset-fuzzer-5521982557782016 | Bin 1228 -> + 0 bytes + ...estcase-minimized-hb-subset-fuzzer-5542653037903872 | Bin 160249 -> + 0 bytes + ...estcase-minimized-hb-subset-fuzzer-5609911946838016 | Bin 313 -> + 0 bytes + ...estcase-minimized-hb-subset-fuzzer-5670861909524480 | Bin 1298 -> + 0 bytes + ...estcase-minimized-hb-subset-fuzzer-5750092395970560 | Bin 72435 -> + 0 bytes + ...estcase-minimized-hb-subset-fuzzer-6651660668502016 | Bin 15229 -> + 0 bytes + ...ed-hb-subset-get-codepoints-fuzzer-5973295416475648 | Bin 109 -> + 0 bytes + ...ed-hb-subset-get-codepoints-fuzzer-6136125075750912 | Bin 65816 -> + 0 bytes + test/api/test-subset-glyf.c | 2 +- + test/api/test-subset-hdmx.c | 4 ++-- + test/api/test-subset-hmtx.c | 2 +- + test/api/test-subset.c | 6 +++--- + .../crash-4b60576767ee4d9fe1cc10959d89baf73d4e8249 | Bin + .../crash-b577db318b30f2851828a4c9ef97cb30678b1b54 | Bin + .../crash-ccc61c92d589f895174cdef6ff2e3b20e9999a1a | Bin + .../crash-e4e0bb1458a91b692eba492c907ae1f94e635480 | Bin + .../fonts/oom-6ef8c96d3710262511bcc730dce9c00e722cb653 | Bin + .../fonts/oom-ccc61c92d589f895174cdef6ff2e3b20e9999a1a | Bin + 18 files changed, 7 insertions(+), 7 deletions(-) + +commit 2e7c716511e8b2cfcd059fa2a2ed4cdd48b351bf +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 16 18:35:03 2018 -0700 + + [buffer] Add an assert + + See if it helps debugging + https://bugs.chromium.org/p/chromium/issues/detail?id=895117 + + src/hb-buffer.cc | 2 ++ + 1 file changed, 2 insertions(+) + +commit 5842756b1398253d38749c4c8a23a1450e642caf +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 16 18:28:55 2018 -0700 + + [fuzzing] Delete blink fuzzed data + + These are text, not font. + + ...minimized-blink_harfbuzz_shaper_fuzzer-5099655095123968 | Bin 88 -> + 0 bytes + 1 file changed, 0 insertions(+), 0 deletions(-) + +commit 25fe7e7e1031401d38db1efed360cd75ea7910b9 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 16 18:22:54 2018 -0700 + + [aat] Comment + + src/hb-aat-layout-common.hh | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 26092bb3d1aa239de5e933700e0371619d147f65 +Author: HinTak <htl10@users.sourceforge.net> +Date: Wed Oct 17 00:54:39 2018 +0100 + + "allow-none" annotation for "out" parameters + + Fixes the following warnings: + hb-ot-tag.cc:330: Warning: HarfBuzz: invalid "allow-none" annotation: + only valid for pointer types and out parameters + hb-ot-tag.cc:334: Warning: HarfBuzz: invalid "allow-none" annotation: + only valid for pointer types and out parameters + + src/hb-ot-tag.cc | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit ba42651608da1be0d152e03ad42ea96fc8476ac7 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 16 17:35:46 2018 -0700 + + Fix indent + + test/fuzzing/run-shape-fuzzer-tests.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 49bdb54427b17d439eadf31732a5f2a0add46bf5 +Author: HinTak <htl10@users.sourceforge.net> +Date: Wed Oct 17 00:36:04 2018 +0100 + + typo in gobject annotation - "in/out" should be "inout" + + "in/out" should be "inout" + + src/hb-ot-layout.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit c0c190c16a2c1b281f40dacdcf515dc5a59ab3bb +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 16 16:39:29 2018 -0700 + + [fuzzing] Run tests against fuzzing fonts + + Some disable. + + test/fuzzing/run-shape-fuzzer-tests.py | 12 ++-- + test/fuzzing/run-subset-fuzzer-tests.py | 35 ++++++----- + test/shaping/data/in-house/Makefile.sources | 1 - + test/shaping/data/in-house/tests/fuzzed.tests | 84 + --------------------------- + 4 files changed, 24 insertions(+), 108 deletions(-) + +commit 7b37705fb579a39334be0618c6215c1b887bf9fc +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 16 16:33:06 2018 -0700 + + [fuzzing] Rename + + ...ebdebc6.ttf => 0509e80afb379d16560e9e47bdd7d888bebdebc6} | Bin + ...63b6daf.ttf => 1a6f1687b7a221f9f2c834b0b360d3c8463b6daf} | Bin + ...28b22cb.ttf => 205edd09bd3d141cc9580f650109556cc28b22cb} | Bin + ...f026462.ttf => 217a934cfe15c548b572c203dceb2befdf026462} | Bin + ...ac34f18.ttf => 3511ff5c1647150595846ac414c595cccac34f18} | Bin + ...675d5a3.ttf => 375d6ae32a3cbe52fbf81a4e5777e3377675d5a3} | Bin + ...9c9a56b.ttf => 43979b90b2dd929723cf4fe1715990bcb9c9a56b} | Bin + ...1a8e2b0.ttf => 558661aa659912f4d30ecd27bd09835171a8e2b0} | Bin + ...0655fa8.ttf => 5a5daf5eb5a4db77a2baa3ad9c7a6ed6e0655fa8} | Bin + ...c149ddc.ttf => 641bd9db850193064d17575053ae2bf8ec149ddc} | Bin + ...bcf861f.ttf => 8240789f6d12d4cfc4b5e8e6f246c3701bcf861f} | Bin + ...1386016.ttf => a34a9191d9376bda419836effeef7e75c1386016} | Bin + ...bdae30e.ttf => a69118c2c2ada48ff803d9149daa54c9ebdae30e} | Bin + ...6b31fe2.ttf => b9e2aaa0d75fcef6971ec3a96d806ba4a6b31fe2} | Bin + ...14a0467.ttf => e88c339237f52d21e01c55f01b9c1b4cc14a0467} | Bin + ...1395725.ttf => fab39d60d758cb586db5a504f218442cd1395725} | Bin + 16 files changed, 0 insertions(+), 0 deletions(-) + +commit 3676c685d407cc7b9b813b4a08e7c5bcd9a47ea1 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 16 16:32:26 2018 -0700 + + [fuzzing] Move rest of fuzzing tests here + + .../fonts/0509e80afb379d16560e9e47bdd7d888bebdebc6.ttf | Bin + .../fonts/1a6f1687b7a221f9f2c834b0b360d3c8463b6daf.ttf | Bin + .../fonts/205edd09bd3d141cc9580f650109556cc28b22cb.ttf | Bin + .../fonts/217a934cfe15c548b572c203dceb2befdf026462.ttf | Bin + .../fonts/3511ff5c1647150595846ac414c595cccac34f18.ttf | Bin + .../fonts/375d6ae32a3cbe52fbf81a4e5777e3377675d5a3.ttf | Bin + .../fonts/43979b90b2dd929723cf4fe1715990bcb9c9a56b.ttf | Bin + .../fonts/558661aa659912f4d30ecd27bd09835171a8e2b0.ttf | Bin + .../fonts/5a5daf5eb5a4db77a2baa3ad9c7a6ed6e0655fa8.ttf | Bin + .../fonts/641bd9db850193064d17575053ae2bf8ec149ddc.ttf | Bin + .../fonts/8240789f6d12d4cfc4b5e8e6f246c3701bcf861f.ttf | Bin + .../fonts/a34a9191d9376bda419836effeef7e75c1386016.ttf | Bin + .../fonts/a69118c2c2ada48ff803d9149daa54c9ebdae30e.ttf | Bin + .../fonts/b9e2aaa0d75fcef6971ec3a96d806ba4a6b31fe2.ttf | Bin + .../fonts/e88c339237f52d21e01c55f01b9c1b4cc14a0467.ttf | Bin + .../fonts/fab39d60d758cb586db5a504f218442cd1395725.ttf | Bin + test/shaping/data/in-house/tests/fuzzed.tests | 16 + ---------------- + 17 files changed, 16 deletions(-) + +commit 1487173dcf4137fb210b15d9a869aa1f0c626d15 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 16 16:30:38 2018 -0700 + + [fuzzing] Delete duplicate fonts + + .../233c1e252e737ca79e03a9fd56b71aaa4a230f2b.ttf | Bin 1048576 -> + 0 bytes + .../243798dd281c1c77c065958e1ff467420faa9bde.ttf | Bin 225 -> + 0 bytes + .../9d8a94a67932a3ab75a596fc8b5c6d0392ca9e49.ttf | Bin 4545 -> + 0 bytes + .../b6acef662e0beb8d5fcf5b61c6b0ca69537b7402.ttf | Bin 3301 -> + 0 bytes + .../bbf4a308c402f0678c3e82844892a4da2ebe598f.ttf | Bin 204 -> + 0 bytes + .../dd9f0c7c7c36f75a18be0cab1cddf8f3ab0f366b.ttf | Bin 2786 -> + 0 bytes + .../ef2511f215aa3ca847cbfffbf861793b42170875.ttf | Bin 1152 -> + 0 bytes + test/shaping/data/in-house/tests/fuzzed.tests | 7 ------- + 8 files changed, 7 deletions(-) + +commit 49c041f7c5b135cbcbd1663e18047afd54fc948b +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 16 16:25:24 2018 -0700 + + Minor + + test/fuzzing/clusterfuzz-testcase-6107935408390144 | Bin 16800 -> 0 bytes + 1 file changed, 0 insertions(+), 0 deletions(-) + +commit 36f38ea7033b4e52c6cd94a8a0d686a95c0cc148 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 16 16:24:03 2018 -0700 + + [gpos] Protect mark attachment against out-of-bounds + + Not sure how can happen, but does... + + src/hb-ot-layout-gpos-table.hh | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +commit 1147ce2392ac6b3d12fdabe69ac5da9bae97e30d +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 16 16:18:32 2018 -0700 + + [fuzzing] Add more tests + + .../fuzzing/fonts/clusterfuzz-testcase-6107935408390144 | Bin 0 -> + 16800 bytes + ...-testcase-minimized-harfbuzz_fuzzer-5973566991106048 | Bin 0 -> + 4047 bytes + ...-testcase-minimized-hb-shape-fuzzer-5633985665826816 | Bin 0 -> + 73 bytes + 3 files changed, 0 insertions(+), 0 deletions(-) + +commit 12cbe195ae65656dbc9e32b4d50696bc4223136b +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 16 16:13:53 2018 -0700 + + [aat] Another non-null offset + + src/hb-aat-layout-ankr-table.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 87205ef935ede70365187549d133014669ea47f2 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 16 15:40:44 2018 -0700 + + [aat] Make sure Lookup offset is never nulled + + It has unbounded size... + + Fixes https://oss-fuzz.com/v2/testcase-detail/5718889451749376 + + src/hb-aat-layout-ankr-table.hh | 2 +- + src/hb-aat-layout-common.hh | 3 ++- + src/hb-aat-layout-kerx-table.hh | 18 ++++++++---------- + src/hb-aat-layout-morx-table.hh | 4 ++-- + src/hb-open-type.hh | 12 ++++++------ + 5 files changed, 19 insertions(+), 20 deletions(-) + +commit 1aa353e4fc79dfa880559ff75113ed58fac8392b +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 16 15:26:51 2018 -0700 + + Fix tests + + test/shaping/data/in-house/tests/fuzzed.tests | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 98d4ad02b97628e5a9a7bfe3187ccc3851c00b18 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 16 15:17:31 2018 -0700 + + [fuzzing] One more + + test/fuzzing/clusterfuzz-testcase-6107935408390144 | Bin 0 -> 16800 bytes + 1 file changed, 0 insertions(+), 0 deletions(-) + +commit e6f267c3dfe3e93dfc726266672da5a235fbd930 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 16 15:16:20 2018 -0700 + + [fuzzing] Add more clusterfuzz tests I had lying around + + .../fonts/clusterfuzz-testcase-5517117891805184 | Bin 0 -> + 178 bytes + ...sterfuzz-testcase-hb-shape-fuzzer-5746142327865344 | Bin 0 -> + 219 bytes + ...sterfuzz-testcase-hb-shape-fuzzer-5750379279548416 | Bin 0 -> + 317 bytes + .../clusterfuzz-testcase-minimized-4884742786777088 | Bin 0 -> + 393 bytes + .../clusterfuzz-testcase-minimized-5255344882188288 | Bin 0 -> 65 bytes + .../clusterfuzz-testcase-minimized-5720051798769664 | Bin 0 -> + 1048576 bytes + .../clusterfuzz-testcase-minimized-5924299061854208 | Bin 0 -> + 2786 bytes + .../clusterfuzz-testcase-minimized-6460279560863744 | Bin 0 -> + 589 bytes + ...ized-blink_harfbuzz_shaper_fuzzer-5099655095123968 | Bin 0 -> 88 bytes + ...estcase-minimized-hb-shape-fuzzer-5650286710882304 | Bin 0 -> 76 bytes + ...stcase-minimized-hb-shape-fuzzer-5672261407735808} | Bin + 11 files changed, 0 insertions(+), 0 deletions(-) + +commit e53206271db4a83834433ab5f82d16815a18b998 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Wed Oct 17 01:42:04 2018 +0330 + + Add all the fonts found by fuzzers to the repo (#1258) + + test/fuzzing/Makefile.am | 1 + + ...clusterfuzz-testcase-hb-fuzzer-4666056377368576 | Bin 0 -> 1152 bytes + ...clusterfuzz-testcase-hb-fuzzer-5662671558934528 | Bin 0 -> 242272 + bytes + ...clusterfuzz-testcase-hb-fuzzer-6243458541944832 | Bin 0 -> 370187 + bytes + ...clusterfuzz-testcase-hb-fuzzer-6303297511096320 | Bin 0 -> 4545 bytes + ...clusterfuzz-testcase-hb-fuzzer-6696647723581440 | Bin 0 -> 3266 bytes + ...z-testcase-minimized-hb-fuzzer-4523479581851648 | Bin 0 -> 322 bytes + ...z-testcase-minimized-hb-fuzzer-4535496598355968 | Bin 0 -> 2786 bytes + ...z-testcase-minimized-hb-fuzzer-4548492505645056 | Bin 0 -> 122 bytes + ...z-testcase-minimized-hb-fuzzer-4595692015190016 | Bin 0 -> 225 bytes + ...z-testcase-minimized-hb-fuzzer-4687441845813248 | Bin 0 -> 162 bytes + ...z-testcase-minimized-hb-fuzzer-4706238090706944 | Bin 0 -> 350 bytes + ...z-testcase-minimized-hb-fuzzer-4769173588672512 | Bin 0 -> 37 bytes + ...z-testcase-minimized-hb-fuzzer-4827735151083520 | Bin 0 -> 1384 bytes + ...z-testcase-minimized-hb-fuzzer-4841745322868736 | Bin 0 -> 660 bytes + ...z-testcase-minimized-hb-fuzzer-4884742786777088 | Bin 0 -> 393 bytes + ...z-testcase-minimized-hb-fuzzer-5216838347653120 | Bin 0 -> 157600 + bytes + ...z-testcase-minimized-hb-fuzzer-5255344882188288 | Bin 0 -> 65 bytes + ...z-testcase-minimized-hb-fuzzer-5294584596791296 | Bin 0 -> 1602 bytes + ...z-testcase-minimized-hb-fuzzer-5303930168803328 | Bin 0 -> 7321 bytes + ...z-testcase-minimized-hb-fuzzer-5331901587914752 | Bin 0 -> 3301 bytes + ...z-testcase-minimized-hb-fuzzer-5388906574905344 | Bin 0 -> 9937 bytes + ...z-testcase-minimized-hb-fuzzer-5517117891805184 | Bin 0 -> 178 bytes + ...z-testcase-minimized-hb-fuzzer-5617496443846656 | Bin 0 -> 195 bytes + ...z-testcase-minimized-hb-fuzzer-5672141338968064 | Bin 0 -> 176 bytes + ...z-testcase-minimized-hb-fuzzer-5700697074958336 | Bin 0 -> 878 bytes + ...z-testcase-minimized-hb-fuzzer-5720051798769664 | Bin 0 -> 1048576 + bytes + ...z-testcase-minimized-hb-fuzzer-5924299061854208 | Bin 0 -> 2786 bytes + ...z-testcase-minimized-hb-fuzzer-6023178755244032 | Bin 0 -> 2261 bytes + ...z-testcase-minimized-hb-fuzzer-6111685556305920 | Bin 0 -> 586 bytes + ...z-testcase-minimized-hb-fuzzer-6160439919509504 | Bin 0 -> 204 bytes + ...z-testcase-minimized-hb-fuzzer-6210176798425088 | Bin 0 -> 1420 bytes + ...z-testcase-minimized-hb-fuzzer-6260579246276608 | Bin 0 -> 700 bytes + ...z-testcase-minimized-hb-fuzzer-6264625609834496 | Bin 0 -> 1731 bytes + ...z-testcase-minimized-hb-fuzzer-6424351550210048 | Bin 0 -> 73 bytes + ...z-testcase-minimized-hb-fuzzer-6460279560863744 | Bin 0 -> 589 bytes + ...z-testcase-minimized-hb-fuzzer-6576177596596224 | Bin 0 -> 385 bytes + ...z-testcase-minimized-hb-fuzzer-6595199411159040 | Bin 0 -> 1862 bytes + ...z-testcase-minimized-hb-fuzzer-6624904746106880 | Bin 0 -> 42 bytes + ...z-testcase-minimized-hb-fuzzer-6723367514144768 | Bin 0 -> 1074 bytes + ...case-minimized-hb-shape-fuzzer-5630246225707008 | Bin 0 -> 109 bytes + ...case-minimized-hb-shape-fuzzer-5635082459545600 | Bin 0 -> 52 bytes + ...case-minimized-hb-shape-fuzzer-5652019562414080 | Bin 0 -> 49 bytes + ...case-minimized-hb-shape-fuzzer-5656511058018304 | Bin 0 -> 28 bytes + ...case-minimized-hb-shape-fuzzer-5659641787187200 | Bin 0 -> 3498 bytes + ...case-minimized-hb-shape-fuzzer-5668791174823936 | Bin 0 -> 3608 bytes + ...ase-minimized-hb-shape-fuzzer-56722614077358084 | Bin 0 -> 192 bytes + ...case-minimized-hb-shape-fuzzer-5674361600606208 | Bin 0 -> 518 bytes + ...case-minimized-hb-shape-fuzzer-5677421274071040 | Bin 0 -> 3608 bytes + ...case-minimized-hb-shape-fuzzer-5679244475105280 | Bin 0 -> 256 bytes + ...case-minimized-hb-shape-fuzzer-5685596677210112 | Bin 0 -> 58 bytes + ...case-minimized-hb-shape-fuzzer-5695615258853376 | Bin 0 -> 194 bytes + ...case-minimized-hb-shape-fuzzer-5696686572175360 | Bin 0 -> 256 bytes + ...case-minimized-hb-shape-fuzzer-5718889451749376 | Bin 0 -> 1680 bytes + ...case-minimized-hb-shape-fuzzer-5719982789361664 | Bin 0 -> 3608 bytes + ...case-minimized-hb-shape-fuzzer-5725129603022848 | Bin 0 -> 3608 bytes + ...case-minimized-hb-shape-fuzzer-5726089628876800 | Bin 0 -> 76 bytes + ...case-minimized-hb-shape-fuzzer-5729361857085440 | Bin 0 -> 2250 bytes + ...case-minimized-hb-shape-fuzzer-5733166795456512 | Bin 0 -> 78 bytes + ...case-minimized-hb-shape-fuzzer-5734736291430400 | Bin 0 -> 66 bytes + ...case-minimized-hb-shape-fuzzer-5740171484463104 | Bin 0 -> 186 bytes + ...case-minimized-hb-shape-fuzzer-5750379279548416 | Bin 0 -> 219 bytes + ...case-minimized-hb-shape-fuzzer-5762490181353472 | Bin 0 -> 101 bytes + ...ase-minimized-hb-subset-fuzzer-5359635656605696 | Bin 0 -> 393270 + bytes + ...ase-minimized-hb-subset-fuzzer-5521982557782016 | Bin 0 -> 1228 bytes + ...ase-minimized-hb-subset-fuzzer-5542653037903872 | Bin 0 -> 160249 + bytes + ...ase-minimized-hb-subset-fuzzer-5609911946838016 | Bin 0 -> 313 bytes + ...ase-minimized-hb-subset-fuzzer-5629878397829120 | Bin 0 -> 3746 bytes + ...ase-minimized-hb-subset-fuzzer-5651059347816448 | Bin 0 -> 2648 bytes + ...ase-minimized-hb-subset-fuzzer-5669437462544384 | Bin 0 -> 284427 + bytes + ...ase-minimized-hb-subset-fuzzer-5670861909524480 | Bin 0 -> 1298 bytes + ...ase-minimized-hb-subset-fuzzer-5696607199166464 | Bin 0 -> 28 bytes + ...ase-minimized-hb-subset-fuzzer-5711951464759296 | Bin 0 -> 284521 + bytes + ...ase-minimized-hb-subset-fuzzer-5747265633779712 | Bin 0 -> 177090 + bytes + ...ase-minimized-hb-subset-fuzzer-5750092395970560 | Bin 0 -> 72435 bytes + ...ase-minimized-hb-subset-fuzzer-5758598970343424 | Bin 0 -> 64 bytes + ...ase-minimized-hb-subset-fuzzer-6543700493598720 | Bin 0 -> 138425 + bytes + ...ase-minimized-hb-subset-fuzzer-6651660668502016 | Bin 0 -> 15229 bytes + ...b-subset-get-codepoints-fuzzer-5203067375976448 | Bin 0 -> 16310 bytes + ...b-subset-get-codepoints-fuzzer-5630904853069824 | Bin 0 -> 580 bytes + ...b-subset-get-codepoints-fuzzer-5687638085337088 | Bin 0 -> 1206 bytes + ...b-subset-get-codepoints-fuzzer-5736539338833920 | Bin 0 -> 512 bytes + ...b-subset-get-codepoints-fuzzer-5973295416475648 | Bin 0 -> 109 bytes + ...b-subset-get-codepoints-fuzzer-6136125075750912 | Bin 0 -> 65816 bytes + ...b-subset-get-codepoints-fuzzer-6394290358976512 | Bin 0 -> 1868 bytes + test/fuzzing/run-shape-fuzzer-tests.py | 4 + + test/shaping/data/in-house/tests/fuzzed.tests | 84 + +++++++++++++++++++++ + 87 files changed, 89 insertions(+) + +commit 2137582c9696b6e38d70b4a0d4199b315c9fd4ce +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 16 14:46:07 2018 -0700 + + [morx] Reword ligation + + Still fails MORX-41. Am talking to Sascha to better understand + what CoreText + is doing. + + src/hb-aat-layout-morx-table.hh | 25 + ++++++++++++---------- + test/shaping/data/text-rendering-tests/DISABLED | 2 ++ + .../data/text-rendering-tests/Makefile.sources | 2 +- + 3 files changed, 17 insertions(+), 12 deletions(-) + +commit c53a25c6579a4d3fe8e6a6fc198d70add41035ec +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 16 13:57:35 2018 -0700 + + [morx] Comment + + src/hb-aat-layout-morx-table.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit c46d42f8f2c303817467c6a4e19d69d0e433dba6 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 16 13:39:54 2018 -0700 + + [test/text-rendering-tests] Update from upstream + + test/shaping/data/text-rendering-tests/Makefile.sources | 1 + + .../text-rendering-tests/fonts/TestMORXFourtyone.ttf | Bin 0 -> + 2248 bytes + .../data/text-rendering-tests/tests/MORX-41.tests | 4 ++++ + 3 files changed, 5 insertions(+) + +commit 5eb7e7f6461bcf5b1e1d8ccb49eb904382762533 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 16 13:32:52 2018 -0700 + + Revert "[vector] Simplify Sort" and "More of the same" + + This reverts commit de0b9a466490c2c13d6ec6f59d5122b0a87d3180. + This reverts commit 921f0e6ec722940a1e37660e1291aa69f9f39db8. + + Annnnd, revert. MSVC doesn't like it. + + src/hb-vector.hh | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +commit 661340c475dc928f227d54b3f36eaf6f41c2b6e3 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 16 13:24:29 2018 -0700 + + [kern] Scale kern pairs before applying + + Fixes https://github.com/harfbuzz/harfbuzz/issues/1255 + Fixes https://github.com/harfbuzz/harfbuzz/issues/1252 + + src/hb-ot-kern-table.hh | 18 ++++++++++++------ + src/hb-ot-shape-fallback.cc | 2 +- + 2 files changed, 13 insertions(+), 7 deletions(-) + +commit de0b9a466490c2c13d6ec6f59d5122b0a87d3180 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 15 22:20:26 2018 -0700 + + [vector] More of the same + + src/hb-vector.hh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 921f0e6ec722940a1e37660e1291aa69f9f39db8 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 15 22:19:17 2018 -0700 + + [vector] Simplify sort + + Hopefully this fits fine with SFINAE with all our compilers. + + src/hb-vector.hh | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +commit 61510b63c15e91d80e36a497260db0e2d6d36c66 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Tue Oct 16 14:17:21 2018 +0330 + + [test] Minor cleanup in test-multithread and test-ot-name (#1256) + + test/api/CMakeLists.txt | 2 +- + test/api/Makefile.am | 2 +- + test/api/test-multithread.c | 6 ++- + test/api/{test-ot-nameid.c => test-ot-name.c} | 58 + ++++++++++++++------------- + 4 files changed, 36 insertions(+), 32 deletions(-) + +commit 42b75dc3a701b13665115e2a234bfa5dedafef3f +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Tue Oct 16 10:58:09 2018 +0330 + + [kerx] Minor, remove debug bit + + src/hb-aat-layout-kerx-table.hh | 1 - + 1 file changed, 1 deletion(-) + +commit 11703afce6cebbb4c5e7cdea59ca59a1787608b8 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 15 21:16:58 2018 -0700 + + [kerx] Fix Format6 sanitize + + Fixes https://oss-fuzz.com/v2/testcase-detail/5650286710882304 + + src/hb-aat-layout-kerx-table.hh | 21 +++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +commit 4c27da7638f6d072c3ff93223488c4ab316236c1 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 15 19:46:45 2018 -0700 + + [CBDT] Fix more offsetting + + Fixes https://oss-fuzz.com/v2/testcase-detail/5750379279548416 + + src/hb-ot-color-cbdt-table.hh | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +commit 0f85edb7781f4d5ec2de676979be75a0f6559d80 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 15 11:15:54 2018 -0700 + + [morx] Another end-of-text corner case + + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10990 + + src/hb-aat-layout-morx-table.hh | 2 ++ + 1 file changed, 2 insertions(+) + +commit 55d5ea666c25f75e9b1bc2eb43cfb104a16ebe04 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 15 11:04:49 2018 -0700 + + [kerx] Merge clusters in Ligature + + src/hb-aat-layout-morx-table.hh | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +commit bb35725cd760f07fdb0586453512a106e534b739 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 15 10:20:39 2018 -0700 + + [kerx/morx] More end-of-text protection + + src/hb-aat-layout-kerx-table.hh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 8f3048a1f838484babc4948754c16dda8f53daf1 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Mon Oct 15 12:16:47 2018 +0330 + + [dump-emoji] minor + + src/dump-emoji.cc | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 27e095a613ed0a753231405cab887da19e9aecd1 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Mon Oct 15 12:04:14 2018 +0330 + + [dump-emoji] better explaination of the usage + + src/dump-emoji.cc | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +commit 8dc6296818e3a52c003852aa185f2b7eb6afa5d3 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 15 01:09:05 2018 -0700 + + [ot-font] Implement TrueType v_origin + + Fixes https://github.com/harfbuzz/harfbuzz/issues/537 + + src/hb-ot-font.cc | 31 +++++++++++++++++- + src/hb-ot-hmtx-table.hh | 43 + ++++++++++++++++--------- + test/shaping/data/in-house/tests/vertical.tests | 2 +- + 3 files changed, 59 insertions(+), 17 deletions(-) + +commit 6e07076fd094afc8c9c8ad8f08453e7882294592 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 14 22:22:45 2018 -0700 + + [blob] Fix UBSan error + + src/hb-blob.cc | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit fc812faaa96aa4e67814a92376b2da751d5a0aba +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 14 21:32:09 2018 -0700 + + [CBDT] Fix more offsetting issues + + Fixes https://github.com/harfbuzz/harfbuzz/issues/960 + + dump-emoji still segfaults. Needs debugging. + + src/hb-ot-color-cbdt-table.hh | 28 +++++++++++++++------------- + 1 file changed, 15 insertions(+), 13 deletions(-) + +commit 6aee3bb87cee88525b745a640df294cb721245f6 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 14 21:08:42 2018 -0700 + + [CBDT] Fix offset handling + + Fixes https://github.com/harfbuzz/harfbuzz/issues/960 + + src/hb-ot-color-cbdt-table.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit da744c6b3e79b778f414ec9f4d9070d06ec2a706 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 14 20:49:21 2018 -0700 + + [CBDT] More UnsizedArrayOf cleanup + + src/hb-ot-color-cbdt-table.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 2995b4465bce52b30de2cb6ba24cc80d8602413d +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 14 20:37:57 2018 -0700 + + [CBDT] Simplify sanitize + + src/hb-ot-color-cbdt-table.hh | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +commit 1c76c8f6ff7877e486f6e94d04b2dc65348b26d5 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 14 19:39:31 2018 -0700 + + [morx] Handle end-of-text conditions in Insertion + + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10955 + + src/hb-aat-layout-morx-table.hh | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit 60c13976733ea05e71c66c486d62e31ffbb71bac +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 14 19:36:46 2018 -0700 + + [buffer] Fix output_glyph at end of buffer + + Part of https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10955 + + src/hb-buffer.hh | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +commit 7efa38257b6f79d1c6e2a9bad29c33af276abe29 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 14 19:30:44 2018 -0700 + + [aat] More protection against buffer fail + + src/hb-aat-layout-common.hh | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +commit e1add2a275a8afa5efc22aa44a4e62646f0b0ba4 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 14 16:26:03 2018 -0700 + + [hmtx] Whitespace + + src/hb-ot-hmtx-table.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 62376a7d983442408059b0b8987e7ca8d1de154e +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 14 15:20:50 2018 -0700 + + Ignore signed-integer-overflow while kerning + + Fixes https://github.com/harfbuzz/harfbuzz/issues/1247 + + src/hb-ot-kern-table.hh | 1 + + src/hb.hh | 9 +++++++++ + 2 files changed, 10 insertions(+) + +commit 40f2b9355cf827c7b82ea5e55b112ce0032a9abf +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 14 14:56:32 2018 -0700 + + [kerx] Fix Format1 sanitize + + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10948 + + src/hb-aat-layout-kerx-table.hh | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +commit 44af1f93ee32e236a5c14085c72d3fa102a14f5e +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 14 14:52:17 2018 -0700 + + [aat] Whitespace + + src/hb-aat-layout-common.hh | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +commit 56b8dd17f677ffe97e4d917c47924e1ac7632c71 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sat Oct 13 19:03:33 2018 -0400 + + [aat] Finish off massaging table + + src/hb-aat-layout.cc | 163 + +++++++++++++++++++++++++-------------------------- + 1 file changed, 81 insertions(+), 82 deletions(-) + +commit e0c5e0d91bbc0c8b2bb547ba5cb118989affc617 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sat Oct 13 18:37:14 2018 -0400 + + [aat] WIP remove feature mapping here from hb-coretext + + Need to map enum values to numerics since we don't have CoreText + headers. + + src/hb-aat-layout.cc | 94 +++++++++++++++++++++++++ + src/hb-aat-layout.hh | 22 ++++++ + src/hb-coretext.cc | 189 + +-------------------------------------------------- + 3 files changed, 117 insertions(+), 188 deletions(-) + +commit cb057749131826dd89bc3b92527116a974ae3bbe +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sat Oct 13 17:03:32 2018 -0400 + + [coretext] Prepare AAT feature mapping to be moved + + src/hb-coretext.cc | 39 ++++++++++++++++++++++----------------- + 1 file changed, 22 insertions(+), 17 deletions(-) + +commit de6e414c565de5f27b9da8c7b8b11f88659a4c42 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sat Oct 13 13:48:22 2018 -0400 + + [kerx] Sanitize more + + src/hb-aat-layout-kerx-table.hh | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +commit 71f76f2f39c88998b430b171c99b85818d4fa0ab +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sat Oct 13 13:36:27 2018 -0400 + + [kerx] Fix-up previous commit + + A "&" was missing. Go back to using pointers that are less + error-prone. + + src/hb-aat-layout-kerx-table.hh | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +commit 6d4b054234b4736ca9927268ee3e2d9a0f8f6ead +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sat Oct 13 12:20:33 2018 -0400 + + [kerx] Use sanitizer instead of handcoded runtime sanitization + + src/hb-aat-layout-kerx-table.hh | 24 +++++++++--------------- + 1 file changed, 9 insertions(+), 15 deletions(-) + +commit 5733113662e668a25187e0042935d955e44fb488 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sat Oct 13 12:16:12 2018 -0400 + + [kerx] Wire up context down to get_kerning + + src/hb-aat-layout-kerx-table.hh | 32 ++++++++++++++------------------ + 1 file changed, 14 insertions(+), 18 deletions(-) + +commit c4502833b711a76cce1af0c5bf075692b965c991 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sat Oct 13 11:48:49 2018 -0400 + + [kerx] Use sanitizer.get_num_glyphs() instead of + face->get_num_glyphs() + + src/hb-aat-layout-kerx-table.hh | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit fc45e698f2d8a6d577f33b1e69a83714aceae528 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sat Oct 13 11:39:12 2018 -0400 + + [kerx] Protext against overflows + + src/hb-aat-layout-kerx-table.hh | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +commit ed2ee78136c40de8e7b915dfdfd3ca92880912c3 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sat Oct 13 09:47:51 2018 -0400 + + [hangul] Fix use-after-free issue + + out_info might have moved since we copied it's position into local + info var. + + Fixes https://bugs.chromium.org/p/chromium/issues/detail?id=894937 + + src/hb-ot-shape-complex-hangul.cc | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +commit 63109432cf61333e01af4ef5163d4202bb43f84d +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Sat Oct 13 14:00:05 2018 +0330 + + Cosmetic and minor changes + + src/hb-buffer-serialize.cc | 4 +- + src/hb-ot-cmap-table.hh | 4 +- + src/hb-ot-layout-common.hh | 4 +- + src/hb-ot-layout-gsubgpos.hh | 8 +-- + src/hb-ot-layout.cc | 127 + +++++++++++++++++++------------------------ + src/hb-ot-layout.h | 25 +++++---- + src/hb-ot-math-table.hh | 8 +-- + src/hb-ot-name.h | 1 - + src/hb-ot-shape-complex.hh | 18 +++--- + 9 files changed, 93 insertions(+), 106 deletions(-) + +commit c0a6814b49e376984a0cae9d385a6f6ba8c73579 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Oct 12 16:05:56 2018 -0400 + + Touch up new API + + New API: + +hb_ot_layout_feature_get_name_ids() + +hb_ot_layout_feature_get_characters() + + src/hb-ot-layout.cc | 16 +++++++++------- + src/hb-ot-layout.h | 2 -- + test/api/test-ot-nameid.c | 16 ++++++++++------ + 3 files changed, 19 insertions(+), 15 deletions(-) + +commit 477bc9aafeaf89708d13a436869126351e2d9b50 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Oct 12 15:52:31 2018 -0400 + + Add hb-ot-name.h + + Actual name-fetching API to come later. + + New API: + hb_name_id_t + HB_NAME_ID_INVALID + + src/Makefile.sources | 1 + + src/hb-ot-layout-common.hh | 2 +- + src/hb-ot-layout.h | 12 ++--------- + src/hb-ot-name.h | 54 + ++++++++++++++++++++++++++++++++++++++++++++++ + src/hb-ot.h | 1 + + 5 files changed, 59 insertions(+), 11 deletions(-) + +commit dc49bd8d813571fe16d9e5342e4a3926ff947bd6 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Fri Oct 12 03:00:59 2018 +0330 + + Add two APIs for getting stylistic set labels + + * hb_ot_layout_feature_get_characters + * hb_ot_layout_feature_get_name_ids + + However HarfBuzz currently doesn't expose an API for retrieving + the actual + information associated with NameId from the `name` table and that + should be + done separately. + + docs/harfbuzz-sections.txt | 2 + + src/hb-ot-layout-common.hh | 14 +++++ + src/hb-ot-layout.cc | 133 + +++++++++++++++++++++++++++++++++++++++++++++ + src/hb-ot-layout.h | 29 ++++++++++ + test/api/CMakeLists.txt | 2 + + test/api/Makefile.am | 1 + + test/api/fonts/cv01.otf | Bin 0 -> 1956 bytes + test/api/test-ot-nameid.c | 96 ++++++++++++++++++++++++++++++++ + 8 files changed, 277 insertions(+) + +commit e9f9c0d81c73d8b6d87700aadb5b886bd289769a +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 21:37:45 2018 -0400 + + [sanitize] Reorder condition to silence bogus gcc warning + + Was givin a dozen of: + + ../../src/hb-machinery.hh: In member function ‘bool + AAT::ankr::sanitize(hb_sanitize_context_t*) const’: + ../../src/hb-machinery.hh:307:23: warning: missed loop optimization, + the loop counter may overflow [-Wunsafe-loop-optimizations] + bool ok = --this->max_ops > 0 && + ~~~~~~~~~~~~~~~~~~~~~~ + this->start <= p && + ~~~~~~~~~~~~~~~~~~~ + p <= this->end && + ~~~~~~~~~~~~~~~^~ + (unsigned int) (this->end - p) >= len; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + I believe those are bogus, but this silences them and does not + introduce + logic issues I believe. + + src/hb-machinery.hh | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 1a6b5ac6c300ed2ccdcd8eadde433120f6e07f2a +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 21:22:49 2018 -0400 + + Add HB_DEPRECATED_FOR and mark relevant symbols + + src/hb-common.h | 8 ++++++++ + src/hb-deprecated.h | 10 +++++----- + src/hb-graphite2.h | 2 +- + 3 files changed, 14 insertions(+), 6 deletions(-) + +commit c9413d7bb575093411b39ac21974795b6ad91454 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 21:19:39 2018 -0400 + + [graphite] Add HB_DEPRECATED annotation + + src/hb-graphite2.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 68c86af187ff645a1305ac3b64832f3bb2350519 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 21:18:20 2018 -0400 + + Always compile deprecated symbols + + We haven't been keeping this updated. So, while we don't expose the + symbols in the headers if HB_DISABLE_DEPRECATED is defined, we still + always build them. + + src/hb-font.cc | 4 ---- + 1 file changed, 4 deletions(-) + +commit c55100000bc20d7c8319cfc54294215a923ffc25 +Author: David Corbett <corbett.dav@husky.neu.edu> +Date: Thu Oct 11 22:08:14 2018 -0400 + + Add missing colons to GObject annotations + + src/hb-ot-tag.cc | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 1e816d62efe1b3540ef605092b97794e68ec0832 +Author: David Corbett <corbett.dav@husky.neu.edu> +Date: Thu Oct 11 20:37:49 2018 -0400 + + Fix Indic script tags in Graphite + + src/hb-graphite2.cc | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit bf8469be9a8932cc407b60daf4d494fef46e233b +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 20:45:00 2018 -0400 + + Attach CursivePositioning backwards, not forward + + This is how Uniscribe does it. So, adjust. This is only relevant + to fonts that apply cursive positioning from a contextual lookup. + + Fixes https://github.com/harfbuzz/harfbuzz/issues/1181 + + src/hb-ot-layout-gpos-table.hh | 20 + ++++++++++---------- + .../9fc3e6960b3520e5304033ef5fd540285f72f14d.ttf | Bin 0 -> 2380 bytes + .../data/in-house/tests/cursive-positioning.tests | 1 + + 3 files changed, 11 insertions(+), 10 deletions(-) + +commit bdb53ca24a5ad9671d8e29e17d1d8981505bd882 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 20:20:00 2018 -0400 + + [myanmar] Implement Zawgyi shaper + + Enabled if script tag 'Qaag' is passed to HarfBuzz. Disables mark + advance-zeroing and fallback mark-positioning. + + Fixes https://github.com/harfbuzz/harfbuzz/issues/1162 + + src/hb-ot-shape-complex-myanmar.cc | 22 + +++++++++++++++++++++ + src/hb-ot-shape-complex.hh | 5 +++++ + src/hb.hh | 8 ++++++++ + test/shaping/data/in-house/Makefile.sources | 1 + + .../ab14b4eb9d7a67e293f51d30d719add06c9d6e06.ttf | Bin 0 -> 1792 bytes + .../data/in-house/tests/myanmar-zawgyi.tests | 1 + + 6 files changed, 37 insertions(+) + +commit 00c5c4a79dfb352a679a5c56bf9c756ab0fa98d2 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 20:15:31 2018 -0400 + + [myanmar] Shuffle + + src/hb-ot-shape-complex-myanmar.cc | 33 +++++++++++++++++---------------- + 1 file changed, 17 insertions(+), 16 deletions(-) + +commit ec8f493bf9fefc33f027db24c4b175990b2d751c +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 20:15:00 2018 -0400 + + [graphite] Remove assert + + src/hb-graphite2.cc | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +commit 5646dcbd1125049c3af342fadfcfcbd523ce53d3 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 19:39:07 2018 -0400 + + Minor + + src/hb-ot-tag.cc | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +commit 788e1478557603d30966f12449eef0d0bd51c880 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 19:24:52 2018 -0400 + + [test] Add test for USE indic3 + + test/shaping/data/in-house/Makefile.sources | 1 + + .../fonts/3c96e7a303c58475a8c750bf4289bbe73784f37d.ttf | Bin 0 -> + 3364 bytes + test/shaping/data/in-house/tests/use-indic3.tests | 1 + + 3 files changed, 2 insertions(+) + +commit a11972787a2a90b541f92cc56bb885859390a0c0 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 19:23:36 2018 -0400 + + Minor + + test/shaping/record-test.sh | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +commit 654365dc894326f04abaaba415f48ca5ba2d1286 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 17:51:21 2018 -0400 + + Pass indic3 tags to USE shaper + + Fixes https://github.com/harfbuzz/harfbuzz/issues/539 + + src/hb-ot-shape-complex.hh | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +commit 28d091d045b042506a1ec2cdefe7cf0d718e8b22 +Author: David Corbett <corbett.dav@husky.neu.edu> +Date: Thu Oct 11 17:15:22 2018 -0400 + + Parse Indic3 tags + + src/hb-ot-tag.cc | 11 ++++++++--- + test/api/test-ot-tag.c | 44 +++++++++++++++++++++++++------------------- + 2 files changed, 33 insertions(+), 22 deletions(-) + +commit 211cd3691ba01b1cb2eeb8a91ac3532181791a8a +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 17:31:29 2018 -0400 + + Remove remains of get-codepoint-fuzzer + + test/fuzzing/CMakeLists.txt | 7 +------ + test/fuzzing/run-subset-fuzzer-tests.py | 12 ------------ + 2 files changed, 1 insertion(+), 18 deletions(-) + +commit 120ed0272569e6a34172a511d4a5a70a3a18f1d2 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 17:08:12 2018 -0400 + + [fuzzing] Fold get-codepoints-fuzzer into subset-fuzzer + + test/fuzzing/Makefile.am | 16 ---------------- + test/fuzzing/hb-subset-fuzzer.cc | 5 +++++ + test/fuzzing/hb-subset-get-codepoints-fuzzer.cc | 23 + ----------------------- + 3 files changed, 5 insertions(+), 39 deletions(-) + +commit 2c824d3644e16643c2bbe85fb88f9fb6fed53ce7 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 16:41:01 2018 -0400 + + [aat] Fix two wrongs that made a right before! + + Unfortunately our static asserts (DEFINE_SIZE_STATIC) don't actually + fail when used in templates, thanks to SFINAE. Le sighs. + + Probably fixes + https://oss-fuzz.com/v2/testcase-detail/5740171484463104 + + src/hb-aat-layout-common.hh | 4 ++-- + src/hb-open-type.hh | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +commit e940530c9723c3a581a5d5b31e5f419865dd6cc7 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 15:56:17 2018 -0400 + + [aat] Fix mul overflow + + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10897 + + src/hb-aat-layout-common.hh | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +commit 1d995a340b9e17fc8dca7a3e88e0918de2d8f02c +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 15:42:54 2018 -0400 + + Minor + + test/api/hb-subset-test.h | 6 ++---- + test/api/test-multithread.c | 5 +---- + test/fuzzing/main.cc | 2 +- + 3 files changed, 4 insertions(+), 9 deletions(-) + +commit 0744a02cb12e4d800abb611dfa5d268bb2dfd9f3 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 15:14:18 2018 -0400 + + [arabic] Update to latest UTR#53 + + From Lorna Evans: "That was a new character added to Unicode 11.0" + + src/hb-ot-shape-complex-arabic.cc | 1 + + 1 file changed, 1 insertion(+) + +commit 57b05210b1a8968d18ccbbe70879b2e11b6a09f2 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 15:03:21 2018 -0400 + + [test] Fix use of deprecated symbols + + test/api/test-ot-tag.c | 60 + ++++++++++++++++++++++++++++++++++++++------------ + 1 file changed, 46 insertions(+), 14 deletions(-) + +commit 4f9e36e8cf5d9d3d3e5a1ed46149355ee5f5e9fb +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 14:32:59 2018 -0400 + + [graphite] Remove deprecated symbol use + + src/hb-graphite2.cc | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +commit da591f2a9d2ae2a5878d3b2ef78a6d589b19aab0 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 14:30:15 2018 -0400 + + Whitespace + + src/hb-ot-tag.cc | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +commit 4d205f0462b19f371df495b9cc12c0128f507de9 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 14:25:48 2018 -0400 + + [graphite] Fix deva/dev2 resolution + + See + https://github.com/harfbuzz/harfbuzz/pull/730#issuecomment-428277800 + + src/hb-graphite2.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 8061664ad1a5933098adc3bc1dca0b5be48586ef +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 14:16:55 2018 -0400 + + Add doc stubs for recently added API + + Thanks to David Corbett who revamped our script and language + processing + and implemented full BCP 47 support. + + https://github.com/harfbuzz/harfbuzz/pull/730 + + New API: + +hb_ot_layout_table_select_script() + +hb_ot_layout_script_select_language() + +HB_OT_MAX_TAGS_PER_SCRIPT + +HB_OT_MAX_TAGS_PER_LANGUAGE + +hb_ot_tags_from_script_and_language() + +hb_ot_tags_to_script_and_language() + + Deprecated API: + -hb_ot_layout_table_choose_script() + -hb_ot_layout_script_find_language() + -hb_ot_tags_from_script() + -hb_ot_tag_from_language() + + src/hb-ot-layout.cc | 10 ++++++++++ + src/hb-ot-tag.cc | 21 ++++++++++++++++----- + src/hb-ot-tag.h | 10 ++++++++++ + src/hb-unicode.h | 2 +- + 4 files changed, 37 insertions(+), 6 deletions(-) + +commit cf975ac653bff369f4ed7ba7fc04fae6ce2cec95 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 14:07:44 2018 -0400 + + Remove use of deprecated function + + src/hb-ot-layout.cc | 23 ++++++++++++----------- + src/hb-ot-layout.h | 12 ++++++------ + 2 files changed, 18 insertions(+), 17 deletions(-) + +commit 66790d64c7120b75c72bf91c769dc52d95858909 +Author: David Corbett <corbett.dav@husky.neu.edu> +Date: Mon Sep 10 13:15:00 2018 -0400 + + Increase HB_OT_MAX_TAGS_PER_SCRIPT to 3 + + No script has 3 tags yet, but the plan is for the Indic scripts + to each + get a third tag someday. + + src/hb-ot-tag.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit bca7a16938609539e4adb5cdf943734b7dfa1561 +Author: David Corbett <corbett.dav@husky.neu.edu> +Date: Mon Sep 10 12:05:51 2018 -0400 + + Update language system tag registry to OT 1.8.3 + + src/gen-tag-table.py | 10 +++++++++- + src/hb-ot-tag-table.hh | 44 +++++++++++++++++++++++++++++++++----------- + 2 files changed, 42 insertions(+), 12 deletions(-) + +commit 7f1fbfe2e312f397db9271dd17a8e701489ffc79 +Author: David Corbett <corbett.dav@husky.neu.edu> +Date: Mon Jul 23 21:19:23 2018 -0400 + + Add hb_ot_tags_to_script_and_language + + docs/harfbuzz-sections.txt | 3 +- + src/hb-ot-map.cc | 2 +- + src/hb-ot-tag.cc | 75 + ++++++++++++++++++++++++++++++++++++++++------ + src/hb-ot-tag.h | 18 +++++++---- + test/api/test-ot-tag.c | 33 ++++++++++++++++++-- + 5 files changed, 112 insertions(+), 19 deletions(-) + +commit 3f8877473fb4c72a6f3edfcfc927b9993a5f3616 +Author: David Corbett <corbett.dav@husky.neu.edu> +Date: Thu Jul 19 13:48:07 2018 -0400 + + Switch on the first char of a complex language tag + + This results in a tenfold speed-up for the common case of tags + that are + not complex, in the sense of `hb_ot_tags_from_complex_language`. + + src/gen-tag-table.py | 171 ++++-- + src/hb-ot-tag-table.hh | 1580 + ++++++++++++++++++++++++------------------------ + 2 files changed, 922 insertions(+), 829 deletions(-) + +commit a754d44195021603306af2a296d06187eda95409 +Author: David Corbett <corbett.dav@husky.neu.edu> +Date: Mon Jul 16 21:14:48 2018 -0400 + + Map Quechua languages to closest ones with tags + + OpenType only officially maps four ISO 639 codes to Quechua languages, + but prior versions of HarfBuzz also mapped qu to 'QUZ '. Because qu + is a + macrolanguage, the mapping now applies to all individual Quechua + languages. OpenType calls 'QUZ ' "Quechua", but it really corresponds + to + Cusco Quechua, so the individual Quechua languages should not all + necessarily be mapped to it. + + src/gen-tag-table.py | 32 ++++++++++++++++++++++++++ + src/hb-ot-tag-table.hh | 62 + +++++++++++++++++++++++++++----------------------- + 2 files changed, 65 insertions(+), 29 deletions(-) + +commit 65d01f77552a5102ee114d9917fd2ecf091a35c3 +Author: David Corbett <corbett.dav@husky.neu.edu> +Date: Thu Jan 18 16:33:39 2018 -0500 + + Test deprecated tag fallback in a font + + The font supports the deprecated tag 'DHV ' instead of 'DIV '. dv is + mapped to 'DIV ' and 'DHV ', in that order. The test specifies + `--language=dv`, demonstrating that if a font does not support + the first + OpenType tag mapped to a BCP 47 tag, it will fall back to the + next tag. + + .../fonts/d3129450fafe5e5c98cfc25a4e71809b1b4d2855.ttf | Bin 0 -> + 956 bytes + test/shaping/data/in-house/tests/language-tags.tests | 1 + + 2 files changed, 1 insertion(+) + +commit 7c7cb2a98907d99ca86bdbfca0bf9c48bfa4ed49 +Author: David Corbett <corbett.dav@husky.neu.edu> +Date: Sat Jan 20 15:53:09 2018 -0500 + + Match extlang subtags + + If the second subtag of a BCP 47 tag is three letters long, it denotes + an extended language. The tag converter ignores the language + subtag and + uses the extended language instead. + + There are some grandfathered exceptions, which are handled earlier. + + src/gen-tag-table.py | 2 +- + src/hb-ot-tag-table.hh | 21 +++++++++++++++++++++ + src/hb-ot-tag.cc | 10 +++++++++- + test/api/test-ot-tag.c | 7 +++++++ + 4 files changed, 38 insertions(+), 2 deletions(-) + +commit 2f1f961cc0f0f907916b4b00342d8a2dda8b4ee1 +Author: David Corbett <corbett.dav@husky.neu.edu> +Date: Fri Dec 8 22:45:52 2017 -0500 + + Autogenerate the BCP 47 to OpenType mappings + + The new script, gen-tag-table.py, generates `ot_languages` + automatically + from the [OpenType language system tag registry][ot] and the [IANA + Language Subtag Registry][bcp47] with some manual modifications. If an + OpenType tag maps to a BCP 47 macrolanguage, all the macrolanguage's + individual languages are mapped to the same OpenType tag, except for + individual languages with their own OpenType mappings. Deprecated + BCP 47 tags are canonicalized. + + [ot]: + https://docs.microsoft.com/en-us/typography/opentype/spec/languagetags + [bcp47]: + https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry + + Some OpenType tags correspond to multiple ISO 639 codes. The mapping + from ISO 639 codes lists OpenType tags in priority order, such + that more + specific or more likely tags appear first. + + Some OpenType tags have no corresponding ISO 639 code in the + registry so + their mappings use BCP 47 subtags besides the language. For example, + any + BCP 47 tag with a fonipa variant subtag is mapped to 'IPPH', and + 'IPPH' + is mapped back to und-fonipa. + + Other OpenType tags have no corresponding ISO 639 code because it + is not + clear what they are for. HarfBuzz just ignores these tags. + + One such ignored tag is 'ZHP ' (Chinese Phonetic). It probably means + zh-Latn. However, it is used in Microsoft JhengHei and Microsoft YaHei + with the script tag 'hani', implying that it is not a romanization + scheme after all. It would be simple enough to add this mapping to + gen-tag-table.py once a definitive mapping is determined. + + The manual modifications are mainly either obvious mappings that the + OpenType registry omits or mappings for compatibility with previous + versions of HarfBuzz. Some of the old mappings were discarded, though, + for homophonous language names. For example, OpenType maps 'KUI ' to + kxu; previous versions of HarfBuzz also mapped it to kvd, because kvd + and kxu both happen to be called "Kui". + + gen-tag-table.py also generates a function to convert multi-subtag + tags + like el-polyton and zh-HK to OpenType tags, replacing + `ot_languages_zh` + and the hard-coded list of special cases in + `hb_ot_tags_from_language`. + It also generates a function to convert OpenType tags to BCP 47, + replacing the hard-coded list of special cases in + `hb_ot_tag_to_language`. + + src/Makefile.am | 9 +- + src/Makefile.sources | 1 + + src/gen-tag-table.py | 1013 ++++++++++++++++++++++++ + src/hb-ot-tag-table.hh | 1997 + ++++++++++++++++++++++++++++++++++++++++++++++++ + src/hb-ot-tag.cc | 842 +------------------- + src/hb-ot-tag.h | 2 +- + test/api/test-ot-tag.c | 66 +- + 7 files changed, 3092 insertions(+), 838 deletions(-) + +commit 2c7d4db7af16e228bb30eddf7334a524b74ae26c +Author: David Corbett <corbett.dav@husky.neu.edu> +Date: Fri Dec 29 20:19:05 2017 +0800 + + Deprecate obsolete functions + + `hb_ot_tags` replaces `hb_ot_tags_from_script` and + `hb_ot_tag_from_language`. + + `hb_ot_layout_table_select_script` replaces + `hb_ot_layout_table_choose_script`. + + `hb_ot_layout_script_select_language` replaces + `hb_ot_layout_script_find_language`. + + docs/harfbuzz-sections.txt | 8 ++++---- + src/hb-deprecated.h | 23 +++++++++++++++++++++++ + src/hb-ot-layout.h | 15 --------------- + src/hb-ot-tag.h | 8 -------- + 4 files changed, 27 insertions(+), 27 deletions(-) + +commit 91067716f5e7b15d9a642f69019246c83fc7c108 +Author: David Corbett <corbett.dav@husky.neu.edu> +Date: Fri Dec 8 11:21:14 2017 -0500 + + Refactor the selection of script and language tags + + The old hb-ot-tag.cc functions, `hb_ot_tags_from_script` and + `hb_ot_tag_from_language`, are now wrappers around a new function: + `hb_ot_tags`. It converts a script and a language to arrays of script + tags and language tags. This will make it easier to add new script + tags + to scripts, like 'dev3'. It also allows for language fallback chains; + nothing produces more than one language yet though. + + Where the old functions return the default tags 'DFLT' and 'dflt', + `hb_ot_tags` returns an empty array. The caller is responsible for + using the default tag in that case. + + The new function also adds a new private use subtag syntax for script + overrides: "x-hbscabcd" requests a script tag of 'abcd'. + + The old hb-ot-layout.cc functions,`hb_ot_layout_table_choose_script` + and + `hb_ot_layout_script_find_language` are now wrappers around the new + functions `hb_ot_layout_table_select_script` and + `hb_ot_layout_script_select_language`. They are essentially the + same as + the old ones plus a tag count parameter. + + Closes #495. + + docs/harfbuzz-sections.txt | 5 + + src/hb-ot-layout.cc | 43 +- + src/hb-ot-layout.h | 16 + + src/hb-ot-map.cc | 13 +- + src/hb-ot-tag.cc | 1639 + ++++++++++++++++++++++++-------------------- + src/hb-ot-tag.h | 11 + + test/api/test-ot-tag.c | 107 +++ + 7 files changed, 1070 insertions(+), 764 deletions(-) + +commit a03f5f4dfbbf885db567c3909241a55eb5869fce +Author: David Corbett <corbett.dav@husky.neu.edu> +Date: Thu Dec 28 22:59:29 2017 +0800 + + Replace "ISO 639" with "BCP 47" + + `hb_language_from_string` accepts not only ISO 639 but also BCP + 47. Not + all ISO 639 codes are valid BCP 47 tags but the function does + not accept + overlong language subtags anyway. + + src/hb-buffer.cc | 2 +- + src/hb-common.cc | 6 +++--- + 2 files changed, 4 insertions(+), 4 deletions(-) + +commit 0b9d60e1a1c4b7867ac907bbd7c004191a14e697 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 13:26:58 2018 -0400 + + [aat] Apply kerx if GPOS kern was not applied + + Ned tells me this is what Apple does. + + src/hb-ot-shape.cc | 18 ++++++++---------- + 1 file changed, 8 insertions(+), 10 deletions(-) + +commit b59a428af08d6451a47f40ed01e594815ebf6303 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 13:24:17 2018 -0400 + + Minor + + src/hb-ot-shape.cc | 6 +++++- + src/hb-ot-shape.hh | 5 +++-- + 2 files changed, 8 insertions(+), 3 deletions(-) + +commit 100e95f48e3d137c654d206e858d6419ea62a12c +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 11:30:45 2018 -0400 + + [trak] Add tests + + test/shaping/data/in-house/Makefile.sources | 1 + + test/shaping/data/in-house/fonts/TestTRAK.ttf | Bin 0 -> 2456 bytes + test/shaping/data/in-house/tests/aat-trak.tests | 8 ++++++++ + 3 files changed, 9 insertions(+) + +commit 04f72e8990ea61ffc6b62105c75e0a3e1b1ebab4 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 11:25:07 2018 -0400 + + [trak] Implement extrapolation + + This concludes trak, as well as AAT shaping support! + + src/hb-aat-layout-trak-table.hh | 39 + ++++++++++++++++++++------------------- + 1 file changed, 20 insertions(+), 19 deletions(-) + +commit d6a12dba6da6262fd9e5d8397b46ac8516136cae +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 11:10:06 2018 -0400 + + [trak] Fix, and hook up + + Works beautifully! Test coming. + + src/hb-aat-layout-common.hh | 4 ++-- + src/hb-aat-layout-trak-table.hh | 6 ++++-- + src/hb-aat-layout.cc | 25 ++++++++++++++++++++++++- + src/hb-aat-layout.hh | 8 ++++++++ + src/hb-ot-shape.cc | 2 ++ + 5 files changed, 40 insertions(+), 5 deletions(-) + +commit 3d7dea6dfdc9e75dcca100a79525aa3736dbe29c +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 10:32:08 2018 -0400 + + [trak] Handle nSizes=0 and 1 + + src/hb-aat-layout-trak-table.hh | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +commit 451f3de521ff1b7f4d3b8ebb2cc0b95d88c9314a +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 10:30:32 2018 -0400 + + [trak] Fix counting + + src/hb-aat-layout-trak-table.hh | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit a5be380cae9b49ed85c8620f1921209ef61a72ad +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 10:29:02 2018 -0400 + + [trak] More + + src/hb-aat-layout-trak-table.hh | 26 +++++++++++++++++--------- + 1 file changed, 17 insertions(+), 9 deletions(-) + +commit d06c4a867f0d383d8c27f2957e646d9e3fe6853b +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 10:22:01 2018 -0400 + + [trak] Only adjust around first glyph + + Assumes graphemes only have one base glyph. + + src/hb-aat-layout-trak-table.hh | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +commit 071a2cbcddcbafae9458e674c21db5001b39518d +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 10:18:46 2018 -0400 + + [trak] Clean up + + src/hb-aat-layout-trak-table.hh | 67 + +++++++++++++++++++++++------------------ + 1 file changed, 37 insertions(+), 30 deletions(-) + +commit fbbd926dba163d9a2a6a62f380951f03363c2b14 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 01:22:29 2018 -0400 + + [kerx] Implement Format4 action_type=1 contour-point-based attachment + + Untested. + + This concludes kerx table support! + + src/hb-aat-layout-kerx-table.hh | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +commit b6bc0d4ff62e4509643db3b304306a72bbcb2c38 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 01:17:57 2018 -0400 + + [kerx] Implement Format4 action_type=2 coordinate-based attachment + + Untested. + + src/hb-aat-layout-kerx-table.hh | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) + +commit 1622ba5943d14b2d50d45dc17fb723f4c9ddb0bb +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 01:14:18 2018 -0400 + + [kerx] Implement Format4 'ankr'-based mark attachment + + Tested with Kannada MN: + + $ HB_OPTIONS=aat ./hb-shape Kannada\ MN.ttc -u 0CCD,0C95,0CD6 + [kn_ka.vattu=0+230|kn_ai_length_mark=1@326,0+607] + + src/hb-aat-layout-common.hh | 8 ++++++-- + src/hb-aat-layout-kerx-table.hh | 20 +++++++++++++++++--- + src/hb-aat-layout.cc | 20 ++++++++++++++++---- + src/hb-ot-layout-gpos-table.hh | 4 ---- + 4 files changed, 39 insertions(+), 13 deletions(-) + +commit 7bb4da7d9538f3d4b1d28030d43e0c3d720d821b +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 00:52:07 2018 -0400 + + [aat] Wire up 'ankr' table to apply context + + src/hb-aat-layout-common.hh | 7 +++++-- + src/hb-aat-layout.cc | 8 +++++++- + 2 files changed, 12 insertions(+), 3 deletions(-) + +commit 28f0367aab648c486d6e8d0e13dbbb2af1b65dcc +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 11 00:12:49 2018 -0400 + + [kerx] Flesh out Format4 + + Doesn't apply actions yet. + + src/hb-aat-layout-kerx-table.hh | 122 + ++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 118 insertions(+), 4 deletions(-) + +commit 947962a287d9aca2cb509c11f44cb5150aa6daf1 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 23:07:03 2018 -0400 + + [ankr] Implement table access + + src/hb-aat-layout-ankr-table.hh | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +commit 7281cb3eeb00091c6e6085895afd4a38a0516f35 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 22:56:52 2018 -0400 + + [ankr] Start fixing + + src/hb-aat-layout-ankr-table.hh | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +commit 34caadc5c78e3d09faf11ef60bfade8f64f55de2 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 22:17:07 2018 -0400 + + Ugh. Re-enable accidentally disabled GPOS + + src/hb-ot-shape.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit f7c45bc33ec1559c960a039b770d5c37bd82f057 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 22:15:13 2018 -0400 + + [kerx] Allow granularly disabling kerning + + src/hb-aat-layout-kerx-table.hh | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +commit 2b72c4b63d29eea39b646c8a1a1cfc2db732e1a6 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 21:53:14 2018 -0400 + + [kerx] Comment + + src/hb-aat-layout-kerx-table.hh | 3 +++ + 1 file changed, 3 insertions(+) + +commit 9f450f07b0a1593962e3b45d00f2cf93916f3466 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 21:46:58 2018 -0400 + + [kerx] Make Format1 work + + Tested using Kannada MN: + + $ HB_OPTIONS=aat ./hb-shape Kannada\ MN.ttc -u 0C95,0CCd,C95,CCD + [kn_ka.virama=0+1299|kn_ka.vattu=0+115|_blank=0@-115,0+385] + + $ HB_OPTIONS=aat ./hb-shape Kannada\ MN.ttc -u 0C95,0CCd,C95,CCD + --features=-kern + [kn_ka.virama=0+1799|kn_ka.vattu=0+230|_blank=0+0] + + I don't see the GPOS table in the font do the same. ¯\_(ツ)_/¯ + + src/hb-aat-layout-kerx-table.hh | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +commit 504cb68fc972c7f606bf9fc62015376382f78f45 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 21:29:46 2018 -0400 + + Disable mark advance zeroing as well as mark fallback positioning + if doing kerx + + src/hb-ot-shape.cc | 50 + ++++++++++++++++++++++++++------------------------ + 1 file changed, 26 insertions(+), 24 deletions(-) + +commit 84967537966a76297c89460d95e7336f1bfc332d +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 21:18:37 2018 -0400 + + [kerx] Implement Format1 + + Untested. + + src/hb-aat-layout-kerx-table.hh | 62 + +++++++++++++++++++++++++++++++++-------- + src/hb-aat-layout-morx-table.hh | 2 +- + 2 files changed, 52 insertions(+), 12 deletions(-) + +commit c9165f5450b99e6d93e2a168b198384a221eef58 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 20:43:21 2018 -0400 + + [kerx] More UnsizedArrayOf<> + + src/hb-aat-layout-kerx-table.hh | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +commit ca54eba4846d0afda4601929556617a7ebe51714 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 20:41:16 2018 -0400 + + [kerx] Fix bound-checking error introduced a couple commits past + + src/hb-aat-layout-kerx-table.hh | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 339036dd970625e03696b4533ced1e25fc4fd131 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 20:37:22 2018 -0400 + + [kerx] Start fleshing out Format1 + + src/hb-aat-layout-kerx-table.hh | 59 + +++++++++++++++++++++++++++++++++++------ + src/hb-aat-layout-morx-table.hh | 2 +- + 2 files changed, 52 insertions(+), 9 deletions(-) + +commit ab1f30bd059f1d2270793e9726b60666b328d2b8 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 20:10:20 2018 -0400 + + [kerx] Implement Format6 + + Untested. The only Apple font shipping with this format is San + Francisco fonts + that use this for their kerx variation tables, which we don't support. + + src/hb-aat-layout-kerx-table.hh | 73 + +++++++++++++++++++++++++++++++++-------- + 1 file changed, 60 insertions(+), 13 deletions(-) + +commit c9a2ce9e05f91730a2150b9214dc6a49f31555c1 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 20:00:44 2018 -0400 + + [kerx] Move bounds-checking to subtable length itself + + src/hb-aat-layout-kerx-table.hh | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +commit 22955b23cdeb48e46cdffd0eb906a855a420c4d1 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 19:58:20 2018 -0400 + + [kerx] Start fleshing out Format6 + + src/hb-aat-layout-kerx-table.hh | 42 + ++++++++++++++++++++++++++++++++--------- + src/hb-open-type.hh | 3 +++ + 2 files changed, 36 insertions(+), 9 deletions(-) + +commit f6aaad9b4ffb42e6cd8398f6439fe420e393c8f6 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 19:20:06 2018 -0400 + + [kerx] When rejecting variable kerning, also check for tupleCount + + src/hb-aat-layout-kerx-table.hh | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 7ed5366d3cfca9c533250cb419e8cc878f32505d +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 19:11:30 2018 -0400 + + [kerx] No-op + + Tested that Format0 works with Kannada MN font: + + $ make -j5 lib -s && HB_OPTIONS=aat ./hb-shape Kannada\ MN.ttc + -u 0C95,0CC2 + [kn_ka=0+1000|kn_matra_uu=0@-30,0+1345] + + $ make -j5 lib -s && HB_OPTIONS=aat ./hb-shape Kannada\ MN.ttc -u + 0C95,0CC2 --features=-kern + [kn_ka=0+1030|kn_matra_uu=0+1375] + + Note that GPOS does the same with 'dist' feature, and applies the + whole difference to the + same glyph: + + $ make -j5 lib -s && ./hb-shape Kannada\ MN.ttc -u 0C95,0CC2 + [kn_ka=0+970|kn_matra_uu=0+1375] + + $ make -j5 lib -s && ./hb-shape Kannada\ MN.ttc -u 0C95,0CC2 + --features=-dist + [kn_ka=0+1030|kn_matra_uu=0+1375] + + src/hb-aat-layout-kerx-table.hh | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +commit 7fa69e92ca3dd9d8fa92aba0e01098165d2b7975 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 19:02:32 2018 -0400 + + Comment + + src/hb-machinery.hh | 7 +++++++ + 1 file changed, 7 insertions(+) + +commit 7e6e5bf6147596d6d096e2ba37f3a6eefd7429cd +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 18:59:07 2018 -0400 + + Fix option string matching + + src/hb-common.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 5d34164d98f04816aafaa0abfc44cd899c7d70b3 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 18:14:41 2018 -0400 + + [kern/kerx] Fix offset base + + Disable kern Format2. + + Fix kerx Format2. Manually tested this with Tamil MN font and + it works: + + $ HB_OPTIONS=aat ./hb-shape Tamil\ MN.ttc -u 0B94,0B95 + [tgv_au=0+3435|tgc_ka=1@-75,0+1517] + + HB_OPTIONS=aat ./hb-shape Tamil\ MN.ttc -u 0B94,0B95 --features=-kern + [tgv_au=0+3510|tgc_ka=1+1592] + + src/hb-aat-layout-kerx-table.hh | 73 + +++++++++++++++++++++++++---------------- + src/hb-ot-kern-table.hh | 7 ++++ + 2 files changed, 52 insertions(+), 28 deletions(-) + +commit 60f86d32d7c735ccf783b382e18ecdc096eaa682 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 18:10:05 2018 -0400 + + [kerx] Don't loop over kerning subtables if kerning disabled + + src/hb-aat-layout-kerx-table.hh | 12 ++++++++++++ + src/hb-ot-shape.cc | 4 ++-- + src/hb-ot-shape.hh | 1 + + 3 files changed, 15 insertions(+), 2 deletions(-) + +commit 38a7a8a89ed035a1d1fc34a675a1860ad660b6ff +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 17:44:46 2018 -0400 + + Allow HB_OPTIONS=aat to prefer AAT tables over OT + + Fixes https://github.com/harfbuzz/harfbuzz/issues/322 + + src/hb-common.cc | 23 +++++++++++++++++++++-- + src/hb-debug.hh | 7 ++++--- + src/hb-ot-shape.cc | 24 ++++++++++++++++-------- + 3 files changed, 41 insertions(+), 13 deletions(-) + +commit 44f09afd5bd4f4f1ea47ca54ac9d605219b06910 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 17:32:32 2018 -0400 + + [kerx] Skip variation subtables + + src/hb-aat-layout-kerx-table.hh | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +commit 1e8fdd285f90b7b715b6d9ca9222a3c91cbea6b8 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 16:32:35 2018 -0400 + + Remove HAVE_OT + + We never tested compiling without it. Just kill it. We always build + our own shaper. + + CMakeLists.txt | 1 - + configure.ac | 6 ------ + src/Makefile.am | 2 -- + src/hb-shaper-list.hh | 2 -- + src/hb.hh | 2 -- + test/api/Makefile.am | 4 +--- + test/api/test-c.c | 5 +---- + util/Makefile.am | 4 ---- + util/options.cc | 4 ---- + util/options.hh | 2 -- + 10 files changed, 2 insertions(+), 30 deletions(-) + +commit 7727e737566ddc826647e19fc645b296ad5a0cac +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 13:24:51 2018 -0400 + + [kerx] Actually hook up, and fix crash + + src/hb-aat-layout-common.hh | 6 ++++++ + src/hb-aat-layout-kerx-table.hh | 4 ++-- + src/hb-ot-shape.cc | 4 ++-- + 3 files changed, 10 insertions(+), 4 deletions(-) + +commit b3390990f508def9c375716614b92fc7b0038228 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 12:07:49 2018 -0400 + + Add per-subtable set-digests + + This speeds up Roboto shaping by ~10%. I was hoping for more. + Still, good defense against lookups with many subtables. + + src/hb-null.hh | 2 +- + src/hb-ot-layout-gsubgpos.hh | 108 + +++++++++++++++++++++++-------------------- + 2 files changed, 59 insertions(+), 51 deletions(-) + +commit e78549edfb4df617128a5f5ddd12692f1d0af4bf +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 11:54:48 2018 -0400 + + Move apply down into subtables accel + + src/hb-ot-layout-gsubgpos.hh | 10 +++++++++- + src/hb-ot-layout.cc | 17 +++-------------- + 2 files changed, 12 insertions(+), 15 deletions(-) + +commit 78c09bf21335a0f2b538b37de6647af08e3b1161 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 11:50:46 2018 -0400 + + Move subtable array into lookup accel + + src/hb-null.hh | 2 +- + src/hb-ot-layout-gsubgpos.hh | 14 +++++++++++--- + src/hb-ot-layout.cc | 16 ++++++---------- + 3 files changed, 18 insertions(+), 14 deletions(-) + +commit 97e5913d5ac2cd313fb3923e9602358d7f75f11d +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 11:41:05 2018 -0400 + + Move more code + + src/hb-ot-layout-gsubgpos.hh | 17 +++++++++++++++++ + src/hb-ot-layout.cc | 12 ++++++------ + src/hb-ot-layout.hh | 20 ++------------------ + src/hb-ot-shape-complex-arabic-fallback.hh | 2 +- + 4 files changed, 26 insertions(+), 25 deletions(-) + +commit c8f2d9334c0f91ec30f1c7821eb44bb5149bd31c +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 11:36:28 2018 -0400 + + Move code + + In preparation to move add per-subtable set digests... + + src/hb-ot-layout-gsubgpos.hh | 50 ++++++++++++++++++++++++++++++++++++++ + src/hb-ot-layout.cc | 57 + ++++---------------------------------------- + 2 files changed, 54 insertions(+), 53 deletions(-) + +commit a03850a3567d532c3a4d7655aa71bfe73dfb0e33 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 10:57:28 2018 -0400 + + Fix GPOS/kern interaction + + Oops. Was checking for kern feature in GSUB, not GPOS. + + src/hb-ot-shape.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit d1be805e784dfaadf2ce9caa830a3f851fdd67da +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 10:49:45 2018 -0400 + + More rewriting plan compile + + Hopefully more clear. + + src/hb-ot-shape.cc | 55 + ++++++++++++++++++++++++++++++++++++++---------------- + src/hb-ot-shape.hh | 1 - + 2 files changed, 39 insertions(+), 17 deletions(-) + +commit 961ab46b24ca9f3ef42a56398646191f106bf5bd +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 10:42:10 2018 -0400 + + More reshuffle plan compile + + src/hb-ot-shape.cc | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +commit 2091b509e3e3b7fb7315539679fae81da2879280 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 10:41:08 2018 -0400 + + [kerx] Hook up to shaper + + src/hb-aat-layout.cc | 31 ++++++++++++++++++++++++------- + src/hb-aat-layout.hh | 3 +++ + src/hb-ot-shape.cc | 6 ++++-- + src/hb-ot-shape.hh | 1 + + 4 files changed, 32 insertions(+), 9 deletions(-) + +commit 8d00c39bfc558895c63e22148d88db51cde39164 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 10:18:39 2018 -0400 + + [kern] Minor + + src/hb-ot-shape-fallback.cc | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +commit e655fd38cf20eefb1c071a52282a4caccb6f08ea +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 10:16:09 2018 -0400 + + Apply TT or fallback kerning when GPOS does not have kern feature + + Previously we only did if there was no GPOS whatsoever. This applies + to Arial, Times New Roman, etc in Win7. Was not kerning before. It + is now. + + src/hb-ot-shape.cc | 25 ++++++++++++++++--------- + 1 file changed, 16 insertions(+), 9 deletions(-) + +commit 754cf440bf80ced36461a98a5d4607a700f44fd3 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 10 10:04:05 2018 -0400 + + Minor + + src/hb-ot-shape-fallback.cc | 2 ++ + 1 file changed, 2 insertions(+) + +commit 187df7d7a9a1d9cd67cb2f72d4d6ed8cae1eed61 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Wed Oct 10 17:12:52 2018 +0330 + + [circleci] Add an iOS bot (#1233) + + .circleci/config.yml | 12 +++++ + CMakeLists.txt | 140 + ++++++++++++++++++++++++++++++++------------------- + 2 files changed, 100 insertions(+), 52 deletions(-) + +commit 0537a40193e803d50a99cd6b993d6d9301e84ebf +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 23:35:07 2018 -0400 + + [kerx] Comment + + src/hb-aat-layout-kerx-table.hh | 2 +- + src/hb-ot-kern-table.hh | 1 + + 2 files changed, 2 insertions(+), 1 deletion(-) + +commit 362d3241195bb7054c395fb4b029b6d55da4612a +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 23:27:00 2018 -0400 + + [aat] Rename + + src/hb-aat-layout-kerx-table.hh | 4 ++-- + src/hb-aat-layout-morx-table.hh | 6 +++--- + 2 files changed, 5 insertions(+), 5 deletions(-) + +commit 54c9ecb92d196e62901eef3f8bc025c024ed16bb +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 23:18:19 2018 -0400 + + [morx] Use subtable range for embedded sanitizer here as well + + src/hb-aat-layout-morx-table.hh | 2 ++ + 1 file changed, 2 insertions(+) + +commit d35315cc028e70dd1b3ffc8cb079a2336b22a0c3 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 23:17:32 2018 -0400 + + [aat] Fixup recent commit + + For 329f2401082011007d9ce12b15ce0225cd267c57 + + max_ops is signed. + + src/hb-aat-layout-common.hh | 2 +- + src/hb-machinery.hh | 5 ++++- + 2 files changed, 5 insertions(+), 2 deletions(-) + +commit 948f59a13a4c643ae310f5fc643e29fefd6c3787 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 23:07:47 2018 -0400 + + [kerx] Use subtable range for runtime checks + + src/hb-aat-layout-kerx-table.hh | 4 +++- + src/hb-machinery.hh | 8 ++++++++ + 2 files changed, 11 insertions(+), 1 deletion(-) + +commit 329f2401082011007d9ce12b15ce0225cd267c57 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 23:02:53 2018 -0400 + + [aat] Set embedded sanitizer max ops really high + + Since we consume it legitimately during shaping. + + src/hb-aat-layout-common.hh | 1 + + src/hb-machinery.hh | 2 ++ + 2 files changed, 3 insertions(+) + +commit ad763074861da60ed51211931788ca5b27fc1512 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 22:57:00 2018 -0400 + + [kerx] Comment + + src/hb-aat-layout-kerx-table.hh | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +commit db9600bbe15035cea6c2d4e8e9d184a5e23e357e +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 22:55:47 2018 -0400 + + [kerx] Remove junk + + src/hb-aat-layout-kerx-table.hh | 16 ---------------- + 1 file changed, 16 deletions(-) + +commit 27db859416c0362f211e2b42dc9a2ebb53b0e0f4 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 22:52:41 2018 -0400 + + [kern/kerx] Adjust bounds check + + src/hb-aat-layout-kerx-table.hh | 8 +++----- + src/hb-ot-kern-table.hh | 8 +++----- + 2 files changed, 6 insertions(+), 10 deletions(-) + +commit c66f7f8c5deaac109e34bf65fc16cff92b74e69a +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 22:49:33 2018 -0400 + + [kerx] Implement Format2 apply() + + Still, not hooked. + + src/hb-aat-layout-kerx-table.hh | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +commit 4b461785bdf356e4b5586cb6e5b226f47da04b7d +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 22:46:30 2018 -0400 + + Fix check + + src/hb-aat-layout-kerx-table.hh | 2 ++ + src/hb-aat-layout.cc | 4 +++- + 2 files changed, 5 insertions(+), 1 deletion(-) + +commit 4df8eb200def767d342762654b96d5d9314e5b21 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 22:46:12 2018 -0400 + + [kern] Use kern subtable length for sanitizing in the accelerator + + src/hb-ot-kern-table.hh | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +commit 8bff1d2994876a5202c8605d1cc37522431c6c84 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 22:39:31 2018 -0400 + + [kern] Minor + + src/hb-ot-kern-table.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 53e55945000347fb19168bb4c13a470d30d46251 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 22:35:22 2018 -0400 + + [kerx] Implement Format0 apply() + + Not hooked up to be called yet. + + src/hb-aat-layout-common.hh | 6 ++++-- + src/hb-aat-layout-kerx-table.hh | 29 ++++++++++++++++++++++++++--- + src/hb-aat-layout.cc | 6 ++++-- + src/hb-aat-layout.hh | 12 +++++++----- + src/hb-ot-shape.cc | 2 +- + 5 files changed, 42 insertions(+), 13 deletions(-) + +commit 60318f87153b559e5da103f0bfcce6bad8bab3b0 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 22:25:53 2018 -0400 + + Minor + + src/hb-mutex.hh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 210f899acad1959d60892538ac1968a36dbbb51b +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 21:56:37 2018 -0400 + + [kern] Sanitize 4 bytes, not 2 + + src/hb-ot-kern-table.hh | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit be2f148da474d6dd30132c22dd467ea33a942edf +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 16:24:50 2018 -0400 + + [ft] Use mutex to lock access to FT_Face + + Makes our FT-backed hb_font_t safe to use from multiple threads. + Still, + the underlying FT_Face should NOT be used from other threads by client + or other libraries. + + Maybe I add a lock()/unlock() public API ala PangoFT2 and cairo-ft. + Maybe not. + + src/hb-ft.cc | 18 +++++++++++++++++- + src/hb-mutex.hh | 8 ++++++++ + test/api/test-multithread.c | 7 ++----- + 3 files changed, 27 insertions(+), 6 deletions(-) + +commit d18c3c5861d40291077eb8b8667dc2f12b649cf2 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 16:07:55 2018 -0400 + + [ft] Remove (probably) stale comment + + src/hb-ft.cc | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +commit 7003b601afd02b0ba7e839510a7d0b886da09aaa +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 15:55:26 2018 -0400 + + Minor + + src/hb-ot-shape-complex-arabic.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 07899435b8065d494e563f83e0a35300c828eefe +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 15:39:51 2018 -0400 + + Install ot-funcs on newly created funcs + + **Finally**! Casual users can stop caring about font-funcs + completely now, + like they haven't been needing to care re unicode-funcs for a + few years. + + src/hb-font.cc | 39 ++++++++++++++++++++++++++------------- + 1 file changed, 26 insertions(+), 13 deletions(-) + +commit 55153553675445e8aad06e363295d399aa79c54f +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 15:12:09 2018 -0400 + + [ot-font] Don't pre-load cmap table + + Now that we have get_h_advances() and get_nominal_glyphs() + implemented, the + overhead of doing a proper atomic load would be once per run, NOT + once per + glyph. So, no need to pre-load the tables to avoid that overhead. + + As such, hb_ot_font_set_funcs() has become really cheap. + Can *finally* make + it be default font functions on all newly created fonts! + + src/hb-ot-font.cc | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +commit ec84460e46fdaa5f8a3c16c8d48dabe2b0c869da +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 15:07:04 2018 -0400 + + [ot/ft] Implement get_nominal_glyphs() callback + + Some more measurable speedup. The recent commits' speedups are + as follows: + + Testing with Roboto, ****when disabling kern and liga****: + + Before: + + FT --features=-kern,-liga + user↦ 0m0.521s + + OT --features=-liga,-kern + user↦ 0m0.568s + + After: + + FT --features=-liga,-kern + user↦ 0m0.428s + + OT --features=-liga,-kern + user↦ 0m0.470s + + So, 17% speedup. + + Note that FT callbacks are faster than OT these days since we added + an advance + cache to FT. I don't think the difference is enough to justify + adding a cache + to OT. + + When not disabling kern, the thing is three times slower, so the + speedups + are three times less impressive... Still, 5% not bad for a codebase + that I + otherwise thought is optimized out. + + Note that, because of this and other optimiztions in our main shaper, + disabling kern and liga, the OT shaper is now *faster* than the + fallback + shaper. So, that's my recommendation to clients that need the + absolute + fastest... + + src/hb-ft.cc | 26 ++++++++++++++++++++++++++ + src/hb-ot-font.cc | 24 ++++++++++++++++++++++++ + 2 files changed, 50 insertions(+) + +commit e883f52732a25f5495ec30656489954afd8cc3a4 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 14:50:57 2018 -0400 + + Call get_nominal_glyphs() for runs of simple clusters at a time + + Even without FT or OT font funcs implementing get_nominal_glyphs(), + there's measurable + speedup. + + src/hb-buffer.hh | 20 +++++++++++++++++++- + src/hb-ot-shape-normalize.cc | 9 +++++++++ + 2 files changed, 28 insertions(+), 1 deletion(-) + +commit 8008bca83b0bb310fc434dbdd339545af951193b +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 14:38:23 2018 -0400 + + Whitespace + + src/hb-font.hh | 2 +- + src/hb-ot-shape-normalize.cc | 52 + ++++++++++++++++++++++++-------------------- + 2 files changed, 29 insertions(+), 25 deletions(-) + +commit 30c114ffec335770452e60729224b1634586c5b0 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 14:37:08 2018 -0400 + + Avoid sort and recompose stages if all clusters simple + + Even has measurable speedup... + + src/hb-ot-shape-normalize.cc | 52 + ++++++++++++++++++++++++-------------------- + 1 file changed, 29 insertions(+), 23 deletions(-) + +commit 9f79365c3b183278d14352ba6241c7d4ec274984 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 14:36:25 2018 -0400 + + Fix warning + + How come this one is not generated by clang everything bot?! + + ../../../test/api/test-multithread.c:37:26: warning: initialization + discards ‘const’ qualifier from pointer target type + [-Wdiscarded-qualifiers] + static char *font_path = "fonts/Inconsolata-Regular.abc.ttf"; + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ../../../test/api/test-multithread.c:38:21: warning: initialization + discards ‘const’ qualifier from pointer target type + [-Wdiscarded-qualifiers] + + test/api/test-multithread.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 24382debe893450088acd1e4b387ac31145d4553 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 14:33:24 2018 -0400 + + Rewrite main normalizer loop to isolate runs of simple clusters + + src/hb-ot-shape-normalize.cc | 24 +++++++++++++++++++----- + 1 file changed, 19 insertions(+), 5 deletions(-) + +commit b5371f18effbeb91565fd8c554c120b911641f0b +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 14:12:59 2018 -0400 + + Inline decompose_cluster + + Towards separating the common case into its own loop. + + src/hb-ot-shape-normalize.cc | 14 ++++---------- + 1 file changed, 4 insertions(+), 10 deletions(-) + +commit b314c4e9abf4236c6650a63d1287471b61f64885 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 09:23:51 2018 -0400 + + [font] Add get_nominal_glyphs() callback (note the plural) + + Unused as of now. To be wired up to normalizer, which would remove + overhead and allow hb-ot-font initialization to become a no-op, so + we can enable it by default. + + docs/harfbuzz-sections.txt | 3 +++ + src/hb-font.cc | 33 +++++++++++++++++++++++++++++++++ + src/hb-font.h | 24 ++++++++++++++++++++++++ + src/hb-font.hh | 13 +++++++++++++ + 4 files changed, 73 insertions(+) + +commit ca6a317012a13ee84b58a69e14e74c94c5b158ff +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 09:06:07 2018 -0400 + + Minor + + src/hb-font.cc | 6 +++--- + src/hb-font.h | 8 ++++---- + src/hb-font.hh | 2 +- + 3 files changed, 8 insertions(+), 8 deletions(-) + +commit 4035158de46ce373b7521daf61c5b6df83312968 +Author: Chun-wei Fan <fanchunwei@src.gnome.org> +Date: Wed Jul 25 18:26:10 2018 +0800 + + test/api/test-subset-*.c: Fix build on pre-C99 + + Ensure that we have the variables at the beginning of the block. + These + are the only fixes that we need for building HarfBuzz on older + compilers. + + test/api/test-collect-unicodes.c | 9 ++++++--- + test/api/test-subset-glyf.c | 19 +++++++++++++------ + test/api/test-subset-hdmx.c | 8 ++++++-- + test/api/test-subset-hmtx.c | 3 ++- + test/api/test-subset-post.c | 3 ++- + test/api/test-subset-vmtx.c | 6 ++++-- + test/api/test-subset.c | 12 +++++++++--- + 7 files changed, 42 insertions(+), 18 deletions(-) + +commit 8e4ad1d7a0a35298ca04828ef1ef18b4c019ec03 +Author: Chun-wei Fan <fanchunwei@src.gnome.org> +Date: Wed Jul 25 18:12:34 2018 +0800 + + builds: Fix and clean up MSVC DLL builds + + Instead of passing a CFLAG/CXXFLAG to define HB_EXTERN, define it + directly in src/hb.hh as __declspec(dllexport) extern when we are + building HarfBuzz as DLLs on Visual Studio. Define HB_INTERNAL + as nothing without defining HB_NO_VISIBILITY when building HarfBuzz as + DLLs to avoid linker errors on Visual Studio builds. + + Also "install" harfbuzz-subset.dll into $(PREFIX)\bin as the + hb-subset utility will depend on that DLL at runtime, when HarfBuzz is + built as DLLs. Since it consists of private APIs that are subject to + change, we do not install its headers nor .lib file. + + CMakeLists.txt | 7 ++++++- + src/hb.hh | 10 ++++++++-- + 2 files changed, 14 insertions(+), 3 deletions(-) + +commit e640f3a6b16f41cee5f7868ec738fda01244e96a +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 08:28:07 2018 -0400 + + Another old bot fix + + src/hb-aat-layout-kerx-table.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit e4f27f368f8f0509fa47f6a28f3984e90b40588f +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 08:20:10 2018 -0400 + + Try fixing older bots + + src/hb-ot-shape-fallback.cc | 42 + +++++++++++++++++++++--------------------- + 1 file changed, 21 insertions(+), 21 deletions(-) + +commit bee93e269711a3eda4e7d762b730522564fe6e87 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 08:01:49 2018 -0400 + + Add const to get_*_advances API + + Ouch! + + src/hb-font.cc | 10 +++++----- + src/hb-font.h | 8 ++++---- + src/hb-font.hh | 6 +++--- + src/hb-ft.cc | 2 +- + src/hb-ot-font.cc | 4 ++-- + 5 files changed, 15 insertions(+), 15 deletions(-) + +commit eb2be97f864c726feaa2434e290f962ddfa97069 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 07:48:52 2018 -0400 + + Port test off deprecated API + + test/api/test-shape.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit cc126f2817844a2e83e973129e5b2caa18de599f +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 01:10:15 2018 -0400 + + Minor + + src/Makefile.am | 2 +- + test/shaping/Makefile.am | 2 ++ + test/subset/Makefile.am | 2 +- + 3 files changed, 4 insertions(+), 2 deletions(-) + +commit b2fbe55b828ea5864bc0aed54db7109a2e189de2 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 01:07:36 2018 -0400 + + [icu] Unbreak + + src/hb-icu.cc | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit a353c1768dc1d7934b8ac293761620f561304bb2 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 01:05:28 2018 -0400 + + Remove test for deprecated hb_set_invert() + + test/api/test-set.c | 4 ---- + 1 file changed, 4 deletions(-) + +commit a52bc039c33b3c01dbb96b815dc24df7f03bc4be +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 00:56:33 2018 -0400 + + Properly remove deprecated stuff + + src/hb-glib.cc | 15 ++++++--------- + src/hb-icu.cc | 15 ++++++--------- + src/hb-ucdn.cc | 15 ++++++--------- + 3 files changed, 18 insertions(+), 27 deletions(-) + +commit fc50916589a300e49183b5ee598e64ca28d0bd9a +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 00:39:42 2018 -0400 + + Remove deprecated decompose_compatibility stuff + + src/hb-glib.cc | 31 +----------------------------- + src/hb-icu.cc | 33 +------------------------------- + src/hb-ucdn.cc | 8 +------- + test/api/test-unicode.c | 51 + ------------------------------------------------- + 4 files changed, 3 insertions(+), 120 deletions(-) + +commit eed737f6726d3408191a4e64592805b70d8bb247 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 00:33:30 2018 -0400 + + Remove deprecated eastasian_width + + src/hb-glib.cc | 8 +------ + src/hb-icu.cc | 19 +-------------- + src/hb-ucdn.cc | 9 +------ + test/api/test-unicode.c | 64 + ------------------------------------------------- + 4 files changed, 3 insertions(+), 97 deletions(-) + +commit 47030b1855f04c0d75899ffb6f5021fea3c19b90 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 00:30:45 2018 -0400 + + [ft/ot] Remove implementation of deprecated kerning funcs + + src/hb-ft.cc | 19 ------------------- + src/hb-ot-font.cc | 13 ------------- + 2 files changed, 32 deletions(-) + +commit 977c8a8e5c811995f47b0eb721199d0dc3689e48 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 00:22:08 2018 -0400 + + [kern] Minor + + src/hb-ot-kern-table.hh | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +commit ed5cfa42c7fb8d5ff2d74bdb452a0590174f4e19 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 00:20:35 2018 -0400 + + [kern] Minor + + src/hb-aat-layout-kerx-table.hh | 1 + + 1 file changed, 1 insertion(+) + +commit d219f899f4b2fb4b39ebc1dff9fb648fc5d6d112 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 9 00:01:09 2018 -0400 + + Deprecate font kern API + + docs/harfbuzz-sections.txt | 16 +++++++------- + src/hb-deprecated.h | 54 + ++++++++++++++++++++++++++++++++++++++++++++++ + src/hb-font.cc | 3 +++ + src/hb-font.h | 51 + ------------------------------------------- + 4 files changed, 65 insertions(+), 59 deletions(-) + +commit a51958819fcf51ade3f8eb38001e680a419ebbba +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 8 23:57:45 2018 -0400 + + Apply TrueType/OpenType kern table when GPOS kern feature is not + available + + Fixes https://github.com/harfbuzz/harfbuzz/issues/250 + + src/hb-ot-kern-table.hh | 24 +++++++++++-------- + src/hb-ot-layout.cc | 57 + ++++++++++++++++++++------------------------- + src/hb-ot-layout.hh | 13 +++++++++++ + src/hb-ot-shape-fallback.cc | 4 ++-- + src/hb-ot-shape.cc | 10 +++++--- + src/hb-ot-shape.hh | 1 + + 6 files changed, 62 insertions(+), 47 deletions(-) + +commit 09ad2613c8d8a60dac69a878c2d568adfea054c8 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 8 23:30:24 2018 -0400 + + Separate fallback kern vs mark positioning + + src/hb-ot-shape-fallback.cc | 12 ++++++------ + src/hb-ot-shape-fallback.hh | 12 ++++++------ + src/hb-ot-shape.cc | 15 ++++++++------- + src/hb-ot-shape.hh | 4 ++-- + 4 files changed, 22 insertions(+), 21 deletions(-) + +commit 3c23ff9b7c4241ec23054a95f1fdfbdef2c51f40 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 8 23:26:26 2018 -0400 + + [kern] Add kerning driver to TT kern table + + src/hb-ot-kern-table.hh | 19 +++++++++++++++++-- + src/hb-ot-shape-fallback.cc | 2 +- + 2 files changed, 18 insertions(+), 3 deletions(-) + +commit 683c3a95330928129cfbb1488650f708414d68ba +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 8 23:09:48 2018 -0400 + + [kern] Abstract away kerning machine + + src/hb-font.hh | 2 +- + src/hb-ot-kern-table.hh | 71 + +++++++++++++++++++++++++++++++++++++++++++++ + src/hb-ot-shape-fallback.cc | 67 + +++++++++++------------------------------- + 3 files changed, 89 insertions(+), 51 deletions(-) + +commit fb4f43838154a77912a9fc3437110c81e9d34aac +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 8 22:44:16 2018 -0400 + + Add HB_DEPRECATED + + Fixes https://github.com/harfbuzz/harfbuzz/issues/1232 + + src/hb-common.h | 9 +++++++++ + src/hb-deprecated.h | 12 ++++++------ + 2 files changed, 15 insertions(+), 6 deletions(-) + +commit 80e3102b8a216f9a751d073f9a2f7900ca758086 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 8 22:41:08 2018 -0400 + + [kerx] Process coverage flags + + src/hb-aat-layout-kerx-table.hh | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +commit 26d7305da7a7e2cf765b068f565836442872ffe7 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 8 22:31:35 2018 -0400 + + Deprecate decompose_compatibility stuff + + docs/harfbuzz-sections.txt | 7 +++--- + src/hb-deprecated.h | 63 + ++++++++++++++++++++++++++++++++++++++++++++++ + src/hb-unicode.h | 47 ---------------------------------- + 3 files changed, 67 insertions(+), 50 deletions(-) + +commit 42b51eee54f143854b7c6c3be5d84bfbbd895100 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 8 22:26:39 2018 -0400 + + Deprecate eastasian_width stuff + + docs/harfbuzz-sections.txt | 5 +++-- + src/hb-deprecated.h | 37 +++++++++++++++++++++++++++++++++++++ + src/hb-unicode.h | 28 ---------------------------- + 3 files changed, 40 insertions(+), 30 deletions(-) + +commit 286a45641fc6732bb7cab02f06c90396834541b1 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 8 16:41:08 2018 -0400 + + Minor + + src/hb-ot-shape-normalize.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit c0d3bf1bafe7b6d2e8f2798c1f55aaec71350d90 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 8 16:32:44 2018 -0400 + + Minor + + src/hb-ot-shape.cc | 26 +++++++++++++------------- + 1 file changed, 13 insertions(+), 13 deletions(-) + +commit 9c1bb81f5c5ca64ad1c665edd16947e4bc6f6c46 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 8 16:10:54 2018 -0400 + + [test/text-rendering-tests] Update from upstream + + test/shaping/data/text-rendering-tests/DISABLED | 3 --- + test/shaping/data/text-rendering-tests/Makefile.sources | 2 +- + test/shaping/data/text-rendering-tests/tests/MORX-35.tests | 4 ++-- + 3 files changed, 3 insertions(+), 6 deletions(-) + +commit 1a5a3325a26f4989ab8c4bb91515d4898ffa4631 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 7 23:08:39 2018 -0400 + + [kerx] Minor + + src/hb-aat-layout-kerx-table.hh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit d62b4011cc600ade2b130f81a077dd08d4e4464f +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 7 22:58:06 2018 -0400 + + [kern] Shout less + + src/hb-ot-kern-table.hh | 36 +++++++++++++++++++----------------- + 1 file changed, 19 insertions(+), 17 deletions(-) + +commit c6bb3a588f493630b40d8823532b482f407bacbf +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 7 22:52:53 2018 -0400 + + [kerx] Clean up Format2 + + src/hb-aat-layout-kerx-table.hh | 48 + ++++++++--------------------------------- + 1 file changed, 9 insertions(+), 39 deletions(-) + +commit 8aa83d97f9e7f63e2fcb4ae965b75a39961c7d87 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 7 22:43:59 2018 -0400 + + [kern/kerx] Fix Format2 offsetting + + "The values in the right class table are stored pre-multiplied by the + number of bytes in a single kerning value, and the values in the left + class table are stored pre-multiplied by the number of bytes in one + row. This eliminates needing to multiply the row and column values + together to determine the location of the kerning value. The array can + be indexed by doing the right- and left-hand class mappings, + adding the + class values to the address of the array, and fetching the kerning + value to which the new address points." + + src/hb-aat-layout-kerx-table.hh | 2 +- + src/hb-ot-kern-table.hh | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit ed2a404272bc99234c6f71f22b5a642834e59e6c +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 7 22:33:41 2018 -0400 + + [kerx] Clean up Format0 + + src/hb-aat-layout-kerx-table.hh | 48 + +++++++++++------------------------------ + 1 file changed, 12 insertions(+), 36 deletions(-) + +commit 4c3b19d52ec7a1fa46f8d0971e377a7d29b87e27 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 7 22:30:42 2018 -0400 + + Support HBUINT32 BinSearchArrayOf + + src/hb-open-type.hh | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +commit 456a68c506238e9c6b019244237d4443bd3589af +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 7 22:28:45 2018 -0400 + + Move code + + src/hb-aat-layout-common.hh | 105 + -------------------------------------------- + src/hb-open-type.hh | 105 + +++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 104 insertions(+), 106 deletions(-) + +commit 3515c8b187e2316dcf3abaefc84917b09449d485 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 7 22:27:00 2018 -0400 + + [aat] Rename + + src/hb-aat-layout-common.hh | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +commit e42cd58c997adafca5517faa9aacf651b90520f5 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 7 20:46:11 2018 -0400 + + Rename invisible_codepoint to invisible_glyph in API + + Deleted recently added API: + hb_buffer_set_invisible_codepoint() + hb_buffer_get_invisible_codepoint() + + hb-shape / hb-view --invisible-codepoint + + New API: + hb_buffer_set_invisible_glyph() + hb_buffer_get_invisible_glyph() + + hb-shape / hb-view --invisible-glyph + + Fixes https://github.com/harfbuzz/harfbuzz/issues/1216 + + docs/harfbuzz-sections.txt | 4 ++-- + src/hb-buffer.cc | 12 ++++++------ + src/hb-buffer.h | 6 +++--- + util/options.cc | 2 +- + util/options.hh | 6 +++--- + 5 files changed, 15 insertions(+), 15 deletions(-) + +commit 2a5cb37fdb43230217e055f3d7c770a35cfd5c21 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 7 20:36:46 2018 -0400 + + Revert "[morx] Fix MORX-35" + + This reverts commit f62f6e90ad1f1a83f77771ad65ee1ffb79470a8a. + + src/hb-aat-layout-morx-table.hh | 14 + +++++--------- + test/shaping/data/text-rendering-tests/DISABLED | 3 +++ + test/shaping/data/text-rendering-tests/Makefile.sources | 2 +- + 3 files changed, 9 insertions(+), 10 deletions(-) + +commit 14ebf8af0c04efcae6ca788ac85601bfe462f28d +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 7 20:35:06 2018 -0400 + + [buffer] Improve shift_forward() + + "Improve" is a strong word in this case though, I understand. + + src/hb-buffer.cc | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +commit f62f6e90ad1f1a83f77771ad65ee1ffb79470a8a +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 7 18:06:53 2018 -0400 + + [morx] Fix MORX-35 + + Fixes https://github.com/harfbuzz/harfbuzz/issues/1224 + + src/hb-aat-layout-morx-table.hh | 14 + ++++++++++---- + test/shaping/data/text-rendering-tests/DISABLED | 3 --- + test/shaping/data/text-rendering-tests/Makefile.sources | 2 +- + 3 files changed, 11 insertions(+), 8 deletions(-) + +commit 94368855c6bd7201d562cab3d2107685589e69c8 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 7 18:52:12 2018 -0400 + + Remove some code + + We use scratch-flags to short-circuit this function. No need for + previous + early loop. + + src/hb-ot-shape.cc | 16 +++------------- + 1 file changed, 3 insertions(+), 13 deletions(-) + +commit c07b91b812dc66b38b11329cd6a93258a3769f9e +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 7 18:00:14 2018 -0400 + + [test/text-rendering-tests] Update from upstream + + test/shaping/data/text-rendering-tests/Makefile.sources | 6 +++++- + .../data/text-rendering-tests/fonts/TestMORXForty.ttf | Bin 0 -> + 2408 bytes + .../text-rendering-tests/fonts/TestMORXThirtyeight.ttf | Bin 0 -> + 2444 bytes + .../text-rendering-tests/fonts/TestMORXThirtynine.ttf | Bin 0 -> + 2436 bytes + .../text-rendering-tests/fonts/TestMORXThirtyseven.ttf | Bin 0 -> + 2444 bytes + .../data/text-rendering-tests/tests/MORX-35.tests | 4 ++-- + .../data/text-rendering-tests/tests/MORX-37.tests | 4 ++++ + .../data/text-rendering-tests/tests/MORX-38.tests | 4 ++++ + .../data/text-rendering-tests/tests/MORX-39.tests | 4 ++++ + .../data/text-rendering-tests/tests/MORX-40.tests | 4 ++++ + 10 files changed, 23 insertions(+), 3 deletions(-) + +commit fdce1e15434f14b7f4802edd67f7af737cf2b075 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 7 14:01:33 2018 -0400 + + [kerx] Clean up kerx and KerxTable structures + + src/hb-aat-layout-kerx-table.hh | 169 + ++++++++++++++++++++++++++-------------- + src/hb-aat-layout-morx-table.hh | 2 +- + 2 files changed, 113 insertions(+), 58 deletions(-) + +commit 71b65eb27dd0867f51d9906887b9e372eb37f54a +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 7 18:41:52 2018 +0200 + + Add API for setting invisible-codepoint + + Fixes https://github.com/harfbuzz/harfbuzz/issues/1216 + + New API: + hb_buffer_set_invisible_codepoint() + hb_buffer_get_invisible_codepoint() + + hb-shape / hb-view --invisible-codepoint + + docs/harfbuzz-sections.txt | 2 ++ + src/hb-buffer.cc | 42 + ++++++++++++++++++++++++++++++++++++++++++ + src/hb-buffer.h | 7 +++++++ + src/hb-buffer.hh | 1 + + src/hb-ot-shape.cc | 8 ++++---- + util/options.cc | 1 + + util/options.hh | 3 +++ + 7 files changed, 60 insertions(+), 4 deletions(-) + +commit 13da3be0b342e8e2f060eba8753c6957c477c4ee +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 7 18:23:45 2018 +0200 + + [ot-font] Load hmtx/vmtx lazily + + Since we have get_*_advanes() API now, the overhead is once per shape, + not once per glyph. + + Only cmap is warmed-up at set_funcs() time now. + + src/hb-ot-font.cc | 26 +++++++++++++------------- + 1 file changed, 13 insertions(+), 13 deletions(-) + +commit 856db4c9184e39c0457cc07c815f90058937c8a2 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 7 18:21:15 2018 +0200 + + Minor + + src/hb-ot-font.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit f92330b5e0b1a5a61768494bd7081e3fc235b182 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 7 17:51:50 2018 +0200 + + Minor + + test/api/test-multithread.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit b2e398c077cf9437298bfe2ee53b7407a5865c14 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Oct 7 16:31:33 2018 +0200 + + [coretext] Fix OS X check + + Fixes https://github.com/harfbuzz/harfbuzz/issues/1230 + + src/hb-coretext.cc | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 7ee50af8366547c382047a30a94f7f5f739aabcb +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sat Oct 6 21:31:44 2018 +0200 + + [morx] Fix memory access issues with unsafe_to_break + + src/hb-aat-layout-common.hh | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +commit f58c5175890e666503b6f140d238e1abca91598e +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Sat Oct 6 22:42:56 2018 +0330 + + Make msan output a little more readable + + .circleci/config.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit e9abe33963739f753cdfb007eed40101ce33f550 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Sat Oct 6 12:19:33 2018 +0330 + + Use tempfile in run-tests as a fix for Windows CI fails (#1228) + + test/shaping/run-tests.py | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +commit 0816a549789a1b647443c2b33cfda3f4400a0f87 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sat Oct 6 02:40:57 2018 +0200 + + [uniscribe/coretext] Fix for previous change + + src/hb-coretext.cc | 2 +- + src/hb-uniscribe.cc | 12 ++++++------ + 2 files changed, 7 insertions(+), 7 deletions(-) + +commit 341206eb609202e4b2f0d03d29cb577ebe8390b9 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Oct 5 18:39:48 2018 +0200 + + [vector] Make hb_vector_t relocatable / nestable + + Ugly, but... + Fixes https://github.com/harfbuzz/harfbuzz/issues/1227 + + src/hb-face.cc | 2 +- + src/hb-machinery.hh | 2 +- + src/hb-ot-cmap-table.hh | 2 +- + src/hb-ot-post-table.hh | 2 +- + src/hb-set.hh | 4 +-- + src/hb-subset.cc | 2 +- + src/hb-vector.hh | 94 + +++++++++++++++++++++++++++++++------------------ + 7 files changed, 66 insertions(+), 42 deletions(-) + +commit 5469d80707d32c733b1c60f79ab2f217e879de55 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Oct 5 18:21:08 2018 +0200 + + Add hb_vector_t::fini_deep () + + src/hb-vector.hh | 8 ++++++++ + 1 file changed, 8 insertions(+) + +commit 4831e615d173be9c7e140be0fa9017e4d9e499af +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Oct 5 18:14:13 2018 +0200 + + [morx] Fix memory access issue + + If buffer was enlarged, info was being outdated. + + Fixes https://github.com/harfbuzz/harfbuzz/issues/1225 + + src/hb-aat-layout-common.hh | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +commit 5a41cf6be69adb0b5b29976a33c4c6dd6ce7afc5 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Oct 5 11:33:19 2018 +0200 + + [test/text-rendering-tests] Update from upstream + + test/shaping/data/text-rendering-tests/DISABLED | 3 +++ + test/shaping/data/text-rendering-tests/Makefile.sources | 2 ++ + .../text-rendering-tests/fonts/TestMORXThirtyfive.ttf | Bin 0 -> + 1968 bytes + .../text-rendering-tests/fonts/TestMORXThirtysix.ttf | Bin 0 -> + 1836 bytes + .../data/text-rendering-tests/tests/MORX-35.tests | 2 ++ + .../data/text-rendering-tests/tests/MORX-36.tests | 1 + + 6 files changed, 8 insertions(+) + +commit a62f37d6fa412b799b7247b813f6e65a968e7645 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Oct 5 02:49:29 2018 +0200 + + Change vendor features from Harf/Buzz to HARF/BUZZ + + https://github.com/harfbuzz/harfbuzz/commit/a01194aaf4c15160330b4042066263b2c963b658#commitcomment-30772041 + + "The tag space of tags consisting of four uppercase letters (A-Z) + with no punctuation, + spaces, or numbers, is reserved as a vendor space. Font vendors may + use such tags to + identify private features." + + src/hb-ot-shape.cc | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 7b3ae5ffd202346cb3742fe0f8cfafe8c36a4bd5 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 4 16:36:42 2018 +0200 + + More bot fixes + + test/shaping/run-tests.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 310bdac4a08b99a25de6a16a20464873f90b52e4 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 4 16:31:14 2018 +0200 + + Fix a warning + + util/view-cairo.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 0abce58139bb58b8b97171db6387d2ac7eebdee0 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 4 16:23:42 2018 +0200 + + [test] Choose 'ot' shaper specifically + + Now that we added morx support, our OS X bot is running them through + CoreText + and failing (with a DoS / infinite loop no less!). Always run + tests through + our own shaper. + + test/shaping/run-tests.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit c93d379bf2414eb6ee6d38fb9753ddf818a777ea +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 4 13:28:13 2018 +0200 + + [TODO] Clean up + + TODO | 10 +--------- + 1 file changed, 1 insertion(+), 9 deletions(-) + +commit a01194aaf4c15160330b4042066263b2c963b658 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 4 13:00:37 2018 +0200 + + Enable two OpenType features, 'Harf' and 'Buzz' + + One early, before script-specific features, one late, after. + Allows font + developers to detect us and behave differently if needed. + + src/hb-ot-shape.cc | 4 ++++ + 1 file changed, 4 insertions(+) + +commit 55468ca01b4cdf274900fb752fbf9ae05a78705e +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 4 12:13:55 2018 +0200 + + [test/text-rendering-tests] Update from upstream + + test/shaping/data/text-rendering-tests/Makefile.sources | 6 +++++- + test/shaping/data/text-rendering-tests/extract-tests.py | 12 + ++++++++++++ + .../data/text-rendering-tests/fonts/TestGSUBThree.ttf | Bin 0 -> + 1504 bytes + .../text-rendering-tests/fonts/TestMORXThirtyfour.ttf | Bin 0 -> + 3608 bytes + .../text-rendering-tests/fonts/TestMORXThirtythree.ttf | Bin 0 -> + 1520 bytes + .../text-rendering-tests/fonts/TestMORXTwentyfour.ttf | Bin 0 -> + 1828 bytes + .../shaping/data/text-rendering-tests/tests/GSUB-3.tests | 1 + + .../data/text-rendering-tests/tests/MORX-24.tests | 1 + + .../data/text-rendering-tests/tests/MORX-32.tests | 8 ++++---- + .../data/text-rendering-tests/tests/MORX-33.tests | 3 +++ + .../data/text-rendering-tests/tests/MORX-34.tests | 1 + + test/shaping/run-tests.py | 15 + +++++++++------ + 12 files changed, 36 insertions(+), 11 deletions(-) + +commit 6ff8a8a10b62a54a87d53b0af66ccaba5d58b107 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 4 12:09:45 2018 +0200 + + Minor + + test/shaping/data/text-rendering-tests/extract-tests.py | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 14ff3cbe0f30dea24e1bb175b1e8e41039f6afdc +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 4 11:34:21 2018 +0200 + + Apply morx if there's no GSUB! + + src/hb-ot-shape.cc | 23 ++++++++++++---- + src/hb-ot-shape.hh | 5 ++++ + test/shaping/data/text-rendering-tests/DISABLED | 32 + ---------------------- + .../data/text-rendering-tests/Makefile.sources | 14 +++++----- + 4 files changed, 29 insertions(+), 45 deletions(-) + +commit 3417037eb13a59dce6add0b1691ddb1b2b54c1e4 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Oct 4 11:08:15 2018 +0200 + + [aat] Add +hb_aat_layout_has_substitution + + src/hb-aat-layout-morx-table.hh | 2 ++ + src/hb-aat-layout.cc | 6 ++++++ + src/hb-aat-layout.hh | 2 ++ + 3 files changed, 10 insertions(+) + +commit 1f14107f71a6c3da8270ed21c3588f945fa91733 +Author: Sascha Brawer <sascha@brawer.ch> +Date: Thu Oct 4 09:17:08 2018 +0200 + + Minor: Fix autoconf warning + + Before this change, autoconf was emitting the following warnings: + + ``` + configure.ac:22: warning: AC_COMPILE_IFELSE was called before + AC_USE_SYSTEM_EXTENSIONS + ../../lib/autoconf/specific.m4:368: AC_USE_SYSTEM_EXTENSIONS is + expanded from... + configure.ac:22: the top level + configure.ac:22: warning: AC_RUN_IFELSE was called before + AC_USE_SYSTEM_EXTENSIONS + ../../lib/autoconf/specific.m4:368: AC_USE_SYSTEM_EXTENSIONS is + expanded from... + configure.ac:22: the top level + configure.ac:22: warning: AC_COMPILE_IFELSE was called before + AC_USE_SYSTEM_EXTENSIONS + ../../lib/autoconf/specific.m4:368: AC_USE_SYSTEM_EXTENSIONS is + expanded from... + configure.ac:22: the top level + configure.ac:22: warning: AC_RUN_IFELSE was called before + AC_USE_SYSTEM_EXTENSIONS + ../../lib/autoconf/specific.m4:368: AC_USE_SYSTEM_EXTENSIONS is + expanded from... + configure.ac:22: the top level + configure.ac:22: warning: AC_COMPILE_IFELSE was called before + AC_USE_SYSTEM_EXTENSIONS + ../../lib/autoconf/specific.m4:368: AC_USE_SYSTEM_EXTENSIONS is + expanded from... + configure.ac:22: the top level + configure.ac:22: warning: AC_RUN_IFELSE was called before + AC_USE_SYSTEM_EXTENSIONS + ../../lib/autoconf/specific.m4:368: AC_USE_SYSTEM_EXTENSIONS is + expanded from... + configure.ac:22: the top level + configure.ac:22: warning: AC_COMPILE_IFELSE was called before + AC_USE_SYSTEM_EXTENSIONS + ../../lib/autoconf/specific.m4:368: AC_USE_SYSTEM_EXTENSIONS is + expanded from... + configure.ac:22: the top level + configure.ac:22: warning: AC_RUN_IFELSE was called before + AC_USE_SYSTEM_EXTENSIONS + ../../lib/autoconf/specific.m4:368: AC_USE_SYSTEM_EXTENSIONS is + expanded from... + configure.ac:22: the top level + ``` + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 7810bb1a59ea71afeed7ea489400801ebdf642e4 +Author: Sascha Brawer <sascha@brawer.ch> +Date: Thu Oct 4 09:24:08 2018 +0200 + + [morx] Only insert glyphs at mark when a mark has been set before + + This reverts commit f4072e8cb81072cd6d51a2607efedb76c02e7db1. + https://github.com/harfbuzz/harfbuzz/issues/1195 + + src/hb-aat-layout-morx-table.hh | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +commit 5de2d9cdbdca870901c0ba9472f5b78c48ba0a58 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Thu Oct 4 02:14:18 2018 +0330 + + Minor, fix double-promotion warnings (#1221) + + .circleci/config.yml | 2 +- + src/dump-emoji.cc | 2 +- + src/hb-common.cc | 2 +- + src/hb-ot-var-fvar-table.hh | 2 +- + 4 files changed, 4 insertions(+), 4 deletions(-) + +commit c2c7e6471ca912c91c82f6d71338082978f13dc6 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Thu Oct 4 00:29:40 2018 +0330 + + State our graphite2 dependency no-deprecated compile flag (#1220) + + .circleci/config.yml | 2 +- + .travis.yml | 2 -- + configure.ac | 2 +- + 3 files changed, 2 insertions(+), 4 deletions(-) + +commit e4e74c2751ac24178086cce2811d34d8019b6f85 +Author: mhosken <mhosken@users.noreply.github.com> +Date: Thu Oct 4 02:33:26 2018 +0700 + + Update Graphite API to latest (#1215) + + src/hb-graphite2.cc | 28 +++++++++++++++++++++++++++- + 1 file changed, 27 insertions(+), 1 deletion(-) + +commit 81f5eb09eca010337ffb3369000a3d5c1e8e2cda +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 3 21:30:48 2018 +0200 + + Add emoji test for recent work + + test/shaping/data/in-house/Makefile.sources | 2 +- + .../fonts/3cf6f8ac6d647473a43a3100e7494b202b2cfafe.ttf | Bin 0 -> + 16596 bytes + test/shaping/data/in-house/tests/emoji-flag-tags.tests | 2 -- + test/shaping/data/in-house/tests/emoji.tests | 4 ++++ + 4 files changed, 5 insertions(+), 3 deletions(-) + +commit 9e2824cca0e42a53fafda7b2feb095986df40675 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Wed Oct 3 22:49:02 2018 +0330 + + [ci] Delete azure-pipelines + + End of experiment, we might get back to it later + + azure-pipelines.yml | 10 ---------- + 1 file changed, 10 deletions(-) + +commit b710ea4fdeb1a620b396bd07665fc129fe5fc074 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 3 21:17:59 2018 +0200 + + Clean Fitzpatrick hack + + src/hb-ot-layout.hh | 2 +- + src/hb-ot-shape.cc | 9 +++++++-- + src/hb-unicode.hh | 20 -------------------- + 3 files changed, 8 insertions(+), 23 deletions(-) + +commit 95e5f1ae69036108f318b93b11d85b2ebc19109b +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 3 21:11:13 2018 +0200 + + Unbreak Fitzpatrick + + Fixes https://github.com/harfbuzz/harfbuzz/issues/1159 + + src/hb-ot-layout.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 03fb6dd4c7d12a98cc0ef325432658c3c76ab208 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 3 21:02:16 2018 +0200 + + Rewrite grapheme-formation in terms of new work + + Also, don't attach ZWNJ to previous cluster. Closer to Unicode + graphemes. + + src/hb-coretext.cc | 2 +- + src/hb-ot-shape.cc | 48 + ++++++---------------- + .../in-house/tests/indic-joiner-candrabindu.tests | 2 +- + .../data/in-house/tests/indic-joiners.tests | 6 +-- + 4 files changed, 18 insertions(+), 40 deletions(-) + +commit 68106b1d9b96caf79b0a778a7da75caf54e7d44a +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 3 20:50:12 2018 +0200 + + Minor + + src/hb-ot-layout.hh | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +commit 3f1c741b7a85d9c2d66e7f2446e988470c538b49 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 3 20:45:19 2018 +0200 + + [test] Split a test + + .../fonts/4d4206e30b2dbf1c1ef492a8eae1c9e7829ebad8.ttf | Bin 0 -> + 51924 bytes + .../fonts/bb29ce50df2bdba2d10726427c6b7609bf460e04.ttf | Bin 74856 -> + 0 bytes + .../in-house/tests/mongolian-variation-selector.tests | 17 + ++++++++++++++++- + 3 files changed, 16 insertions(+), 1 deletion(-) + +commit ba813aab0909375af0c8f8e0c34595680c2762a4 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Wed Oct 3 21:52:15 2018 +0330 + + Update azure-pipelines.yml + + azure-pipelines.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 06922acbc4558699e43a4ed98ffb21f1e84abfc6 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 3 20:19:17 2018 +0200 + + Fix distcheck + + src/Makefile.sources | 1 + + 1 file changed, 1 insertion(+) + +commit 4eea2e279b019ac627b2b9e2234a194957971022 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 3 20:16:03 2018 +0200 + + [thai] Set continuation on decomposed nikhahit + + src/hb-ot-shape-complex-thai.cc | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 8edc91022c3943fb306cee26ed6eb85381b5ea76 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 3 20:13:20 2018 +0200 + + [indic] Reset continuation on inserted dottedcircle + + src/hb-ot-shape-complex-indic.cc | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +commit 2a6f15213ec30e5eb07465dd9dc81c2c386cb1e0 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 3 20:09:14 2018 +0200 + + [buffer] Inline some more + + src/hb-buffer.cc | 44 -------------------------------------------- + src/hb-buffer.hh | 52 + ++++++++++++++++++++++++++++++++++++++++++++-------- + 2 files changed, 44 insertions(+), 52 deletions(-) + +commit 6f39c22029867c6d00cf70d7df242a28ca8f12bc +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 3 20:06:32 2018 +0200 + + Add code + + src/hb-ot-layout.hh | 5 +++++ + 1 file changed, 5 insertions(+) + +commit 19d50aa2620f1464da8e00185b746e46fb0d80c4 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 3 20:05:28 2018 +0200 + + [indic] Simplify dottedcircle + + src/hb-ot-shape-complex-indic.cc | 23 +++++++++++++++-------- + 1 file changed, 15 insertions(+), 8 deletions(-) + +commit 3b7831851052ecf2611a115cc2b80ef970d83df8 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 3 19:44:15 2018 +0200 + + [emoji] Mark emoji contination sequences as continuation + + This adds a new grapheme bit. Not used yet. + + Part of https://github.com/harfbuzz/harfbuzz/issues/1159 + + src/hb-ot-layout.hh | 83 + +++++++++++++++++++++++++---------------------------- + src/hb-ot-shape.cc | 24 ++++++++++++++++ + src/hb-unicode.hh | 5 ---- + 3 files changed, 63 insertions(+), 49 deletions(-) + +commit 123326e20a30a51e25339c2eca272e4e6c847742 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 3 19:19:51 2018 +0200 + + Dotted-circle all marks, not just non-spacing, at text beginning + + src/hb-ot-shape.cc | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +commit 4146c00caa29e53ee9a29def151f12792ac76596 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Wed Oct 3 21:26:58 2018 +0330 + + [test] Use an in-repo font for test-multithread (#1218) + + As Khaled's suggestion, hard-coded font paths was only for my own + testing. + + test/api/hb-subset-test.h | 13 +++++++++---- + test/api/test-multithread.c | 41 + ++++++++++++++++++++++++++--------------- + test/fuzzing/main.cc | 6 ++++++ + 3 files changed, 41 insertions(+), 19 deletions(-) + +commit fde9b8852d7cd6224afeffcfe363f4b445ab1ece +Author: azure-pipelines[bot] +<azure-pipelines[bot]@users.noreply.github.com> +Date: Wed Oct 3 17:47:05 2018 +0000 + + [ci] Add a test Azure Pipelines Linux bot + + Related #1219 + + azure-pipelines.yml | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +commit 674560cf244054a7e8c16073a59aa1b01e1ba5ea +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 3 19:10:28 2018 +0200 + + Fix build + + src/test-unicode-ranges.cc | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 45e55f70801e2ccd28e1ee30bdf5341b1ac6efe5 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 3 18:07:49 2018 +0200 + + [indic] Fix clang everything + + src/hb-ot-shape-complex-indic.cc | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +commit 4df02e3240ada0734748a47572baa2fc1c6afbd1 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 3 17:54:09 2018 +0200 + + Minor + + src/hb-ot-os2-unicode-ranges.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 1e8f195b96765480007808da60789de9ac501c3b +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 3 17:46:48 2018 +0200 + + [emoji] Add emoji Extended_Pictographic table and function + + Part of https://github.com/harfbuzz/harfbuzz/issues/1159 + + . + + src/Makefile.am | 12 +- + src/gen-emoji-table.py | 64 ++++++++++ + src/hb-ot-os2-table.hh | 2 +- + src/hb-ot-os2-unicode-ranges.hh | 6 +- + src/hb-unicode-emoji-table.hh | 269 + ++++++++++++++++++++++++++++++++++++++++ + src/hb-unicode.cc | 16 +++ + src/hb-unicode.hh | 37 +++++- + 7 files changed, 398 insertions(+), 8 deletions(-) + +commit 1dc601b04a816a5b5ed12ae1c01ddcfd60a8398f +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 3 17:27:46 2018 +0200 + + [os2] Minor rename/shuffle + + ...unicode-ranges.py => gen-os2-unicode-ranges.py} | 2 +- + src/hb-ot-os2-unicode-ranges.hh | 45 + +++++++++++----------- + 2 files changed, 24 insertions(+), 23 deletions(-) + +commit 7a1ab0464d3ee1ca5c9b31215fbffb8601ae860d +Author: lantw44 <lantw44@gmail.com> +Date: Wed Oct 3 23:22:43 2018 +0800 + + Fix test-multithread build on FreeBSD (#1217) + + Add the default font path used by FreeBSD ports. + + test/api/test-multithread.c | 2 ++ + 1 file changed, 2 insertions(+) + +commit df32eaae42b505b00de4a8b5efce9ab948bed847 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 3 14:44:25 2018 +0200 + + [indic] Disallow vowel mark combinations that spoof other vowel marks + + Fixes https://github.com/harfbuzz/harfbuzz/issues/1019 + + New numbers: + + BENGALI: 353725 out of 354188 tests passed. 463 failed (0.130722%) + DEVANAGARI: 707261 out of 707394 tests passed. 133 failed (0.0188014%) + GUJARATI: 366353 out of 366457 tests passed. 104 failed (0.0283799%) + GURMUKHI: 60729 out of 60747 tests passed. 18 failed (0.0296311%) + KANNADA: 951300 out of 951913 tests passed. 613 failed (0.0643966%) + MALAYALAM: 1048136 out of 1048334 tests passed. 198 failed + (0.0188871%) + ORIYA: 42327 out of 42329 tests passed. 2 failed (0.00472489%) + SINHALA: 271596 out of 271847 tests passed. 251 failed (0.0923313%) + TAMIL: 1091754 out of 1091754 tests passed. 0 failed (0%) + TELUGU: 970555 out of 970573 tests passed. 18 failed (0.00185457%) + + Devanagari regressed because Uniscribe doesn't enforce the full set. + + Tests added with the *-vowel-letters.txt files in tree and Noto fonts. + + src/hb-ot-shape-complex-indic.cc | 256 + ++++++++++++++++++++- + test/shaping/data/in-house/Makefile.sources | 1 + + .../03e3f463c3a985bc42096620cc415342818454fb.ttf | Bin 0 -> 2904 bytes + .../1a5face3fcbd929d228235c2f72bbd6f8eb37424.ttf | Bin 0 -> 8188 bytes + .../2c25beb56d9c556622d56b0b5d02b4670c034f89.ttf | Bin 0 -> 2460 bytes + .../604026ae5aaca83c49cd8416909d71ba3e1c1194.ttf | Bin 0 -> 4120 bytes + .../738d9f3b8c2dfd03875bf35a61d28fd78faf17c8.ttf | Bin 0 -> 2336 bytes + .../7d18685e1529e4ceaad5b6095dfab2f9789e5bce.ttf | Bin 0 -> 3452 bytes + .../881642af1667ae30a54e58de8be904566d00508f.ttf | Bin 0 -> 2760 bytes + .../af85624080af5627fb050f570d148a62f04fda74.ttf | Bin 0 -> 2656 bytes + .../tests/indic-vowel-letter-spoofing.tests | 53 +++++ + 11 files changed, 309 insertions(+), 1 deletion(-) + +commit 1b8d5e999192035c08f918aa1fcfcebdea67d82e +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 3 14:44:19 2018 +0200 + + [thai] Minor + + src/hb-ot-shape-complex-thai.cc | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit d3d0cbd27831a6ea41b89f50d380296565c0016d +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 3 13:54:21 2018 +0200 + + Typo + + .../{bengali-vowel-leters.txt => bengali-vowel-letters.txt} + | 0 + .../{gujarati-vowel-letter.txt => gujarati-vowel-letters.txt} + | 0 + 2 files changed, 0 insertions(+), 0 deletions(-) + +commit 0dd9101fd0ddff80fff10ba98e93523aed95c8f5 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 3 13:26:26 2018 +0200 + + Minor + + src/hb-ot-shape-complex-indic.cc | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 9c4ffd10c4040ada9b1ffeb13c35f1330336359e +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 3 12:53:54 2018 +0200 + + Minor + + src/hb-ot-shape-complex.hh | 11 +++-------- + 1 file changed, 3 insertions(+), 8 deletions(-) + +commit bd1be8738fc4c73635cab7d77965264748d747cc +Author: HinTak <htl10@users.sourceforge.net> +Date: Wed Oct 3 07:11:22 2018 +0800 + + Missing colon for gobject annotation + + There should be a colon separating "(transfer full)" and the + rest. Warned by g-ir-scanner. + + src/hb-face.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 75114e01d29b90f72a9398ed5dbc4298aba5a6b8 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Oct 3 12:29:56 2018 +0200 + + [use] Add Halant_Or_Vowel_Modifier category + + Fixes https://github.com/harfbuzz/harfbuzz/issues/1102 + + src/gen-use-table.py | 7 +- + src/hb-ot-shape-complex-use-machine.hh | 518 + +++++++++++---------- + src/hb-ot-shape-complex-use-machine.rl | 9 +- + src/hb-ot-shape-complex-use-table.cc | 4 +- + src/hb-ot-shape-complex-use.hh | 5 +- + .../28f497629c04ceb15546c9a70e0730125ed6698d.ttf | Bin 0 -> 1496 bytes + .../shaping/data/in-house/tests/use-syllable.tests | 3 + + 7 files changed, 301 insertions(+), 245 deletions(-) + +commit 6353cc1f83c862910860976411a1157f7ed571bc +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Tue Oct 2 21:39:19 2018 +0330 + + [circleci] Fix some of warnings from clang-everything bot (#1211) + + * -Wshift-sign-overflow + * -Wmissing-prototypes + + .circleci/config.yml | 4 ++-- + src/dump-emoji.cc | 19 ++++++++++--------- + src/hb-ucdn.cc | 3 +++ + src/test-unicode-ranges.cc | 4 ++-- + test/fuzzing/hb-subset-fuzzer.cc | 32 +++++++++++++++++--------------- + util/ansi-print.cc | 4 ++-- + 6 files changed, 36 insertions(+), 30 deletions(-) + +commit 9f1dee32fbad3b1486725c18570199156b57a94d +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 2 18:56:20 2018 +0200 + + [tests] Allow test-runner to ignore shaping output + + Fixes https://github.com/harfbuzz/harfbuzz/issues/1212 + + test/shaping/data/in-house/tests/fuzzed.tests | 46 + +++++++++++++-------------- + test/shaping/run-tests.py | 2 +- + 2 files changed, 24 insertions(+), 24 deletions(-) + +commit fef7af1e22efb399517137b35d0ba9f307411ca3 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 2 18:46:13 2018 +0200 + + [tibetan] Remove unused Tibetan shaper + + src/Makefile.sources | 1 - + src/hb-ot-shape-complex-tibetan.cc | 63 + -------------------------------------- + src/hb-ot-shape-complex.hh | 1 - + 3 files changed, 65 deletions(-) + +commit 32a438166fbccac6e0d9a615a492fc8cabfd21ab +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 2 18:43:29 2018 +0200 + + [tibetan] Route Tibetan through USE + + Fixes https://github.com/harfbuzz/harfbuzz/pull/933 + https://github.com/harfbuzz/harfbuzz/issues/1012 + + Tibetan failures go from 0 to 2: + + TIBETAN: 208467 out of 208469 tests passed. 2 failed (0.000959375%) + + src/gen-use-table.py | 30 ++++++++++------ + src/hb-ot-shape-complex-use-table.cc | 70 + ++++++++++++++++++++++-------------- + src/hb-ot-shape-complex.hh | 8 +---- + 3 files changed, 65 insertions(+), 43 deletions(-) + +commit 77792187be1405599e6aecfc3ed1fc771d505ddb +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 2 18:20:16 2018 +0200 + + [khmer] Remove unused khmer_position() + + src/dump-khmer-data.cc | 8 +++----- + src/hb-ot-shape-complex-khmer.hh | 1 - + 2 files changed, 3 insertions(+), 6 deletions(-) + +commit 5101abd42f4027edf182eddfa58c629b11c2a7f6 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 2 17:49:06 2018 +0200 + + [indic/use] Factor common expressions in ragel machine + + No machine change. + + src/hb-ot-shape-complex-indic-machine.hh | 46 + ++++++++++++++++---------------- + src/hb-ot-shape-complex-indic-machine.rl | 10 ++++--- + src/hb-ot-shape-complex-use-machine.hh | 38 +++++++++++++------------- + src/hb-ot-shape-complex-use-machine.rl | 20 +++++++------- + 4 files changed, 58 insertions(+), 56 deletions(-) + +commit 6f457f8370de5d96452ee3a2d1b0a97b025ef1d1 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 2 17:46:27 2018 +0200 + + [indic] Minor flip grammar around + + No behavior change. + + src/hb-ot-shape-complex-indic-machine.rl | 2 +- + src/hb-ot-shape-complex-use-machine.rl | 1 - + 2 files changed, 1 insertion(+), 2 deletions(-) + +commit d992982d23ef0c39ea42595ed0e8a4752977d1a5 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 2 17:16:01 2018 +0200 + + [indic] Add some confusable sequences from Unicode Standard + + .../script-bengali/bengali-vowel-leters.txt | 3 ++ + .../devanagari-atomic-consonants.txt | 33 + ++++++++++++++++++++++ + .../script-devanagari/devanagari-vowel-letters.txt | 17 +++++++++++ + .../script-gujarati/gujarati-vowel-letter.txt | 8 ++++++ + .../script-gurmukhi/gurmukhi-vowel-letters.txt | 9 ++++++ + .../script-kannada/kannada-vowel-letters.txt | 3 ++ + .../script-malayalam/malayalam-vowel-letters.txt | 5 ++++ + .../script-oriya/oriya-vowel-letters.txt | 3 ++ + .../script-telugu/telugu-vowel-letters.txt | 5 ++++ + 9 files changed, 86 insertions(+) + +commit 40d5d19d5b875eef526a2a66892c3f638f633fa3 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 2 17:04:05 2018 +0200 + + [ragel] Use ts/te (token-start / token-end) instead of manual tracking + + src/hb-ot-shape-complex-indic-machine.hh | 22 ++++++++++------------ + src/hb-ot-shape-complex-indic-machine.rl | 8 +++----- + src/hb-ot-shape-complex-khmer-machine.hh | 22 ++++++++++------------ + src/hb-ot-shape-complex-khmer-machine.rl | 8 +++----- + src/hb-ot-shape-complex-myanmar-machine.hh | 22 ++++++++++------------ + src/hb-ot-shape-complex-myanmar-machine.rl | 8 +++----- + src/hb-ot-shape-complex-use-machine.hh | 22 ++++++++++------------ + src/hb-ot-shape-complex-use-machine.rl | 8 +++----- + 8 files changed, 52 insertions(+), 68 deletions(-) + +commit 9efddb9de821fc909a3ea8354f3dfd39c823e97b +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 2 16:05:26 2018 +0200 + + Treat a base+mark... ligature as base, not ligature + + Fixes https://github.com/harfbuzz/harfbuzz/issues/746 + + src/hb-ot-layout-gsubgpos.hh | 22 +++++++++++++++------- + 1 file changed, 15 insertions(+), 7 deletions(-) + +commit 3cca978723db43233d25402254d297dfccf991a3 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 2 15:02:16 2018 +0200 + + Move code around + + src/hb-ot-layout-gsub-table.hh | 3 --- + src/hb-ot-layout-gsubgpos.hh | 22 +++++++++++----------- + 2 files changed, 11 insertions(+), 14 deletions(-) + +commit 0a371fee4d22ed63207aa76c00b05b75bbc95f5f +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 2 14:48:39 2018 +0200 + + Minor + + src/hb-ot-map.hh | 6 ++++-- + src/hb-ot-shape-complex-arabic.cc | 6 +++--- + src/hb-ot-shape-complex-myanmar.cc | 4 ++-- + src/hb-ot-shape-complex-use.cc | 8 ++++---- + src/hb-ot-shape.cc | 4 ++-- + 5 files changed, 15 insertions(+), 13 deletions(-) + +commit 94d15528f80dbb7110d816fb5845f257f605a0be +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 2 14:45:09 2018 +0200 + + Minor + + src/hb-ot-map.hh | 1 + + src/hb-ot-shape.cc | 39 ++++++++++++++++++--------------------- + 2 files changed, 19 insertions(+), 21 deletions(-) + +commit 729f634728fb553300021d52089495271dfb19fd +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 2 14:40:14 2018 +0200 + + Disable joiner-skipping when looking back for base to attach mark to + + Fixes https://github.com/harfbuzz/harfbuzz/issues/1189 + + src/hb-ot-shape.cc | 5 ++++- + test/shaping/data/in-house/Makefile.sources | 1 + + .../fonts/641ca9d7808b01cafa9a666c13811c9b56eb9c52.ttf | Bin 0 -> + 11492 bytes + .../data/in-house/tests/arabic-mark-attach.tests | 1 + + 4 files changed, 6 insertions(+), 1 deletion(-) + +commit c36f3f5bef52e660541933f003fafa6e3a14785d +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 2 14:34:29 2018 +0200 + + [arabic] Use manual-zwj instead of flipping joiners + + src/hb-buffer.hh | 3 +-- + src/hb-ot-layout.hh | 12 ++---------- + src/hb-ot-shape-complex-arabic.cc | 41 + ++++++--------------------------------- + 3 files changed, 9 insertions(+), 47 deletions(-) + +commit 48c513fec978819927535bc86b43be74315f746c +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 2 14:17:42 2018 +0200 + + Minor + + src/hb-ot-shape-complex-arabic.cc | 2 +- + src/hb-ot-shape-complex-default.cc | 2 +- + src/hb-ot-shape-complex-hangul.cc | 2 +- + src/hb-ot-shape-complex-hebrew.cc | 14 +------------- + src/hb-ot-shape-complex-indic.cc | 2 +- + src/hb-ot-shape-complex-indic.hh | 2 -- + src/hb-ot-shape-complex-khmer.cc | 2 +- + src/hb-ot-shape-complex-myanmar.cc | 4 ++-- + src/hb-ot-shape-complex-thai.cc | 2 +- + src/hb-ot-shape-complex-tibetan.cc | 2 +- + src/hb-ot-shape-complex-use.cc | 2 +- + src/hb-ot-shape-complex.hh | 11 ++++------- + src/hb-ot-shape.cc | 8 ++++---- + 13 files changed, 19 insertions(+), 36 deletions(-) + +commit cca757ae56d6a82cfad35edc6dbae58049a34f91 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 2 13:27:11 2018 +0200 + + Minor + + src/hb-ot-shape.cc | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 96eca87f89588126d3fa5c7f3884ae2f302a91e1 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 2 13:24:40 2018 +0200 + + Move things + + src/hb-ot-shape.cc | 22 ++++++++++------------ + src/hb-ot-shape.hh | 3 +++ + 2 files changed, 13 insertions(+), 12 deletions(-) + +commit 588a4ac8bc9fd20464c7a77ead27ae34478c9bc8 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 2 13:13:47 2018 +0200 + + Rename + + src/hb-ot-face.cc | 20 +++++++------- + src/hb-ot-face.hh | 78 + +++++++++++++++++++++++++++---------------------------- + 2 files changed, 49 insertions(+), 49 deletions(-) + +commit 10b6c7c63870fa04cd8adcf9f38644c2a799db8a +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 2 13:11:18 2018 +0200 + + Minor include cleanup + + src/hb-ot-shape-complex.hh | 1 + + src/hb-ot-shape.cc | 4 +--- + src/hb-ot-shape.hh | 2 +- + 3 files changed, 3 insertions(+), 4 deletions(-) + +commit 1d1734e985e1f2a746b4fff0cd82d96d477577d5 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Oct 2 13:04:05 2018 +0200 + + Shuffle code around + + src/hb-ot-shape-complex-hebrew.cc | 2 +- + src/hb-ot-shape-fallback.cc | 2 +- + src/hb-ot-shape-normalize.cc | 2 +- + src/hb-ot-shape.cc | 32 ++++++++++++++++++++++++++++---- + src/hb-ot-shape.hh | 29 ++++++----------------------- + 5 files changed, 37 insertions(+), 30 deletions(-) + +commit bf5088b3dcd94106937290c180f3f40bc8524b48 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Tue Oct 2 11:07:06 2018 +0330 + + Minor, fix -Weverthing bot warnings (#1210) + + test/api/test-buffer.c | 8 ++++---- + test/api/test-multithread.c | 3 +-- + 2 files changed, 5 insertions(+), 6 deletions(-) + +commit d27e5ec3a236b8eb37ef9ce558ad54077e46b003 +Author: Khaled Hosny <khaledhosny@eglug.org> +Date: Tue Oct 2 08:25:29 2018 +0200 + + Skip BOM in the Python sample file + + Fixes https://github.com/harfbuzz/harfbuzz/issues/1208 + + src/sample.py | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit f9ea3dc4c6e85c417dd4c8546e5ebe02b67131b9 +Author: HinTak <htl10@users.sourceforge.net> +Date: Tue Oct 2 06:43:06 2018 +0100 + + Missing "out" indicator (#1209) + + Missing "out" indicator. Affect gobject introspection. + + src/hb-font.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 9742679b8253919f8bfec8a77532092044e951aa +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Tue Oct 2 03:20:48 2018 +0330 + + [circleci] Remove some of the not needed flags + + .circleci/config.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit f72b748371da2d7ce327a5d15feea46960aa7dd3 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Tue Oct 2 00:16:08 2018 +0330 + + [circleci] Fix "msan" and "everything" bots (#1205) + + .circleci/config.yml | 13 ++++++------- + src/check-symbols.sh | 2 -- + test/fuzzing/main.cc | 22 +++++++++------------- + test/fuzzing/run-shape-fuzzer-tests.py | 2 -- + test/fuzzing/run-subset-fuzzer-tests.py | 2 -- + 5 files changed, 15 insertions(+), 26 deletions(-) + +commit 8bf4027d23318c7e1ff7fe9f5e7ad8b0380e5415 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 1 20:05:00 2018 +0200 + + [indic] Remove Consonant_Medial from grammar and code + + The only Indic CM is U+0A75 GURMUKHI SIGN YAKASH, which Uniscribe + doesn't treat + specially, and font designers design for that. So, do the same. + + src/hb-ot-shape-complex-indic-machine.hh | 1244 + ++++++++++++++---------------- + src/hb-ot-shape-complex-indic-machine.rl | 10 +- + src/hb-ot-shape-complex-indic.cc | 2 +- + src/hb-ot-shape-complex-indic.hh | 6 +- + 4 files changed, 589 insertions(+), 673 deletions(-) + +commit ab4c37f73a7d4fcf48584cda3fff94e98a672086 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 1 19:35:48 2018 +0200 + + [khmer] Add mark-ordering tests + + Fixes https://github.com/harfbuzz/harfbuzz/issues/667 + + test/shaping/data/in-house/Makefile.sources | 2 ++ + .../b6031119874ae9ff1dd65383a335e361c0962220.ttf | Bin 0 -> 2564 bytes + .../data/in-house/tests/khmer-mark-order.tests | 25 + +++++++++++++++++++++ + 3 files changed, 27 insertions(+) + +commit 51436547162a18e88144e7125ad6ce4a69a08d4b +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 1 19:09:58 2018 +0200 + + [khmer] Rewrite grammar completely + + Based on experimenting with Uniscribe to extract grammar and + categories. + + Failures down from 44 to 35: + + KHMER: 299089 out of 299124 tests passed. 35 failed (0.0117008%) + + We still don't enforce the one-matra rule pre-decomposition, + but enforce + an order and one-matra-per-position post-decomposition. + + https://github.com/harfbuzz/harfbuzz/issues/667 + + src/hb-ot-shape-complex-indic.hh | 2 +- + src/hb-ot-shape-complex-khmer-machine.hh | 300 + ++++++++++++++++++++----------- + src/hb-ot-shape-complex-khmer-machine.rl | 42 +++-- + src/hb-ot-shape-complex-khmer.cc | 4 +- + src/hb-ot-shape-complex-khmer.hh | 99 +++++----- + 5 files changed, 270 insertions(+), 177 deletions(-) + +commit aaaa65baa7fcfb65ae814528bdd93cc5c4ea540d +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 1 16:59:48 2018 +0200 + + [khmer] Remove unused code + + src/hb-ot-shape-complex-khmer.hh | 12 ------------ + 1 file changed, 12 deletions(-) + +commit eb1e60287732ede6040ce6f7498c10909448d248 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 1 15:31:50 2018 +0200 + + [test] Try import unicodedata2 as unicodedata + + test/shaping/hb_test_tools.py | 4 ++++ + 1 file changed, 4 insertions(+) + +commit 81afdbe803ca949d915d03cab4a6ed6c6e6ff304 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 1 15:01:04 2018 +0200 + + [use] Disable automatic ZWJ for 'akhn' feature + + Fixes https://github.com/harfbuzz/harfbuzz/issues/746 + + src/hb-ot-shape-complex-use.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit ceef311dcaea7e1ecfedb4f1257a705572611f0f +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 1 12:45:06 2018 +0200 + + [use] Change categories for Left_And_* matras + + These are only relevant to Sinhala, because they decompose in other + cases. The USE spec categorizes them all as VPst. No idea why we + weren't following that before. + + src/gen-use-table.py | 4 ++-- + src/hb-ot-shape-complex-use-table.cc | 24 ++++++++++++------------ + 2 files changed, 14 insertions(+), 14 deletions(-) + +commit 3426a361571a1996b5a895fb9374ce3a4a7f9af3 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 1 12:55:57 2018 +0200 + + Unbreak bots + + src/hb-cache.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 98ac01d3b3deb7c7f5411f6f25c6e7588d84b5f9 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 1 12:10:00 2018 +0200 + + [morx] Break out if buffer gets into error + + Was getting stuck not making progress somehow. + + src/hb-aat-layout-common.hh | 2 ++ + src/hb-aat-layout-morx-table.hh | 4 ++++ + 2 files changed, 6 insertions(+) + +commit df827a6ab88cd8bde346176fc53a5c2d57eee808 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Oct 1 11:34:20 2018 +0200 + + [cache] Fix cache coherency corner-case + + If key_bits+value_bits-cache_bits==32 then -1 is ambiguous... + + src/hb-cache.hh | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +commit 0fa1edbd3bbf825be078677dc46c3440f9802551 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Mon Oct 1 09:40:29 2018 +0330 + + [circleci] Couple of fixes (#1200) + + * Raise error on warnings on -everything + * Enable fontconfig to two bots + * Fix msan bot now that all of its real complain are gone + + .circleci/config.yml | 14 ++++++-------- + src/check-symbols.sh | 2 ++ + src/hb-ucdn.cc | 2 ++ + test/fuzzing/run-shape-fuzzer-tests.py | 2 ++ + test/fuzzing/run-subset-fuzzer-tests.py | 2 ++ + util/helper-cairo.cc | 2 ++ + 6 files changed, 16 insertions(+), 8 deletions(-) + +commit 3babb0813c69d2b419f06773f366a44a9ad32cdb +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 30 20:02:30 2018 +0200 + + [msan] Disable icu explicitly + + .circleci/config.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit dc9b47ae87096d34d146e50e44e742a76861976f +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 30 18:35:12 2018 +0200 + + [msan] Remove uninstrumented libraries + + .circleci/config.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit ad1c190ecfbac66ffeef69db769073a33331eed3 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 30 18:26:45 2018 +0200 + + Correct fix for glib-mkenum warning + + src/hb-buffer.h | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +commit 1dd1e56bf42af5b11afc3e34f78869e93d39867e +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 30 18:25:58 2018 +0200 + + Revert "Fix glib-mkenum warning" + + This reverts commit 247756a7d89008ee6a7d1171dc07ba22454c6034. + + Was wrong. Right fix coming. + + src/hb-buffer.h | 2 ++ + 1 file changed, 2 insertions(+) + +commit 3f08750fa6772e7e342b96192b84cb9963f7335b +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 30 18:23:34 2018 +0200 + + Move _POSIX_SOURCE to hb.hh + + src/hb-blob.cc | 5 ----- + src/hb.hh | 4 ++++ + 2 files changed, 4 insertions(+), 5 deletions(-) + +commit 90dd255e570bf8ea3436e2f29242068845256e55 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 30 18:19:54 2018 +0200 + + Change _HB_SCRIPT_MAX_VALUE from 0xFFFFFFFF to 0x7FFFFFFF + + Fixes https://github.com/harfbuzz/harfbuzz/issues/504 + + src/hb-common.h | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +commit dcfcb950b81a2865ef01f5a69087264b79ed1bfd +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 30 18:14:50 2018 +0200 + + [test] Fix -Wunused-parameter warnings + + test/api/hb-test.h | 1 + + test/api/test-blob.c | 2 +- + test/api/test-c.c | 2 +- + test/api/test-font.c | 16 ++++++++-------- + test/api/test-multithread.c | 2 +- + test/api/test-ot-color.c | 2 +- + test/api/test-shape.c | 14 +++++++------- + test/api/test-unicode.c | 10 +++++----- + 8 files changed, 25 insertions(+), 24 deletions(-) + +commit be0b2ed3162f465dbf44a0f018d4e2af5dcdf87c +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 30 18:01:20 2018 +0200 + + More warning fixes + + test/api/test-multithread.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +commit 5c65ed800de4caef5ee9ad2111225fa5d8235737 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 30 17:48:55 2018 +0200 + + Fix bug introduced in 9b0b40b3c1ac8155c80ed5dc976228f4d3ec7e1f + + Also discovered by msan bot. + + src/hb-ot-shape-fallback.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 247756a7d89008ee6a7d1171dc07ba22454c6034 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 30 13:10:54 2018 +0200 + + Fix glib-mkenum warning + + GEN hb-gobject-enums.h + WARNING: Failed to parse "/*< private >*/" in ../../src/hb-buffer.h + + src/hb-buffer.h | 2 -- + 1 file changed, 2 deletions(-) + +commit 0a89f9572fe2d0d9fbf0297e0a69307f0ba1a17c +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Sun Sep 30 17:44:15 2018 +0330 + + [circleci] Pass freetype compile flags to right place + + .circleci/config.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit ad701f05cc86c22e8e53b7f5458887457e3a5e5f +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Sun Sep 30 17:30:42 2018 +0330 + + [circleci] Use an instrumented freetype on msan bot + + .circleci/config.yml | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +commit 57aabbc29ec6dfa7f1b57da7b6c62fdc547f8ef8 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Sun Sep 30 16:31:28 2018 +0330 + + [circleci] Another on fixing msan + + .circleci/config.yml | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +commit 24f148df3ecc899c9cf6d5359d3d35ee5e84a98c +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Sun Sep 30 14:46:56 2018 +0330 + + [circleci] minor + + .circleci/config.yml | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +commit 0a9aab672287149540e8d90b5063ad4c562c423c +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Sun Sep 30 14:45:43 2018 +0330 + + [circleci] Try to fix msan bot + + .circleci/config.yml | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +commit b5285b34798cb7ee672343d00cbe066ea8a2ef83 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 30 12:23:01 2018 +0200 + + [util] Remove unneeded virtual + + clang warning: + + ../../util/options.hh:72:13: warning: destination for this 'memset' + call is a pointer to dynamic class + 'option_parser_t'; vtable pointer will be overwritten + [-Wdynamic-class-memaccess] + memset (this, 0, sizeof (*this)); + ~~~~~~ ^ + ../../util/options.hh:72:13: note: explicitly cast the pointer to + silence this warning + memset (this, 0, sizeof (*this)); + ^ + (void*) + + util/options.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 89ed040b21b366c927199bedd0e4cb060389d076 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 30 06:06:26 2018 -0400 + + [util] Fix more non-virtual-destructor warnings + + util/options.hh | 28 ++++++++++++++++++---------- + 1 file changed, 18 insertions(+), 10 deletions(-) + +commit 2382dd07fa6ff49638b146a523e9d2e93cf69ceb +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 30 05:54:47 2018 -0400 + + Minor + + util/options.hh | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 9caa432d0c5c09c8151cfce1e2cc184fbdd89594 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 30 05:49:08 2018 -0400 + + [util] Use HB_FALLTHROUGH + + Sure, gcc knows to warn about this as well: + + ../../util/options.cc:175:17: warning: this statement may fall through + [-Wimplicit-fallthrough=] + case 1: m.r = m.t; + ~~~~^~~~~ + ../../util/options.cc:176:5: note: here + case 2: m.b = m.t; + ^~~~ + + But HOLY SMOKES, look at clang -Weverything bot message: + + options.cc:176:5: warning: unannotated fall-through between switch + labels [-Wimplicit-fallthrough] + case 2: m.b = m.t; + ^ + options.cc:176:5: note: insert 'HB_FALLTHROUGH;' to silence this + warning + case 2: m.b = m.t; + ^ + HB_FALLTHROUGH; + + Right, it's telling me to insert "HB_FALLTHROUGH;" there!!!!!!!!! + + util/options.cc | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +commit 2e728a7d86c714d845524a0722c2b653feb9d915 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 30 05:47:36 2018 -0400 + + [util] Mark var static + + From clang -Weverything bot: + + options.cc:39:3: warning: no previous extern declaration + for non-static variable 'supported_font_funcs' + [-Wmissing-variable-declarations] + + util/options.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit e910a1aef4b2413c627240fc06d2a5696b24747a +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 30 05:46:20 2018 -0400 + + [util] Add empty virtual destructor to option_group_t + + From clang -Weverything bot: + + ./options.hh:57:8: warning: 'option_group_t' has virtual functions + but non-virtual destructor [-Wnon-virtual-dtor] + struct option_group_t + ^ + + util/options.hh | 2 ++ + 1 file changed, 2 insertions(+) + +commit b1e07e1e6cc7a8e5445c7aeb9491ae629029011b +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 30 05:43:22 2018 -0400 + + [indic/khmer] Remove use of global constructors + + Alternative woul have been to resurrect F_COMBINE that I removed in + 70136a78cb9eda244767f8e8a3d30d0f3c569d01 + + But this does it for now. I'm not sure why check-static-inits.sh + didn't + catch this before. Clang -Weverything bot did: + + CXX libharfbuzz_la-hb-ot-shape-complex-indic.lo + hb-ot-shape-complex-indic.cc:99:1: warning: declaration requires a + global constructor [-Wglobal-constructors] + indic_features[] = + ^ + 1 warning generated. + CXX libharfbuzz_la-hb-ot-shape-complex-khmer.lo + hb-ot-shape-complex-khmer.cc:36:1: warning: declaration requires a + global constructor [-Wglobal-constructors] + khmer_features[] = + ^ + 1 warning generated. + + src/hb-ot-map.hh | 2 ++ + src/hb-ot-shape-complex-indic.cc | 34 +++++++++++++++++----------------- + src/hb-ot-shape-complex-khmer.cc | 18 +++++++++--------- + 3 files changed, 28 insertions(+), 26 deletions(-) + +commit 00cd00e64130694ff7b49456d4bc421a153b4e6d +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 30 05:34:30 2018 -0400 + + Tweak HB_TAG and HB_UNTAG + + uint32_t was getting promoted to signed int, which is not what + we wanted... + + Wow, clang has become good at generating warnings... + + ../../src/hb-common.h:349:29: warning: signed shift result + (0xFF000000) sets the sign bit of the shift expression's type ('int') + and becomes negative [-Wshift-sign-overflow] + _HB_SCRIPT_MAX_VALUE = HB_TAG_MAX, /*< + skip >*/ + ^~~~~~~~~~ + ../../src/hb-common.h:93:20: note: expanded from macro 'HB_TAG_MAX' + define HB_TAG_MAX HB_TAG(0xff,0xff,0xff,0xff) + ^~~~~~~~~~~~~~~~~~~~~~~~~~~ + ../../src/hb-common.h:89:57: note: expanded from macro 'HB_TAG' + define HB_TAG(c1,c2,c3,c4) + ((hb_tag_t)((((uint8_t)(c1))<<24)|(((uint8_t)(c2))<<16)|(((uint8_t)(c3))<<8)|((uint8_t)(c4)))) + ~~~~~~~~~~~~~~~^ ~~ + ../../src/hb-common.h:349:3: warning: ISO C restricts enumerator + values to range of 'int' (4294967295 is too large) [-Wpedantic] + _HB_SCRIPT_MAX_VALUE = HB_TAG_MAX, /*< + skip >*/ + ^ ~~~~~~~~~~ + + src/hb-common.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 8a31e406291f4cb27480fc85049f08abd739cb59 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 30 05:27:39 2018 -0400 + + [font] Make *_advance() fallback to *_advances + + And remove redundant implementations. + + src/hb-font.cc | 12 ++++++++++++ + src/hb-ft.cc | 19 ------------------- + src/hb-ot-font.cc | 22 ---------------------- + 3 files changed, 12 insertions(+), 41 deletions(-) + +commit bd07d2878ff28baecf7b4b587a18ffbb744b7eb1 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 30 03:54:40 2018 -0400 + + Use buffer scratch_flags to remember if we had any joiners + + src/hb-buffer.hh | 3 ++- + src/hb-ot-layout.hh | 12 ++++++++++-- + src/hb-ot-shape-complex-arabic.cc | 3 +++ + 3 files changed, 15 insertions(+), 3 deletions(-) + +commit ba0f0f156fe05bda760efcb0c8d34f303fa26ab0 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 30 03:49:52 2018 -0400 + + Document setlocale() threadsafety issue + + "Fixes" //github.com/harfbuzz/harfbuzz/issues/1191 + + src/hb-buffer.cc | 2 ++ + src/hb-common.cc | 7 +++++++ + 2 files changed, 9 insertions(+) + +commit 06be2aa93fa6ea8cc32684a4b51bfe927c5202bb +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Sun Sep 30 00:15:25 2018 +0330 + + [ci] Build glib and freetype and enable msan bot (#1198) + + .circleci/config.yml | 41 +++++++++++++++++++++-------------------- + 1 file changed, 21 insertions(+), 20 deletions(-) + +commit cefdef0247026f941eba8930c73b66b0498bb63c +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Sat Sep 29 10:19:54 2018 +0330 + + Minor on test-multithread, align the actual and expected results + + test/api/test-multithread.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 678beff64ca3b2963de25d8a76a2bf3710c3d7a6 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Sat Sep 29 10:16:14 2018 +0330 + + [circleci] Add -Wno-reserved-id-macro to clang-everything + + .circleci/config.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit c763b9440189b541316054ba4f623e728b5aae77 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Sep 28 20:53:07 2018 -0400 + + [test-multithread] Disable FreeType funcs + + test/api/test-multithread.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +commit 9b0b40b3c1ac8155c80ed5dc976228f4d3ec7e1f +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Sep 28 11:16:18 2018 -0400 + + Fix fallback kerning to check for current glyph's mask + + src/hb-ot-shape-fallback.cc | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +commit 909a07b587884e9cd1d92ba9f3d5b96d8774c67a +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Sat Sep 29 03:10:13 2018 +0330 + + [circleci] Improve clang-everything bot log, more to come + + #1196 + + .circleci/config.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 9be8062b4d241f02bb96df436e98f10f08bda4f8 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Sat Sep 29 02:11:05 2018 +0330 + + [ci] Another try on mingw bot + + appveyor.yml | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit d4d261a97723b27fb9ad9a69b8dc7fd8c560a98b +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Sat Sep 29 01:57:50 2018 +0330 + + [ci] Another try on fixing mingw bots + + Per + https://github.com/Alexpux/MSYS2-packages/issues/163#issuecomment-73555971 + + appveyor.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 7b68edf2abc7680199360d52ed283cfc4f49b7d5 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Fri Sep 28 20:53:48 2018 +0330 + + [tests] Don't try to get glyph names on failures + + As it may cause a race unrelated to the issue actually happened + + test/api/test-multithread.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit d289d6381864649504abfb1196ac20a1d4664a4e +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Fri Sep 28 20:47:21 2018 +0330 + + [ci] Trying to fix mingw bot + + As https://github.com/Alexpux/MSYS2-packages/issues/702 + + appveyor.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 33231a855f0e3d2a14e5e2fcb921c6fc773ae6cf +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Sep 28 11:06:49 2018 -0400 + + Fix pthread fail for real + + Using a hack... + + test/api/Makefile.am | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +commit 8cb8209c911a69442f23f744981e3ed01e44a3fc +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Sep 28 10:55:28 2018 -0400 + + Fix bot fails + + test/api/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit f4072e8cb81072cd6d51a2607efedb76c02e7db1 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Sep 28 10:14:23 2018 -0400 + + [morx] Remove mark_set from Insertion + + text-rendering-tests test MORX-32 shows that for Insertion, an unset + mark is treated + as mark set at 0. This is unlike the Reordering lookup where un + unset mark performs + nothing. + + Fixes MORX-32. + + src/hb-aat-layout-morx-table.hh | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +commit 0d18ec5467818fa8f763ec2871146a64d39987e7 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Sep 28 10:00:07 2018 -0400 + + [morx] unsafe-to-break in Insertion + + Makes MORX-29, MORX-30, MORX-31 pass. + + src/hb-aat-layout-morx-table.hh | 2 ++ + 1 file changed, 2 insertions(+) + +commit 02bebe42c1ffbd8e11b232c943317c8cd8141afb +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Sep 28 09:51:35 2018 -0400 + + [test/text-rendering-tests] Update from upstream + + test/shaping/data/text-rendering-tests/DISABLED | 4 ++++ + test/shaping/data/text-rendering-tests/Makefile.sources | 4 ++++ + .../text-rendering-tests/fonts/TestMORXThirtyone.ttf | Bin 0 -> + 2964 bytes + .../text-rendering-tests/fonts/TestMORXThirtytwo.ttf | Bin 0 -> + 2948 bytes + .../text-rendering-tests/fonts/TestMORXTwentynine.ttf | Bin 0 -> + 3012 bytes + .../data/text-rendering-tests/tests/MORX-29.tests | 4 ++++ + .../data/text-rendering-tests/tests/MORX-30.tests | 4 ++++ + .../data/text-rendering-tests/tests/MORX-31.tests | 8 ++++++++ + .../data/text-rendering-tests/tests/MORX-32.tests | 4 ++++ + 9 files changed, 28 insertions(+) + +commit 4cd342baea323bf9709340bbabfc092c976c239c +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Sep 28 09:47:45 2018 -0400 + + Fix ubsan bot + + test/api/Makefile.am | 1 + + 1 file changed, 1 insertion(+) + +commit b435df3a5b6f7fddc091c4362a36840305144a57 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Sep 28 09:13:14 2018 -0400 + + More atomic tuneup + + src/hb-atomic.hh | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +commit 7e6e094abd27fd022fe9aea1872ef82f6a0cdcec +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Sep 28 08:45:57 2018 -0400 + + [test-multithread] Install ot funcs before filling ref buffer + + test/api/test-multithread.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +commit 21fbee831e0eab2c2f4513825c939158f4578156 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Sep 28 08:43:37 2018 -0400 + + [test-multithread] Take num-threads and num-iters from command-line + + test/api/test-multithread.c | 5 +++++ + 1 file changed, 5 insertions(+) + +commit 598be3bb38fd11a288f8155b8c27ffef4ebdd8b9 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Sep 28 08:33:26 2018 -0400 + + Minor + + test/api/test-multithread.c | 1 + + 1 file changed, 1 insertion(+) + +commit c09bf3d50589c8eb95b322ef3e4eb8a288dacebe +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Fri Sep 28 16:13:01 2018 +0330 + + test-multithread, check the results on every iteration (#1194) + + test/api/test-multithread.c | 59 + ++++++++++++++++++++++++--------------------- + 1 file changed, 32 insertions(+), 27 deletions(-) + +commit dbc3070a15290310bb5aade11d04eb24fe958094 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Fri Sep 28 16:01:15 2018 +0330 + + Make test-multithread pass the tsan bot test (#1193) + + test/api/test-multithread.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +commit d2542cd28c70b2ba7ab28c0fe5459a1b4a873478 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Sep 27 17:23:24 2018 -0400 + + More atomic fixup + + src/hb-atomic.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 3ee96984f4633852736b33640c89d1706bc77e0b +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Sep 27 17:20:26 2018 -0400 + + Fixup atomics from recent change + + src/hb-atomic.hh | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +commit 305468708dc9ce9dadad36c117c380f13bcc6a26 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Sep 27 16:54:23 2018 -0400 + + [cache] Use atomic writes in clear() + + To help TSan. + + src/hb-cache.hh | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +commit 9e9a36ee651502b69717895385387951a2d0802a +Author: Volker Krause <vkrause@kde.org> +Date: Thu Sep 27 16:33:49 2018 +0200 + + Fix infinite loop when walking up the directory hierarchy (#1183) + + A single find_package(harfbuzz) line in user code resulted in + this loop + getting stuck when _harfbuzz_libdir_iter became "/". + + src/harfbuzz-config.cmake.in | 4 ++++ + 1 file changed, 4 insertions(+) + +commit 0c1d852bc41a4f69f890be4817c84bd7de56e07a +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Thu Sep 27 11:53:17 2018 +0330 + + Use clang for compiling freetype for tsan bot + + .circleci/config.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 662f7d7e8bfa77b21ffa05e853f61dda993dcc8a +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Sep 26 18:42:37 2018 -0400 + + [arabic] Do the joiner-flipping only for rlig feature + + See comment. + + src/hb-ot-shape-complex-arabic.cc | 24 +++++++++++++++++++----- + 1 file changed, 19 insertions(+), 5 deletions(-) + +commit 7f30629cddcf0196d7b754df0cb2d4a8e5fed4b6 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Sep 26 16:40:23 2018 -0400 + + [ft] Make TSan happy + + src/hb-ft.cc | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit ec743fce2a72a1cb76ac9401747a442a03a051d9 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Sep 26 16:37:18 2018 -0400 + + Add more atomic intrinsics + + src/hb-atomic.hh | 21 ++++++++++++++++++--- + 1 file changed, 18 insertions(+), 3 deletions(-) + +commit d183b33c1dd42055a9432f4a756ea20856913201 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Sep 26 16:29:35 2018 -0400 + + Rename test + + test/api/Makefile.am | 2 +- + test/api/{test-subset-codepoints.c => test-collect-unicodes.c} | 0 + 2 files changed, 1 insertion(+), 1 deletion(-) + +commit c9c75fe3d9eb36f166d594ceb5889a1dc0b14fe6 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Thu Sep 27 00:08:06 2018 +0330 + + [ci] Compile freetype on tsan and put sanitizer flags on correct + places (#1188) + + .circleci/config.yml | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +commit 39da1914b4fd1c58d61cb29c78a0904ff6b905c6 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Wed Sep 26 23:32:45 2018 +0330 + + Test freetype funcs on test-multithread (#1187) + + test/api/Makefile.am | 6 ++++-- + test/api/test-multithread.c | 25 +++++++++++++++++-------- + 2 files changed, 21 insertions(+), 10 deletions(-) + +commit e88009a93f5d13ed31b6262f928761e9574dcef1 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Wed Sep 26 22:53:02 2018 +0330 + + Minor, remove the no longer needed comment on test-multithread + + test/api/test-multithread.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 90a0f9fa0c020c268ac3ba31c7f1337eed85f35e +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Sep 26 15:03:07 2018 -0400 + + Make TSan happy with make_immutable() + + src/hb-blob.cc | 2 ++ + src/hb-face.cc | 2 ++ + src/hb-font.cc | 4 ++++ + src/hb-unicode.cc | 2 ++ + 4 files changed, 10 insertions(+) + +commit 34d5a2595331c568ae524057d031c9d5d2573978 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Sep 26 15:02:21 2018 -0400 + + Fix test-multithread and increase num_threads to 30 + + What were you thinking? ;) + + test/api/test-multithread.c | 56 + +++++++++++++++++++++------------------------ + 1 file changed, 26 insertions(+), 30 deletions(-) + +commit 8bb73dad7f3279e1f1362cf9a137504e8ef08985 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Wed Sep 26 20:50:51 2018 +0330 + + Add a multithreaded test (#1184) + + test/api/Makefile.am | 6 ++ + test/api/test-multithread.c | 146 + ++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 152 insertions(+) + +commit 04caf11608d2db13eb6ed2ecc3d406e284b4c13c +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Sep 26 12:13:47 2018 -0400 + + [hb-view] Change subpixel bits from 8 to 6 + + To match FreeType units, such that FreeType gets correct size from us. + This matters more now that we allow setting --ft-load-flags. + + util/hb-view.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 824111d4842b9a7bbbdcd147325f8f372ed3d37c +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Sep 25 12:47:37 2018 -0400 + + Fix iOS build + + Fixes https://github.com/harfbuzz/harfbuzz/pull/1179 + + src/hb-coretext.cc | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 4b4be7701f635f8378e7f868cfbe8d4571fc841f +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Tue Sep 25 09:24:35 2018 +0330 + + [circle] Add an obsessive clang bot (#1178) + + .circleci/config.yml | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +commit 8282e881b51363811078bce53fad6aa5b41f7b41 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 24 19:43:01 2018 -0400 + + Disable msan bot again + + Fixes https://github.com/harfbuzz/harfbuzz/issues/1175 + + .circleci/config.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 6c0e7eb6a6f3f888442c0a97ce6a771631990ed6 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 24 19:07:23 2018 -0400 + + Minor + + src/hb-ot-map.hh | 1 + + src/hb-ot-shape-complex-indic.cc | 34 +++++++++++++++++----------------- + src/hb-ot-shape-complex-khmer.cc | 18 +++++++++--------- + 3 files changed, 27 insertions(+), 26 deletions(-) + +commit d748dc76644f28d4130f9cb1dee7a22cbe81c25d +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 24 18:30:50 2018 -0400 + + More iter inits + + src/hb-ot-layout-gsubgpos.hh | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +commit d9867497d09af929554eaa89cc6fee865b018646 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 24 18:11:59 2018 -0400 + + Minor + + src/hb-ot-shape.cc | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 70136a78cb9eda244767f8e8a3d30d0f3c569d01 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 24 18:03:34 2018 -0400 + + Remove F_COMBINE + + Now I wonder if any bots will be unhappy we calling | in static + const initializations... + Or would that cost runtime init? Our tests don't detect any.. + + src/hb-ot-map.hh | 2 -- + src/hb-ot-shape-complex-arabic.cc | 2 +- + 2 files changed, 1 insertion(+), 3 deletions(-) + +commit f048ead84a4d3fe0bb712ed228c2f39c01ce9705 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 24 18:01:53 2018 -0400 + + Some more + + src/hb-ot-map.cc | 5 +++-- + src/hb-ot-map.hh | 13 +++++++------ + src/hb-ot-shape-complex-arabic.cc | 18 +++++++++--------- + src/hb-ot-shape-complex-hangul.cc | 2 +- + src/hb-ot-shape-complex-indic.cc | 8 ++++---- + src/hb-ot-shape-complex-khmer.cc | 8 ++++---- + src/hb-ot-shape-complex-myanmar.cc | 10 +++++----- + src/hb-ot-shape-complex-tibetan.cc | 2 +- + src/hb-ot-shape-complex-use.cc | 20 ++++++++++---------- + src/hb-ot-shape.cc | 30 +++++++++++++++--------------- + 10 files changed, 59 insertions(+), 57 deletions(-) + +commit 1676f608c8e4f880789252ca448bb008f6dd51b4 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 24 17:55:03 2018 -0400 + + Minor refactoring + + src/hb-ot-map.hh | 15 ++++++++++- + src/hb-ot-shape-complex-hangul.cc | 2 +- + src/hb-ot-shape-complex-indic.cc | 52 + +++++++++++++++----------------------- + src/hb-ot-shape-complex-khmer.cc | 38 ++++++++++------------------ + src/hb-ot-shape-complex-myanmar.cc | 2 +- + 5 files changed, 51 insertions(+), 58 deletions(-) + +commit 10203339600e85d6aaffba6034ac250e72fdfc12 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Tue Sep 25 01:00:32 2018 +0330 + + [circleci] Update sanitizer bots with newer clang and Ubuntu version + (#1176) + + .circleci/config.yml | 48 + ++++++++++++++++++++++++++++++++---------------- + 1 file changed, 32 insertions(+), 16 deletions(-) + +commit 12b8baa7653741ba13a89cd40f1f36b8bac11666 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 24 17:22:39 2018 -0400 + + [msan] Enable again to get a build log, and try to play with + suppressions + + .circleci/config.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit aec0d3cbc923a8801c5bd9e9ae05801a31a7260c +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 24 13:12:15 2018 -0400 + + [ubsan] Re-enable now that it passes locally + + .circleci/config.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 4839807340cc73d5ba826dff4b4ba358775a213d +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 24 13:11:34 2018 -0400 + + [check-static-inits.sh] Allow some if ubsan is in effect + + src/check-static-inits.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit e45ba31dc723988150ef766758fa89fecd50ca03 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 24 13:04:48 2018 -0400 + + [check-symbols.sh] Allow weak objects "V" + + ubsan generates these. + + src/check-symbols.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit d07f3111b4bc38798e16a2459b80a16d7a9f9ff1 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 24 13:01:35 2018 -0400 + + Link API test programs with C++ linker + + Needed to make ubsan work. + + Fixes https://github.com/harfbuzz/harfbuzz/issues/1174 + + test/api/Makefile.am | 2 ++ + 1 file changed, 2 insertions(+) + +commit a96508cfc9bd9013d24b18547fcd9c03e08fe2f2 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 24 12:52:42 2018 -0400 + + [msan] Add MSAN_OPTIONS=exitcode=42 + + Default exit value is 77, which causes autotools to "skip" test. + + .circleci/config.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 45f5aa97905996e3486c6dbba8493b11cfa0cf15 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 24 12:43:29 2018 -0400 + + [circleci] Disable msan and ubsan builds + + https://github.com/harfbuzz/harfbuzz/issues/1174 + https://github.com/harfbuzz/harfbuzz/issues/1175 + + .circleci/config.yml | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 2d93148a0f915bb52433ecc9d66845191a2f9135 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 24 11:52:22 2018 -0400 + + Ignore weak symbols in check-symbols.sh + + Some clang versions leave a std::round(float) weak symbol around... + + src/check-symbols.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 55bae6825ed2058255a512a73293e3cdff0e78a4 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 24 10:43:06 2018 -0400 + + [docs] A few improvements + + If we wrote just this much every day... + + src/hb-buffer.cc | 4 ++++ + src/hb-buffer.h | 20 +++++++++++++++----- + src/hb-face.cc | 11 +++++++---- + src/hb-font.cc | 12 +++++++----- + 4 files changed, 33 insertions(+), 14 deletions(-) + +commit 57fa2c23de8b6b66894d6872d192ac90ec8bf05a +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 24 09:57:52 2018 -0400 + + Readjust Hebrew composition again + + src/hb-ot-shape-complex-hebrew.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 7f335390f3a498119319a0e6c3ce7656a3902066 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 24 09:56:18 2018 -0400 + + Revert change that would decompose text if GPOS mark feature is + available + + https://github.com/harfbuzz/harfbuzz/issues/653#issuecomment-423905920 + + src/hb-ot-shape-normalize.cc | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +commit a6f4b2f7cd088aeb44e1aac672434641f4f9e484 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 24 09:54:37 2018 -0400 + + Fix normalization + + https://github.com/harfbuzz/harfbuzz/commit/62d1e0852a5549a1b510ad46a4b89f12730bb708#commitcomment-30613091 + + src/hb-ot-shape-normalize.cc | 1 - + 1 file changed, 1 deletion(-) + +commit 3583fb03b14a10ec5ab5f9c480e150934101fd0b +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 23 22:33:38 2018 -0400 + + Simplify ZWJ-skipping a bit + + Towards disabling ZWJ-skipping in certain GPOS contexts. + + Part of https://github.com/flutter/flutter/issues/16886 + + src/hb-ot-layout-gsubgpos.hh | 6 +++--- + src/hb-ot-shape-complex-indic.cc | 21 ++++++++++++++++----- + src/hb-ot-shape-complex-khmer.cc | 21 ++++++++++++++------- + src/hb-ot-shape-complex-myanmar.cc | 15 ++++++++++++++- + src/hb-ot-shape-complex-use.cc | 15 +++++++++++++-- + 5 files changed, 60 insertions(+), 18 deletions(-) + +commit 9516cbd3df7ccdb40b27a7ba99a1e0da8a6b170c +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 23 22:00:34 2018 -0400 + + Reinit skippy iters when auto_zwj / auto_zwnj change + + Ouch. How did we not hit this bug before... + + src/hb-ot-layout-gsubgpos.hh | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +commit 62d1e0852a5549a1b510ad46a4b89f12730bb708 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 23 21:32:18 2018 -0400 + + Prefer decomposed form if font has GPOS mark feature + + Fixes https://github.com/harfbuzz/harfbuzz/issues/653 + + src/hb-ot-shape-complex-hebrew.cc | 2 +- + src/hb-ot-shape-normalize.cc | 126 + ++++++++++++++++++++------------------ + src/hb-ot-shape-normalize.hh | 7 ++- + 3 files changed, 72 insertions(+), 63 deletions(-) + +commit d7f21777e6a797758ab234555f5f7e07c87278f9 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 23 19:12:52 2018 -0400 + + [ot-font] Fix leak + + Fixes https://github.com/harfbuzz/harfbuzz/issues/1171 + + I'm glad we have leak-detector bots now. + + src/hb-ot-post-table.hh | 1 + + 1 file changed, 1 insertion(+) + +commit ae39a53f55e6b812defb4c7b48562651c9eb13a3 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Sat Sep 22 14:22:17 2018 +0330 + + Add bots with address- and thread-sanitizer + + .circleci/config.yml | 52 + ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 52 insertions(+) + +commit 24dd6c1a9d8d571c30dce4d39c1975b1d1cedc2a +Author: Matt Oliver <protogonoi@gmail.com> +Date: Sun Sep 23 18:08:30 2018 +1000 + + src/hb-blob.cc: Fix mmap functionality with UWP. + + src/hb-blob.cc | 27 +++++++++++++++++++++++++++ + src/hb.hh | 4 +++- + 2 files changed, 30 insertions(+), 1 deletion(-) + +commit b7f1bbc2f8b14a402fa9e42e88919dc0173373ce +Author: Khaled Hosny <khaledhosny@eglug.org> +Date: Sat Sep 22 16:41:56 2018 +0200 + + [test] Fix printing subprocess error messages + + Decode the string as Python 3 returns bytes string, and also don’t + assume that it ends with a new line. + + test/shaping/run-tests.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 403019482b0d7f17fbdb5def2be5f43e28bafcf3 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Sat Sep 22 17:24:03 2018 +0330 + + Fix test-subset-* leak issues + + See also https://github.com/harfbuzz/harfbuzz/pull/1169 + + test/api/hb-subset-test.h | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +commit f6ebe1f4dc95a7c4b3a0af23086873a11867c1d9 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Sat Sep 22 17:05:52 2018 +0330 + + Fix test-ot-math leak issue + + See also https://github.com/harfbuzz/harfbuzz/pull/1169 + + test/api/test-ot-math.c | 4 ++++ + 1 file changed, 4 insertions(+) + +commit 669ac81ac52e9d559324db851a9ee46ef651e7b0 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Sat Sep 22 16:49:23 2018 +0330 + + Fix test-set leak issue + + See also https://github.com/harfbuzz/harfbuzz/pull/1169 + + test/api/test-set.c | 1 + + 1 file changed, 1 insertion(+) + +commit ef9307fd2227bf0f750d8f7fafae466affc81454 +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Sat Sep 22 16:45:31 2018 +0330 + + Fix test-font leak issue + + See also https://github.com/harfbuzz/harfbuzz/pull/1169 + + test/api/test-font.c | 1 + + 1 file changed, 1 insertion(+) + +commit 5fd8bce945e7efaa48d0c29eb8b2700027bd3c0b +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Sep 19 22:34:09 2018 -0400 + + [morx] Fix mark_set check + + src/hb-aat-layout-morx-table.hh | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +commit 0739b28169eb63332b31420deb5bf58b5446f154 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Sep 19 17:32:21 2018 -0400 + + [aat] Minor + + src/hb-aat-layout-common.hh | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 7671cb9b04770d50b1b2a05a24f6fadc35993cd1 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Sep 19 17:10:26 2018 -0400 + + [coretext] Minor + + src/hb-coretext.cc | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +commit dc8ed45292ce4e522c3bda03fd83873da7b6591e +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Sep 19 16:46:41 2018 -0400 + + [morx] Implement forward/backward processing + + We reverse too many times. Can be optimized. But I doubt many fonts + use reverse lookups, so doesn't matter. + + Other than not applying user features, this completes morx table + implementation. + + src/hb-aat-layout-morx-table.hh | 40 + ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 40 insertions(+) + +commit 3bccd62196b5dff70d446c3fe053b1b47bb9c19e +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Sep 19 16:24:34 2018 -0400 + + [morx] Implement horiz-only/vert-only subtables + + src/hb-aat-layout-morx-table.hh | 24 +++++++++++++++++++++++- + 1 file changed, 23 insertions(+), 1 deletion(-) + +commit 041a08de3d0ca74d3e2fdccfa5311ff26a8b97e4 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Sep 19 16:02:56 2018 -0400 + + [morx] Improve buffer position in Insertion w DontAdvance and wo + + Just speculation. Needs tests to determine which is correct behavior. + + src/hb-aat-layout-morx-table.hh | 23 ++++++++++++++++++----- + 1 file changed, 18 insertions(+), 5 deletions(-) + +commit 388ab91642734e1ba0d7a4a4f29a17b15f1b249d +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 17 19:29:34 2018 +0200 + + [morx] Implement InsertionChain + + src/hb-aat-layout-morx-table.hh | 87 + ++++++++++++++++------------------------- + 1 file changed, 33 insertions(+), 54 deletions(-) + +commit d8d1e7df0057c79f54d855b7bfec2d21f59b09e8 +Author: David Corbett <corbett.dav@husky.neu.edu> +Date: Mon Sep 17 11:09:51 2018 -0400 + + Don't enforce a native direction for Old Hungarian + + src/hb-common.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 6a97d0f3d377a35ea691d15ac142ce043f953e71 +Author: Simon Hausmann <hausmann@gmail.com> +Date: Mon Sep 17 10:33:34 2018 +0200 + + Fix installation of cmake config when building with cmake (#1161) + + When building with the auto tools, the manually mantained + harfbuzz-config.cmake is installed. When building with cmake, we + can use + cmake to generate the correct config files for us and install them. + + CMakeLists.txt | 5 +++++ + 1 file changed, 5 insertions(+) + +commit 606bf57430370810f7bb62ba12b9685d8943685d +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 16 19:33:48 2018 +0200 + + Revert forcing use of single-parameter static_assert() + + Some clang versions define static_assert as a macro apparently, + so we cannot + redefine it... + + This reverts commit 94bfea0ce6a7b4d5641c198d50751748a353df11. + This reverts commit 4e62627831e7457ed60ff87712570065b14b200a. + + src/hb-atomic.hh | 4 ++-- + src/hb-buffer.cc | 2 +- + src/hb-buffer.hh | 4 ++-- + src/hb-cache.hh | 4 ++-- + src/hb-coretext.cc | 2 +- + src/hb-debug.hh | 2 +- + src/hb-dsalgs.hh | 4 ++-- + src/hb-machinery.hh | 4 ++-- + src/hb-null.hh | 8 +++---- + src/hb-open-type.hh | 4 ++-- + src/hb-ot-layout-common.hh | 2 +- + src/hb-ot-layout-gdef-table.hh | 6 +++--- + src/hb-ot-layout.cc | 14 ++++++------ + src/hb-ot-map.cc | 2 +- + src/hb-ot-math-table.hh | 2 +- + src/hb-ot-shape-complex-arabic-fallback.hh | 2 +- + src/hb-ot-shape-complex-indic.hh | 2 +- + src/hb-ot-shape-complex-use.cc | 2 +- + src/hb-set-digest.hh | 4 ++-- + src/hb-set.hh | 6 +++--- + src/hb-uniscribe.cc | 2 +- + src/hb.hh | 34 + +++++++++++++----------------- + util/options.cc | 3 ++- + 23 files changed, 58 insertions(+), 61 deletions(-) + +commit cbcaba6ffdf6b147d45baa95d62fd29cec67ed54 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 16 19:25:19 2018 +0200 + + One more bot fix + + src/hb-unicode.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 94bfea0ce6a7b4d5641c198d50751748a353df11 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 16 19:12:19 2018 +0200 + + Fix build, another try + + util/options.cc | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +commit 89dd4b959773d35981299551074ccc7a1eb332bd +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 16 18:11:46 2018 +0200 + + Fix bots + + "Unused private member" warning turned error. ugh. + + src/hb-aat-layout-morx-table.hh | 2 ++ + 1 file changed, 2 insertions(+) + +commit 4e62627831e7457ed60ff87712570065b14b200a +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 16 18:09:36 2018 +0200 + + Enforce single-param static_assert() only + + So we don't accidentally break it again. + + src/hb-atomic.hh | 4 ++-- + src/hb-buffer.cc | 2 +- + src/hb-buffer.hh | 4 ++-- + src/hb-cache.hh | 4 ++-- + src/hb-coretext.cc | 2 +- + src/hb-debug.hh | 2 +- + src/hb-dsalgs.hh | 4 ++-- + src/hb-machinery.hh | 4 ++-- + src/hb-null.hh | 8 +++---- + src/hb-open-type.hh | 4 ++-- + src/hb-ot-layout-common.hh | 2 +- + src/hb-ot-layout-gdef-table.hh | 6 +++--- + src/hb-ot-layout.cc | 14 ++++++------ + src/hb-ot-map.cc | 2 +- + src/hb-ot-math-table.hh | 2 +- + src/hb-ot-shape-complex-arabic-fallback.hh | 2 +- + src/hb-ot-shape-complex-indic.hh | 2 +- + src/hb-ot-shape-complex-use.cc | 2 +- + src/hb-set-digest.hh | 4 ++-- + src/hb-set.hh | 6 +++--- + src/hb-uniscribe.cc | 2 +- + src/hb.hh | 34 + +++++++++++++++++------------- + 22 files changed, 60 insertions(+), 56 deletions(-) + +commit f1a86e1e6f3906f33fc89de694a4bbbc3e40d2bc +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 16 18:01:32 2018 +0200 + + Remove unused try + + src/hb-null.hh | 13 ------------- + 1 file changed, 13 deletions(-) + +commit ebd50b3c83a22a0fdba53271275b8619a23739aa +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Sep 16 17:57:12 2018 +0200 + + Fix static_assert + + src/hb-open-type.hh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 10642b3fbfbc1776e784b190c43a9e0693dd423a +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sat Sep 15 19:43:33 2018 +0200 + + Disallow null-enabled offsets to unsized structures... + + ...like UnsizedArrayOf<>. + + This fixes a class of crasher bugs, mostly with color and AAT tables. + We + cannot use nullable offsets to varsized data that does not declare + min_size, + because it's nost safe to use our fixed-size null pool for types + that have + their size external. So, use non_null'able offsets for these. + + A further enhancement would be to make use of min_size in Null<> + itself. + Will try that after. + + src/hb-aat-layout-common.hh | 8 ++++---- + src/hb-aat-layout-feat-table.hh | 2 +- + src/hb-aat-layout-morx-table.hh | 10 +++++----- + src/hb-aat-layout-trak-table.hh | 4 ++-- + src/hb-aat-ltag-table.hh | 2 +- + src/hb-open-type.hh | 5 +++++ + src/hb-ot-color-cbdt-table.hh | 4 +--- + src/hb-ot-color-colr-table.hh | 4 ++-- + src/hb-ot-color-cpal-table.hh | 8 ++++---- + src/hb-ot-color-svg-table.hh | 2 +- + src/hb-ot-layout-common.hh | 18 ++++++++++-------- + src/hb-ot-layout-jstf-table.hh | 4 ++-- + 12 files changed, 38 insertions(+), 33 deletions(-) + +commit 9ff76c6025b55d184c96b193f23aa935ab32f1fc +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sat Sep 15 18:31:14 2018 +0200 + + [morx] Respect default feature settings + + Does NOT apply user-selected features. But at least now enables + correct subtables. + + src/hb-aat-layout-morx-table.hh | 34 +++++++++++++++++++++++----------- + 1 file changed, 23 insertions(+), 11 deletions(-) + +commit 2f97da6e2d6629e112789d399765d90f96952c0a +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sat Sep 15 14:51:50 2018 +0200 + + [aat] Change version field + + src/hb-aat-layout-morx-table.hh | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +commit 29c2bd1795b933a611512af50a14f25e25d43159 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sat Sep 15 14:47:18 2018 +0200 + + [morx] Add stub for InsertionChain + + src/hb-aat-layout-morx-table.hh | 209 + ++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 200 insertions(+), 9 deletions(-) + +commit f8ccb545c47abe8f0f4ed318ff7b5bf176913893 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Sep 14 18:59:53 2018 +0200 + + [dfont] Disable null-processsing for offsets + + An offset to unsized arrayis not safe to be redirected to our + fixed-sized + null pool. Plus, we want to reject, not repair, bad-looking dfonts. + + src/hb-open-file.hh | 8 ++++---- + src/hb-open-type.hh | 2 +- + 2 files changed, 5 insertions(+), 5 deletions(-) + +commit 01b9148d9ae7d18228538774243e49840cfd2499 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Sep 14 14:23:09 2018 +0200 + + [unicode] Move Fitzpatrick hack from ot-layout into unicode.hh + + src/hb-ot-layout.hh | 12 +----------- + src/hb-unicode.hh | 36 +++++++++++++++++++++++++++--------- + 2 files changed, 28 insertions(+), 20 deletions(-) + +commit 6ebbf514ac90712fe089b2b64f68d1cf681edd5d +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Sep 14 12:15:53 2018 +0200 + + Minor + + src/hb-ot-layout.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 957dbed388fc3214248f6aca65902ad277d070fb +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Sep 14 12:14:42 2018 +0200 + + Fix builds + + src/hb-aat-layout-common.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 4653e6cf3c1ef5005886d901df30e952d57eed6c +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Sep 14 11:31:33 2018 +0200 + + [aat] Add enums for pre-defined state and classes + + Not sure how I didn't add before... + + src/hb-aat-layout-common.hh | 19 ++++++++++++++++--- + 1 file changed, 16 insertions(+), 3 deletions(-) + +commit 67449c39331babb88f7d29d737895d786cd5da33 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Sep 14 10:58:00 2018 +0200 + + Don't dereference offset before check_struct() + + src/hb-open-file.hh | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +commit ca746f261e1e54cec2f9c8bc7a6f930491e19418 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Sep 13 20:35:21 2018 +0200 + + [dfont] Also check dataLen range in sanitize + + Just to disagree with myself re being done with this code... + + src/hb-open-file.hh | 1 + + 1 file changed, 1 insertion(+) + +commit 3789c557ca06aef430726f4942cafecac6fe4eef +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Sep 13 20:30:04 2018 +0200 + + [dfont] Solve the mystery +2 offset thing! + + Previously, ResourceForkHeader was defined as 30 bytes, having the + typeCountM1 as last member. + There was a mysterious offset-by-2 in the code, derived from FontTools + and JDK code this was + ported from. + + In testing, I observed that typeListZ offset is actually 28. + Suggesting that the typeCountM1 + does NOT actually belong to ResourceForkHeader, but belongs to the + array itself. Adjusting for + that resolves the mystery +2 offset hack, so everything is clean + and good now. + + This, concludes my dfont hacking. The code looks great now, and + I'm happy to leave it. + Fuzzers might disagree though, we will see! + + src/hb-open-file.hh | 30 ++++++++++++------------------ + src/hb-open-type.hh | 44 ++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 56 insertions(+), 18 deletions(-) + +commit effc7ced72a6ce0fea328a8b68dc3d55f09774f1 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Sep 13 20:21:54 2018 +0200 + + Rename HeadlessArrayOf::len to lenP1 + + So it doesn't accidentally match our templates, etc. + + src/hb-open-type.hh | 14 +++++++------- + src/hb-ot-layout-gsub-table.hh | 10 +++++----- + src/hb-ot-layout-gsubgpos.hh | 10 +++++----- + 3 files changed, 17 insertions(+), 17 deletions(-) + +commit 180a88a96ce327e4103df3635c73559de65d1546 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Sep 13 19:19:57 2018 +0200 + + [dfont] Some more + + src/hb-open-file.hh | 21 ++++++++------------- + 1 file changed, 8 insertions(+), 13 deletions(-) + +commit 0ab0f1e5ac5ccb07c57364e9f5be0b991398eb6f +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Sep 13 19:13:01 2018 +0200 + + [dfont] Push methods further down + + src/hb-open-file.hh | 58 + ++++++++++++++++++++++++++++++----------------------- + 1 file changed, 33 insertions(+), 25 deletions(-) + +commit 8c9bdcc1feeab321a642bdaac50b716e48ce4263 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Sep 13 19:08:22 2018 +0200 + + [dfont] Minor + + src/hb-open-file.hh | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit 4479d3a2eda57d278700f5c78414ef6ef617d2a9 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Sep 13 19:05:59 2018 +0200 + + [dfon]t Sanitize OpenTypeFontFace + + src/hb-dsalgs.hh | 6 ------ + src/hb-open-file.hh | 21 +++++++++------------ + 2 files changed, 9 insertions(+), 18 deletions(-) + +commit 3fba41906fba28c5ea01cc0749654de862453bf4 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Sep 13 18:49:16 2018 +0200 + + [dfont] Minor + + src/hb-open-file.hh | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +commit bf852f0e62a8bdbb809af6a975f8ae8eed708d70 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Sep 13 18:47:53 2018 +0200 + + [dfont] Make test pass + + Offset 0 is not null in this context. + + src/hb-open-file.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 29faebe911a13916aa3d737e93d38deedc53567f +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Sep 13 18:45:35 2018 +0200 + + Allow Offset<>'s that have no 0==null + + src/hb-open-type.hh | 43 +++++++++++++++++++++---------------------- + 1 file changed, 21 insertions(+), 22 deletions(-) + +commit 82f4d776c21b7c1224dd7073ce69cdf76d85f16b +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Sep 13 18:27:20 2018 +0200 + + [dfont] Minor + + src/hb-open-file.hh | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 07e0ca930c29757217c2f9e4e0e6954657b6b82d +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Sep 13 17:39:09 2018 +0200 + + [bytes] Rename content to arrayZ + + src/hb-dsalgs.hh | 16 ++++++++-------- + src/hb-ot-post-table.hh | 2 +- + 2 files changed, 9 insertions(+), 9 deletions(-) + +commit dbb764dceb61365b7360a48d581ba5a4b3526e98 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Sep 13 16:49:26 2018 +0200 + + [dfont] Clean up sanitize() + + I don't think I broke anything. Fuzzers will let me know.. + + src/hb-dsalgs.hh | 8 ++++ + src/hb-open-file.hh | 122 + ++++++++++++++++++++++++---------------------------- + 2 files changed, 64 insertions(+), 66 deletions(-) + +commit 361fc2686152ad8c0ebaf19e0522e0fc58ba3953 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Sep 13 16:47:33 2018 +0200 + + Fix OffsetTo::sanitize() after reshuffling + + src/hb-open-type.hh | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +commit 4c6b0fb5f6668a6e562260d16f629ad3c41e8961 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Sep 13 16:39:30 2018 +0200 + + OffsetTo::sanitize() Add version with three user_data + + src/hb-open-type.hh | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +commit a73bea69c599787b4cfeac92a3afd00749e00434 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Sep 13 16:31:31 2018 +0200 + + OffsetTo::sanitize() more shuffling + + src/hb-open-type.hh | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +commit b482e5231cd5987082dd2c05fd649c3653f3c67a +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Sep 13 16:29:49 2018 +0200 + + OffsetTo::sanitize() reshuffling + + src/hb-open-type.hh | 26 +++++++++++++++++++------- + 1 file changed, 19 insertions(+), 7 deletions(-) + +commit bd75fd45cdbd0edb24568326bb7fde59d299a82c +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Sep 11 18:12:26 2018 +0200 + + [dfont] Some renaming, plus add link to reference doc + + src/hb-open-file.hh | 79 + ++++++++++++++++++++++++----------------------------- + 1 file changed, 35 insertions(+), 44 deletions(-) + +commit 4134ec1307bbaff24972e238bc5e4a403cd3f1c1 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Sep 11 17:56:03 2018 +0200 + + [dfont] Sanitize only sfnt resources as OpenTypeFontFile + + src/hb-open-file.hh | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +commit 6b5e4d07adb6b739dc294da513c4a7acd03977f7 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Sep 11 17:26:24 2018 +0200 + + [dfont] Minor + + src/hb-open-file.hh | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +commit d5c509272f2fbd1b4c56e3b530da7e42e7f03901 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Sep 11 17:18:21 2018 +0200 + + [dfont] Fix test expecatation and minor touch up + + I have no way to authoritatively know, but looks like test font only + has one + face. So, adjust test expectation instead. + + src/hb-open-file.hh | 18 + ++++++------------ + test/shaping/data/in-house/tests/collections.tests | 2 +- + 2 files changed, 7 insertions(+), 13 deletions(-) + +commit 2b2ed1e536061cfd3a0f29522118f42b451678bd +Author: Ebrahim Byagowi <ebrahim@gnu.org> +Date: Mon Jul 2 17:26:43 2018 +0430 + + [dfont] Add test + + test/shaping/data/in-house/Makefile.sources | 1 + + test/shaping/data/in-house/fonts/TestDFONT.dfont | Bin 0 -> 3505 bytes + test/shaping/data/in-house/fonts/TestTTC.ttc | Bin 0 -> 2608 bytes + test/shaping/data/in-house/tests/collections.tests | 6 ++++++ + 4 files changed, 7 insertions(+) + +commit 9479ffefbfa3ea4ee39747e34177d26ab1ebbec9 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Sep 11 16:41:26 2018 +0200 + + [dfont] Re-enable and fix offset handling + + Fixes https://github.com/harfbuzz/harfbuzz/pull/1085 + + src/hb-face.cc | 5 +++-- + src/hb-open-file.hh | 19 +++++++++++++------ + 2 files changed, 16 insertions(+), 8 deletions(-) + +commit a1814e2bec3a43b9eeb4d50a67daae3fc52fd0a5 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Sep 11 14:45:23 2018 +0200 + + Whitespace + + src/hb-open-file.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 383060cc3354e12611dec3082a6fe08fdb25f652 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Sep 11 14:41:19 2018 +0200 + + [ft] Invalidate advance cache if font size changed + + src/hb-ft.cc | 9 +++++++++ + 1 file changed, 9 insertions(+) + +commit 54998befc43ef38e47b74b3153380adbcf6279d4 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Sep 11 14:35:26 2018 +0200 + + [ft] Cache advances + + I decided to always use the cache, instead of my previous sketch + direction + that was to only allocate and use cache if fast advances are not + available. + The cache is a mere 1kb, so just use it... + + TODO: Invalidate cache on font size change. + + Fixes https://github.com/harfbuzz/harfbuzz/issues/651 + Fixes https://github.com/harfbuzz/harfbuzz/pull/1082 + + src/hb-cache.hh | 2 +- + src/hb-ft.cc | 37 +++++++++++++++++-------------------- + 2 files changed, 18 insertions(+), 21 deletions(-) + +commit f90bab8560816b60b4b3f2379b36c08756b21e6c +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Sep 11 14:21:15 2018 +0200 + + [util] Add --ft-load-flags + + Useful for performance testing. + + Not hooked to cairo yet. Just changes shaping, not rasterization. + + util/helper-cairo.cc | 2 +- + util/options.cc | 4 ++++ + util/options.hh | 2 ++ + 3 files changed, 7 insertions(+), 1 deletion(-) + +commit 93f7596254808d567b9e1e01fb4855efcd34677c +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Sep 11 14:11:10 2018 +0200 + + [util] Add -n shorthand for --num-iterations + + Meh. + + util/options.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 047a84c5dd76cdfc072de25c572e30866f87a1f7 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Sep 11 14:05:16 2018 +0200 + + [ft] Towards caching slow get_h_advance results + + Related to https://github.com/harfbuzz/harfbuzz/pull/1082 + + src/hb-ft.cc | 24 ++++++++++++++++++++---- + 1 file changed, 20 insertions(+), 4 deletions(-) + +commit 237f21537842e6b471cdd6c86b98edfc0da0756c +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Sep 11 13:05:47 2018 +0200 + + [ft] Add advances() callback + + src/hb-ft.cc | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +commit cbea7d49ab8d4765a2d72dcbf608d326bdf9af3d +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Sep 11 12:56:17 2018 +0200 + + [ot-font] Rename + + src/hb-ot-font.cc | 74 + +++++++++++++++++++++++++++---------------------------- + 1 file changed, 37 insertions(+), 37 deletions(-) + +commit d8a67dac2a673138bb4d41cd7eab97c9ee987958 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Sep 11 12:55:54 2018 +0200 + + [ot-font] Add advances() callbacks + + src/hb-ot-font.cc | 43 ++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 42 insertions(+), 1 deletion(-) + +commit 0ea42e117ba2c76e118974fe114ae5d9ceef5743 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Sep 11 12:22:42 2018 +0200 + + [cache] Minor + + src/hb-cache.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 0f520adaacca3c7b6d8e84a7722343184105f612 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Sep 11 12:02:34 2018 +0200 + + Revert "Remove unused hb_cache_t" + + This reverts commit 473b17af4d421f4ce7ac18c769731bb2aa4088f8. + + Updates to recent changes. + + src/Makefile.sources | 1 + + src/hb-cache.hh | 75 + ++++++++++++++++++++++++++++++++++++++++++++++++++++ + src/hb-ft.cc | 1 + + 3 files changed, 77 insertions(+) + +commit cfdea884754ed40ffa5cc00cb1ecaa86cb46a394 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Sep 11 10:57:48 2018 +0200 + + [random] Switch to 32bit RNG + + src/hb-ot-layout-gsubgpos.hh | 7 ++++--- + test/shaping/data/in-house/tests/rand.tests | 4 ++-- + 2 files changed, 6 insertions(+), 5 deletions(-) + +commit 08260c708ae6adc4efa9bde5e9ede01b7e4d42cc +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Sep 11 10:51:19 2018 +0200 + + [random] Shuffle + + src/hb-ot-layout-gsub-table.hh | 5 +---- + src/hb-ot-layout-gsubgpos.hh | 6 ++++++ + 2 files changed, 7 insertions(+), 4 deletions(-) + +commit 71c9f84e7c0afe41a8987b8a4ebc2b45a22fac56 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 10 22:37:19 2018 +0200 + + Make --features rand=1 available to the user + + Use rand=255 to mean "randomize". + + Part of https://github.com/harfbuzz/harfbuzz/pull/803 + + src/hb-ot-layout-gsub-table.hh | 11 ++++------- + src/hb-ot-layout-gsubgpos.hh | 1 + + src/hb-ot-map.cc | 4 ++-- + src/hb-ot-map.hh | 3 +++ + src/hb-ot-shape.cc | 2 +- + 5 files changed, 11 insertions(+), 10 deletions(-) + +commit cc1c4fdf88f6953dcd07fb42ee963404657cdef4 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 10 16:36:05 2018 +0200 + + Respect user's wish if they set rand feature manually + + Except if the set it to 1, which would mean "randomize"... Ugly. + + src/hb-ot-layout-gsub-table.hh | 30 ++++++++++++++++-------------- + 1 file changed, 16 insertions(+), 14 deletions(-) + +commit 80de4bcd2677bfb0907ea7059524f918b109ac37 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 10 16:24:52 2018 +0200 + + Minor clean up of 'rand' patchset + + src/hb-ot-layout-gsub-table.hh | 7 +++++-- + src/hb-ot-layout-gsubgpos.hh | 7 ++++--- + src/hb-ot-shape.cc | 13 ++++++------- + test/shaping/data/in-house/tests/rand.tests | 2 +- + 4 files changed, 16 insertions(+), 13 deletions(-) + +commit b545e27d8891f1e7f1fd034dd84abe44c839c380 +Author: David Corbett <corbett.dav@husky.neu.edu> +Date: Fri Feb 23 12:22:32 2018 -0500 + + Don't seed the RNG from the contents of the buffer + + src/hb-ot-layout-gsubgpos.hh | 7 ++----- + src/hb-ot-layout.cc | 5 +---- + test/shaping/data/in-house/tests/rand.tests | 2 +- + 3 files changed, 4 insertions(+), 10 deletions(-) + +commit 2de96e846844d21888af6893378b21a33fc19232 +Author: David Corbett <corbett.dav@husky.neu.edu> +Date: Sat Jan 27 19:48:38 2018 -0500 + + Test 'rand' + + test/shaping/data/in-house/Makefile.sources | 1 + + .../fonts/5bb74492f5e0ffa1fbb72e4c881be035120b6513.ttf | Bin 0 -> + 1352 bytes + test/shaping/data/in-house/tests/rand.tests | 3 +++ + 3 files changed, 4 insertions(+) + +commit f05df643b44d9bbfd742e93f02c235fc821190d0 +Author: David Corbett <corbett.dav@husky.neu.edu> +Date: Fri Jan 26 21:36:15 2018 -0500 + + Allow requesting a specific glyph for 'rand' + + Randomization only happens by default. If the user specifies a + value for + 'rand', that value is respected. + + src/hb-ot-map.cc | 3 ++- + src/hb-ot-map.hh | 4 +++- + src/hb-ot-shape.cc | 7 ++++++- + 3 files changed, 11 insertions(+), 3 deletions(-) + +commit c2a75e07e54314f6c611dda0f050ed5f09909e43 +Author: David Corbett <corbett.dav@husky.neu.edu> +Date: Thu Jan 25 14:22:03 2018 -0500 + + Implement 'rand' + + src/hb-ot-layout-gsub-table.hh | 19 ++++++++++++------- + src/hb-ot-layout-gsubgpos.hh | 8 ++++++++ + src/hb-ot-layout.cc | 8 ++++++++ + src/hb-ot-map.cc | 7 +++++-- + src/hb-ot-map.hh | 4 +++- + src/hb-ot-shape.cc | 1 + + 6 files changed, 37 insertions(+), 10 deletions(-) + +commit 96471fe8593575deceb44d3757c227f65f10a25e +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Sep 11 01:39:23 2018 +0200 + + [uniscribe] Fix build + + src/hb-uniscribe.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit becd84aa2f2902ea9d2d1677b28945e103a68816 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Sep 11 01:26:18 2018 +0200 + + Add HB_FEATURE_GLOBAL_START/END + + Fixes https://github.com/harfbuzz/harfbuzz/issues/1141 + + New API: + HB_FEATURE_GLOBAL_START + HB_FEATURE_GLOBAL_END + + docs/harfbuzz-sections.txt | 2 ++ + src/hb-common.cc | 4 ++-- + src/hb-common.h | 13 +++++++++++++ + 3 files changed, 17 insertions(+), 2 deletions(-) + +commit 13a8786c7c580651d8a6db9345b9aa85ca8ed956 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Sep 11 01:07:06 2018 +0200 + + Add (unused) hb_array_t<> + + src/hb-dsalgs.hh | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +commit bccf3e1827eec07433340eea705597201b6d0a32 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Sep 11 01:04:50 2018 +0200 + + Minor + + src/hb-open-type.hh | 1 - + 1 file changed, 1 deletion(-) + +commit dff2c45f1e2a30767f6813d3cb6a70978d98d424 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 10 23:29:26 2018 +0200 + + Port rest from VAR to UnsizedArrayOf<> + + src/hb-aat-layout-common.hh | 14 +++++++------- + src/hb-aat-layout-morx-table.hh | 16 ++++++++-------- + src/hb-open-type.hh | 10 +++++----- + src/hb-ot-cmap-table.hh | 8 +++++--- + src/hb-ot-color-cbdt-table.hh | 16 ++++++++-------- + src/hb-ot-glyf-table.hh | 10 +++++----- + src/hb-ot-hdmx-table.hh | 30 +++++++++++++----------------- + src/hb-ot-hmtx-table.hh | 8 ++++---- + src/hb-ot-kern-table.hh | 20 ++++++++++---------- + src/hb-ot-layout-common.hh | 9 +++++---- + src/hb-ot-layout-gpos-table.hh | 26 +++++++++++++------------- + src/hb-ot-math-table.hh | 36 +++++++++++++++++++----------------- + src/hb-ot-maxp-table.hh | 2 +- + src/hb-ot-name-table.hh | 13 +++++++------ + src/hb-ot-post-table.hh | 5 +++-- + 15 files changed, 113 insertions(+), 110 deletions(-) + +commit 9507b05a7a65962d5d02eb424e4f5d8570976f4e +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 10 23:18:07 2018 +0200 + + Simplify sanitize->check_array() + + Fix a bug in CBDT sanitize, and redundant check in avar. + + src/hb-aat-layout-common.hh | 10 ++++------ + src/hb-aat-layout-morx-table.hh | 2 +- + src/hb-machinery.hh | 3 ++- + src/hb-open-type.hh | 6 +++--- + src/hb-ot-color-cbdt-table.hh | 4 ++-- + src/hb-ot-kern-table.hh | 2 +- + src/hb-ot-layout-common.hh | 2 +- + src/hb-ot-layout-gpos-table.hh | 8 ++++---- + src/hb-ot-layout-gsubgpos.hh | 4 ++-- + src/hb-ot-math-table.hh | 8 ++------ + src/hb-ot-name-table.hh | 2 +- + src/hb-ot-var-avar-table.hh | 4 ++-- + src/hb-ot-var-fvar-table.hh | 2 +- + src/hb-ot-var-hvar-table.hh | 2 +- + src/hb-ot-var-mvar-table.hh | 2 +- + 15 files changed, 28 insertions(+), 33 deletions(-) + +commit bc485a98122131efc4768fef9147823f2bce146b +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 10 23:02:24 2018 +0200 + + Port some VAR arrays to UnsizedArrayOf<> + + Fix avar sanitize(). + + src/hb-ot-layout-gsubgpos.hh | 59 + +++++++++++++++++++++++--------------------- + src/hb-ot-var-avar-table.hh | 10 +++++--- + src/hb-ot-var-fvar-table.hh | 7 +++--- + src/hb-ot-var-hvar-table.hh | 9 ++++--- + src/hb-ot-var-mvar-table.hh | 9 ++++--- + 5 files changed, 51 insertions(+), 43 deletions(-) + +commit 1bc7a8d6c4deb9fa6e010d7be08b68cad88579ae +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 10 22:51:26 2018 +0200 + + [indic] Cache hb_options().uniscribe_bug_compatible on indic_plan + + src/hb-ot-shape-complex-indic.cc | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +commit 24f1d9622489a016904314a5d4e3c637da2e1c77 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 10 18:19:37 2018 +0200 + + Unbreak HB_OPTIONS + + Fixes https://github.com/harfbuzz/harfbuzz/issues/1154 + + src/hb-debug.hh | 3 +++ + 1 file changed, 3 insertions(+) + +commit e46c51f1e985ac9c0ffa90fda4ea436d54b4009c +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 10 17:38:19 2018 +0200 + + [indic] Do NOT allow matra after Halant,ZWJ + + Fixes https://github.com/harfbuzz/harfbuzz/issues/556 + + Devanagari regresses 12 tests, and Gujarati 2. See: + + https://github.com/harfbuzz/harfbuzz/issues/556#issuecomment-419957472 + + New numbers: + + BENGALI: 353725 out of 354188 tests passed. 463 failed (0.130722%) + DEVANAGARI: 707299 out of 707394 tests passed. 95 failed (0.0134296%) + GUJARATI: 366353 out of 366457 tests passed. 104 failed (0.0283799%) + GURMUKHI: 60729 out of 60747 tests passed. 18 failed (0.0296311%) + KANNADA: 951300 out of 951913 tests passed. 613 failed (0.0643966%) + MALAYALAM: 1048136 out of 1048334 tests passed. 198 failed + (0.0188871%) + ORIYA: 42327 out of 42329 tests passed. 2 failed (0.00472489%) + SINHALA: 271596 out of 271847 tests passed. 251 failed (0.0923313%) + TAMIL: 1091754 out of 1091754 tests passed. 0 failed (0%) + TELUGU: 970555 out of 970573 tests passed. 18 failed (0.00185457%) + + src/hb-ot-shape-complex-indic-machine.hh | 1688 + ++++++++++++++---------------- + src/hb-ot-shape-complex-indic-machine.rl | 2 +- + 2 files changed, 784 insertions(+), 906 deletions(-) + +commit 5dfd6e07626a9022a995eb7fa16767eff66c6047 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 10 15:45:32 2018 +0200 + + Fix sanitize or Context Rule + + Fixes https://github.com/harfbuzz/harfbuzz/issues/1110 + + src/hb-ot-layout-gsubgpos.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 20a11a824d2a07a8544649477ad03e809bdd8e19 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 10 13:56:28 2018 +0200 + + Revert "[subset] Disable GSUB/GPOS subsetting for now" + + This reverts commit 616fd34a69bb69bc35c7e4ea939e71c3ea2e92cb. + + src/hb-subset.cc | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 54d332dd9b0263821376161cdffb60ffb3c7847f +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Sep 10 11:37:24 2018 +0200 + + 1.9.0 + + NEWS | 19 +++++++++++++++++++ + configure.ac | 2 +- + src/hb-face.cc | 10 +++++----- + src/hb-unicode.h | 5 +++++ + src/hb-version.h | 6 +++--- + 5 files changed, 33 insertions(+), 9 deletions(-) + commit 616fd34a69bb69bc35c7e4ea939e71c3ea2e92cb Author: Behdad Esfahbod <behdad@behdad.org> Date: Mon Sep 10 11:19:49 2018 +0200 diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/NEWS b/Build/source/libs/harfbuzz/harfbuzz-src/NEWS index c9af0f36853..58e21a592fc 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/NEWS +++ b/Build/source/libs/harfbuzz/harfbuzz-src/NEWS @@ -1,3 +1,71 @@ +Overview of changes leading to 2.0.0 +Wednesday, October 17, 2018 +==================================== +- Added AAT shaping support (morx/kerx/trak). + Automatically used if GSUB/GPOS are not available respectively. + Set HB_OPTIONS=aat env var to have morx/kerx preferred over + GSUB/GPOS. +- Apply TrueType kern table internally, instead of relying on + hb_font_t callbacks. +- Khmer shaper significantly rewritten to better match Uniscribe. +- Indic3 tags ('dev3', etc) are passed to USE shaper. +- .dfont Mac font containers implemented. +- Script- and language-mapping revamped to better use BCP 47. +- Misc USE and Indic fixes. +- Misc everything fixes. +- Too many things to list. Biggest release since 0.9.1, with + over 500 commits in just over 5 weeks! Didn't intend it to + be a big release. Just happened to become. +- hb-ft now locks underlying FT_Face during use. + +API changes: + +- Newly-created hb_font_t's now have our internal "hb-ot-font" + callbacks set on them, so they should work out of the box + without any callbacks set. If callbacks are set, everything + is back to what it was before, the fallback callbacks are + null. If you to get the internal implementation modified, + sub_font it. + +- New hb_font_funcs_set_nominal_glyphs_func() allows speeding + up character to glyph mapping. + +New API: ++HB_FEATURE_GLOBAL_START ++HB_FEATURE_GLOBAL_END ++hb_buffer_set_invisible_glyph() ++hb_buffer_get_invisible_glyph() ++hb_font_funcs_set_nominal_glyphs_func() ++hb_ot_layout_table_select_script() ++hb_ot_layout_script_select_language() ++hb_ot_layout_feature_get_name_ids() ++hb_ot_layout_feature_get_characters() ++hb_name_id_t ++HB_NAME_ID_INVALID ++HB_OT_MAX_TAGS_PER_SCRIPT ++hb_ot_tags_from_script_and_language() ++hb_ot_tags_to_script_and_language() + +Deprecated API: +-hb_font_funcs_set_glyph_func() +-hb_unicode_eastasian_width_func_t +-hb_unicode_funcs_set_eastasian_width_func() +-hb_unicode_eastasian_width() +-hb_unicode_decompose_compatibility_func_t +-HB_UNICODE_MAX_DECOMPOSITION_LEN +-hb_unicode_funcs_set_decompose_compatibility_func() +-hb_unicode_decompose_compatibility() +-hb_font_funcs_set_glyph_h_kerning_func() +-hb_font_funcs_set_glyph_v_kerning_func() +-hb_font_get_glyph_h_kerning() +-hb_font_get_glyph_v_kerning() +-hb_font_get_glyph_kerning_for_direction() +-hb_ot_layout_table_choose_script() +-hb_ot_layout_script_find_language() +-hb_ot_tags_from_script() +-hb_ot_tag_from_language() + + Overview of changes leading to 1.9.0 Monday, September 10, 2018 ==================================== diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/TODO b/Build/source/libs/harfbuzz/harfbuzz-src/TODO index 6dac0be5298..d2c5812a007 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/TODO +++ b/Build/source/libs/harfbuzz/harfbuzz-src/TODO @@ -1,9 +1,3 @@ -General fixes: -============= - -- Implement 'rand' feature. - - API issues: =========== @@ -19,12 +13,10 @@ API additions - Add hb-cairo glue -- Add sanitize API (and a cached version, that saves result on blob user-data) +- Add sanitize API. - BCP 47 language handling / API (language_matches?) -- Add hb_font_create_unscaled()? - - Add query / enumeration API for aalt-like features? - Add segmentation API diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/config.h.in b/Build/source/libs/harfbuzz/harfbuzz-src/config.h.in index c2d5c3ad4aa..029518d7c83 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/config.h.in +++ b/Build/source/libs/harfbuzz/harfbuzz-src/config.h.in @@ -85,9 +85,6 @@ /* Define to 1 if you have the `newlocale' function. */ #undef HAVE_NEWLOCALE -/* Have native OpenType Layout backend */ -#undef HAVE_OT - /* Define to 1 if you have the `posix_memalign' function. */ #undef HAVE_POSIX_MEMALIGN diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac b/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac index 1c698087132..a3ce8c1e8fb 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac +++ b/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ([2.64]) AC_INIT([HarfBuzz], - [1.9.0], + [2.0.0], [https://github.com/harfbuzz/harfbuzz/issues/new], [harfbuzz], [http://harfbuzz.org/]) @@ -12,6 +12,7 @@ AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE([1.13.0 gnits tar-ustar dist-bzip2 no-dist-gzip -Wall no-define color-tests -Wno-portability]) AM_SILENT_RULES([yes]) AX_CODE_COVERAGE +AC_USE_SYSTEM_EXTENSIONS # Initialize libtool m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) @@ -19,7 +20,6 @@ LT_PREREQ([2.2]) LT_INIT([disable-static]) # Check for programs -AC_USE_SYSTEM_EXTENSIONS AC_PROG_CC AC_PROG_CC_C99 AM_PROG_CC_C_O @@ -148,12 +148,6 @@ AM_CONDITIONAL(HAVE_PTHREAD, $have_pthread) dnl ========================================================================== -have_ot=true -if $have_ot; then - AC_DEFINE(HAVE_OT, 1, [Have native OpenType Layout backend]) -fi -AM_CONDITIONAL(HAVE_OT, $have_ot) - have_fallback=true if $have_fallback; then AC_DEFINE(HAVE_FALLBACK, 1, [Have simple TrueType Layout backend]) @@ -330,7 +324,7 @@ AC_ARG_WITH(graphite2, [Use the graphite2 library @<:@default=no@:>@])],, [with_graphite2=no]) have_graphite2=false -GRAPHITE2_DEPS="graphite2" +GRAPHITE2_DEPS="graphite2 >= 1.2.0" AC_SUBST(GRAPHITE2_DEPS) if test "x$with_graphite2" = "xyes" -o "x$with_graphite2" = "xauto"; then PKG_CHECK_MODULES(GRAPHITE2, $GRAPHITE2_DEPS, have_graphite2=true, :) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am index 9e7fd2995c3..c74bab5d9e7 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am @@ -13,7 +13,7 @@ TESTS = check_PROGRAMS = # Convenience targets: -lib: $(BUILT_SOURCES) libharfbuzz.la libharfbuzz-subset.la +lib: $(BUILT_SOURCES) libharfbuzz.la libs: $(BUILT_SOURCES) $(lib_LTLIBRARIES) fuzzing: $(BUILT_SOURCES) libharfbuzz-fuzzing.la libharfbuzz-subset-fuzzing.la @@ -29,11 +29,9 @@ HBSOURCES = $(HB_BASE_sources) HBSOURCES += $(HB_BASE_RAGEL_GENERATED_sources) HBHEADERS = $(HB_BASE_headers) -if HAVE_OT HBSOURCES += $(HB_OT_sources) HBSOURCES += $(HB_OT_RAGEL_GENERATED_sources) HBHEADERS += $(HB_OT_headers) -endif if HAVE_FALLBACK HBSOURCES += $(HB_FALLBACK_sources) @@ -289,13 +287,16 @@ harfbuzz-gobject.def: $(HB_GOBJECT_headers) GENERATORS = \ gen-arabic-table.py \ + gen-def.py \ + gen-emoji-table.py \ gen-indic-table.py \ + gen-os2-unicode-ranges.py \ + gen-tag-table.py \ gen-use-table.py \ - gen-def.py \ $(NULL) EXTRA_DIST += $(GENERATORS) -unicode-tables: arabic-table indic-table use-table +unicode-tables: arabic-table indic-table tag-table use-table emoji-table arabic-table: gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-arabic-table.hh \ @@ -305,13 +306,21 @@ indic-table: gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategor $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-indic-table.cc \ || ($(RM) $(srcdir)/hb-ot-shape-complex-indic-table.cc; false) +tag-table: gen-tag-table.py languagetags language-subtag-registry + $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-tag-table.hh \ + || ($(RM) $(srcdir)/hb-ot-tag-table.hh; false) + use-table: gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-use-table.cc \ || ($(RM) $(srcdir)/hb-ot-shape-complex-use-table.cc; false) +emoji-table: gen-emoji-table.py emoji-data.txt + $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-unicode-emoji-table.hh \ + || ($(RM) $(srcdir)/hb-unicode-emoji-table.hh; false) + built-sources: $(BUILT_SOURCES) -.PHONY: unicode-tables arabic-table indic-table use-table built-sources +.PHONY: unicode-tables arabic-table indic-table tag-table use-table emoji-table built-sources RAGEL_GENERATED = \ $(patsubst %,$(srcdir)/%,$(HB_BASE_RAGEL_GENERATED_sources)) \ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources index 654255e20c7..59cde6bd1d5 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources @@ -7,6 +7,7 @@ HB_BASE_sources = \ hb-buffer.hh \ hb-buffer-serialize.cc \ hb-buffer.cc \ + hb-cache.hh \ hb-common.cc \ hb-debug.hh \ hb-dsalgs.hh \ @@ -37,6 +38,7 @@ HB_BASE_sources = \ hb-ot-os2-unicode-ranges.hh \ hb-ot-post-macroman.hh \ hb-ot-post-table.hh \ + hb-ot-tag-table.hh \ hb-ot-tag.cc \ hb.hh \ hb-set-digest.hh \ @@ -52,6 +54,7 @@ HB_BASE_sources = \ hb-static.cc \ hb-string-array.hh \ hb-unicode.hh \ + hb-unicode-emoji-table.hh \ hb-unicode.cc \ hb-vector.hh \ hb-utf.hh \ @@ -136,7 +139,6 @@ HB_OT_sources = \ hb-ot-shape-complex-myanmar.hh \ hb-ot-shape-complex-myanmar.cc \ hb-ot-shape-complex-thai.cc \ - hb-ot-shape-complex-tibetan.cc \ hb-ot-shape-complex-use.cc \ hb-ot-shape-complex-use.hh \ hb-ot-shape-complex-use-table.cc \ @@ -171,6 +173,7 @@ HB_OT_headers = \ hb-ot-font.h \ hb-ot-layout.h \ hb-ot-math.h \ + hb-ot-name.h \ hb-ot-shape.h \ hb-ot-tag.h \ hb-ot-var.h \ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/check-static-inits.sh b/Build/source/libs/harfbuzz/harfbuzz-src/src/check-static-inits.sh index 71551cbd4c8..def25c70143 100755 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/check-static-inits.sh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/check-static-inits.sh @@ -7,7 +7,6 @@ test -z "$srcdir" && srcdir=. test -z "$libs" && libs=.libs stat=0 - if which objdump 2>/dev/null >/dev/null; then : else @@ -31,7 +30,8 @@ done echo "Checking that no object file has lazy static C++ constructors/destructors or other such stuff" for obj in $OBJS; do - if objdump -t "$obj" | grep '__cxa_'; then + if objdump -t "$obj" | grep -q '__cxa_' && ! objdump -t "$obj" | grep -q __ubsan_handle; then + objdump -t "$obj" | grep '__cxa_' echo "Ouch, $obj has lazy static C++ constructors/destructors or other such stuff" stat=1 fi diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.sh b/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.sh index d4eca5079cb..cea8684889a 100755 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.sh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.sh @@ -26,7 +26,7 @@ for soname in harfbuzz harfbuzz-subset harfbuzz-icu harfbuzz-gobject; do symprefix= if test $suffix = dylib; then symprefix=_; fi - EXPORTED_SYMBOLS="`nm "$so" | grep ' [BCDGINRSTVW] .' | grep -v " $symprefix\\($IGNORED_SYMBOLS\\>\\)" | cut -d' ' -f3 | c++filt`" + EXPORTED_SYMBOLS="`nm "$so" | grep ' [BCDGINRST] .' | grep -v " $symprefix\\($IGNORED_SYMBOLS\\>\\)" | cut -d' ' -f3 | c++filt`" prefix=$symprefix`basename "$so" | sed 's/libharfbuzz/hb/; s/-/_/g; s/[.].*//'` diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-emoji.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-emoji.cc index 65214692ff5..f45bc3106dd 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-emoji.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-emoji.cc @@ -45,8 +45,8 @@ #include <stdlib.h> #include <stdio.h> -void cbdt_callback (const uint8_t* data, unsigned int length, - unsigned int group, unsigned int gid) +static void cbdt_callback (const uint8_t* data, unsigned int length, + unsigned int group, unsigned int gid) { char output_path[255]; sprintf (output_path, "out/cbdt-%d-%d.png", group, gid); @@ -55,8 +55,8 @@ void cbdt_callback (const uint8_t* data, unsigned int length, fclose (f); } -void sbix_callback (const uint8_t* data, unsigned int length, - unsigned int group, unsigned int gid) +static 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); @@ -65,8 +65,8 @@ void sbix_callback (const uint8_t* data, unsigned int length, fclose (f); } -void svg_callback (const uint8_t* data, unsigned int length, - unsigned int start_glyph, unsigned int end_glyph) +static 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) @@ -83,8 +83,8 @@ void svg_callback (const uint8_t* data, unsigned int length, 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) +static 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) { @@ -146,7 +146,7 @@ void colr_cpal_rendering (cairo_font_face_t *cairo_face, unsigned int upem, unsi 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_set_source_rgba (cr, r / 255., g / 255., b / 255., alpha); cairo_glyph_t glyph; glyph.index = glyph_id; @@ -162,7 +162,8 @@ void colr_cpal_rendering (cairo_font_face_t *cairo_face, unsigned int upem, unsi } } -void dump_glyphs (cairo_font_face_t *cairo_face, unsigned int upem, unsigned int num_glyphs) +static void dump_glyphs (cairo_font_face_t *cairo_face, unsigned int upem, + unsigned int num_glyphs) { // Dump every glyph available on the font return; // disabled for now @@ -210,10 +211,29 @@ void dump_glyphs (cairo_font_face_t *cairo_face, unsigned int upem, unsigned int int main (int argc, char **argv) { if (argc != 2) { - fprintf (stderr, "usage: %s font-file.ttf\n", argv[0]); + fprintf (stderr, "usage: %s font-file.ttf\n" + "run it like `rm -rf out && mkdir out && %s font-file.ttf`\n", + argv[0], argv[0]); exit (1); } + + FILE *font_name_file = fopen ("out/_font_name_file.txt", "r"); + if (font_name_file != nullptr) + { + fprintf (stderr, "Purge or move ./out folder in order to run a new dump\n"); + exit (1); + } + + font_name_file = fopen ("out/_font_name_file.txt", "w"); + if (font_name_file == nullptr) + { + fprintf (stderr, "./out is not accessible, create it please\n"); + exit (1); + } + fwrite (argv[1], 1, strlen (argv[1]), font_name_file); + fclose (font_name_file); + hb_blob_t *blob = hb_blob_create_from_file (argv[1]); hb_face_t *face = hb_face_create (blob, 0); hb_font_t *font = hb_font_create (face); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-khmer-data.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-khmer-data.cc index 12871fa850f..1e79a976732 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-khmer-data.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-khmer-data.cc @@ -34,10 +34,8 @@ main (void) hb_glyph_info_t info; info.codepoint = u; set_khmer_properties (info); - if (info.khmer_category() != INDIC_SYLLABIC_CATEGORY_OTHER || - info.khmer_position() != INDIC_MATRA_CATEGORY_NOT_APPLICABLE) - printf("U+%04X %u %u\n", u, - info.khmer_category(), - info.khmer_position()); + if (info.khmer_category() != INDIC_SYLLABIC_CATEGORY_OTHER) + printf("U+%04X %u\n", u, + info.khmer_category()); } } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-emoji-table.py b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-emoji-table.py new file mode 100644 index 00000000000..278e0b2d4a7 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-emoji-table.py @@ -0,0 +1,64 @@ +#!/usr/bin/python + +from __future__ import print_function, division, absolute_import +import sys +import os.path +from collections import OrderedDict + +if len (sys.argv) != 2: + print("usage: ./gen-emoji-table.py emoji-data.txt", file=sys.stderr) + sys.exit (1) + +f = open(sys.argv[1]) +header = [f.readline () for _ in range(10)] + +sets = OrderedDict() +for line in f.readlines(): + line = line.strip() + if not line or line[0] == '#': + continue + rang, typ = [s.strip() for s in line.split('#')[0].split(';')[:2]] + + rang = [int(s, 16) for s in rang.split('..')] + if len(rang) > 1: + start, end = rang + else: + start = end = rang[0] + + if typ not in sets: + sets[typ] = set() + sets[typ].add((start, end)) + + + +print ("/* == Start of generated table == */") +print ("/*") +print (" * The following tables are generated by running:") +print (" *") +print (" * ./gen-emoji-table.py emoji-data.txt") +print (" *") +print (" * on file with this header:") +print (" *") +for l in header: + print (" * %s" % (l.strip())) +print (" */") +print () +print ("#ifndef HB_UNICODE_EMOJI_TABLE_HH") +print ("#define HB_UNICODE_EMOJI_TABLE_HH") +print () +print ('#include "hb-unicode.hh"') +print () + +for typ,s in sets.items(): + if typ != "Extended_Pictographic": continue + print() + print("static const struct hb_unicode_range_t _hb_unicode_emoji_%s_table[] =" % typ) + print("{") + for pair in sorted(s): + print(" {0x%04X, 0x%04X}," % pair) + print("};") + +print () +print ("#endif /* HB_UNICODE_EMOJI_TABLE_HH */") +print () +print ("/* == End of generated table == */") diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-os2-unicode-ranges.py b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-os2-unicode-ranges.py new file mode 100644 index 00000000000..d768313ddde --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-os2-unicode-ranges.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- + +# Generates the code for a sorted unicode range array as used in hb-ot-os2-unicode-ranges.hh +# Input is a tab seperated list of unicode ranges from the otspec +# (https://docs.microsoft.com/en-us/typography/opentype/spec/os2#ulunicoderange1). + +from __future__ import print_function, division, absolute_import + +import io +import re +import sys + +reload(sys) +sys.setdefaultencoding('utf-8') + +print ("""static OS2Range _hb_os2_unicode_ranges[] = +{""") + +args = sys.argv[1:] +input_file = args[0] + +with io.open(input_file, mode="r", encoding="utf-8") as f: + + all_ranges = []; + current_bit = 0 + while True: + line = f.readline().strip() + if not line: + break + fields = re.split(r'\t+', line) + if len(fields) == 3: + current_bit = fields[0] + fields = fields[1:] + elif len(fields) > 3: + raise Error("bad input :(.") + + name = fields[0] + ranges = re.split("-", fields[1]) + if len(ranges) != 2: + raise Error("bad input :(.") + + v = tuple((int(ranges[0], 16), int(ranges[1], 16), int(current_bit), name)) + all_ranges.append(v) + +all_ranges = sorted(all_ranges, key=lambda t: t[0]) + +for ranges in all_ranges: + start = ("0x%X" % ranges[0]).rjust(8) + end = ("0x%X" % ranges[1]).rjust(8) + bit = ("%s" % ranges[2]).rjust(3) + + print (" {%s, %s, %s}, // %s" % (start, end, bit, ranges[3])) + +print ("""};""") diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-tag-table.py b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-tag-table.py new file mode 100644 index 00000000000..13004629d2b --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-tag-table.py @@ -0,0 +1,1126 @@ +#!/usr/bin/python + +"""Generator of the mapping from OpenType tags to BCP 47 tags and vice +versa. + +It creates a ``const LangTag[]``, matching the tags from the OpenType +languages system tag list to the language subtags of the BCP 47 language +subtag registry, with some manual adjustments. The mappings are +supplemented with macrolanguages' sublanguages and retired codes' +replacements, according to BCP 47 and some manual additions where BCP 47 +omits a retired code entirely. + +Also generated is a function, ``hb_ot_ambiguous_tag_to_language``, +intended for use by ``hb_ot_tag_to_language``. It maps OpenType tags +back to BCP 47 tags. Ambiguous OpenType tags (those that correspond to +multiple BCP 47 tags) are listed here, except when the alphabetically +first BCP 47 tag happens to be the chosen disambiguated tag. In that +case, the fallback behavior will choose the right tag anyway. +""" + +from __future__ import absolute_import, division, print_function, unicode_literals + +import collections +try: + from HTMLParser import HTMLParser + def write (s): + print (s.encode ('utf-8'), end='') +except ImportError: + from html.parser import HTMLParser + def write (s): + sys.stdout.flush () + sys.stdout.buffer.write (s.encode ('utf-8')) +import io +import itertools +import re +import sys +import unicodedata + +if len (sys.argv) != 3: + print ('usage: ./gen-tag-table.py languagetags language-subtag-registry', file=sys.stderr) + sys.exit (1) + +try: + from html import unescape + def html_unescape (parser, entity): + return unescape (entity) +except ImportError: + def html_unescape (parser, entity): + return parser.unescape (entity) + +def expect (condition, message=None): + if not condition: + if message is None: + raise AssertionError + raise AssertionError (message) + +# from http://www-01.sil.org/iso639-3/iso-639-3.tab +ISO_639_3_TO_1 = { + 'aar': 'aa', + 'abk': 'ab', + 'afr': 'af', + 'aka': 'ak', + 'amh': 'am', + 'ara': 'ar', + 'arg': 'an', + 'asm': 'as', + 'ava': 'av', + 'ave': 'ae', + 'aym': 'ay', + 'aze': 'az', + 'bak': 'ba', + 'bam': 'bm', + 'bel': 'be', + 'ben': 'bn', + 'bis': 'bi', + 'bod': 'bo', + 'bos': 'bs', + 'bre': 'br', + 'bul': 'bg', + 'cat': 'ca', + 'ces': 'cs', + 'cha': 'ch', + 'che': 'ce', + 'chu': 'cu', + 'chv': 'cv', + 'cor': 'kw', + 'cos': 'co', + 'cre': 'cr', + 'cym': 'cy', + 'dan': 'da', + 'deu': 'de', + 'div': 'dv', + 'dzo': 'dz', + 'ell': 'el', + 'eng': 'en', + 'epo': 'eo', + 'est': 'et', + 'eus': 'eu', + 'ewe': 'ee', + 'fao': 'fo', + 'fas': 'fa', + 'fij': 'fj', + 'fin': 'fi', + 'fra': 'fr', + 'fry': 'fy', + 'ful': 'ff', + 'gla': 'gd', + 'gle': 'ga', + 'glg': 'gl', + 'glv': 'gv', + 'grn': 'gn', + 'guj': 'gu', + 'hat': 'ht', + 'hau': 'ha', + 'hbs': 'sh', + 'heb': 'he', + 'her': 'hz', + 'hin': 'hi', + 'hmo': 'ho', + 'hrv': 'hr', + 'hun': 'hu', + 'hye': 'hy', + 'ibo': 'ig', + 'ido': 'io', + 'iii': 'ii', + 'iku': 'iu', + 'ile': 'ie', + 'ina': 'ia', + 'ind': 'id', + 'ipk': 'ik', + 'isl': 'is', + 'ita': 'it', + 'jav': 'jv', + 'jpn': 'ja', + 'kal': 'kl', + 'kan': 'kn', + 'kas': 'ks', + 'kat': 'ka', + 'kau': 'kr', + 'kaz': 'kk', + 'khm': 'km', + 'kik': 'ki', + 'kin': 'rw', + 'kir': 'ky', + 'kom': 'kv', + 'kon': 'kg', + 'kor': 'ko', + 'kua': 'kj', + 'kur': 'ku', + 'lao': 'lo', + 'lat': 'la', + 'lav': 'lv', + 'lim': 'li', + 'lin': 'ln', + 'lit': 'lt', + 'ltz': 'lb', + 'lub': 'lu', + 'lug': 'lg', + 'mah': 'mh', + 'mal': 'ml', + 'mar': 'mr', + 'mkd': 'mk', + 'mlg': 'mg', + 'mlt': 'mt', + 'mol': 'mo', + 'mon': 'mn', + 'mri': 'mi', + 'msa': 'ms', + 'mya': 'my', + 'nau': 'na', + 'nav': 'nv', + 'nbl': 'nr', + 'nde': 'nd', + 'ndo': 'ng', + 'nep': 'ne', + 'nld': 'nl', + 'nno': 'nn', + 'nob': 'nb', + 'nor': 'no', + 'nya': 'ny', + 'oci': 'oc', + 'oji': 'oj', + 'ori': 'or', + 'orm': 'om', + 'oss': 'os', + 'pan': 'pa', + 'pli': 'pi', + 'pol': 'pl', + 'por': 'pt', + 'pus': 'ps', + 'que': 'qu', + 'roh': 'rm', + 'ron': 'ro', + 'run': 'rn', + 'rus': 'ru', + 'sag': 'sg', + 'san': 'sa', + 'sin': 'si', + 'slk': 'sk', + 'slv': 'sl', + 'sme': 'se', + 'smo': 'sm', + 'sna': 'sn', + 'snd': 'sd', + 'som': 'so', + 'sot': 'st', + 'spa': 'es', + 'sqi': 'sq', + 'srd': 'sc', + 'srp': 'sr', + 'ssw': 'ss', + 'sun': 'su', + 'swa': 'sw', + 'swe': 'sv', + 'tah': 'ty', + 'tam': 'ta', + 'tat': 'tt', + 'tel': 'te', + 'tgk': 'tg', + 'tgl': 'tl', + 'tha': 'th', + 'tir': 'ti', + 'ton': 'to', + 'tsn': 'tn', + 'tso': 'ts', + 'tuk': 'tk', + 'tur': 'tr', + 'twi': 'tw', + 'uig': 'ug', + 'ukr': 'uk', + 'urd': 'ur', + 'uzb': 'uz', + 'ven': 've', + 'vie': 'vi', + 'vol': 'vo', + 'wln': 'wa', + 'wol': 'wo', + 'xho': 'xh', + 'yid': 'yi', + 'yor': 'yo', + 'zha': 'za', + 'zho': 'zh', + 'zul': 'zu', +} + +class LanguageTag (object): + """A BCP 47 language tag. + + Attributes: + subtags (List[str]): The list of subtags in this tag. + grandfathered (bool): Whether this tag is grandfathered. If + ``true``, the entire lowercased tag is the ``language`` + and the other subtag fields are empty. + language (str): The language subtag. + script (str): The script subtag. + region (str): The region subtag. + variant (str): The variant subtag. + + Args: + tag (str): A BCP 47 language tag. + + """ + def __init__ (self, tag): + global bcp_47 + self.subtags = tag.lower ().split ('-') + self.grandfathered = tag.lower () in bcp_47.grandfathered + if self.grandfathered: + self.language = tag.lower () + self.script = '' + self.region = '' + self.variant = '' + else: + self.language = self.subtags[0] + self.script = self._find_first (lambda s: len (s) == 4 and s[0] > '9', self.subtags) + self.region = self._find_first (lambda s: len (s) == 2 and s[0] > '9' or len (s) == 3 and s[0] <= '9', self.subtags[1:]) + self.variant = self._find_first (lambda s: len (s) > 4 or len (s) == 4 and s[0] <= '9', self.subtags) + + def __str__(self): + return '-'.join(self.subtags) + + def __repr__ (self): + return 'LanguageTag(%r)' % str(self) + + @staticmethod + def _find_first (function, sequence): + try: + return next (iter (filter (function, sequence))) + except StopIteration: + return None + + def is_complex (self): + """Return whether this tag is too complex to represent as a + ``LangTag`` in the generated code. + + Complex tags need to be handled in + ``hb_ot_tags_from_complex_language``. + + Returns: + Whether this tag is complex. + """ + return not (len (self.subtags) == 1 + or self.grandfathered + and len (self.subtags[1]) != 3 + and ot.from_bcp_47[self.subtags[0]] == ot.from_bcp_47[self.language]) + + def get_group (self): + """Return the group into which this tag should be categorized in + ``hb_ot_tags_from_complex_language``. + + The group is the first letter of the tag, or ``'und'`` if this tag + should not be matched in a ``switch`` statement in the generated + code. + + Returns: + This tag's group. + """ + return ('und' + if (self.language == 'und' + or self.variant in bcp_47.prefixes and len (bcp_47.prefixes[self.variant]) == 1) + else self.language[0]) + +class OpenTypeRegistryParser (HTMLParser): + """A parser for the OpenType language system tag registry. + + Attributes: + header (str): The "last updated" line of the registry. + names (Mapping[str, str]): A map of language system tags to the + names they are given in the registry. + ranks (DefaultDict[str, int]): A map of language system tags to + numbers. If a single BCP 47 tag corresponds to multiple + OpenType tags, the tags are ordered in increasing order by + rank. The rank is based on the number of BCP 47 tags + associated with a tag, though it may be manually modified. + to_bcp_47 (DefaultDict[str, AbstractSet[str]]): A map of + OpenType language system tags to sets of BCP 47 tags. + from_bcp_47 (DefaultDict[str, AbstractSet[str]]): ``to_bcp_47`` + inverted. Its values start as unsorted sets; + ``sort_languages`` converts them to sorted lists. + + """ + def __init__ (self): + HTMLParser.__init__ (self) + self.header = '' + self.names = {} + self.ranks = collections.defaultdict (int) + self.to_bcp_47 = collections.defaultdict (set) + self.from_bcp_47 = collections.defaultdict (set) + # Whether the parser is in a <td> element + self._td = False + # The text of the <td> elements of the current <tr> element. + self._current_tr = [] + + def handle_starttag (self, tag, attrs): + if tag == 'meta': + for attr, value in attrs: + if attr == 'name' and value == 'updated_at': + self.header = self.get_starttag_text () + break + elif tag == 'td': + self._td = True + self._current_tr.append ('') + elif tag == 'tr': + self._current_tr = [] + + def handle_endtag (self, tag): + if tag == 'td': + self._td = False + elif tag == 'tr' and self._current_tr: + expect (2 <= len (self._current_tr) <= 3) + name = self._current_tr[0].strip () + tag = self._current_tr[1].strip ("\t\n\v\f\r '") + rank = 0 + if len (tag) > 4: + expect (tag.endswith (' (deprecated)'), 'ill-formed OpenType tag: %s' % tag) + name += ' (deprecated)' + tag = tag.split (' ')[0] + rank = 1 + self.names[tag] = re.sub (' languages$', '', name) + if not self._current_tr[2]: + return + iso_codes = self._current_tr[2].strip () + self.to_bcp_47[tag].update (ISO_639_3_TO_1.get (code, code) for code in iso_codes.replace (' ', '').split (',')) + rank += 2 * len (self.to_bcp_47[tag]) + self.ranks[tag] = rank + + def handle_data (self, data): + if self._td: + self._current_tr[-1] += data + + def handle_charref (self, name): + self.handle_data (html_unescape (self, '&#%s;' % name)) + + def handle_entityref (self, name): + self.handle_data (html_unescape (self, '&%s;' % name)) + + def parse (self, filename): + """Parse the OpenType language system tag registry. + + Args: + filename (str): The file name of the registry. + """ + with io.open (filename, encoding='utf-8') as f: + self.feed (f.read ()) + expect (self.header) + for tag, iso_codes in self.to_bcp_47.items (): + for iso_code in iso_codes: + self.from_bcp_47[iso_code].add (tag) + + def add_language (self, bcp_47_tag, ot_tag): + """Add a language as if it were in the registry. + + Args: + bcp_47_tag (str): A BCP 47 tag. If the tag is more than just + a language subtag, and if the language subtag is a + macrolanguage, then new languages are added corresponding + to the macrolanguages' individual languages with the + remainder of the tag appended. + ot_tag (str): An OpenType language system tag. + """ + global bcp_47 + self.to_bcp_47[ot_tag].add (bcp_47_tag) + self.from_bcp_47[bcp_47_tag].add (ot_tag) + if bcp_47_tag.lower () not in bcp_47.grandfathered: + try: + [macrolanguage, suffix] = bcp_47_tag.split ('-', 1) + if macrolanguage in bcp_47.macrolanguages: + s = set () + for language in bcp_47.macrolanguages[macrolanguage]: + if language.lower () not in bcp_47.grandfathered: + s.add ('%s-%s' % (language, suffix)) + bcp_47.macrolanguages['%s-%s' % (macrolanguage, suffix)] = s + except ValueError: + pass + + @staticmethod + def _remove_language (tag_1, dict_1, dict_2): + for tag_2 in dict_1.pop (tag_1): + dict_2[tag_2].remove (tag_1) + if not dict_2[tag_2]: + del dict_2[tag_2] + + def remove_language_ot (self, ot_tag): + """Remove an OpenType tag from the registry. + + Args: + ot_tag (str): An OpenType tag. + """ + self._remove_language (ot_tag, self.to_bcp_47, self.from_bcp_47) + + def remove_language_bcp_47 (self, bcp_47_tag): + """Remove a BCP 47 tag from the registry. + + Args: + bcp_47_tag (str): A BCP 47 tag. + """ + self._remove_language (bcp_47_tag, self.from_bcp_47, self.to_bcp_47) + + def inherit_from_macrolanguages (self): + """Copy mappings from macrolanguages to individual languages. + + If a BCP 47 tag for an individual mapping has no OpenType + mapping but its macrolanguage does, the mapping is copied to + the individual language. For example, als (Tosk Albanian) has no + explicit mapping, so it inherits from sq (Albanian) the mapping + to SQI. + + If a BCP 47 tag for a macrolanguage has no OpenType mapping but + all of its individual languages do and they all map to the same + tags, the mapping is copied to the macrolanguage. + """ + global bcp_47 + original_ot_from_bcp_47 = dict (self.from_bcp_47) + for macrolanguage, languages in dict (bcp_47.macrolanguages).items (): + ot_macrolanguages = set (original_ot_from_bcp_47.get (macrolanguage, set ())) + if ot_macrolanguages: + for ot_macrolanguage in ot_macrolanguages: + for language in languages: + # Remove the following condition if e.g. nn should map to NYN,NOR + # instead of just NYN. + if language not in original_ot_from_bcp_47: + self.add_language (language, ot_macrolanguage) + self.ranks[ot_macrolanguage] += 1 + else: + for language in languages: + if language in original_ot_from_bcp_47: + if ot_macrolanguages: + ml = original_ot_from_bcp_47[language] + if ml: + ot_macrolanguages &= ml + else: + pass + else: + ot_macrolanguages |= original_ot_from_bcp_47[language] + else: + ot_macrolanguages.clear () + if not ot_macrolanguages: + break + for ot_macrolanguage in ot_macrolanguages: + self.add_language (macrolanguage, ot_macrolanguage) + + def sort_languages (self): + """Sort the values of ``from_bcp_47`` in ascending rank order.""" + for language, tags in self.from_bcp_47.items (): + self.from_bcp_47[language] = sorted (tags, + key=lambda t: (self.ranks[t] + rank_delta (language, t), t)) + +ot = OpenTypeRegistryParser () + +class BCP47Parser (object): + """A parser for the BCP 47 subtag registry. + + Attributes: + header (str): The "File-Date" line of the registry. + names (Mapping[str, str]): A map of subtags to the names they + are given in the registry. Each value is a + ``'\\n'``-separated list of names. + scopes (Mapping[str, str]): A map of language subtags to strings + suffixed to language names, including suffixes to explain + language scopes. + macrolanguages (DefaultDict[str, AbstractSet[str]]): A map of + language subtags to the sets of language subtags which + inherit from them. See + ``OpenTypeRegistryParser.inherit_from_macrolanguages``. + prefixes (DefaultDict[str, AbstractSet[str]]): A map of variant + subtags to their prefixes. + grandfathered (AbstractSet[str]): The set of grandfathered tags, + normalized to lowercase. + + """ + def __init__ (self): + self.header = '' + self.names = {} + self.scopes = {} + self.macrolanguages = collections.defaultdict (set) + self.prefixes = collections.defaultdict (set) + self.grandfathered = set () + + def parse (self, filename): + """Parse the BCP 47 subtag registry. + + Args: + filename (str): The file name of the registry. + """ + with io.open (filename, encoding='utf-8') as f: + subtag_type = None + subtag = None + deprecated = False + has_preferred_value = False + line_buffer = '' + for line in itertools.chain (f, ['']): + line = line.rstrip () + if line.startswith (' '): + line_buffer += line[1:] + continue + line, line_buffer = line_buffer, line + if line.startswith ('Type: '): + subtag_type = line.split (' ')[1] + deprecated = False + has_preferred_value = False + elif line.startswith ('Subtag: ') or line.startswith ('Tag: '): + subtag = line.split (' ')[1] + if subtag_type == 'grandfathered': + self.grandfathered.add (subtag.lower ()) + elif line.startswith ('Description: '): + description = line.split (' ', 1)[1].replace (' (individual language)', '') + description = re.sub (' (\((individual |macro)language\)|languages)$', '', + description) + if subtag in self.names: + self.names[subtag] += '\n' + description + else: + self.names[subtag] = description + elif subtag_type == 'language' or subtag_type == 'grandfathered': + if line.startswith ('Scope: '): + scope = line.split (' ')[1] + if scope == 'macrolanguage': + scope = ' [macrolanguage]' + elif scope == 'collection': + scope = ' [family]' + else: + continue + self.scopes[subtag] = scope + elif line.startswith ('Deprecated: '): + self.scopes[subtag] = ' (retired code)' + self.scopes.get (subtag, '') + deprecated = True + elif deprecated and line.startswith ('Comments: see '): + # If a subtag is split into multiple replacement subtags, + # it essentially represents a macrolanguage. + for language in line.replace (',', '').split (' ')[2:]: + self._add_macrolanguage (subtag, language) + elif line.startswith ('Preferred-Value: '): + # If a subtag is deprecated in favor of a single replacement subtag, + # it is either a dialect or synonym of the preferred subtag. Either + # way, it is close enough to the truth to consider the replacement + # the macrolanguage of the deprecated language. + has_preferred_value = True + macrolanguage = line.split (' ')[1] + self._add_macrolanguage (macrolanguage, subtag) + elif not has_preferred_value and line.startswith ('Macrolanguage: '): + self._add_macrolanguage (line.split (' ')[1], subtag) + elif subtag_type == 'variant': + if line.startswith ('Prefix: '): + self.prefixes[subtag].add (line.split (' ')[1]) + elif line.startswith ('File-Date: '): + self.header = line + expect (self.header) + + def _add_macrolanguage (self, macrolanguage, language): + global ot + if language not in ot.from_bcp_47: + for l in self.macrolanguages.get (language, set ()): + self._add_macrolanguage (macrolanguage, l) + if macrolanguage not in ot.from_bcp_47: + for ls in list (self.macrolanguages.values ()): + if macrolanguage in ls: + ls.add (language) + return + self.macrolanguages[macrolanguage].add (language) + + def remove_extra_macrolanguages (self): + """Make every language have at most one macrolanguage.""" + inverted = collections.defaultdict (list) + for macrolanguage, languages in self.macrolanguages.items (): + for language in languages: + inverted[language].append (macrolanguage) + for language, macrolanguages in inverted.items (): + if len (macrolanguages) > 1: + macrolanguages.sort (key=lambda ml: len (self.macrolanguages[ml])) + biggest_macrolanguage = macrolanguages.pop () + for macrolanguage in macrolanguages: + self._add_macrolanguage (biggest_macrolanguage, macrolanguage) + + def get_name (self, lt): + """Return the names of the subtags in a language tag. + + Args: + lt (LanguageTag): A BCP 47 language tag. + + Returns: + The name form of ``lt``. + """ + name = self.names[lt.language].split ('\n')[0] + if lt.script: + name += '; ' + self.names[lt.script.title ()].split ('\n')[0] + if lt.region: + name += '; ' + self.names[lt.region.upper ()].split ('\n')[0] + if lt.variant: + name += '; ' + self.names[lt.variant].split ('\n')[0] + return name + +bcp_47 = BCP47Parser () + +ot.parse (sys.argv[1]) +bcp_47.parse (sys.argv[2]) + +ot.add_language ('ary', 'MOR') + +ot.add_language ('ath', 'ATH') + +ot.add_language ('bai', 'BML') + +ot.ranks['BAL'] = ot.ranks['KAR'] + 1 + +ot.add_language ('ber', 'BBR') + +ot.remove_language_ot ('PGR') +ot.add_language ('el-polyton', 'PGR') + +bcp_47.macrolanguages['et'] = {'ekk'} + +bcp_47.names['flm'] = 'Falam Chin' +bcp_47.scopes['flm'] = ' (retired code)' +bcp_47.macrolanguages['flm'] = {'cfm'} + +ot.ranks['FNE'] = ot.ranks['TNE'] + 1 + +ot.add_language ('und-fonipa', 'IPPH') + +ot.add_language ('und-fonnapa', 'APPH') + +ot.remove_language_ot ('IRT') +ot.add_language ('ga-Latg', 'IRT') + +ot.remove_language_ot ('KGE') +ot.add_language ('und-Geok', 'KGE') + +ot.add_language ('guk', 'GUK') +ot.names['GUK'] = 'Gumuz (SIL fonts)' +ot.ranks['GUK'] = ot.ranks['GMZ'] + 1 + +bcp_47.macrolanguages['id'] = {'in'} + +bcp_47.macrolanguages['ijo'] = {'ijc'} + +ot.add_language ('kht', 'KHN') +ot.names['KHN'] = ot.names['KHT'] + ' (Microsoft fonts)' +ot.names['KHT'] = ot.names['KHT'] + ' (OpenType spec and SIL fonts)' +ot.ranks['KHN'] = ot.ranks['KHT'] +ot.ranks['KHT'] += 1 + +ot.ranks['LCR'] = ot.ranks['MCR'] + 1 + +ot.names['MAL'] = 'Malayalam Traditional' +ot.ranks['MLR'] += 1 + +bcp_47.names['mhv'] = 'Arakanese' +bcp_47.scopes['mhv'] = ' (retired code)' + +ot.add_language ('no', 'NOR') + +ot.add_language ('oc-provenc', 'PRO') + +ot.add_language ('qu', 'QUZ') +ot.add_language ('qub', 'QWH') +ot.add_language ('qud', 'QVI') +ot.add_language ('qug', 'QVI') +ot.add_language ('qup', 'QVI') +ot.add_language ('qur', 'QWH') +ot.add_language ('qus', 'QUH') +ot.add_language ('quw', 'QVI') +ot.add_language ('qux', 'QWH') +ot.add_language ('qva', 'QWH') +ot.add_language ('qvh', 'QWH') +ot.add_language ('qvj', 'QVI') +ot.add_language ('qvl', 'QWH') +ot.add_language ('qvm', 'QWH') +ot.add_language ('qvn', 'QWH') +ot.add_language ('qvo', 'QVI') +ot.add_language ('qvp', 'QWH') +ot.add_language ('qvw', 'QWH') +ot.add_language ('qvz', 'QVI') +ot.add_language ('qwa', 'QWH') +ot.add_language ('qws', 'QWH') +ot.add_language ('qxa', 'QWH') +ot.add_language ('qxc', 'QWH') +ot.add_language ('qxh', 'QWH') +ot.add_language ('qxl', 'QVI') +ot.add_language ('qxn', 'QWH') +ot.add_language ('qxo', 'QWH') +ot.add_language ('qxr', 'QVI') +ot.add_language ('qxt', 'QWH') +ot.add_language ('qxw', 'QWH') + +bcp_47.macrolanguages['ro'].remove ('mo') +bcp_47.macrolanguages['ro-MD'].add ('mo') + +ot.add_language ('sgw', 'SGW') +ot.names['SGW'] = ot.names['CHG'] + ' (SIL fonts)' +ot.ranks['SGW'] = ot.ranks['CHG'] + 1 + +ot.remove_language_ot ('SYRE') +ot.remove_language_ot ('SYRJ') +ot.remove_language_ot ('SYRN') +ot.add_language ('und-Syre', 'SYRE') +ot.add_language ('und-Syrj', 'SYRJ') +ot.add_language ('und-Syrn', 'SYRN') + +bcp_47.names['xst'] = u"Silt'e" +bcp_47.scopes['xst'] = ' (retired code)' +bcp_47.macrolanguages['xst'] = {'stv', 'wle'} + +ot.add_language ('xwo', 'TOD') + +ot.remove_language_ot ('ZHH') +ot.remove_language_ot ('ZHP') +ot.remove_language_ot ('ZHT') +bcp_47.macrolanguages['zh'].remove ('lzh') +bcp_47.macrolanguages['zh'].remove ('yue') +ot.add_language ('zh-Hant-MO', 'ZHH') +ot.add_language ('zh-Hant-HK', 'ZHH') +ot.add_language ('zh-Hans', 'ZHS') +ot.add_language ('zh-Hant', 'ZHT') +ot.add_language ('zh-HK', 'ZHH') +ot.add_language ('zh-MO', 'ZHH') +ot.add_language ('zh-TW', 'ZHT') +ot.add_language ('lzh', 'ZHT') +ot.add_language ('lzh-Hans', 'ZHS') +ot.add_language ('yue', 'ZHH') +ot.add_language ('yue-Hans', 'ZHS') + +bcp_47.macrolanguages['zom'] = {'yos'} + +def rank_delta (bcp_47, ot): + """Return a delta to apply to a BCP 47 tag's rank. + + Most OpenType tags have a constant rank, but a few have ranks that + depend on the BCP 47 tag. + + Args: + bcp_47 (str): A BCP 47 tag. + ot (str): An OpenType tag to. + + Returns: + A number to add to ``ot``'s rank when sorting ``bcp_47``'s + OpenType equivalents. + """ + if bcp_47 == 'ak' and ot == 'AKA': + return -1 + if bcp_47 == 'tw' and ot == 'TWI': + return -1 + return 0 + +disambiguation = { + 'ALT': 'alt', + 'ARK': 'rki', + 'BHI': 'bhb', + 'BLN': 'bjt', + 'BTI': 'beb', + 'CCHN': 'cco', + 'CMR': 'swb', + 'CPP': 'crp', + 'CRR': 'crx', + 'DUJ': 'dwu', + 'ECR': 'crj', + 'HAL': 'cfm', + 'HND': 'hnd', + 'KIS': 'kqs', + 'LRC': 'bqi', + 'NDB': 'nd', + 'NIS': 'njz', + 'PLG': 'pce', + 'PRO': 'pro', + 'QIN': 'bgr', + 'QUH': 'quh', + 'QVI': 'qvi', + 'QWH': 'qwh', + 'SIG': 'stv', + 'TNE': 'yrk', + 'ZHH': 'zh-HK', + 'ZHS': 'zh-Hans', + 'ZHT': 'zh-Hant', +} + +ot.inherit_from_macrolanguages () +bcp_47.remove_extra_macrolanguages () +ot.inherit_from_macrolanguages () +ot.sort_languages () + +print ('/* == Start of generated table == */') +print ('/*') +print (' * The following table is generated by running:') +print (' *') +print (' * %s languagetags language-subtag-registry' % sys.argv[0]) +print (' *') +print (' * on files with these headers:') +print (' *') +print (' * %s' % ot.header.strip ()) +print (' * %s' % bcp_47.header) +print (' */') +print () +print ('#ifndef HB_OT_TAG_TABLE_HH') +print ('#define HB_OT_TAG_TABLE_HH') +print () +print ('static const LangTag ot_languages[] = {') + +def hb_tag (tag): + """Convert a tag to ``HB_TAG`` form. + + Args: + tag (str): An OpenType tag. + + Returns: + A snippet of C++ representing ``tag``. + """ + return u"HB_TAG('%s','%s','%s','%s')" % tuple (('%-4s' % tag)[:4]) + +def get_variant_set (name): + """Return a set of variant language names from a name. + + Args: + name (str): A list of language names from the BCP 47 registry, + joined on ``'\\n'``. + + Returns: + A set of normalized language names. + """ + return set (unicodedata.normalize ('NFD', n.replace ('\u2019', u"'")) + .encode ('ASCII', 'ignore') + .strip () + for n in re.split ('[\n(),]', name) if n) + +def language_name_intersection (a, b): + """Return the names in common between two language names. + + Args: + a (str): A list of language names from the BCP 47 registry, + joined on ``'\\n'``. + b (str): A list of language names from the BCP 47 registry, + joined on ``'\\n'``. + + Returns: + The normalized language names shared by ``a`` and ``b``. + """ + return get_variant_set (a).intersection (get_variant_set (b)) + +def get_matching_language_name (intersection, candidates): + return next (iter (c for c in candidates if not intersection.isdisjoint (get_variant_set (c)))) + +maximum_tags = 0 +for language, tags in sorted (ot.from_bcp_47.items ()): + if language == '' or '-' in language: + continue + print (' {\"%s\",\t{' % language, end='') + maximum_tags = max (maximum_tags, len (tags)) + tag_count = len (tags) + for i, tag in enumerate (tags, start=1): + if i > 1: + print ('\t\t ', end='') + print (hb_tag (tag), end='') + if i == tag_count: + print ('}}', end='') + print (',\t/* ', end='') + bcp_47_name = bcp_47.names.get (language, '') + bcp_47_name_candidates = bcp_47_name.split ('\n') + intersection = language_name_intersection (bcp_47_name, ot.names[tag]) + scope = bcp_47.scopes.get (language, '') + if not intersection: + write ('%s%s -> %s' % (bcp_47_name_candidates[0], scope, ot.names[tag])) + else: + name = get_matching_language_name (intersection, bcp_47_name_candidates) + bcp_47.names[language] = name + write ('%s%s' % (name if len (name) > len (ot.names[tag]) else ot.names[tag], scope)) + print (' */') + +print ('};') +print () +print ('static_assert (HB_OT_MAX_TAGS_PER_LANGUAGE == %iu, "");' % maximum_tags) +print () + +print ('/**') +print (' * hb_ot_tags_from_complex_language:') +print (' * @lang_str: a BCP 47 language tag to convert.') +print (' * @limit: a pointer to the end of the substring of @lang_str to consider for') +print (' * conversion.') +print (' * @count: maximum number of language tags to retrieve (IN) and actual number of') +print (' * language tags retrieved (OUT). If no tags are retrieved, it is not modified.') +print (' * @tags: array of size at least @language_count to store the language tag') +print (' * results') +print (' *') +print (' * Converts a multi-subtag BCP 47 language tag to language tags.') +print (' *') +print (' * Return value: Whether any language systems were retrieved.') +print (' **/') +print ('static bool') +print ('hb_ot_tags_from_complex_language (const char *lang_str,') +print ('\t\t\t\t const char *limit,') +print ('\t\t\t\t unsigned int *count /* IN/OUT */,') +print ('\t\t\t\t hb_tag_t *tags /* OUT */)') +print ('{') + +def print_subtag_matches (subtag, new_line): + if subtag: + if new_line: + print () + print ('\t&& ', end='') + print ('subtag_matches (lang_str, limit, "-%s")' % subtag, end='') + +complex_tags = collections.defaultdict (list) +for initial, group in itertools.groupby ((lt_tags for lt_tags in [ + (LanguageTag (language), tags) + for language, tags in sorted (ot.from_bcp_47.items (), + key=lambda i: (-len (i[0]), i[0])) + ] if lt_tags[0].is_complex ()), + key=lambda lt_tags: lt_tags[0].get_group ()): + complex_tags[initial] += group + +for initial, items in sorted (complex_tags.items ()): + if initial != 'und': + continue + for lt, tags in items: + if lt.variant in bcp_47.prefixes: + expect (next (iter (bcp_47.prefixes[lt.variant])) == lt.language, + '%s is not a valid prefix of %s' % (lt.language, lt.variant)) + print (' if (', end='') + print_subtag_matches (lt.script, False) + print_subtag_matches (lt.region, False) + print_subtag_matches (lt.variant, False) + print (')') + print (' {') + write (' /* %s */' % bcp_47.get_name (lt)) + print () + if len (tags) == 1: + write (' tags[0] = %s; /* %s */' % (hb_tag (tags[0]), ot.names[tags[0]])) + print () + print (' *count = 1;') + else: + print (' hb_tag_t possible_tags[] = {') + for tag in tags: + write (' %s, /* %s */' % (hb_tag (tag), ot.names[tag])) + print () + print (' };') + print (' for (i = 0; i < %s && i < *count; i++)' % len (tags)) + print (' tags[i] = possible_tags[i];') + print (' *count = i;') + print (' return true;') + print (' }') + +print (' switch (lang_str[0])') +print (' {') +for initial, items in sorted (complex_tags.items ()): + if initial == 'und': + continue + print (" case '%s':" % initial) + for lt, tags in items: + print (' if (', end='') + if lt.grandfathered: + print ('0 == strcmp (&lang_str[1], "%s")' % lt.language[1:], end='') + else: + string_literal = lt.language[1:] + '-' + if lt.script: + string_literal += lt.script + lt.script = None + if lt.region: + string_literal += '-' + lt.region + lt.region = None + if string_literal[-1] == '-': + print ('0 == strncmp (&lang_str[1], "%s", %i)' % (string_literal, len (string_literal)), end='') + else: + print ('lang_matches (&lang_str[1], "%s")' % string_literal, end='') + print_subtag_matches (lt.script, True) + print_subtag_matches (lt.region, True) + print_subtag_matches (lt.variant, True) + print (')') + print (' {') + write (' /* %s */' % bcp_47.get_name (lt)) + print () + if len (tags) == 1: + write (' tags[0] = %s; /* %s */' % (hb_tag (tags[0]), ot.names[tags[0]])) + print () + print (' *count = 1;') + else: + print (' unsigned int i;') + print (' hb_tag_t possible_tags[] = {') + for tag in tags: + write ('\t%s, /* %s */' % (hb_tag (tag), ot.names[tag])) + print () + print (' };') + print (' for (i = 0; i < %s && i < *count; i++)' % len (tags)) + print ('\ttags[i] = possible_tags[i];') + print (' *count = i;') + print (' return true;') + print (' }') + print (' break;') + +print (' }') +print (' return false;') +print ('}') +print () +print ('/**') +print (' * hb_ot_ambiguous_tag_to_language') +print (' * @tag: A language tag.') +print (' *') +print (' * Converts @tag to a BCP 47 language tag if it is ambiguous (it corresponds to') +print (' * many language tags) and the best tag is not the alphabetically first, or if') +print (' * the best tag consists of multiple subtags.') +print (' *') +print (' * Return value: The #hb_language_t corresponding to the BCP 47 language tag,') +print (' * or #HB_LANGUAGE_INVALID if @tag is not ambiguous.') +print (' **/') +print ('static hb_language_t') +print ('hb_ot_ambiguous_tag_to_language (hb_tag_t tag)') +print ('{') +print (' switch (tag)') +print (' {') + +def verify_disambiguation_dict (): + """Verify and normalize ``disambiguation``. + + ``disambiguation`` is a map of ambiguous OpenType language system + tags to the particular BCP 47 tags they correspond to. This function + checks that all its keys really are ambiguous and that each key's + value is valid for that key. It checks that no ambiguous tag is + missing, except when it can figure out which BCP 47 tag is the best + by itself. + + It modifies ``disambiguation`` to remove keys whose values are the + same as those that the fallback would return anyway, and to add + ambiguous keys whose disambiguations it determined automatically. + + Raises: + AssertionError: Verification failed. + """ + global bcp_47 + global disambiguation + global ot + for ot_tag, bcp_47_tags in ot.to_bcp_47.items (): + primary_tags = list (t for t in bcp_47_tags if t not in bcp_47.grandfathered and ot.from_bcp_47.get (t)[0] == ot_tag) + if len (primary_tags) == 1: + expect (ot_tag not in disambiguation, 'unnecessary disambiguation for OT tag: %s' % ot_tag) + if '-' in primary_tags[0]: + disambiguation[ot_tag] = primary_tags[0] + elif len (primary_tags) == 0: + expect (ot_tag not in disambiguation, 'There is no possible valid disambiguation for %s' % ot_tag) + else: + macrolanguages = list (t for t in primary_tags if bcp_47.scopes.get (t) == ' [macrolanguage]') + if len (macrolanguages) != 1: + macrolanguages = list (t for t in primary_tags if bcp_47.scopes.get (t) == ' [family]') + if len (macrolanguages) != 1: + macrolanguages = list (t for t in primary_tags if 'retired code' not in bcp_47.scopes.get (t, '')) + if len (macrolanguages) != 1: + expect (ot_tag in disambiguation, 'ambiguous OT tag: %s %s' % (ot_tag, str (macrolanguages))) + expect (disambiguation[ot_tag] in bcp_47_tags, + '%s is not a valid disambiguation for %s' % (disambiguation[ot_tag], ot_tag)) + elif ot_tag not in disambiguation: + disambiguation[ot_tag] = macrolanguages[0] + if disambiguation[ot_tag] == sorted (primary_tags)[0] and '-' not in disambiguation[ot_tag]: + del disambiguation[ot_tag] + for ot_tag in disambiguation.keys (): + expect (ot_tag in ot.to_bcp_47, 'unknown OT tag: %s' % ot_tag) + +verify_disambiguation_dict () +for ot_tag, bcp_47_tag in sorted (disambiguation.items ()): + write (' case %s: /* %s */' % (hb_tag (ot_tag), ot.names[ot_tag])) + print () + write (' return hb_language_from_string (\"%s\", -1); /* %s */' % (bcp_47_tag, bcp_47.get_name (LanguageTag (bcp_47_tag)))) + print () + +print (' default:') +print (' return HB_LANGUAGE_INVALID;') +print (' }') +print ('}') + +print () +print ('#endif /* HB_OT_TAG_TABLE_HH */') +print () +print ('/* == End of generated table == */') + diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py index a8724619a03..ebfae6fab8f 100755 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py @@ -8,7 +8,7 @@ if len (sys.argv) != 5: 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"] +BLACKLISTED_BLOCKS = ["Thai", "Lao"] files = [io.open (x, encoding='utf-8') for x in sys.argv[1:]] @@ -197,7 +197,10 @@ def is_CONS_SUB(U, UISC, UGC): def is_CONS_WITH_STACKER(U, UISC, UGC): return UISC == Consonant_With_Stacker def is_HALANT(U, UISC, UGC): - return UISC in [Virama, Invisible_Stacker] + return UISC in [Virama, Invisible_Stacker] and not is_HALANT_OR_VOWEL_MODIFIER(U, UISC, UGC) +def is_HALANT_OR_VOWEL_MODIFIER(U, UISC, UGC): + # https://github.com/harfbuzz/harfbuzz/issues/1102 + return U == 0x11046 def is_HALANT_NUM(U, UISC, UGC): return UISC == Number_Joiner def is_ZWNJ(U, UISC, UGC): @@ -248,6 +251,7 @@ use_mapping = { 'SUB': is_CONS_SUB, 'CS': is_CONS_WITH_STACKER, 'H': is_HALANT, + 'HVM': is_HALANT_OR_VOWEL_MODIFIER, 'HN': is_HALANT_NUM, 'ZWNJ': is_ZWNJ, 'ZWJ': is_ZWJ, @@ -281,8 +285,8 @@ use_positions = { 'V': { 'Abv': [Top, Top_And_Bottom, Top_And_Bottom_And_Right, Top_And_Right], 'Blw': [Bottom, Overstruck, Bottom_And_Right], - 'Pst': [Right], - 'Pre': [Left, Top_And_Left, Top_And_Left_And_Right, Left_And_Right], + 'Pst': [Right, Top_And_Left, Top_And_Left_And_Right, Left_And_Right], + 'Pre': [Left], }, 'VM': { 'Abv': [Top], @@ -295,6 +299,7 @@ use_positions = { 'Blw': [Bottom], }, 'H': None, + 'HVM': None, 'B': None, 'FM': None, 'SUB': None, @@ -307,11 +312,28 @@ def map_to_use(data): # Resolve Indic_Syllabic_Category - # TODO: These don't have UISC assigned in Unicode 8.0, but - # have UIPC + # TODO: These don't have UISC assigned in Unicode 8.0, but have UIPC if U == 0x17DD: UISC = Vowel_Dependent if 0x1CE2 <= U <= 0x1CE8: UISC = Cantillation_Mark + # Tibetan: + # TODO: These don't have UISC assigned in Unicode 11.0, but have UIPC + if 0x0F18 <= U <= 0x0F19 or 0x0F3E <= U <= 0x0F3F: UISC = Vowel_Dependent + if 0x0F86 <= U <= 0x0F87: UISC = Tone_Mark + # Overrides to allow NFC order matching syllable + # https://github.com/harfbuzz/harfbuzz/issues/1012 + if UBlock == 'Tibetan' and is_VOWEL (U, UISC, UGC): + if UIPC == Top: + UIPC = Bottom + + # TODO: https://github.com/harfbuzz/harfbuzz/pull/982 + # also https://github.com/harfbuzz/harfbuzz/issues/1012 + if UBlock == 'Chakma' and is_VOWEL (U, UISC, UGC): + if UIPC == Top: + UIPC = Bottom + elif UIPC == Bottom: + UIPC = Top + # TODO: https://github.com/harfbuzz/harfbuzz/pull/627 if 0x1BF2 <= U <= 0x1BF3: UISC = Nukta; UIPC = Bottom @@ -359,13 +381,6 @@ def map_to_use(data): # https://github.com/roozbehp/unicode-data/issues/8 if U == 0x0A51: UIPC = Bottom - # TODO: https://github.com/harfbuzz/harfbuzz/pull/982 - if UBlock == 'Chakma' and is_VOWEL (U, UISC, UGC): - if UIPC == Top: - UIPC = Bottom - elif UIPC == Bottom: - UIPC = Top - assert (UIPC in [Not_Applicable, Visual_Order_Left] or USE in use_positions), "%s %s %s %s %s" % (hex(U), UIPC, USE, UISC, UGC) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-config.cmake.in b/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-config.cmake.in index 87b15721a3a..304410d9bae 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-config.cmake.in +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-config.cmake.in @@ -12,7 +12,11 @@ set(_harfbuzz_libdir "@libdir@") string(REPLACE "${_harfbuzz_remove_string}/" "" _harfbuzz_libdir "${_harfbuzz_libdir}") set(_harfbuzz_libdir_iter "${_harfbuzz_libdir}") while (_harfbuzz_libdir_iter) + set(_harfbuzz_libdir_prev_iter "${_harfbuzz_libdir_iter}") get_filename_component(_harfbuzz_libdir_iter "${_harfbuzz_libdir_iter}" DIRECTORY) + if (_harfbuzz_libdir_prev_iter STREQUAL _harfbuzz_libdir_iter) + break() + endif () get_filename_component(_harfbuzz_prefix "${_harfbuzz_prefix}" DIRECTORY) endwhile () unset(_harfbuzz_libdir_iter) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-ankr-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-ankr-table.hh index a197cec8112..2e3ed275851 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-ankr-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-ankr-table.hh @@ -45,32 +45,47 @@ struct Anchor return_trace (c->check_struct (this)); } + public: FWORD xCoordinate; FWORD yCoordinate; public: DEFINE_SIZE_STATIC (4); }; +typedef LArrayOf<Anchor> GlyphAnchors; + struct ankr { static const hb_tag_t tableTag = HB_AAT_TAG_ankr; + inline const Anchor &get_anchor (hb_codepoint_t glyph_id, + unsigned int i, + unsigned int num_glyphs, + const char *end) const + { + unsigned int offset = (this+lookupTable).get_value_or_null (glyph_id, num_glyphs); + const GlyphAnchors &anchors = StructAtOffset<GlyphAnchors> (&(this+anchorData), offset); + /* TODO Use sanitizer; to avoid overflows and more. */ + if (unlikely ((const char *) &anchors + anchors.get_size () > end)) + return Null(Anchor); + return anchors[i]; + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && version == 0 && - lookupTable.sanitize (c, this) && - anchors.sanitize (c, this))); + lookupTable.sanitize (c, this))); } protected: HBUINT16 version; /* Version number (set to zero) */ HBUINT16 flags; /* Flags (currently unused; set to zero) */ - LOffsetTo<Lookup<HBUINT16> > + LOffsetTo<Lookup<Offset<HBUINT16, false> >, false> lookupTable; /* Offset to the table's lookup table */ - LOffsetTo<LArrayOf<Anchor> > - anchors; /* Offset to the glyph data table */ + LOffsetTo<HBUINT8, false> + anchorData; /* Offset to the glyph data table */ public: DEFINE_SIZE_STATIC (12); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh index 25f4fe14a75..89ed91f28a7 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh @@ -36,111 +36,6 @@ using namespace OT; /* - * Binary Searching Tables - */ - -struct BinSearchHeader -{ - - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); - } - - HBUINT16 unitSize; /* Size of a lookup unit for this search in bytes. */ - HBUINT16 nUnits; /* Number of units of the preceding size to be searched. */ - HBUINT16 searchRange; /* The value of unitSize times the largest power of 2 - * that is less than or equal to the value of nUnits. */ - HBUINT16 entrySelector; /* The log base 2 of the largest power of 2 less than - * or equal to the value of nUnits. */ - HBUINT16 rangeShift; /* The value of unitSize times the difference of the - * value of nUnits minus the largest power of 2 less - * than or equal to the value of nUnits. */ - public: - DEFINE_SIZE_STATIC (10); -}; - -template <typename Type> -struct BinSearchArrayOf -{ - inline const Type& operator [] (unsigned int i) const - { - if (unlikely (i >= header.nUnits)) return Null(Type); - return StructAtOffset<Type> (bytesZ, i * header.unitSize); - } - inline Type& operator [] (unsigned int i) - { - return StructAtOffset<Type> (bytesZ, i * header.unitSize); - } - inline unsigned int get_size (void) const - { return header.static_size + header.nUnits * header.unitSize; } - - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c))) 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 && StructAtOffset<Type> (bytesZ, 0).sanitize (c)); - - return_trace (true); - } - inline bool sanitize (hb_sanitize_context_t *c, const void *base) const - { - TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c))) return_trace (false); - unsigned int count = header.nUnits; - for (unsigned int i = 0; i < count; i++) - if (unlikely (!(*this)[i].sanitize (c, base))) - return_trace (false); - return_trace (true); - } - - template <typename T> - inline const Type *bsearch (const T &key) const - { - unsigned int size = header.unitSize; - int min = 0, max = (int) header.nUnits - 1; - while (min <= max) - { - int mid = (min + max) / 2; - const Type *p = (const Type *) (((const char *) bytesZ) + (mid * size)); - int c = p->cmp (key); - if (c < 0) - max = mid - 1; - else if (c > 0) - min = mid + 1; - else - return p; - } - return nullptr; - } - - private: - inline bool sanitize_shallow (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (header.sanitize (c) && - Type::static_size >= header.unitSize && - c->check_array (bytesZ, header.unitSize, header.nUnits)); - } - - protected: - BinSearchHeader header; - HBUINT8 bytesZ[VAR]; - public: - DEFINE_SIZE_ARRAY (10, bytesZ); -}; - - -/* * Lookup Table */ @@ -213,7 +108,7 @@ struct LookupFormat2 protected: HBUINT16 format; /* Format identifier--format = 2 */ - BinSearchArrayOf<LookupSegmentSingle<T> > + VarSizedBinSearchArrayOf<LookupSegmentSingle<T> > segments; /* The actual segments. These must already be sorted, * according to the first word in each one (the last * glyph in each segment). */ @@ -243,7 +138,7 @@ struct LookupSegmentArray GlyphID last; /* Last GlyphID in this segment */ GlyphID first; /* First GlyphID in this segment */ - OffsetTo<UnsizedArrayOf<T> > + OffsetTo<UnsizedArrayOf<T>, HBUINT16, false> valuesZ; /* A 16-bit offset from the start of * the table to the data. */ public: @@ -269,8 +164,8 @@ struct LookupFormat4 } protected: - HBUINT16 format; /* Format identifier--format = 2 */ - BinSearchArrayOf<LookupSegmentArray<T> > + HBUINT16 format; /* Format identifier--format = 4 */ + VarSizedBinSearchArrayOf<LookupSegmentArray<T> > segments; /* The actual segments. These must already be sorted, * according to the first word in each one (the last * glyph in each segment). */ @@ -292,7 +187,7 @@ struct LookupSingle GlyphID glyph; /* Last GlyphID */ T value; /* The lookup value (only one) */ public: - DEFINE_SIZE_STATIC (4 + T::static_size); + DEFINE_SIZE_STATIC (2 + T::static_size); }; template <typename T> @@ -315,7 +210,7 @@ struct LookupFormat6 protected: HBUINT16 format; /* Format identifier--format = 6 */ - BinSearchArrayOf<LookupSingle<T> > + VarSizedBinSearchArrayOf<LookupSingle<T> > entries; /* The actual entries, sorted by glyph index. */ public: DEFINE_SIZE_ARRAY (8, entries); @@ -329,7 +224,8 @@ struct LookupFormat8 private: inline const T* get_value (hb_codepoint_t glyph_id) const { - return firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount ? &valueArrayZ[glyph_id - firstGlyph] : nullptr; + return firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount ? + &valueArrayZ[glyph_id - firstGlyph] : nullptr; } inline bool sanitize (hb_sanitize_context_t *c) const @@ -339,7 +235,7 @@ struct LookupFormat8 } protected: - HBUINT16 format; /* Format identifier--format = 6 */ + HBUINT16 format; /* Format identifier--format = 8 */ GlyphID firstGlyph; /* First glyph index included in the trimmed array. */ HBUINT16 glyphCount; /* Total number of glyphs (equivalent to the last * glyph minus the value of firstGlyph plus 1). */ @@ -365,6 +261,12 @@ struct Lookup } } + inline const T& get_value_or_null (hb_codepoint_t glyph_id, unsigned int num_glyphs) const + { + const T *v = get_value (glyph_id, num_glyphs); + return v ? *v : Null(T); + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -391,6 +293,25 @@ struct Lookup public: DEFINE_SIZE_UNION (2, format); }; +/* Lookup 0 has unbounded size (dependant on num_glyphs). So we need to defined + * special NULL objects for Lookup<> objects, but since it's template our macros + * don't work. So we have to hand-code them here. UGLY. */ +} /* Close namespace. */ +/* Ugly hand-coded null objects for template Lookup<> :(. */ +extern HB_INTERNAL const unsigned char _hb_Null_AAT_Lookup[2]; +template <> +/*static*/ inline const AAT::Lookup<OT::HBUINT16>& Null<AAT::Lookup<OT::HBUINT16> > (void) { + return *reinterpret_cast<const AAT::Lookup<OT::HBUINT16> *> (_hb_Null_AAT_Lookup); +} +template <> +/*static*/ inline const AAT::Lookup<OT::HBUINT32>& Null<AAT::Lookup<OT::HBUINT32> > (void) { + return *reinterpret_cast<const AAT::Lookup<OT::HBUINT32> *> (_hb_Null_AAT_Lookup); +} +template <> +/*static*/ inline const AAT::Lookup<OT::Offset<OT::HBUINT16, false> >& Null<AAT::Lookup<OT::Offset<OT::HBUINT16, false> > > (void) { + return *reinterpret_cast<const AAT::Lookup<OT::Offset<OT::HBUINT16, false> > *> (_hb_Null_AAT_Lookup); +} +namespace AAT { /* @@ -439,10 +360,23 @@ struct Entry<void> template <typename Extra> struct StateTable { + enum State + { + STATE_START_OF_TEXT = 0, + STATE_START_OF_LINE = 1, + }; + enum Class + { + CLASS_END_OF_TEXT = 0, + CLASS_OUT_OF_BOUNDS = 1, + CLASS_DELETED_GLYPH = 2, + CLASS_END_OF_LINE = 3, + }; + inline unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs) const { const HBUINT16 *v = (this+classTable).get_value (glyph_id, num_glyphs); - return v ? *v : 1; + return v ? (unsigned) *v : (unsigned) CLASS_OUT_OF_BOUNDS; } inline const Entry<Extra> *get_entries () const @@ -472,6 +406,8 @@ struct StateTable const HBUINT16 *states = (this+stateArrayTable).arrayZ; const Entry<Extra> *entries = (this+entryTable).arrayZ; + unsigned int num_classes = nClasses; + unsigned int num_states = 1; unsigned int num_entries = 0; @@ -479,20 +415,25 @@ struct StateTable unsigned int entry = 0; while (state < num_states) { + if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size))) + return_trace (false); + if (unlikely (!c->check_array (states, - states[0].static_size * nClasses, - num_states))) + num_states, + num_classes * states[0].static_size))) + return_trace (false); + if ((c->max_ops -= num_states - state) < 0) return_trace (false); { /* Sweep new states. */ - const HBUINT16 *stop = &states[num_states * nClasses]; - for (const HBUINT16 *p = &states[state * nClasses]; p < stop; p++) + const HBUINT16 *stop = &states[num_states * num_classes]; + for (const HBUINT16 *p = &states[state * num_classes]; p < stop; p++) num_entries = MAX<unsigned int> (num_entries, *p + 1); state = num_states; } - if (unlikely (!c->check_array (entries, - entries[0].static_size, - num_entries))) + if (unlikely (!c->check_array (entries, num_entries))) + return_trace (false); + if ((c->max_ops -= num_entries - entry) < 0) return_trace (false); { /* Sweep new entries. */ const Entry<Extra> *stop = &entries[num_entries]; @@ -511,11 +452,11 @@ struct StateTable protected: HBUINT32 nClasses; /* Number of classes, which is the number of indices * in a single line in the state array. */ - LOffsetTo<Lookup<HBUINT16> > + LOffsetTo<Lookup<HBUINT16>, false> classTable; /* Offset to the class table. */ - LOffsetTo<UnsizedArrayOf<HBUINT16> > + LOffsetTo<UnsizedArrayOf<HBUINT16>, false> stateArrayTable;/* Offset to the state array. */ - LOffsetTo<UnsizedArrayOf<Entry<Extra> > > + LOffsetTo<UnsizedArrayOf<Entry<Extra> >, false> entryTable; /* Offset to the entry array. */ public: @@ -535,31 +476,32 @@ struct StateTableDriver template <typename context_t> inline void drive (context_t *c) { - hb_glyph_info_t *info = buffer->info; - if (!c->in_place) buffer->clear_output (); - unsigned int state = 0; + unsigned int state = StateTable<EntryData>::STATE_START_OF_TEXT; bool last_was_dont_advance = false; for (buffer->idx = 0;;) { unsigned int klass = buffer->idx < buffer->len ? - machine.get_class (info[buffer->idx].codepoint, num_glyphs) : - 0 /* End of text */; + machine.get_class (buffer->info[buffer->idx].codepoint, num_glyphs) : + (unsigned) StateTable<EntryData>::CLASS_END_OF_TEXT; const Entry<EntryData> *entry = machine.get_entryZ (state, klass); if (unlikely (!entry)) break; /* Unsafe-to-break before this if not in state 0, as things might - * go differently if we start from state 0 here. */ - if (state && buffer->idx) + * go differently if we start from state 0 here. + * + * Ugh. The indexing here is ugly... */ + if (state && buffer->backtrack_len () && buffer->idx < buffer->len) { /* If there's no action and we're just epsilon-transitioning to state 0, * safe to break. */ if (c->is_actionable (this, entry) || - !(entry->newState == 0 && entry->flags == context_t::DontAdvance)) - buffer->unsafe_to_break (buffer->idx - 1, buffer->idx + 1); + !(entry->newState == StateTable<EntryData>::STATE_START_OF_TEXT && + entry->flags == context_t::DontAdvance)) + buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1); } /* Unsafe-to-break if end-of-text would kick in here. */ @@ -573,6 +515,8 @@ struct StateTableDriver if (unlikely (!c->transition (this, entry))) break; + if (unlikely (!buffer->successful)) return; + last_was_dont_advance = (entry->flags & context_t::DontAdvance) && buffer->max_ops-- > 0; state = entry->newState; @@ -586,9 +530,10 @@ struct StateTableDriver if (!c->in_place) { - for (; buffer->idx < buffer->len;) - buffer->next_glyph (); - buffer->swap_buffers (); + for (; buffer->successful && buffer->idx < buffer->len;) + buffer->next_glyph (); + if (likely (buffer->successful)) + buffer->swap_buffers (); } } @@ -599,6 +544,7 @@ struct StateTableDriver }; +struct ankr; struct hb_aat_apply_context_t : hb_dispatch_context_t<hb_aat_apply_context_t, bool, HB_DEBUG_APPLY> @@ -609,24 +555,33 @@ struct hb_aat_apply_context_t : static return_t default_return_value (void) { return false; } bool stop_sublookup_iteration (return_t r) const { return r; } + hb_ot_shape_plan_t *plan; hb_font_t *font; hb_face_t *face; hb_buffer_t *buffer; hb_sanitize_context_t sanitizer; + const ankr &ankr_table; + const char *ankr_end; /* Unused. For debug tracing only. */ unsigned int lookup_index; unsigned int debug_depth; - inline hb_aat_apply_context_t (hb_font_t *font_, + inline hb_aat_apply_context_t (hb_ot_shape_plan_t *plan_, + hb_font_t *font_, hb_buffer_t *buffer_, - hb_blob_t *table) : - font (font_), face (font->face), buffer (buffer_), - sanitizer (), lookup_index (0), debug_depth (0) - { - sanitizer.init (table); + hb_blob_t *blob = const_cast<hb_blob_t *> (&Null(hb_blob_t)), + const ankr &ankr_table_ = Null(ankr), + const char *ankr_end_ = nullptr) : + plan (plan_), font (font_), face (font->face), buffer (buffer_), + sanitizer (), + ankr_table (ankr_table_), ankr_end (ankr_end_), + lookup_index (0), debug_depth (0) + { + sanitizer.init (blob); sanitizer.set_num_glyphs (face->get_num_glyphs ()); sanitizer.start_processing (); + sanitizer.set_max_ops (HB_SANITIZE_MAX_OPS_MAX); } inline void set_lookup_index (unsigned int i) { lookup_index = i; } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-feat-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-feat-table.hh index b7007631662..b670caab83b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-feat-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-feat-table.hh @@ -78,7 +78,7 @@ struct FeatureName protected: HBUINT16 feature; /* Feature type. */ HBUINT16 nSettings; /* The number of records in the setting name array. */ - LOffsetTo<UnsizedArrayOf<SettingName> > + LOffsetTo<UnsizedArrayOf<SettingName>, false> 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 diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh index 615a8f8d4c3..c09a6d31075 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh @@ -30,7 +30,8 @@ #include "hb-open-type.hh" #include "hb-aat-layout-common.hh" -#include "hb-aat-layout-ankr-table.hh" +#include "hb-ot-layout-gpos-table.hh" +#include "hb-ot-kern-table.hh" /* * kerx -- Extended Kerning @@ -44,7 +45,7 @@ namespace AAT { using namespace OT; -struct KerxFormat0Records +struct KerxSubTableHeader { inline bool sanitize (hb_sanitize_context_t *c) const { @@ -52,217 +53,565 @@ struct KerxFormat0Records return_trace (likely (c->check_struct (this))); } - protected: - GlyphID left; - GlyphID right; - FWORD value; public: - DEFINE_SIZE_STATIC (6); + HBUINT32 length; + HBUINT32 coverage; + HBUINT32 tupleCount; + public: + DEFINE_SIZE_STATIC (12); }; struct KerxSubTableFormat0 { - // TODO(ebraminio) Enable when we got suitable BinSearchArrayOf - // inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const - // { - // hb_glyph_pair_t pair = {left, right}; - // int i = pairs.bsearch (pair); - // if (i == -1) - // return 0; - // return pairs[i].get_kerning (); - // } + inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const + { + hb_glyph_pair_t pair = {left, right}; + int i = pairs.bsearch (pair); + return i == -1 ? 0 : pairs[i].get_kerning (); + } + + inline bool apply (hb_aat_apply_context_t *c) const + { + TRACE_APPLY (this); + + if (!c->plan->requested_kerning) + return false; + + hb_kern_machine_t<KerxSubTableFormat0> machine (*this); + + machine.kern (c->font, c->buffer, c->plan->kern_mask); + + return_trace (true); + } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && - recordsZ.sanitize (c, nPairs))); + return_trace (likely (pairs.sanitize (c))); } 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. */ - UnsizedArrayOf<KerxFormat0Records> - recordsZ; /* VAR=nPairs */ + KerxSubTableHeader header; + BinSearchArrayOf<KernPair, HBUINT32> + pairs; /* Sorted kern records. */ public: - DEFINE_SIZE_ARRAY (16, recordsZ); + DEFINE_SIZE_ARRAY (28, pairs); }; struct KerxSubTableFormat1 { - inline bool sanitize (hb_sanitize_context_t *c) const + struct EntryData { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && - stateHeader.sanitize (c))); - } + HBUINT16 kernActionIndex;/* Index into the kerning value array. If + * this index is 0xFFFF, then no kerning + * is to be performed. */ + public: + DEFINE_SIZE_STATIC (2); + }; + + struct driver_context_t + { + static const bool in_place = true; + enum Flags + { + Push = 0x8000, /* If set, push this glyph on the kerning stack. */ + DontAdvance = 0x4000, /* If set, don't advance to the next glyph + * before going to the new state. */ + Reset = 0x2000, /* If set, reset the kerning data (clear the stack) */ + Reserved = 0x1FFF, /* Not used; set to 0. */ + }; + + inline driver_context_t (const KerxSubTableFormat1 *table, + hb_aat_apply_context_t *c_) : + c (c_), + /* Apparently the offset kernAction is from the beginning of the state-machine, + * similar to offsets in morx table, NOT from beginning of this table, like + * other subtables in kerx. Discovered via testing. */ + kernAction (&table->machine + table->kernAction), + depth (0) {} + + inline bool is_actionable (StateTableDriver<EntryData> *driver, + const Entry<EntryData> *entry) + { + return entry->data.kernActionIndex != 0xFFFF; + } + inline bool transition (StateTableDriver<EntryData> *driver, + const Entry<EntryData> *entry) + { + hb_buffer_t *buffer = driver->buffer; + unsigned int flags = entry->flags; + + if (flags & Reset) + { + depth = 0; + } + + if (flags & Push) + { + if (likely (depth < ARRAY_LENGTH (stack))) + stack[depth++] = buffer->idx; + else + depth = 0; /* Probably not what CoreText does, but better? */ + } + + if (entry->data.kernActionIndex != 0xFFFF) + { + const FWORD *actions = &kernAction[entry->data.kernActionIndex]; + if (!c->sanitizer.check_array (actions, depth)) + { + depth = 0; + return false; + } + + hb_mask_t kern_mask = c->plan->kern_mask; + for (unsigned int i = 0; i < depth; i++) + { + /* Apparently, when spec says "Each pops one glyph from the kerning stack + * and applies the kerning value to it.", it doesn't mean it in that order. + * The deepest item in the stack corresponds to the first item in the action + * list. Discovered by testing. */ + unsigned int idx = stack[i]; + int v = *actions++; + if (idx < buffer->len && buffer->info[idx].mask & kern_mask) + { + /* XXX Non-forward direction... */ + if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) + buffer->pos[idx].x_advance += c->font->em_scale_x (v); + else + buffer->pos[idx].y_advance += c->font->em_scale_y (v); + } + } + depth = 0; + } + + return true; + } - protected: - StateTable<HBUINT16> stateHeader; - LOffsetTo<ArrayOf<HBUINT16> > valueTable; - public: - DEFINE_SIZE_STATIC (20); -}; + private: + hb_aat_apply_context_t *c; + const UnsizedArrayOf<FWORD> &kernAction; + unsigned int stack[8]; + unsigned int depth; + }; -// TODO(ebraminio): Maybe this can be replaced with Lookup<HBUINT16>? -struct KerxClassTable -{ - inline unsigned int get_class (hb_codepoint_t g) const { return classes[g - firstGlyph]; } + inline bool apply (hb_aat_apply_context_t *c) const + { + TRACE_APPLY (this); + + if (!c->plan->requested_kerning) + return false; + + driver_context_t dc (this, c); + + StateTableDriver<EntryData> driver (machine, c->buffer, c->font->face); + driver.drive (&dc); + + return_trace (true); + } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (firstGlyph.sanitize (c) && - classes.sanitize (c))); + /* The rest of array sanitizations are done at run-time. */ + return_trace (likely (c->check_struct (this) && + machine.sanitize (c))); } protected: - HBUINT16 firstGlyph; /* First glyph in class range. */ - ArrayOf<HBUINT16> classes; /* Glyph classes. */ + KerxSubTableHeader header; + StateTable<EntryData> machine; + LOffsetTo<UnsizedArrayOf<FWORD>, false> kernAction; public: - DEFINE_SIZE_ARRAY (4, classes); + DEFINE_SIZE_STATIC (32); }; struct KerxSubTableFormat2 { - inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const + inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, + hb_aat_apply_context_t *c) const { - unsigned int l = (this+leftClassTable).get_class (left); - unsigned int r = (this+leftClassTable).get_class (left); - unsigned int offset = l * rowWidth + r * sizeof (FWORD); - const FWORD *arr = &(this+array); - if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end)) - return 0; - const FWORD *v = &StructAtOffset<FWORD> (arr, offset); - if (unlikely ((const void *) v < (const void *) arr || (const void *) (v + 1) > (const void *) end)) - return 0; + unsigned int num_glyphs = c->sanitizer.get_num_glyphs (); + unsigned int l = (this+leftClassTable).get_value_or_null (left, num_glyphs); + unsigned int r = (this+rightClassTable).get_value_or_null (right, num_glyphs); + unsigned int offset = l + r; + const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset); + if (unlikely (!v->sanitize (&c->sanitizer))) return 0; return *v; } + inline bool apply (hb_aat_apply_context_t *c) const + { + TRACE_APPLY (this); + + if (!c->plan->requested_kerning) + return false; + + accelerator_t accel (*this, c); + hb_kern_machine_t<accelerator_t> machine (accel); + machine.kern (c->font, c->buffer, c->plan->kern_mask); + + return_trace (true); + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && - rowWidth.sanitize (c) && + return_trace (likely (rowWidth.sanitize (c) && leftClassTable.sanitize (c, this) && rightClassTable.sanitize (c, this) && - array.sanitize (c, this))); + c->check_range (this, array))); } + struct accelerator_t + { + const KerxSubTableFormat2 &table; + hb_aat_apply_context_t *c; + + inline accelerator_t (const KerxSubTableFormat2 &table_, + hb_aat_apply_context_t *c_) : + table (table_), c (c_) {} + + inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const + { return table.get_kerning (left, right, c); } + }; + protected: - HBUINT32 rowWidth; /* The width, in bytes, of a row in the table. */ - LOffsetTo<KerxClassTable> - leftClassTable; /* Offset from beginning of this subtable to - * left-hand class table. */ - LOffsetTo<KerxClassTable> - rightClassTable;/* Offset from beginning of this subtable to - * right-hand class table. */ - LOffsetTo<FWORD> - array; /* Offset from beginning of this subtable to - * the start of the kerning array. */ + KerxSubTableHeader header; + HBUINT32 rowWidth; /* The width, in bytes, of a row in the table. */ + LOffsetTo<Lookup<HBUINT16>, false> + leftClassTable; /* Offset from beginning of this subtable to + * left-hand class table. */ + LOffsetTo<Lookup<HBUINT16>, false> + rightClassTable;/* Offset from beginning of this subtable to + * right-hand class table. */ + LOffsetTo<UnsizedArrayOf<FWORD>, false> + array; /* Offset from beginning of this subtable to + * the start of the kerning array. */ public: - DEFINE_SIZE_STATIC (16); + DEFINE_SIZE_STATIC (28); }; struct KerxSubTableFormat4 { + struct EntryData + { + HBUINT16 ankrActionIndex;/* Either 0xFFFF (for no action) or the index of + * the action to perform. */ + public: + DEFINE_SIZE_STATIC (2); + }; + + struct driver_context_t + { + static const bool in_place = true; + enum Flags + { + Mark = 0x8000, /* If set, remember this glyph as the marked glyph. */ + DontAdvance = 0x4000, /* If set, don't advance to the next glyph before + * going to the new state. */ + Reserved = 0x3FFF, /* Not used; set to 0. */ + }; + + enum SubTableFlags + { + ActionType = 0xC0000000, /* A two-bit field containing the action type. */ + Unused = 0x3F000000, /* Unused - must be zero. */ + Offset = 0x00FFFFFF, /* Masks the offset in bytes from the beginning + * of the subtable to the beginning of the control + * point table. */ + }; + + inline driver_context_t (const KerxSubTableFormat4 *table, + hb_aat_apply_context_t *c_) : + c (c_), + action_type ((table->flags & ActionType) >> 30), + ankrData ((HBUINT16 *) ((const char *) &table->machine + (table->flags & Offset))), + mark_set (false), + mark (0) {} + + inline bool is_actionable (StateTableDriver<EntryData> *driver, + const Entry<EntryData> *entry) + { + return entry->data.ankrActionIndex != 0xFFFF; + } + inline bool transition (StateTableDriver<EntryData> *driver, + const Entry<EntryData> *entry) + { + hb_buffer_t *buffer = driver->buffer; + unsigned int flags = entry->flags; + + if (mark_set && entry->data.ankrActionIndex != 0xFFFF && buffer->idx < buffer->len) + { + hb_glyph_position_t &o = buffer->cur_pos(); + switch (action_type) + { + case 0: /* Control Point Actions.*/ + { + /* indexed into glyph outline. */ + const HBUINT16 *data = &ankrData[entry->data.ankrActionIndex]; + if (!c->sanitizer.check_array (data, 2)) + return false; + HB_UNUSED unsigned int markControlPoint = *data++; + HB_UNUSED unsigned int currControlPoint = *data++; + hb_position_t markX = 0; + hb_position_t markY = 0; + hb_position_t currX = 0; + hb_position_t currY = 0; + if (!c->font->get_glyph_contour_point_for_origin (c->buffer->info[mark].codepoint, + markControlPoint, + HB_DIRECTION_LTR /*XXX*/, + &markX, &markY) || + !c->font->get_glyph_contour_point_for_origin (c->buffer->cur ().codepoint, + currControlPoint, + HB_DIRECTION_LTR /*XXX*/, + &currX, &currY)) + return true; /* True, such that the machine continues. */ + + o.x_offset = markX - currX; + o.y_offset = markY - currY; + } + break; + + case 1: /* Anchor Point Actions. */ + { + /* Indexed into 'ankr' table. */ + const HBUINT16 *data = &ankrData[entry->data.ankrActionIndex]; + if (!c->sanitizer.check_array (data, 2)) + return false; + unsigned int markAnchorPoint = *data++; + unsigned int currAnchorPoint = *data++; + const Anchor markAnchor = c->ankr_table.get_anchor (c->buffer->info[mark].codepoint, + markAnchorPoint, + c->sanitizer.get_num_glyphs (), + c->ankr_end); + const Anchor currAnchor = c->ankr_table.get_anchor (c->buffer->cur ().codepoint, + currAnchorPoint, + c->sanitizer.get_num_glyphs (), + c->ankr_end); + + o.x_offset = c->font->em_scale_x (markAnchor.xCoordinate) - c->font->em_scale_x (currAnchor.xCoordinate); + o.y_offset = c->font->em_scale_y (markAnchor.yCoordinate) - c->font->em_scale_y (currAnchor.yCoordinate); + } + break; + + case 2: /* Control Point Coordinate Actions. */ + { + const FWORD *data = (const FWORD *) &ankrData[entry->data.ankrActionIndex]; + if (!c->sanitizer.check_array (data, 4)) + return false; + int markX = *data++; + int markY = *data++; + int currX = *data++; + int currY = *data++; + + o.x_offset = c->font->em_scale_x (markX) - c->font->em_scale_x (currX); + o.y_offset = c->font->em_scale_y (markY) - c->font->em_scale_y (currY); + } + break; + } + o.attach_type() = ATTACH_TYPE_MARK; + o.attach_chain() = (int) mark - (int) buffer->idx; + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; + } + + if (flags & Mark) + { + mark_set = true; + mark = buffer->idx; + } + + return true; + } + + private: + hb_aat_apply_context_t *c; + unsigned int action_type; + const HBUINT16 *ankrData; + bool mark_set; + unsigned int mark; + }; + + inline bool apply (hb_aat_apply_context_t *c) const + { + TRACE_APPLY (this); + + driver_context_t dc (this, c); + + StateTableDriver<EntryData> driver (machine, c->buffer, c->font->face); + driver.drive (&dc); + + return_trace (true); + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); + /* The rest of array sanitizations are done at run-time. */ return_trace (likely (c->check_struct (this) && - rowWidth.sanitize (c) && - leftClassTable.sanitize (c, this) && - rightClassTable.sanitize (c, this) && - array.sanitize (c, this))); + machine.sanitize (c))); } protected: - HBUINT32 rowWidth; /* The width, in bytes, of a row in the table. */ - LOffsetTo<KerxClassTable> - leftClassTable; /* Offset from beginning of this subtable to - * left-hand class table. */ - LOffsetTo<KerxClassTable> - rightClassTable;/* Offset from beginning of this subtable to - * right-hand class table. */ - LOffsetTo<FWORD> - array; /* Offset from beginning of this subtable to - * the start of the kerning array. */ + KerxSubTableHeader header; + StateTable<EntryData> machine; + HBUINT32 flags; public: - DEFINE_SIZE_STATIC (16); + DEFINE_SIZE_STATIC (32); }; struct KerxSubTableFormat6 { + enum Flags + { + ValuesAreLong = 0x00000001, + }; + + inline bool is_long (void) const { return flags & ValuesAreLong; } + + inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, + hb_aat_apply_context_t *c) const + { + unsigned int num_glyphs = c->sanitizer.get_num_glyphs (); + if (is_long ()) + { + const U::Long &t = u.l; + unsigned int l = (this+t.rowIndexTable).get_value_or_null (left, num_glyphs); + unsigned int r = (this+t.columnIndexTable).get_value_or_null (right, num_glyphs); + unsigned int offset = l + r; + if (unlikely (offset < l)) return 0; /* Addition overflow. */ + if (unlikely (hb_unsigned_mul_overflows (offset, sizeof (FWORD32)))) return 0; + const FWORD32 *v = &StructAtOffset<FWORD32> (&(this+t.array), offset * sizeof (FWORD32)); + if (unlikely (!v->sanitize (&c->sanitizer))) return 0; + return *v; + } + else + { + const U::Short &t = u.s; + unsigned int l = (this+t.rowIndexTable).get_value_or_null (left, num_glyphs); + unsigned int r = (this+t.columnIndexTable).get_value_or_null (right, num_glyphs); + unsigned int offset = l + r; + const FWORD *v = &StructAtOffset<FWORD> (&(this+t.array), offset * sizeof (FWORD)); + if (unlikely (!v->sanitize (&c->sanitizer))) return 0; + return *v; + } + } + + inline bool apply (hb_aat_apply_context_t *c) const + { + TRACE_APPLY (this); + + if (!c->plan->requested_kerning) + return false; + + accelerator_t accel (*this, c); + hb_kern_machine_t<accelerator_t> machine (accel); + machine.kern (c->font, c->buffer, c->plan->kern_mask); + + return_trace (true); + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && - rowIndexTable.sanitize (c, this) && - columnIndexTable.sanitize (c, this) && - kerningArray.sanitize (c, this) && - kerningVector.sanitize (c, this))); + (is_long () ? + ( + u.l.rowIndexTable.sanitize (c, this) && + u.l.columnIndexTable.sanitize (c, this) && + c->check_range (this, u.l.array) + ) : ( + u.s.rowIndexTable.sanitize (c, this) && + u.s.columnIndexTable.sanitize (c, this) && + c->check_range (this, u.s.array) + )))); } + struct accelerator_t + { + const KerxSubTableFormat6 &table; + hb_aat_apply_context_t *c; + + inline accelerator_t (const KerxSubTableFormat6 &table_, + hb_aat_apply_context_t *c_) : + table (table_), c (c_) {} + + inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const + { return table.get_kerning (left, right, c); } + }; + protected: - HBUINT32 flags; - HBUINT16 rowCount; - HBUINT16 columnCount; - LOffsetTo<Lookup<HBUINT16> > rowIndexTable; - LOffsetTo<Lookup<HBUINT16> > columnIndexTable; - LOffsetTo<Lookup<HBUINT16> > kerningArray; - LOffsetTo<Lookup<HBUINT16> > kerningVector; + KerxSubTableHeader header; + HBUINT32 flags; + HBUINT16 rowCount; + HBUINT16 columnCount; + union U + { + struct Long + { + LOffsetTo<Lookup<HBUINT32>, false> rowIndexTable; + LOffsetTo<Lookup<HBUINT32>, false> columnIndexTable; + LOffsetTo<UnsizedArrayOf<FWORD32>, false> array; + } l; + struct Short + { + LOffsetTo<Lookup<HBUINT16>, false> rowIndexTable; + LOffsetTo<Lookup<HBUINT16>, false> columnIndexTable; + LOffsetTo<UnsizedArrayOf<FWORD>, false> array; + } s; + } u; public: - DEFINE_SIZE_STATIC (24); -}; - -enum coverage_flags_t -{ - COVERAGE_VERTICAL_FLAG = 0x80u, - COVERAGE_CROSSSTREAM_FLAG = 0x40u, - COVERAGE_VARIATION_FLAG = 0x20u, - COVERAGE_PROCESS_DIRECTION = 0x10u, + DEFINE_SIZE_STATIC (32); }; struct KerxTable { - inline bool apply (hb_aat_apply_context_t *c, const AAT::ankr *ankr) const + friend struct kerx; + + inline unsigned int get_size (void) const { return u.header.length; } + inline unsigned int get_type (void) const { return u.header.coverage & SubtableType; } + + enum Coverage { - TRACE_APPLY (this); - /* TODO */ - return_trace (false); + Vertical = 0x80000000, /* Set if table has vertical kerning values. */ + CrossStream = 0x40000000, /* Set if table has cross-stream kerning values. */ + Variation = 0x20000000, /* Set if table has variation kerning values. */ + Backwards = 0x10000000, /* If clear, process the glyphs forwards, that + * is, from first to last in the glyph stream. + * If we, process them from last to first. + * This flag only applies to state-table based + * 'kerx' subtables (types 1 and 4). */ + Reserved = 0x0FFFFF00, /* Reserved, set to zero. */ + SubtableType = 0x000000FF, /* Subtable type. */ + }; + + template <typename context_t> + inline typename context_t::return_t dispatch (context_t *c) const + { + unsigned int subtable_type = get_type (); + TRACE_DISPATCH (this, subtable_type); + switch (subtable_type) { + case 0 : return_trace (c->dispatch (u.format0)); + case 1 : return_trace (c->dispatch (u.format1)); + case 2 : return_trace (c->dispatch (u.format2)); + case 4 : return_trace (c->dispatch (u.format4)); + case 6 : return_trace (c->dispatch (u.format6)); + default: return_trace (c->default_return_value ()); + } } - inline unsigned int get_size (void) const { return length; } - inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (this))) + if (!u.header.sanitize (c) || + !c->check_range (this, u.header.length)) return_trace (false); - switch (format) { - case 0: return u.format0.sanitize (c); - case 1: return u.format1.sanitize (c); - case 2: return u.format2.sanitize (c); - case 4: return u.format4.sanitize (c); - case 6: return u.format6.sanitize (c); - default:return_trace (false); - } + return_trace (dispatch (c)); } protected: - HBUINT32 length; - HBUINT8 coverage; - HBUINT16 unused; - HBUINT8 format; - HBUINT32 tupleIndex; union { + KerxSubTableHeader header; KerxSubTableFormat0 format0; KerxSubTableFormat1 format1; KerxSubTableFormat2 format2; @@ -273,71 +622,91 @@ public: DEFINE_SIZE_MIN (12); }; -struct SubtableGlyphCoverageArray -{ - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); - } - protected: - HBUINT32 length; - HBUINT32 coverage; - HBUINT32 tupleCount; - public: - DEFINE_SIZE_STATIC (12); -}; +/* + * The 'kerx' Table + */ struct 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 + inline bool has_data (void) const { return version != 0; } + + inline void apply (hb_aat_apply_context_t *c) const { - TRACE_APPLY (this); - const KerxTable &table = StructAfter<KerxTable> (*this); - return_trace (table.apply (c, ankr)); + c->set_lookup_index (0); + const KerxTable *table = &firstTable; + unsigned int count = tableCount; + for (unsigned int i = 0; i < count; i++) + { + bool reverse; + + if (table->u.header.coverage & (KerxTable::CrossStream | KerxTable::Variation) || + table->u.header.tupleCount) + goto skip; /* We do NOT handle cross-stream or variation kerning. */ + + if (HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) != + bool (table->u.header.coverage & KerxTable::Vertical)) + goto skip; + + reverse = bool (table->u.header.coverage & KerxTable::Backwards) != + HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction); + + if (!c->buffer->message (c->font, "start kerx subtable %d", c->lookup_index)) + goto skip; + + if (reverse) + c->buffer->reverse (); + + c->sanitizer.set_object (*table); + + /* XXX Reverse-kern is not working yet... + * hb_kern_machine_t would need to know that it's reverse-kerning. + * Or better yet, make it work in reverse as well, so we don't have + * to reverse and reverse back? */ + table->dispatch (c); + + if (reverse) + c->buffer->reverse (); + + (void) c->buffer->message (c->font, "end kerx subtable %d", c->lookup_index); + + skip: + table = &StructAfter<KerxTable> (*table); + } } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (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 (unlikely (!(table->sanitize (c)))) + if (!version.sanitize (c) || version < 2 || + !tableCount.sanitize (c)) return_trace (false); - for (unsigned int i = 0; i < nTables - 1; ++i) + const KerxTable *table = &firstTable; + unsigned int count = tableCount; + for (unsigned int i = 0; i < count; i++) { + if (!table->sanitize (c)) + return_trace (false); table = &StructAfter<KerxTable> (*table); - if (unlikely (!(table->sanitize (c)))) - return_trace (false); } - // If version is less than 3, we are done here; otherwise better to check footer also - if (version < 3) - return_trace (true); - - // TODO: Investigate why this just work on some fonts no matter of version - // const SubtableGlyphCoverageArray &footer = - // StructAfter<SubtableGlyphCoverageArray> (*table); - // return_trace (footer.sanitize (c)); - return_trace (true); } protected: - HBUINT16 version; - HBUINT16 padding; - HBUINT32 nTables; -/*KerxTable tablesZ[VAR]; XXX ArrayOf??? */ -/*SubtableGlyphCoverageArray coverage_array;*/ + HBUINT16 version; /* The version number of the extended kerning table + * (currently 2, 3, or 4). */ + HBUINT16 unused; /* Set to 0. */ + HBUINT32 tableCount; /* The number of subtables included in the extended kerning + * table. */ + KerxTable firstTable; /* Subtables. */ +/*subtableGlyphCoverageArray*/ /* Only if version >= 3. We don't use. */ + public: - DEFINE_SIZE_STATIC (8); + DEFINE_SIZE_MIN (8); }; } /* namespace AAT */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh index ef452e22b29..651af2188fd 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh @@ -50,7 +50,8 @@ struct RearrangementSubtable struct driver_context_t { static const bool in_place = true; - enum Flags { + enum Flags + { MarkFirst = 0x8000, /* If set, make the current glyph the first * glyph to be rearranged. */ DontAdvance = 0x4000, /* If set, don't advance to the next glyph @@ -163,7 +164,7 @@ struct RearrangementSubtable driver_context_t dc (this); - StateTableDriver<void> driver (machine, c->buffer, c->face); + StateTableDriver<EntryData> driver (machine, c->buffer, c->face); driver.drive (&dc); return_trace (dc.ret); @@ -196,7 +197,8 @@ struct ContextualSubtable struct driver_context_t { static const bool in_place = true; - enum Flags { + enum Flags + { SetMark = 0x8000, /* If set, make the current glyph the marked glyph. */ DontAdvance = 0x4000, /* If set, don't advance to the next glyph before * going to the new state. */ @@ -268,7 +270,7 @@ struct ContextualSubtable private: bool mark_set; unsigned int mark; - const UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT32> &subs; + const UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT32, false> &subs; }; inline bool apply (hb_aat_apply_context_t *c) const @@ -309,7 +311,7 @@ struct ContextualSubtable protected: StateTable<EntryData> machine; - LOffsetTo<UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT32> > + LOffsetTo<UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT32, false>, false> substitutionTables; public: DEFINE_SIZE_STATIC (20); @@ -329,7 +331,8 @@ struct LigatureSubtable struct driver_context_t { static const bool in_place = false; - enum Flags { + enum Flags + { SetComponent = 0x8000, /* Push this glyph onto the component stack for * eventual processing. */ DontAdvance = 0x4000, /* Leave the glyph pointer at this glyph for the @@ -338,7 +341,8 @@ struct LigatureSubtable * group. */ Reserved = 0x1FFF, /* These bits are reserved and should be set to 0. */ }; - enum LigActionFlags { + enum LigActionFlags + { LigActionLast = 0x80000000, /* This is the last action in the list. This also * implies storage. */ LigActionStore = 0x40000000, /* Store the ligature at the current cumulated index @@ -361,7 +365,7 @@ struct LigatureSubtable inline bool is_actionable (StateTableDriver<EntryData> *driver, const Entry<EntryData> *entry) { - return !!(entry->flags & PerformAction); + return entry->flags & PerformAction; } inline bool transition (StateTableDriver<EntryData> *driver, const Entry<EntryData> *entry) @@ -387,12 +391,20 @@ struct LigatureSubtable unsigned int action_idx = entry->data.ligActionIndex; unsigned int action; unsigned int ligature_idx = 0; + + if (unlikely (!match_length)) + return true; + + /* TODO Only when ligation happens? */ + buffer->merge_out_clusters (match_positions[0], buffer->out_len); + + unsigned int cursor = match_length; do { - if (unlikely (!match_length)) - return false; + if (unlikely (!cursor)) + break; - buffer->move_to (match_positions[--match_length]); + buffer->move_to (match_positions[--cursor]); const HBUINT32 &actionData = ligAction[action_idx]; if (unlikely (!actionData.sanitize (&c->sanitizer))) return false; @@ -400,8 +412,10 @@ struct LigatureSubtable uint32_t uoffset = action & LigActionOffset; if (uoffset & 0x20000000) - uoffset += 0xC0000000; + uoffset |= 0xC0000000; /* Sign-extend. */ int32_t offset = (int32_t) uoffset; + if (buffer->idx >= buffer->len) + return false; // TODO Work on previous instead? unsigned int component_idx = buffer->cur().codepoint + offset; const HBUINT16 &componentData = component[component_idx]; @@ -414,21 +428,21 @@ struct LigatureSubtable if (unlikely (!ligatureData.sanitize (&c->sanitizer))) return false; hb_codepoint_t lig = ligatureData; - match_positions[match_length++] = buffer->out_len; buffer->replace_glyph (lig); - //ligature_idx = 0; // XXX Yes or no? - } - else - { - buffer->skip_glyph (); - end--; + /* Now go and delete all subsequent components. */ + while (match_length - 1 > cursor) + { + buffer->move_to (match_positions[--match_length]); + buffer->skip_glyph (); + end--; + } } - /* TODO merge_clusters / unsafe_to_break */ action_idx++; } while (!(action & LigActionLast)); + match_length = 0; buffer->move_to (end); } @@ -469,11 +483,11 @@ struct LigatureSubtable protected: StateTable<EntryData> machine; - LOffsetTo<UnsizedArrayOf<HBUINT32> > + LOffsetTo<UnsizedArrayOf<HBUINT32>, false> ligAction; /* Offset to the ligature action table. */ - LOffsetTo<UnsizedArrayOf<HBUINT16> > + LOffsetTo<UnsizedArrayOf<HBUINT16>, false> component; /* Offset to the component table. */ - LOffsetTo<UnsizedArrayOf<GlyphID> > + LOffsetTo<UnsizedArrayOf<GlyphID>, false> ligature; /* Offset to the actual ligature lists. */ public: DEFINE_SIZE_STATIC (28); @@ -517,19 +531,201 @@ struct NoncontextualSubtable struct InsertionSubtable { + struct EntryData + { + HBUINT16 currentInsertIndex; /* Zero-based index into the insertion glyph table. + * The number of glyphs to be inserted is contained + * in the currentInsertCount field in the flags. + * A value of 0xFFFF indicates no insertion is to + * be done. */ + HBUINT16 markedInsertIndex; /* Zero-based index into the insertion glyph table. + * The number of glyphs to be inserted is contained + * in the markedInsertCount field in the flags. + * A value of 0xFFFF indicates no insertion is to + * be done. */ + public: + DEFINE_SIZE_STATIC (4); + }; + + struct driver_context_t + { + static const bool in_place = false; + enum Flags + { + SetMark = 0x8000, /* If set, mark the current glyph. */ + DontAdvance = 0x4000, /* If set, don't advance to the next glyph before + * going to the new state. This does not mean + * that the glyph pointed to is the same one as + * before. If you've made insertions immediately + * downstream of the current glyph, the next glyph + * processed would in fact be the first one + * inserted. */ + CurrentIsKashidaLike= 0x2000, /* If set, and the currentInsertList is nonzero, + * then the specified glyph list will be inserted + * as a kashida-like insertion, either before or + * after the current glyph (depending on the state + * of the currentInsertBefore flag). If clear, and + * the currentInsertList is nonzero, then the + * specified glyph list will be inserted as a + * split-vowel-like insertion, either before or + * after the current glyph (depending on the state + * of the currentInsertBefore flag). */ + MarkedIsKashidaLike= 0x1000, /* If set, and the markedInsertList is nonzero, + * then the specified glyph list will be inserted + * as a kashida-like insertion, either before or + * after the marked glyph (depending on the state + * of the markedInsertBefore flag). If clear, and + * the markedInsertList is nonzero, then the + * specified glyph list will be inserted as a + * split-vowel-like insertion, either before or + * after the marked glyph (depending on the state + * of the markedInsertBefore flag). */ + CurrentInsertBefore= 0x0800, /* If set, specifies that insertions are to be made + * to the left of the current glyph. If clear, + * they're made to the right of the current glyph. */ + MarkedInsertBefore= 0x0400, /* If set, specifies that insertions are to be + * made to the left of the marked glyph. If clear, + * they're made to the right of the marked glyph. */ + CurrentInsertCount= 0x3E0, /* This 5-bit field is treated as a count of the + * number of glyphs to insert at the current + * position. Since zero means no insertions, the + * largest number of insertions at any given + * current location is 31 glyphs. */ + MarkedInsertCount= 0x001F, /* This 5-bit field is treated as a count of the + * number of glyphs to insert at the marked + * position. Since zero means no insertions, the + * largest number of insertions at any given + * marked location is 31 glyphs. */ + }; + + inline driver_context_t (const InsertionSubtable *table, + hb_aat_apply_context_t *c_) : + ret (false), + c (c_), + mark_set (false), + mark (0), + insertionAction (table+table->insertionAction) {} + + inline bool is_actionable (StateTableDriver<EntryData> *driver, + const Entry<EntryData> *entry) + { + return (entry->flags & (CurrentInsertCount | MarkedInsertCount)) && + (entry->data.currentInsertIndex != 0xFFFF ||entry->data.markedInsertIndex != 0xFFFF); + } + inline bool transition (StateTableDriver<EntryData> *driver, + const Entry<EntryData> *entry) + { + hb_buffer_t *buffer = driver->buffer; + unsigned int flags = entry->flags; + + if (entry->data.markedInsertIndex != 0xFFFF && mark_set) + { + unsigned int count = (flags & MarkedInsertCount); + unsigned int start = entry->data.markedInsertIndex; + const GlyphID *glyphs = &insertionAction[start]; + if (unlikely (!c->sanitizer.check_array (glyphs, count))) return false; + + bool before = flags & MarkedInsertBefore; + + unsigned int end = buffer->out_len; + buffer->move_to (mark); + + if (buffer->idx < buffer->len && !before) + buffer->copy_glyph (); + /* TODO We ignore KashidaLike setting. */ + for (unsigned int i = 0; i < count; i++) + buffer->output_glyph (glyphs[i]); + if (buffer->idx < buffer->len && !before) + buffer->skip_glyph (); + + buffer->move_to (end + count); + + buffer->unsafe_to_break_from_outbuffer (mark, MIN (buffer->idx + 1, buffer->len)); + } + + if (entry->data.currentInsertIndex != 0xFFFF) + { + unsigned int count = (flags & CurrentInsertCount) >> 5; + unsigned int start = entry->data.currentInsertIndex; + const GlyphID *glyphs = &insertionAction[start]; + if (unlikely (!c->sanitizer.check_array (glyphs, count))) return false; + + bool before = flags & CurrentInsertBefore; + + unsigned int end = buffer->out_len; + + if (buffer->idx < buffer->len && !before) + buffer->copy_glyph (); + /* TODO We ignore KashidaLike setting. */ + for (unsigned int i = 0; i < count; i++) + buffer->output_glyph (glyphs[i]); + if (buffer->idx < buffer->len && !before) + buffer->skip_glyph (); + + /* Humm. Not sure where to move to. There's this wording under + * DontAdvance flag: + * + * "If set, don't update the glyph index before going to the new state. + * This does not mean that the glyph pointed to is the same one as + * before. If you've made insertions immediately downstream of the + * current glyph, the next glyph processed would in fact be the first + * one inserted." + * + * This suggests that if DontAdvance is NOT set, we should move to + * end+count. If it *was*, then move to end, such that newly inserted + * glyphs are now visible. + * + * https://github.com/harfbuzz/harfbuzz/issues/1224#issuecomment-427691417 + */ + buffer->move_to ((flags & DontAdvance) ? end : end + count); + } + + if (flags & SetMark) + { + mark_set = true; + mark = buffer->out_len; + } + + return true; + } + + public: + bool ret; + private: + hb_aat_apply_context_t *c; + bool mark_set; + unsigned int mark; + const UnsizedArrayOf<GlyphID> &insertionAction; + }; + inline bool apply (hb_aat_apply_context_t *c) const { TRACE_APPLY (this); - /* TODO */ - return_trace (false); + + driver_context_t dc (this, c); + + StateTableDriver<EntryData> driver (machine, c->buffer, c->face); + driver.drive (&dc); + + return_trace (dc.ret); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - /* TODO */ - return_trace (true); + /* The rest of array sanitizations are done at run-time. */ + return_trace (c->check_struct (this) && machine.sanitize (c) && + insertionAction); } + + protected: + StateTable<EntryData> + machine; + LOffsetTo<UnsizedArrayOf<GlyphID>, false> + insertionAction; /* Byte offset from stateHeader to the start of + * the insertion glyph table. */ + public: + DEFINE_SIZE_STATIC (20); }; @@ -559,9 +755,27 @@ struct ChainSubtable friend struct Chain; inline unsigned int get_size (void) const { return length; } - inline unsigned int get_type (void) const { return coverage & 0xFF; } + inline unsigned int get_type (void) const { return coverage & SubtableType; } - enum Type { + enum Coverage + { + Vertical = 0x80000000, /* If set, this subtable will only be applied + * to vertical text. If clear, this subtable + * will only be applied to horizontal text. */ + Backwards = 0x40000000, /* If set, this subtable will process glyphs + * in descending order. If clear, it will + * process the glyphs in ascending order. */ + AllDirections = 0x20000000, /* If set, this subtable will be applied to + * both horizontal and vertical text (i.e. + * the state of bit 0x80000000 is ignored). */ + Logical = 0x10000000, /* If set, this subtable will process glyphs + * in logical order (or reverse logical order, + * depending on the value of bit 0x80000000). */ + Reserved = 0x0FFFFF00, /* Reserved, set to zero. */ + SubtableType = 0x000000FF, /* Subtable type; see following table. */ + }; + enum Type + { Rearrangement = 0, Contextual = 1, Ligature = 2, @@ -569,11 +783,6 @@ struct ChainSubtable Insertion = 5 }; - inline void apply (hb_aat_apply_context_t *c) const - { - dispatch (c); - } - template <typename context_t> inline typename context_t::return_t dispatch (context_t *c) const { @@ -619,28 +828,94 @@ struct Chain { inline void apply (hb_aat_apply_context_t *c) const { - const ChainSubtable *subtable = &StructAtOffset<ChainSubtable> (featureZ, featureZ[0].static_size * featureCount); + uint32_t flags = defaultFlags; + { + /* Compute applicable flags. TODO Should move this to planning + * stage and take user-requested features into account. */ + unsigned int count = featureCount; + for (unsigned i = 0; i < count; i++) + { + const Feature &feature = featureZ[i]; + if (false) /* XXX Check if feature enabled... */ + { + flags &= feature.disableFlags; + flags |= feature.enableFlags; + } + } + } + + const ChainSubtable *subtable = &StructAtOffset<ChainSubtable> (&featureZ, featureZ[0].static_size * featureCount); unsigned int count = subtableCount; for (unsigned int i = 0; i < count; i++) { + bool reverse; + + if (!(subtable->subFeatureFlags & flags)) + goto skip; + + if (!(subtable->coverage & ChainSubtable::AllDirections) && + HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) != + bool (subtable->coverage & ChainSubtable::Vertical)) + goto skip; + + /* Buffer contents is always in logical direction. Determine if + * we need to reverse before applying this subtable. We reverse + * back after if we did reverse indeed. + * + * Quoting the spac: + * """ + * Bits 28 and 30 of the coverage field control the order in which + * glyphs are processed when the subtable is run by the layout engine. + * Bit 28 is used to indicate if the glyph processing direction is + * the same as logical order or layout order. Bit 30 is used to + * indicate whether glyphs are processed forwards or backwards within + * that order. + + Bit 30 Bit 28 Interpretation for Horizontal Text + 0 0 The subtable is processed in layout order + (the same order as the glyphs, which is + always left-to-right). + 1 0 The subtable is processed in reverse layout order + (the order opposite that of the glyphs, which is + always right-to-left). + 0 1 The subtable is processed in logical order + (the same order as the characters, which may be + left-to-right or right-to-left). + 1 1 The subtable is processed in reverse logical order + (the order opposite that of the characters, which + may be right-to-left or left-to-right). + */ + reverse = subtable->coverage & ChainSubtable::Logical ? + bool (subtable->coverage & ChainSubtable::Backwards) : + bool (subtable->coverage & ChainSubtable::Backwards) != + HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction); + if (!c->buffer->message (c->font, "start chain subtable %d", c->lookup_index)) - { - c->set_lookup_index (c->lookup_index + 1); - continue; - } + goto skip; - subtable->apply (c); - subtable = &StructAfter<ChainSubtable> (*subtable); + if (reverse) + c->buffer->reverse (); + + c->sanitizer.set_object (*subtable); + + subtable->dispatch (c); + + if (reverse) + c->buffer->reverse (); (void) c->buffer->message (c->font, "end chain subtable %d", c->lookup_index); + if (unlikely (!c->buffer->successful)) return; + + skip: + subtable = &StructAfter<ChainSubtable> (*subtable); c->set_lookup_index (c->lookup_index + 1); } } inline unsigned int get_size (void) const { return length; } - inline bool sanitize (hb_sanitize_context_t *c, unsigned int major) const + inline bool sanitize (hb_sanitize_context_t *c, unsigned int version) const { TRACE_SANITIZE (this); if (!length.sanitize (c) || @@ -648,10 +923,10 @@ struct Chain !c->check_range (this, length)) return_trace (false); - if (!c->check_array (featureZ, featureZ[0].static_size, featureCount)) + if (!c->check_array (featureZ.arrayZ, featureCount)) return_trace (false); - const ChainSubtable *subtable = &StructAtOffset<ChainSubtable> (featureZ, featureZ[0].static_size * featureCount); + const ChainSubtable *subtable = &StructAtOffset<ChainSubtable> (&featureZ, featureZ[0].static_size * featureCount); unsigned int count = subtableCount; for (unsigned int i = 0; i < count; i++) { @@ -669,9 +944,9 @@ struct Chain HBUINT32 featureCount; /* Number of feature subtable entries. */ HBUINT32 subtableCount; /* The number of subtables in the chain. */ - Feature featureZ[VAR]; /* Features. */ -/*ChainSubtable subtableX[VAR];*//* Subtables. */ -/*subtableGlyphCoverageArray*/ /* Only if major == 3. */ + UnsizedArrayOf<Feature> featureZ; /* Features. */ +/*ChainSubtable firstSubtable;*//* Subtables. */ +/*subtableGlyphCoverageArray*/ /* Only if version >= 3. We don't use. */ public: DEFINE_SIZE_MIN (16); @@ -679,21 +954,25 @@ struct Chain /* - * The 'mort'/'morx' Tables + * The 'morx' Table */ struct morx { static const hb_tag_t tableTag = HB_AAT_TAG_morx; + inline bool has_data (void) const { return version != 0; } + inline void apply (hb_aat_apply_context_t *c) const { + if (unlikely (!c->buffer->successful)) return; c->set_lookup_index (0); - const Chain *chain = chainsZ; + const Chain *chain = &firstChain; unsigned int count = chainCount; for (unsigned int i = 0; i < count; i++) { chain->apply (c); + if (unlikely (!c->buffer->successful)) return; chain = &StructAfter<Chain> (*chain); } } @@ -701,16 +980,15 @@ struct morx inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!version.sanitize (c) || - (version.major >> (sizeof (HBUINT32) == 4 ? 1 : 0)) != 1 || + if (!version.sanitize (c) || version < 2 || !chainCount.sanitize (c)) return_trace (false); - const Chain *chain = chainsZ; + const Chain *chain = &firstChain; unsigned int count = chainCount; for (unsigned int i = 0; i < count; i++) { - if (!chain->sanitize (c, version.major)) + if (!chain->sanitize (c, version)) return_trace (false); chain = &StructAfter<Chain> (*chain); } @@ -719,11 +997,12 @@ struct morx } protected: - FixedVersion<>version; /* Version number of the glyph metamorphosis table. - * 1 for mort, 2 or 3 for morx. */ + HBUINT16 version; /* Version number of the glyph metamorphosis table. + * 2 or 3. */ + HBUINT16 unused; /* Set to 0. */ HBUINT32 chainCount; /* Number of metamorphosis chains contained in this * table. */ - Chain chainsZ[VAR]; /* Chains. */ + Chain firstChain; /* Chains. */ public: DEFINE_SIZE_MIN (8); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh index c4bec2cab64..4b4bc2ffeee 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh @@ -46,29 +46,33 @@ struct TrackTableEntry { friend struct TrackData; - inline bool sanitize (hb_sanitize_context_t *c, const void *base, - unsigned int size) const + inline float get_track_value () const { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && - (valuesZ.sanitize (c, base, size)))); + return track.to_float (); } - private: - inline float get_track_value () const + inline int get_value (const void *base, + unsigned int index, + unsigned int nSizes) const { - return track.to_float (); + return hb_array_t<FWORD> ((base+valuesZ).arrayZ, nSizes)[index]; } - inline int get_value (const void *base, unsigned int index) const + public: + inline bool sanitize (hb_sanitize_context_t *c, const void *base, + unsigned int nSizes) const { - return (base+valuesZ)[index]; + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + (valuesZ.sanitize (c, base, nSizes)))); } protected: Fixed track; /* Track value for this record. */ - NameID trackNameID; /* The 'name' table index for this track */ - OffsetTo<UnsizedArrayOf<FWORD> > + NameID trackNameID; /* The 'name' table index for this track. + * (a short word or phrase like "loose" + * or "very tight") */ + OffsetTo<UnsizedArrayOf<FWORD>, HBUINT16, false> valuesZ; /* Offset from start of tracking table to * per-size tracking values for this track. */ @@ -78,15 +82,22 @@ struct TrackTableEntry struct TrackData { - inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + inline float interpolate_at (unsigned int idx, + float target_size, + const TrackTableEntry &trackTableEntry, + const void *base) const { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - sizeTable.sanitize (c, base, nSizes) && - trackTable.sanitize (c, nTracks, base, nSizes)); + unsigned int sizes = nSizes; + hb_array_t<Fixed> size_table ((base+sizeTable).arrayZ, sizes); + + float s0 = size_table[idx].to_float (); + float s1 = size_table[idx + 1].to_float (); + float t = unlikely (s0 == s1) ? 0.f : (target_size - s0) / (s1 - s0); + return t * trackTableEntry.get_value (base, idx + 1, sizes) + + (1.f - t) * trackTableEntry.get_value (base, idx, sizes); } - inline float get_tracking (const void *base, float ptem) const + inline int get_tracking (const void *base, float ptem) const { /* CoreText points are CSS pixels (96 per inch), * NOT typographic points (72 per inch). @@ -94,48 +105,59 @@ struct TrackData * https://developer.apple.com/library/content/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html */ float csspx = ptem * 96.f / 72.f; - Fixed fixed_size; - fixed_size.set_float (csspx); - /* XXX Clean this up. Make it work with nSizes==1 and 0. */ + /* + * Choose track. + */ + const TrackTableEntry *trackTableEntry = nullptr; + unsigned int count = nTracks; + for (unsigned int i = 0; i < count; i++) + { + /* Note: Seems like the track entries are sorted by values. But the + * spec doesn't explicitly say that. It just mentions it in the example. */ - unsigned int sizes = nSizes; + /* For now we only seek for track entries with zero tracking value */ - 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.f) - trackTableEntry = &trackTable[0]; - - // We couldn't match any, exit + { + trackTableEntry = &trackTable[i]; + break; + } + } if (!trackTableEntry) return 0.; + /* + * Choose size. + */ + unsigned int sizes = nSizes; + if (!sizes) return 0.; + if (sizes == 1) return trackTableEntry->get_value (base, 0, sizes); + /* TODO bfind() */ + hb_array_t<Fixed> size_table ((base+sizeTable).arrayZ, sizes); unsigned int size_index; - UnsizedArrayOf<Fixed> size_table = base+sizeTable; - for (size_index = 0; size_index < sizes; ++size_index) - if (size_table[size_index] >= fixed_size) + for (size_index = 0; size_index < sizes; size_index++) + if (size_table[size_index].to_float () >= csspx) break; - // TODO(ebraminio): We don't attempt to extrapolate to larger or - // smaller values for now but we should do, per spec - if (size_index == sizes) - return trackTableEntry->get_value (base, sizes - 1); - if (size_index == 0 || size_table[size_index] == fixed_size) - return trackTableEntry->get_value (base, size_index); - - float s0 = size_table[size_index - 1].to_float (); - float s1 = size_table[size_index].to_float (); - float t = (csspx - s0) / (s1 - s0); - return (float) t * trackTableEntry->get_value (base, size_index) + - ((float) 1.0 - t) * trackTableEntry->get_value (base, size_index - 1); + return round (interpolate_at (size_index ? size_index - 1 : 0, csspx, + *trackTableEntry, base)); + } + + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + sizeTable.sanitize (c, base, nSizes) && + trackTable.sanitize (c, nTracks, base, nSizes)); } protected: 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. */ + LOffsetTo<UnsizedArrayOf<Fixed>, false> + sizeTable; /* Offset from start of the tracking table to + * Array[nSizes] of size values.. */ UnsizedArrayOf<TrackTableEntry> trackTable; /* Array[nTracks] of TrackTableEntry records. */ @@ -147,6 +169,8 @@ struct trak { static const hb_tag_t tableTag = HB_AAT_TAG_trak; + inline bool has_data (void) const { return version.to_int () != 0; } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -168,25 +192,25 @@ struct trak if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) { const TrackData &trackData = this+horizData; - float tracking = trackData.get_tracking (this, ptem); - hb_position_t advance_to_add = c->font->em_scalef_x (tracking / 2); + int tracking = trackData.get_tracking (this, ptem); + hb_position_t offset_to_add = c->font->em_scalef_x (tracking / 2); + hb_position_t advance_to_add = c->font->em_scalef_x (tracking); foreach_grapheme (buffer, start, end) { - buffer->pos[start].x_offset += advance_to_add; buffer->pos[start].x_advance += advance_to_add; - buffer->pos[end].x_advance += advance_to_add; + buffer->pos[start].x_offset += offset_to_add; } } else { const TrackData &trackData = this+vertData; - float tracking = trackData.get_tracking (this, ptem); - hb_position_t advance_to_add = c->font->em_scalef_y (tracking / 2); + int tracking = trackData.get_tracking (this, ptem); + hb_position_t offset_to_add = c->font->em_scalef_y (tracking / 2); + hb_position_t advance_to_add = c->font->em_scalef_y (tracking); foreach_grapheme (buffer, start, end) { - buffer->pos[start].y_offset += advance_to_add; buffer->pos[start].y_advance += advance_to_add; - buffer->pos[end].y_advance += advance_to_add; + buffer->pos[start].y_offset += offset_to_add; } } @@ -194,15 +218,17 @@ struct trak } protected: - FixedVersion<> version; /* Version of the tracking table--currently - * 0x00010000u for version 1.0. */ - HBUINT16 format; /* Format of the tracking table */ - OffsetTo<TrackData> horizData; /* TrackData for horizontal text */ - OffsetTo<TrackData> vertData; /* TrackData for vertical text */ + FixedVersion<> version; /* Version of the tracking table + * (0x00010000u for version 1.0). */ + HBUINT16 format; /* Format of the tracking table (set to 0). */ + OffsetTo<TrackData> horizData; /* Offset from start of tracking table to TrackData + * for horizontal text (or 0 if none). */ + OffsetTo<TrackData> vertData; /* Offset from start of tracking table to TrackData + * for vertical text (or 0 if none). */ HBUINT16 reserved; /* Reserved. Set to 0. */ public: - DEFINE_SIZE_MIN (12); + DEFINE_SIZE_STATIC (12); }; } /* namespace AAT */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc index a5e36a40a38..e9da850b390 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc @@ -36,8 +36,101 @@ #include "hb-aat-layout-trak-table.hh" #include "hb-aat-ltag-table.hh" // Just so we compile it; unused otherwise. + +/* Table data courtesy of Apple. Converted from mnemonics to integers + * when moving to this file. */ +static const hb_aat_feature_mapping_t feature_mappings[] = +{ + {HB_TAG ('c','2','p','c'), 38/*kUpperCaseType*/, 2/*kUpperCasePetiteCapsSelector*/, 0/*kDefaultUpperCaseSelector*/}, + {HB_TAG ('c','2','s','c'), 38/*kUpperCaseType*/, 1/*kUpperCaseSmallCapsSelector*/, 0/*kDefaultUpperCaseSelector*/}, + {HB_TAG ('c','a','l','t'), 36/*kContextualAlternatesType*/, 0/*kContextualAlternatesOnSelector*/, 1/*kContextualAlternatesOffSelector*/}, + {HB_TAG ('c','a','s','e'), 33/*kCaseSensitiveLayoutType*/, 0/*kCaseSensitiveLayoutOnSelector*/, 1/*kCaseSensitiveLayoutOffSelector*/}, + {HB_TAG ('c','l','i','g'), 1/*kLigaturesType*/, 18/*kContextualLigaturesOnSelector*/, 19/*kContextualLigaturesOffSelector*/}, + {HB_TAG ('c','p','s','p'), 33/*kCaseSensitiveLayoutType*/, 2/*kCaseSensitiveSpacingOnSelector*/, 3/*kCaseSensitiveSpacingOffSelector*/}, + {HB_TAG ('c','s','w','h'), 36/*kContextualAlternatesType*/, 4/*kContextualSwashAlternatesOnSelector*/, 5/*kContextualSwashAlternatesOffSelector*/}, + {HB_TAG ('d','l','i','g'), 1/*kLigaturesType*/, 4/*kRareLigaturesOnSelector*/, 5/*kRareLigaturesOffSelector*/}, + {HB_TAG ('e','x','p','t'), 20/*kCharacterShapeType*/, 10/*kExpertCharactersSelector*/, 16}, + {HB_TAG ('f','r','a','c'), 11/*kFractionsType*/, 2/*kDiagonalFractionsSelector*/, 0/*kNoFractionsSelector*/}, + {HB_TAG ('f','w','i','d'), 22/*kTextSpacingType*/, 1/*kMonospacedTextSelector*/, 7}, + {HB_TAG ('h','a','l','t'), 22/*kTextSpacingType*/, 6/*kAltHalfWidthTextSelector*/, 7}, + {HB_TAG ('h','i','s','t'), 1/*kLigaturesType*/, 20/*kHistoricalLigaturesOnSelector*/, 21/*kHistoricalLigaturesOffSelector*/}, + {HB_TAG ('h','k','n','a'), 34/*kAlternateKanaType*/, 0/*kAlternateHorizKanaOnSelector*/, 1/*kAlternateHorizKanaOffSelector*/, }, + {HB_TAG ('h','l','i','g'), 1/*kLigaturesType*/, 20/*kHistoricalLigaturesOnSelector*/, 21/*kHistoricalLigaturesOffSelector*/}, + {HB_TAG ('h','n','g','l'), 23/*kTransliterationType*/, 1/*kHanjaToHangulSelector*/, 0/*kNoTransliterationSelector*/}, + {HB_TAG ('h','o','j','o'), 20/*kCharacterShapeType*/, 12/*kHojoCharactersSelector*/, 16}, + {HB_TAG ('h','w','i','d'), 22/*kTextSpacingType*/, 2/*kHalfWidthTextSelector*/, 7}, + {HB_TAG ('i','t','a','l'), 32/*kItalicCJKRomanType*/, 2/*kCJKItalicRomanOnSelector*/, 3/*kCJKItalicRomanOffSelector*/}, + {HB_TAG ('j','p','0','4'), 20/*kCharacterShapeType*/, 11/*kJIS2004CharactersSelector*/, 16}, + {HB_TAG ('j','p','7','8'), 20/*kCharacterShapeType*/, 2/*kJIS1978CharactersSelector*/, 16}, + {HB_TAG ('j','p','8','3'), 20/*kCharacterShapeType*/, 3/*kJIS1983CharactersSelector*/, 16}, + {HB_TAG ('j','p','9','0'), 20/*kCharacterShapeType*/, 4/*kJIS1990CharactersSelector*/, 16}, + {HB_TAG ('l','i','g','a'), 1/*kLigaturesType*/, 2/*kCommonLigaturesOnSelector*/, 3/*kCommonLigaturesOffSelector*/}, + {HB_TAG ('l','n','u','m'), 21/*kNumberCaseType*/, 1/*kUpperCaseNumbersSelector*/, 2}, + {HB_TAG ('m','g','r','k'), 15/*kMathematicalExtrasType*/, 10/*kMathematicalGreekOnSelector*/, 11/*kMathematicalGreekOffSelector*/}, + {HB_TAG ('n','l','c','k'), 20/*kCharacterShapeType*/, 13/*kNLCCharactersSelector*/, 16}, + {HB_TAG ('o','n','u','m'), 21/*kNumberCaseType*/, 0/*kLowerCaseNumbersSelector*/, 2}, + {HB_TAG ('o','r','d','n'), 10/*kVerticalPositionType*/, 3/*kOrdinalsSelector*/, 0/*kNormalPositionSelector*/}, + {HB_TAG ('p','a','l','t'), 22/*kTextSpacingType*/, 5/*kAltProportionalTextSelector*/, 7}, + {HB_TAG ('p','c','a','p'), 37/*kLowerCaseType*/, 2/*kLowerCasePetiteCapsSelector*/, 0/*kDefaultLowerCaseSelector*/}, + {HB_TAG ('p','k','n','a'), 22/*kTextSpacingType*/, 0/*kProportionalTextSelector*/, 7}, + {HB_TAG ('p','n','u','m'), 6/*kNumberSpacingType*/, 1/*kProportionalNumbersSelector*/, 4}, + {HB_TAG ('p','w','i','d'), 22/*kTextSpacingType*/, 0/*kProportionalTextSelector*/, 7}, + {HB_TAG ('q','w','i','d'), 22/*kTextSpacingType*/, 4/*kQuarterWidthTextSelector*/, 7}, + {HB_TAG ('r','u','b','y'), 28/*kRubyKanaType*/, 2/*kRubyKanaOnSelector*/, 3/*kRubyKanaOffSelector*/}, + {HB_TAG ('s','i','n','f'), 10/*kVerticalPositionType*/, 4/*kScientificInferiorsSelector*/, 0/*kNormalPositionSelector*/}, + {HB_TAG ('s','m','c','p'), 37/*kLowerCaseType*/, 1/*kLowerCaseSmallCapsSelector*/, 0/*kDefaultLowerCaseSelector*/}, + {HB_TAG ('s','m','p','l'), 20/*kCharacterShapeType*/, 1/*kSimplifiedCharactersSelector*/, 16}, + {HB_TAG ('s','s','0','1'), 35/*kStylisticAlternativesType*/, 2/*kStylisticAltOneOnSelector*/, 3/*kStylisticAltOneOffSelector*/}, + {HB_TAG ('s','s','0','2'), 35/*kStylisticAlternativesType*/, 4/*kStylisticAltTwoOnSelector*/, 5/*kStylisticAltTwoOffSelector*/}, + {HB_TAG ('s','s','0','3'), 35/*kStylisticAlternativesType*/, 6/*kStylisticAltThreeOnSelector*/, 7/*kStylisticAltThreeOffSelector*/}, + {HB_TAG ('s','s','0','4'), 35/*kStylisticAlternativesType*/, 8/*kStylisticAltFourOnSelector*/, 9/*kStylisticAltFourOffSelector*/}, + {HB_TAG ('s','s','0','5'), 35/*kStylisticAlternativesType*/, 10/*kStylisticAltFiveOnSelector*/, 11/*kStylisticAltFiveOffSelector*/}, + {HB_TAG ('s','s','0','6'), 35/*kStylisticAlternativesType*/, 12/*kStylisticAltSixOnSelector*/, 13/*kStylisticAltSixOffSelector*/}, + {HB_TAG ('s','s','0','7'), 35/*kStylisticAlternativesType*/, 14/*kStylisticAltSevenOnSelector*/, 15/*kStylisticAltSevenOffSelector*/}, + {HB_TAG ('s','s','0','8'), 35/*kStylisticAlternativesType*/, 16/*kStylisticAltEightOnSelector*/, 17/*kStylisticAltEightOffSelector*/}, + {HB_TAG ('s','s','0','9'), 35/*kStylisticAlternativesType*/, 18/*kStylisticAltNineOnSelector*/, 19/*kStylisticAltNineOffSelector*/}, + {HB_TAG ('s','s','1','0'), 35/*kStylisticAlternativesType*/, 20/*kStylisticAltTenOnSelector*/, 21/*kStylisticAltTenOffSelector*/}, + {HB_TAG ('s','s','1','1'), 35/*kStylisticAlternativesType*/, 22/*kStylisticAltElevenOnSelector*/, 23/*kStylisticAltElevenOffSelector*/}, + {HB_TAG ('s','s','1','2'), 35/*kStylisticAlternativesType*/, 24/*kStylisticAltTwelveOnSelector*/, 25/*kStylisticAltTwelveOffSelector*/}, + {HB_TAG ('s','s','1','3'), 35/*kStylisticAlternativesType*/, 26/*kStylisticAltThirteenOnSelector*/, 27/*kStylisticAltThirteenOffSelector*/}, + {HB_TAG ('s','s','1','4'), 35/*kStylisticAlternativesType*/, 28/*kStylisticAltFourteenOnSelector*/, 29/*kStylisticAltFourteenOffSelector*/}, + {HB_TAG ('s','s','1','5'), 35/*kStylisticAlternativesType*/, 30/*kStylisticAltFifteenOnSelector*/, 31/*kStylisticAltFifteenOffSelector*/}, + {HB_TAG ('s','s','1','6'), 35/*kStylisticAlternativesType*/, 32/*kStylisticAltSixteenOnSelector*/, 33/*kStylisticAltSixteenOffSelector*/}, + {HB_TAG ('s','s','1','7'), 35/*kStylisticAlternativesType*/, 34/*kStylisticAltSeventeenOnSelector*/, 35/*kStylisticAltSeventeenOffSelector*/}, + {HB_TAG ('s','s','1','8'), 35/*kStylisticAlternativesType*/, 36/*kStylisticAltEighteenOnSelector*/, 37/*kStylisticAltEighteenOffSelector*/}, + {HB_TAG ('s','s','1','9'), 35/*kStylisticAlternativesType*/, 38/*kStylisticAltNineteenOnSelector*/, 39/*kStylisticAltNineteenOffSelector*/}, + {HB_TAG ('s','s','2','0'), 35/*kStylisticAlternativesType*/, 40/*kStylisticAltTwentyOnSelector*/, 41/*kStylisticAltTwentyOffSelector*/}, + {HB_TAG ('s','u','b','s'), 10/*kVerticalPositionType*/, 2/*kInferiorsSelector*/, 0/*kNormalPositionSelector*/}, + {HB_TAG ('s','u','p','s'), 10/*kVerticalPositionType*/, 1/*kSuperiorsSelector*/, 0/*kNormalPositionSelector*/}, + {HB_TAG ('s','w','s','h'), 36/*kContextualAlternatesType*/, 2/*kSwashAlternatesOnSelector*/, 3/*kSwashAlternatesOffSelector*/}, + {HB_TAG ('t','i','t','l'), 19/*kStyleOptionsType*/, 4/*kTitlingCapsSelector*/, 0/*kNoStyleOptionsSelector*/}, + {HB_TAG ('t','n','a','m'), 20/*kCharacterShapeType*/, 14/*kTraditionalNamesCharactersSelector*/, 16}, + {HB_TAG ('t','n','u','m'), 6/*kNumberSpacingType*/, 0/*kMonospacedNumbersSelector*/, 4}, + {HB_TAG ('t','r','a','d'), 20/*kCharacterShapeType*/, 0/*kTraditionalCharactersSelector*/, 16}, + {HB_TAG ('t','w','i','d'), 22/*kTextSpacingType*/, 3/*kThirdWidthTextSelector*/, 7}, + {HB_TAG ('u','n','i','c'), 3/*kLetterCaseType*/, 14, 15}, + {HB_TAG ('v','a','l','t'), 22/*kTextSpacingType*/, 5/*kAltProportionalTextSelector*/, 7}, + {HB_TAG ('v','e','r','t'), 4/*kVerticalSubstitutionType*/, 0/*kSubstituteVerticalFormsOnSelector*/, 1/*kSubstituteVerticalFormsOffSelector*/}, + {HB_TAG ('v','h','a','l'), 22/*kTextSpacingType*/, 6/*kAltHalfWidthTextSelector*/, 7}, + {HB_TAG ('v','k','n','a'), 34/*kAlternateKanaType*/, 2/*kAlternateVertKanaOnSelector*/, 3/*kAlternateVertKanaOffSelector*/}, + {HB_TAG ('v','p','a','l'), 22/*kTextSpacingType*/, 5/*kAltProportionalTextSelector*/, 7}, + {HB_TAG ('v','r','t','2'), 4/*kVerticalSubstitutionType*/, 0/*kSubstituteVerticalFormsOnSelector*/, 1/*kSubstituteVerticalFormsOffSelector*/}, + {HB_TAG ('z','e','r','o'), 14/*kTypographicExtrasType*/, 4/*kSlashedZeroOnSelector*/, 5/*kSlashedZeroOffSelector*/}, +}; + +const hb_aat_feature_mapping_t * +hb_aat_layout_find_feature_mapping (hb_tag_t tag) +{ + return (const hb_aat_feature_mapping_t *) bsearch (&tag, + feature_mappings, + ARRAY_LENGTH (feature_mappings), + sizeof (feature_mappings[0]), + hb_aat_feature_mapping_t::cmp); +} + + /* - * morx/kerx/trak/ankr + * morx/kerx/trak */ static inline const AAT::morx& @@ -54,28 +147,96 @@ _get_morx (hb_face_t *face, hb_blob_t **blob = nullptr) *blob = hb_ot_face_data (face)->morx.get_blob (); return morx; } +static inline const AAT::kerx& +_get_kerx (hb_face_t *face, hb_blob_t **blob = nullptr) +{ + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) + { + if (blob) + *blob = hb_blob_get_empty (); + return Null(AAT::kerx); + } + const AAT::kerx& kerx = *(hb_ot_face_data (face)->kerx.get ()); + if (blob) + *blob = hb_ot_face_data (face)->kerx.get_blob (); + return kerx; +} +static inline const AAT::ankr& +_get_ankr (hb_face_t *face, hb_blob_t **blob = nullptr) +{ + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) + { + if (blob) + *blob = hb_blob_get_empty (); + return Null(AAT::ankr); + } + const AAT::ankr& ankr = *(hb_ot_face_data (face)->ankr.get ()); + if (blob) + *blob = hb_ot_face_data (face)->ankr.get_blob (); + return ankr; +} +static inline const AAT::trak& +_get_trak (hb_face_t *face) +{ + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(AAT::trak); + return *(hb_ot_face_data (face)->trak.get ()); +} + + +hb_bool_t +hb_aat_layout_has_substitution (hb_face_t *face) +{ + return _get_morx (face).has_data (); +} void -hb_aat_layout_substitute (hb_font_t *font, hb_buffer_t *buffer) +hb_aat_layout_substitute (hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) { hb_blob_t *blob; const AAT::morx& morx = _get_morx (font->face, &blob); - AAT::hb_aat_apply_context_t c (font, buffer, blob); + AAT::hb_aat_apply_context_t c (plan, font, buffer, blob); morx.apply (&c); } + +hb_bool_t +hb_aat_layout_has_positioning (hb_face_t *face) +{ + return _get_kerx (face).has_data (); +} + void -hb_aat_layout_position (hb_font_t *font, hb_buffer_t *buffer) +hb_aat_layout_position (hb_ot_shape_plan_t *plan, + 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); - const AAT::trak& trak = _get_trak (font->face, &blob); - AAT::hb_aat_apply_context_t c (font, buffer, blob); - kerx.apply (&c, &ankr); + hb_blob_t *ankr_blob; + const AAT::ankr& ankr = _get_ankr (font->face, &ankr_blob); + + AAT::hb_aat_apply_context_t c (plan, font, buffer, blob, + ankr, ankr_blob->data + ankr_blob->length); + kerx.apply (&c); +} + +hb_bool_t +hb_aat_layout_has_tracking (hb_face_t *face) +{ + return _get_trak (face).has_data (); +} + +void +hb_aat_layout_track (hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) +{ + const AAT::trak& trak = _get_trak (font->face); + + AAT::hb_aat_apply_context_t c (plan, font, buffer); trak.apply (&c); -#endif } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh index ac9c535395a..d0eb0190db6 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh @@ -29,15 +29,52 @@ #include "hb.hh" -#include "hb-font.hh" -#include "hb-buffer.hh" -#include "hb-open-type.hh" +#include "hb-ot-shape.hh" +struct hb_aat_feature_mapping_t +{ + hb_tag_t otFeatureTag; + uint16_t aatFeatureType; + uint16_t selectorToEnable; + uint16_t selectorToDisable; + + static inline int cmp (const void *key_, const void *entry_) + { + hb_tag_t key = * (unsigned int *) key_; + const hb_aat_feature_mapping_t * entry = (const hb_aat_feature_mapping_t *) entry_; + return key < entry->otFeatureTag ? -1 : + key > entry->otFeatureTag ? 1 : + 0; + } +}; + +HB_INTERNAL const hb_aat_feature_mapping_t * +hb_aat_layout_find_feature_mapping (hb_tag_t tag); + + +HB_INTERNAL hb_bool_t +hb_aat_layout_has_substitution (hb_face_t *face); + HB_INTERNAL void -hb_aat_layout_substitute (hb_font_t *font, hb_buffer_t *buffer); +hb_aat_layout_substitute (hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); + +HB_INTERNAL hb_bool_t +hb_aat_layout_has_positioning (hb_face_t *face); + +HB_INTERNAL void +hb_aat_layout_position (hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); + +HB_INTERNAL hb_bool_t +hb_aat_layout_has_tracking (hb_face_t *face); HB_INTERNAL void -hb_aat_layout_position (hb_font_t *font, hb_buffer_t *buffer); +hb_aat_layout_track (hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); #endif /* HB_AAT_LAYOUT_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-ltag-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-ltag-table.hh index e308ab28c37..08a1b51a9e8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-ltag-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-ltag-table.hh @@ -46,7 +46,7 @@ struct FTStringRange } protected: - OffsetTo<UnsizedArrayOf<HBUINT8> > + OffsetTo<UnsizedArrayOf<HBUINT8>, HBUINT16, false> tag; /* Offset from the start of the table to * the beginning of the string */ HBUINT16 length; /* String length (in bytes) */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh index 6e3672c18bc..5cb7ca5d53d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh @@ -49,17 +49,21 @@ /* Defined externally, i.e. in config.h. */ -#elif !defined(HB_NO_MT) && defined(__ATOMIC_CONSUME) +#elif !defined(HB_NO_MT) && defined(__ATOMIC_ACQUIRE) /* C++11-style GCC primitives. */ +#define _hb_memory_barrier() __sync_synchronize () + #define hb_atomic_int_impl_add(AI, V) __atomic_fetch_add ((AI), (V), __ATOMIC_ACQ_REL) #define hb_atomic_int_impl_set_relaxed(AI, V) __atomic_store_n ((AI), (V), __ATOMIC_RELAXED) +#define hb_atomic_int_impl_set(AI, V) __atomic_store_n ((AI), (V), __ATOMIC_RELEASE) #define hb_atomic_int_impl_get_relaxed(AI) __atomic_load_n ((AI), __ATOMIC_RELAXED) +#define hb_atomic_int_impl_get(AI) __atomic_load_n ((AI), __ATOMIC_ACQUIRE) #define hb_atomic_ptr_impl_set_relaxed(P, V) __atomic_store_n ((P), (V), __ATOMIC_RELAXED) #define hb_atomic_ptr_impl_get_relaxed(P) __atomic_load_n ((P), __ATOMIC_RELAXED) -#define hb_atomic_ptr_impl_get(P) __atomic_load_n ((P), __ATOMIC_CONSUME) +#define hb_atomic_ptr_impl_get(P) __atomic_load_n ((P), __ATOMIC_ACQUIRE) static inline bool _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) { @@ -74,13 +78,19 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) #include <atomic> +#define _hb_memory_barrier() std::atomic_thread_fence(std::memory_order_ack_rel) +#define _hb_memory_r_barrier() std::atomic_thread_fence(std::memory_order_acquire) +#define _hb_memory_w_barrier() std::atomic_thread_fence(std::memory_order_release) + #define hb_atomic_int_impl_add(AI, V) (reinterpret_cast<std::atomic<int> *> (AI)->fetch_add ((V), std::memory_order_acq_rel)) #define hb_atomic_int_impl_set_relaxed(AI, V) (reinterpret_cast<std::atomic<int> *> (AI)->store ((V), std::memory_order_relaxed)) +#define hb_atomic_int_impl_set(AI, V) (reinterpret_cast<std::atomic<int> *> (AI)->store ((V), std::memory_order_release)) #define hb_atomic_int_impl_get_relaxed(AI) (reinterpret_cast<std::atomic<int> *> (AI)->load (std::memory_order_relaxed)) +#define hb_atomic_int_impl_get(AI) (reinterpret_cast<std::atomic<int> *> (AI)->load (std::memory_order_acquire)) #define hb_atomic_ptr_impl_set_relaxed(P, V) (reinterpret_cast<std::atomic<void*> *> (P)->store ((V), std::memory_order_relaxed)) #define hb_atomic_ptr_impl_get_relaxed(P) (reinterpret_cast<std::atomic<void*> *> (P)->load (std::memory_order_relaxed)) -#define hb_atomic_ptr_impl_get(P) (reinterpret_cast<std::atomic<void*> *> (P)->load (std::memory_order_consume)) +#define hb_atomic_ptr_impl_get(P) (reinterpret_cast<std::atomic<void*> *> (P)->load (std::memory_order_acquire)) static inline bool _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) { @@ -109,7 +119,7 @@ static inline void _hb_memory_barrier (void) #define hb_atomic_int_impl_add(AI, V) InterlockedExchangeAdd ((LONG *) (AI), (V)) static_assert ((sizeof (LONG) == sizeof (int)), ""); -#define hb_atomic_ptr_impl_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((P), (N), (O)) == (O)) #elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES) @@ -137,17 +147,17 @@ static inline int _hb_fetch_and_add (int *AI, int V) _hb_memory_r_barrier (); return result; } -static inline bool _hb_compare_and_swap_ptr (const void **P, const void *O, const void *N) +static inline bool _hb_compare_and_swap_ptr (void **P, void *O, void *N) { _hb_memory_w_barrier (); - int result = atomic_cas_ptr ((void **) P, (void *) O, (void *) N) == (void *) O; + bool result = atomic_cas_ptr (P, O, N) == O; _hb_memory_r_barrier (); return result; } #define hb_atomic_int_impl_add(AI, V) _hb_fetch_and_add ((AI), (V)) -#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_compare_and_swap_ptr ((const void **) (P), (O), (N)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_compare_and_swap_ptr ((P), (O), (N)) #elif !defined(HB_NO_MT) && defined(__APPLE__) @@ -164,12 +174,12 @@ static inline bool _hb_compare_and_swap_ptr (const void **P, const void *O, cons #define hb_atomic_int_impl_add(AI, V) (OSAtomicAdd32Barrier ((V), (AI)) - (V)) #if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100) -#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((O), (N), (P)) #else #if __ppc64__ || __x86_64__ || __aarch64__ -#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (void *) (O), (int64_t) (void *) (N), (int64_t*) (P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P)) #else -#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (void *) (O), (int32_t) (void *) (N), (int32_t*) (P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P)) #endif #endif @@ -243,6 +253,12 @@ static_assert ((sizeof (long) == sizeof (void *)), ""); #ifndef hb_atomic_ptr_impl_get_relaxed #define hb_atomic_ptr_impl_get_relaxed(P) (*(P)) #endif +#ifndef hb_atomic_int_impl_set +inline void hb_atomic_int_impl_set (int *AI, int v) { _hb_memory_w_barrier (); *AI = v; } +#endif +#ifndef hb_atomic_int_impl_get +inline int hb_atomic_int_impl_get (int *AI) { int v = *AI; _hb_memory_r_barrier (); return v; } +#endif #ifndef hb_atomic_ptr_impl_get inline void *hb_atomic_ptr_impl_get (void **P) { void *v = *P; _hb_memory_r_barrier (); return v; } #endif @@ -252,7 +268,9 @@ inline void *hb_atomic_ptr_impl_get (void **P) { void *v = *P; _hb_memory_r_barr struct hb_atomic_int_t { inline void set_relaxed (int v_) const { hb_atomic_int_impl_set_relaxed (&v, v_); } + inline void set (int v_) const { hb_atomic_int_impl_set (&v, v_); } inline int get_relaxed (void) const { return hb_atomic_int_impl_get_relaxed (&v); } + inline int get (void) const { return hb_atomic_int_impl_get (&v); } inline int inc (void) { return hb_atomic_int_impl_add (&v, 1); } inline int dec (void) { return hb_atomic_int_impl_add (&v, -1); } @@ -271,9 +289,9 @@ struct hb_atomic_ptr_t inline void init (T* v_ = nullptr) { set_relaxed (v_); } inline void set_relaxed (T* v_) const { hb_atomic_ptr_impl_set_relaxed (&v, v_); } - inline T *get_relaxed (void) const { return hb_atomic_ptr_impl_get_relaxed (&v); } + inline T *get_relaxed (void) const { return (T *) hb_atomic_ptr_impl_get_relaxed (&v); } inline T *get (void) const { return (T *) hb_atomic_ptr_impl_get ((void **) &v); } - inline bool cmpexch (const T *old, T *new_) const{ return hb_atomic_ptr_impl_cmpexch (&v, old, new_); } + inline bool cmpexch (const T *old, T *new_) const { return hb_atomic_ptr_impl_cmpexch ((void **) &v, (void *) old, (void *) new_); } mutable T *v; }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc index a335df308a5..edee6730053 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc @@ -25,11 +25,6 @@ * Red Hat Author(s): Behdad Esfahbod */ -/* http://www.oracle.com/technetwork/articles/servers-storage-dev/standardheaderfiles-453865.html */ -#ifndef _POSIX_C_SOURCE -#define _POSIX_C_SOURCE 200809L -#endif - #include "hb.hh" #include "hb-blob.hh" @@ -293,6 +288,8 @@ hb_blob_make_immutable (hb_blob_t *blob) { if (hb_object_is_inert (blob)) return; + if (blob->immutable) + return; blob->immutable = true; } @@ -510,8 +507,9 @@ struct hb_mapped_file_t #if (defined(HAVE_MMAP) || defined(_WIN32) || defined(__CYGWIN__)) && !defined(HB_NO_MMAP) static void -_hb_mapped_file_destroy (hb_mapped_file_t *file) +_hb_mapped_file_destroy (void *file_) { + hb_mapped_file_t *file = (hb_mapped_file_t *) file_; #ifdef HAVE_MMAP munmap (file->contents, file->length); #elif defined(_WIN32) || defined(__CYGWIN__) @@ -574,18 +572,45 @@ fail_without_close: wchar_t * wchar_file_name = (wchar_t *) malloc (sizeof (wchar_t) * size); if (unlikely (wchar_file_name == nullptr)) goto fail_without_close; mbstowcs (wchar_file_name, file_name, size); +#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) + { + CREATEFILE2_EXTENDED_PARAMETERS ceparams = { 0 }; + ceparams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS); + ceparams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED & 0xFFFF; + ceparams.dwFileFlags = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED & 0xFFF00000; + ceparams.dwSecurityQosFlags = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED & 0x000F0000; + ceparams.lpSecurityAttributes = nullptr; + ceparams.hTemplateFile = nullptr; + fd = CreateFile2 (wchar_file_name, GENERIC_READ, FILE_SHARE_READ, + OPEN_EXISTING, &ceparams); + } +#else fd = CreateFileW (wchar_file_name, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, nullptr); +#endif free (wchar_file_name); if (unlikely (fd == INVALID_HANDLE_VALUE)) goto fail_without_close; +#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) + { + LARGE_INTEGER length; + GetFileSizeEx (fd, &length); + file->length = length.LowPart; + file->mapping = CreateFileMappingFromApp (fd, nullptr, PAGE_READONLY, length.QuadPart, nullptr); + } +#else file->length = (unsigned long) GetFileSize (fd, nullptr); file->mapping = CreateFileMapping (fd, nullptr, PAGE_READONLY, 0, 0, nullptr); +#endif if (unlikely (file->mapping == nullptr)) goto fail; +#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) + file->contents = (char *) MapViewOfFileFromApp (file->mapping, FILE_MAP_READ, 0, 0); +#else file->contents = (char *) MapViewOfFile (file->mapping, FILE_MAP_READ, 0, 0, 0); +#endif if (unlikely (file->contents == nullptr)) goto fail; CloseHandle (fd); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc index 1b6d14731fd..c1d82ab8dfe 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc @@ -440,8 +440,8 @@ hb_bool_t hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, const char *buf, int buf_len, /* -1 means nul-terminated */ - const char **end_ptr, /* May be nullptr */ - hb_font_t *font, /* May be nullptr */ + const char **end_ptr, /* May be NULL */ + hb_font_t *font, /* May be NULL */ hb_buffer_serialize_format_t format) { const char *end; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc index 536ab5d5376..ce9b0530ce9 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc @@ -182,7 +182,11 @@ hb_buffer_t::shift_forward (unsigned int count) if (idx + count > len) { /* Under memory failure we might expose this area. At least - * clean it up. Oh well... */ + * clean it up. Oh well... + * + * Ideally, we should at least set Default_Ignorable bits on + * these, as well as consistent cluster values. But the former + * is layering violation... */ memset (info + len, 0, (idx + count - len) * sizeof (info[0])); } len += count; @@ -219,6 +223,7 @@ hb_buffer_t::reset (void) unicode = hb_unicode_funcs_reference (hb_unicode_funcs_get_default ()); flags = HB_BUFFER_FLAG_DEFAULT; replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT; + invisible = 0; clear (); } @@ -354,6 +359,8 @@ hb_buffer_t::replace_glyphs (unsigned int num_in, { if (unlikely (!make_room_for (num_in, num_out))) return; + assert (idx + num_in <= len); + merge_clusters (idx, idx + num_in); hb_glyph_info_t orig_info = info[idx]; @@ -369,37 +376,6 @@ hb_buffer_t::replace_glyphs (unsigned int num_in, out_len += num_out; } -void -hb_buffer_t::output_glyph (hb_codepoint_t glyph_index) -{ - if (unlikely (!make_room_for (0, 1))) return; - - out_info[out_len] = info[idx]; - out_info[out_len].codepoint = glyph_index; - - out_len++; -} - -void -hb_buffer_t::output_info (const hb_glyph_info_t &glyph_info) -{ - if (unlikely (!make_room_for (0, 1))) return; - - out_info[out_len] = glyph_info; - - out_len++; -} - -void -hb_buffer_t::copy_glyph (void) -{ - if (unlikely (!make_room_for (0, 1))) return; - - out_info[out_len] = info[idx]; - - out_len++; -} - bool hb_buffer_t::move_to (unsigned int i) { @@ -429,8 +405,14 @@ hb_buffer_t::move_to (unsigned int i) unsigned int count = out_len - i; /* This will blow in our face if memory allocation fails later - * in this same lookup... */ - if (unlikely (idx < count && !shift_forward (count + 32))) return false; + * in this same lookup... + * + * We used to shift with extra 32 items, instead of the 0 below. + * But that would leave empty slots in the buffer in case of allocation + * failures. Setting to zero for now to avoid other problems (see + * comments in shift_forward(). This can cause O(N^2) behavior more + * severely than adding 32 empty slots can... */ + if (unlikely (idx < count && !shift_forward (count + 0))) return false; assert (idx >= count); @@ -442,19 +424,6 @@ hb_buffer_t::move_to (unsigned int i) return true; } -void -hb_buffer_t::replace_glyph (hb_codepoint_t glyph_index) -{ - if (unlikely (out_info != info || out_len != idx)) { - if (unlikely (!make_room_for (1, 1))) return; - out_info[out_len] = info[idx]; - } - out_info[out_len].codepoint = glyph_index; - - idx++; - out_len++; -} - void hb_buffer_t::set_masks (hb_mask_t value, @@ -709,6 +678,7 @@ DEFINE_NULL_INSTANCE (hb_buffer_t) = HB_BUFFER_FLAG_DEFAULT, HB_BUFFER_CLUSTER_LEVEL_DEFAULT, HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT, + 0, /* invisible */ HB_BUFFER_SCRATCH_FLAG_DEFAULT, HB_BUFFER_MAX_LEN_DEFAULT, HB_BUFFER_MAX_OPS_DEFAULT, @@ -1028,7 +998,7 @@ hb_buffer_get_script (hb_buffer_t *buffer) * are orthogonal to the scripts, and though they are related, they are * different concepts and should not be confused with each other. * - * Use hb_language_from_string() to convert from ISO 639 language codes to + * Use hb_language_from_string() to convert from BCP 47 language tags to * #hb_language_t. * * Since: 0.9.2 @@ -1211,6 +1181,46 @@ hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer) /** + * hb_buffer_set_invisible_glyph: + * @buffer: an #hb_buffer_t. + * @invisible: the invisible #hb_codepoint_t + * + * Sets the #hb_codepoint_t that replaces invisible characters in + * the shaping result. If set to zero (default), the glyph for the + * U+0020 SPACE character is used. Otherwise, this value is used + * verbatim. + * + * Since: 2.0.0 + **/ +void +hb_buffer_set_invisible_glyph (hb_buffer_t *buffer, + hb_codepoint_t invisible) +{ + if (unlikely (hb_object_is_inert (buffer))) + return; + + buffer->invisible = invisible; +} + +/** + * hb_buffer_get_invisible_glyph: + * @buffer: an #hb_buffer_t. + * + * See hb_buffer_set_invisible_glyph(). + * + * Return value: + * The @buffer invisible #hb_codepoint_t. + * + * Since: 2.0.0 + **/ +hb_codepoint_t +hb_buffer_get_invisible_glyph (hb_buffer_t *buffer) +{ + return buffer->invisible; +} + + +/** * hb_buffer_reset: * @buffer: an #hb_buffer_t. * @@ -1499,6 +1509,8 @@ hb_buffer_reverse_clusters (hb_buffer_t *buffer) * it will be set to the process's default language as returned by * hb_language_get_default(). This may change in the future by * taking buffer script into consideration when choosing a language. + * Note that hb_language_get_default() is NOT threadsafe the first time + * it is called. See documentation for that function for details. * * Since: 0.9.7 **/ @@ -1887,6 +1899,10 @@ hb_buffer_t::sort (unsigned int start, unsigned int end, int(*compar)(const hb_g /** * hb_buffer_diff: + * @buffer: a buffer. + * @reference: other buffer to compare to. + * @dottedcircle_glyph: glyph id of U+25CC DOTTED CIRCLE, or (hb_codepont_t) -1. + * @position_fuzz: allowed absolute difference in position values. * * If dottedcircle_glyph is (hb_codepoint_t) -1 then %HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT * and %HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT are never returned. This should be used by most diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h index 8a2d3e8690f..d0aed02d534 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h @@ -44,7 +44,6 @@ HB_BEGIN_DECLS * hb_glyph_info_t: * @codepoint: either a Unicode code point (before shaping) or a glyph index * (after shaping). - * @mask: * @cluster: the index of the character in the original text that corresponds * to this #hb_glyph_info_t, or whatever the client passes to * hb_buffer_add(). More than one #hb_glyph_info_t can have the same @@ -59,11 +58,13 @@ HB_BEGIN_DECLS * * The #hb_glyph_info_t is the structure that holds information about the * glyphs and their relation to input text. - * */ -typedef struct hb_glyph_info_t { +typedef struct hb_glyph_info_t +{ hb_codepoint_t codepoint; - hb_mask_t mask; /* Holds hb_glyph_flags_t after hb_shape(), plus other things. */ + /*< private >*/ + hb_mask_t mask; + /*< public >*/ uint32_t cluster; /*< private >*/ @@ -92,7 +93,7 @@ typedef struct hb_glyph_info_t { typedef enum { /*< flags >*/ HB_GLYPH_FLAG_UNSAFE_TO_BREAK = 0x00000001, - HB_GLYPH_FLAG_DEFINED = 0x00000001 /* OR of all defined flags */ + HB_GLYPH_FLAG_DEFINED = 0x00000001 /*< skip >*/ /* OR of all defined flags */ } hb_glyph_flags_t; HB_EXTERN hb_glyph_flags_t @@ -298,7 +299,15 @@ hb_buffer_set_flags (hb_buffer_t *buffer, HB_EXTERN hb_buffer_flags_t hb_buffer_get_flags (hb_buffer_t *buffer); -/* +/** + * hb_buffer_cluster_level_t: + * @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES: Return cluster values grouped by graphemes into + * monotone order. + * @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS: Return cluster values grouped into monotone order. + * @HB_BUFFER_CLUSTER_LEVEL_CHARACTERS: Don't group cluster values. + * @HB_BUFFER_CLUSTER_LEVEL_DEFAULT: Default cluster level, + * equal to @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES. + * * Since: 0.9.42 */ typedef enum { @@ -332,6 +341,13 @@ hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer, HB_EXTERN hb_codepoint_t hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer); +HB_EXTERN void +hb_buffer_set_invisible_glyph (hb_buffer_t *buffer, + hb_codepoint_t invisible); + +HB_EXTERN hb_codepoint_t +hb_buffer_get_invisible_glyph (hb_buffer_t *buffer); + HB_EXTERN void hb_buffer_reset (hb_buffer_t *buffer); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh index bcaf066c70b..0d888e1e052 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh @@ -93,6 +93,7 @@ struct hb_buffer_t hb_buffer_flags_t flags; /* BOT / EOT / etc. */ hb_buffer_cluster_level_t cluster_level; hb_codepoint_t replacement; /* U+FFFD or something else. */ + hb_codepoint_t invisible; /* 0 or something else. */ hb_buffer_scratch_flags_t scratch_flags; /* Have space-fallback, etc. */ unsigned int max_len; /* Maximum allowed len. */ int max_ops; /* Maximum allowed operations. */ @@ -212,13 +213,49 @@ struct hb_buffer_t unsigned int num_out, const hb_codepoint_t *glyph_data); - HB_INTERNAL void replace_glyph (hb_codepoint_t glyph_index); + inline void replace_glyph (hb_codepoint_t glyph_index) + { + if (unlikely (out_info != info || out_len != idx)) { + if (unlikely (!make_room_for (1, 1))) return; + out_info[out_len] = info[idx]; + } + out_info[out_len].codepoint = glyph_index; + + idx++; + out_len++; + } /* Makes a copy of the glyph at idx to output and replace glyph_index */ - HB_INTERNAL void output_glyph (hb_codepoint_t glyph_index); - HB_INTERNAL void output_info (const hb_glyph_info_t &glyph_info); + inline hb_glyph_info_t & output_glyph (hb_codepoint_t glyph_index) + { + if (unlikely (!make_room_for (0, 1))) return Crap(hb_glyph_info_t); + + if (unlikely (idx == len && !out_len)) + return Crap(hb_glyph_info_t); + + out_info[out_len] = idx < len ? info[idx] : out_info[out_len - 1]; + out_info[out_len].codepoint = glyph_index; + + out_len++; + + return out_info[out_len - 1]; + } + inline void output_info (const hb_glyph_info_t &glyph_info) + { + if (unlikely (!make_room_for (0, 1))) return; + + out_info[out_len] = glyph_info; + + out_len++; + } /* Copies glyph at idx to output but doesn't advance idx */ - HB_INTERNAL void copy_glyph (void); - HB_INTERNAL bool move_to (unsigned int i); /* i is output-buffer index. */ + inline void copy_glyph (void) + { + if (unlikely (!make_room_for (0, 1))) return; + + out_info[out_len] = info[idx]; + + out_len++; + } /* Copies glyph at idx to output and advance idx. * If there's no output, just advance idx. */ inline void @@ -226,7 +263,8 @@ struct hb_buffer_t { if (have_output) { - if (unlikely (out_info != info || out_len != idx)) { + if (out_info != info || out_len != idx) + { if (unlikely (!make_room_for (1, 1))) return; out_info[out_len] = info[idx]; } @@ -235,10 +273,28 @@ struct hb_buffer_t idx++; } + /* Copies n glyphs at idx to output and advance idx. + * If there's no output, just advance idx. */ + inline void + next_glyphs (unsigned int n) + { + if (have_output) + { + if (out_info != info || out_len != idx) + { + if (unlikely (!make_room_for (n, n))) return; + memmove (out_info + out_len, info + idx, n * sizeof (out_info[0])); + } + out_len += n; + } + idx += n; + } /* Advance idx without copying to output. */ - inline void skip_glyph (void) { idx++; } - + inline void skip_glyph (void) + { + idx++; + } inline void reset_masks (hb_mask_t mask) { for (unsigned int j = 0; j < len; j++) @@ -275,6 +331,8 @@ struct hb_buffer_t /* Internal methods */ + HB_INTERNAL bool move_to (unsigned int i); /* i is output-buffer index. */ + HB_INTERNAL bool enlarge (unsigned int size); inline bool ensure (unsigned int size) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh new file mode 100644 index 00000000000..eb48f18cf94 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh @@ -0,0 +1,80 @@ +/* + * Copyright © 2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_CACHE_HH +#define HB_CACHE_HH + +#include "hb.hh" + + +/* Implements a lock-free cache for int->int functions. */ + +template <unsigned int key_bits, unsigned int value_bits, unsigned int cache_bits> +struct hb_cache_t +{ + static_assert ((key_bits >= cache_bits), ""); + static_assert ((key_bits + value_bits - cache_bits <= 8 * sizeof (hb_atomic_int_t)), ""); + static_assert (sizeof (hb_atomic_int_t) == sizeof (unsigned int), ""); + + inline void init (void) { clear (); } + inline void fini (void) {} + + inline void clear (void) + { + for (unsigned i = 0; i < ARRAY_LENGTH (values); i++) + values[i].set_relaxed (-1); + } + + inline bool get (unsigned int key, unsigned int *value) const + { + unsigned int k = key & ((1u<<cache_bits)-1); + unsigned int v = values[k].get_relaxed (); + if ((key_bits + value_bits - cache_bits == 8 * sizeof (hb_atomic_int_t) && v == (unsigned int) -1) || + (v >> value_bits) != (key >> cache_bits)) + return false; + *value = v & ((1u<<value_bits)-1); + return true; + } + + inline bool set (unsigned int key, unsigned int value) + { + if (unlikely ((key >> key_bits) || (value >> value_bits))) + return false; /* Overflows */ + unsigned int k = key & ((1u<<cache_bits)-1); + unsigned int v = ((key>>cache_bits)<<value_bits) | value; + values[k].set_relaxed (v); + return true; + } + + private: + hb_atomic_int_t values[1u<<cache_bits]; +}; + +typedef hb_cache_t<21, 16, 8> hb_cmap_cache_t; +typedef hb_cache_t<16, 24, 8> hb_advance_cache_t; + + +#endif /* HB_CACHE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc index ed3fed2a35c..4940e7fb561 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc @@ -47,8 +47,27 @@ _hb_options_init (void) u.i = 0; u.opts.initialized = 1; - char *c = getenv ("HB_OPTIONS"); - u.opts.uniscribe_bug_compatible = c && strstr (c, "uniscribe-bug-compatible"); + const char *c = getenv ("HB_OPTIONS"); + if (c) + { + while (*c) + { + const char *p = strchr (c, ':'); + if (!p) + p = c + strlen (c); + +#define OPTION(name, symbol) \ + if (0 == strncmp (c, name, p - c) && strlen (name) == p - c) u.opts.symbol = true; + + OPTION ("uniscribe-bug-compatible", uniscribe_bug_compatible); + OPTION ("aat", aat); + +#undef OPTION + + c = *p ? p + 1 : p; + } + + } /* This is idempotent and threadsafe. */ _hb_options.set_relaxed (u.i); @@ -306,14 +325,14 @@ retry: /** * hb_language_from_string: * @str: (array length=len) (element-type uint8_t): a string representing - * ISO 639 language code + * a BCP 47 language tag * @len: length of the @str, or -1 if it is %NULL-terminated. * - * Converts @str representing an ISO 639 language code to the corresponding + * Converts @str representing a BCP 47 language tag to the corresponding * #hb_language_t. * * Return value: (transfer none): - * The #hb_language_t corresponding to the ISO 639 language code. + * The #hb_language_t corresponding to the BCP 47 language tag. * * Since: 0.9.2 **/ @@ -361,7 +380,14 @@ hb_language_to_string (hb_language_t language) /** * hb_language_get_default: * + * Get default language from current locale. * + * Note that the first time this function is called, it calls + * "setlocale (LC_CTYPE, nullptr)" to fetch current locale. The underlying + * setlocale function is, in many implementations, NOT threadsafe. To avoid + * problems, call this function once before multiple threads can call it. + * This function is only used from hb_buffer_guess_segment_properties() by + * HarfBuzz itself. * * Return value: (transfer none): * @@ -531,7 +557,6 @@ hb_script_get_horizontal_direction (hb_script_t script) /* Unicode-8.0 additions */ case HB_SCRIPT_HATRAN: - case HB_SCRIPT_OLD_HUNGARIAN: /* Unicode-9.0 additions */ case HB_SCRIPT_ADLAM: @@ -545,6 +570,7 @@ hb_script_get_horizontal_direction (hb_script_t script) /* https://github.com/harfbuzz/harfbuzz/issues/1000 */ + case HB_SCRIPT_OLD_HUNGARIAN: case HB_SCRIPT_OLD_ITALIC: case HB_SCRIPT_RUNIC: @@ -877,8 +903,8 @@ parse_feature_indices (const char **pp, const char *end, hb_feature_t *feature) bool has_start; - feature->start = 0; - feature->end = (unsigned int) -1; + feature->start = HB_FEATURE_GLOBAL_START; + feature->end = HB_FEATURE_GLOBAL_END; if (!parse_char (pp, end, '[')) return true; @@ -1065,7 +1091,7 @@ hb_variation_to_string (hb_variation_t *variation, while (len && s[len - 1] == ' ') len--; s[len++] = '='; - len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", variation->value)); + len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", (double) variation->value)); assert (len < ARRAY_LENGTH (s)); len = MIN (len, size - 1); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h index 5dc1ebcd2c5..2f09f431801 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h @@ -63,6 +63,23 @@ typedef unsigned __int64 uint64_t; # include <stdint.h> #endif +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) +#define HB_DEPRECATED __attribute__((__deprecated__)) +#elif defined(_MSC_VER) && (_MSC_VER >= 1300) +#define HB_DEPRECATED __declspec(deprecated) +#else +#define HB_DEPRECATED +#endif + +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) +#define HB_DEPRECATED_FOR(f) __attribute__((__deprecated__("Use '" #f "' instead"))) +#elif defined(_MSC_FULL_VER) && (_MSC_FULL_VER > 140050320) +#define HB_DEPRECATED_FOR(f) __declspec(deprecated("is deprecated. Use '" #f "' instead")) +#else +#define HB_DEPRECATED_FOR(f) HB_DEPRECATED +#endif + + HB_BEGIN_DECLS @@ -86,8 +103,8 @@ typedef union _hb_var_int_t { typedef uint32_t hb_tag_t; -#define HB_TAG(c1,c2,c3,c4) ((hb_tag_t)((((uint8_t)(c1))<<24)|(((uint8_t)(c2))<<16)|(((uint8_t)(c3))<<8)|((uint8_t)(c4)))) -#define HB_UNTAG(tag) ((uint8_t)((tag)>>24)), ((uint8_t)((tag)>>16)), ((uint8_t)((tag)>>8)), ((uint8_t)(tag)) +#define HB_TAG(c1,c2,c3,c4) ((hb_tag_t)((((uint32_t)(c1)&0xFF)<<24)|(((uint32_t)(c2)&0xFF)<<16)|(((uint32_t)(c3)&0xFF)<<8)|((uint32_t)(c4)&0xFF))) +#define HB_UNTAG(tag) (((tag)>>24)&0xFF), (((tag)>>16)&0xFF), (((tag)>>8)&0xFF), ((tag)&0xFF) #define HB_TAG_NONE HB_TAG(0,0,0,0) #define HB_TAG_MAX HB_TAG(0xff,0xff,0xff,0xff) @@ -340,13 +357,15 @@ typedef enum HB_SCRIPT_INVALID = HB_TAG_NONE, /* Dummy values to ensure any hb_tag_t value can be passed/stored as hb_script_t - * without risking undefined behavior. Include both a signed and unsigned max, - * since technically enums are int, and indeed, hb_script_t ends up being signed. + * without risking undefined behavior. We have two, for historical reasons. + * HB_TAG_MAX used to be unsigned, but that was invalid Ansi C, so was changed + * to _HB_SCRIPT_MAX_VALUE to be equal to HB_TAG_MAX_SIGNED as well. + * * See this thread for technicalities: * * https://lists.freedesktop.org/archives/harfbuzz/2014-March/004150.html */ - _HB_SCRIPT_MAX_VALUE = HB_TAG_MAX, /*< skip >*/ + _HB_SCRIPT_MAX_VALUE = HB_TAG_MAX_SIGNED, /*< skip >*/ _HB_SCRIPT_MAX_VALUE_SIGNED = HB_TAG_MAX_SIGNED /*< skip >*/ } hb_script_t; @@ -379,6 +398,19 @@ typedef void (*hb_destroy_func_t) (void *user_data); /* Font features and variations. */ +/** + * HB_FEATURE_GLOBAL_START + * + * Since: 2.0.0 + */ +#define HB_FEATURE_GLOBAL_START 0 +/** + * HB_FEATURE_GLOBAL_END + * + * Since: 2.0.0 + */ +#define HB_FEATURE_GLOBAL_END ((unsigned int) -1) + typedef struct hb_feature_t { hb_tag_t tag; uint32_t value; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc index a7ba85f8350..aa3921a3fdd 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc @@ -32,6 +32,7 @@ #include "hb-shaper-impl.hh" #include "hb-coretext.h" +#include "hb-aat-layout.hh" #include <math.h> /* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */ @@ -210,7 +211,7 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size) } CFURLRef original_url = nullptr; -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 +#if TARGET_OS_OSX && MAC_OS_X_VERSION_MIN_REQUIRED < 1060 ATSFontRef atsFont; FSRef fsref; OSStatus status; @@ -240,7 +241,7 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size) * process in Blink. This can be detected by the new file URL location * that the newly found font points to. */ CFURLRef new_url = nullptr; -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 +#if TARGET_OS_OSX && MAC_OS_X_VERSION_MIN_REQUIRED < 1060 atsFont = CTFontGetPlatformFont (new_ct_font, NULL); status = ATSFontGetFileReference (atsFont, &fsref); if (status == noErr) @@ -431,183 +432,6 @@ struct range_record_t { }; -/* The following enum members are added in OS X 10.8. */ -#define kAltHalfWidthTextSelector 6 -#define kAltProportionalTextSelector 5 -#define kAlternateHorizKanaOffSelector 1 -#define kAlternateHorizKanaOnSelector 0 -#define kAlternateKanaType 34 -#define kAlternateVertKanaOffSelector 3 -#define kAlternateVertKanaOnSelector 2 -#define kCaseSensitiveLayoutOffSelector 1 -#define kCaseSensitiveLayoutOnSelector 0 -#define kCaseSensitiveLayoutType 33 -#define kCaseSensitiveSpacingOffSelector 3 -#define kCaseSensitiveSpacingOnSelector 2 -#define kContextualAlternatesOffSelector 1 -#define kContextualAlternatesOnSelector 0 -#define kContextualAlternatesType 36 -#define kContextualLigaturesOffSelector 19 -#define kContextualLigaturesOnSelector 18 -#define kContextualSwashAlternatesOffSelector 5 -#define kContextualSwashAlternatesOnSelector 4 -#define kDefaultLowerCaseSelector 0 -#define kDefaultUpperCaseSelector 0 -#define kHistoricalLigaturesOffSelector 21 -#define kHistoricalLigaturesOnSelector 20 -#define kHojoCharactersSelector 12 -#define kJIS2004CharactersSelector 11 -#define kLowerCasePetiteCapsSelector 2 -#define kLowerCaseSmallCapsSelector 1 -#define kLowerCaseType 37 -#define kMathematicalGreekOffSelector 11 -#define kMathematicalGreekOnSelector 10 -#define kNLCCharactersSelector 13 -#define kQuarterWidthTextSelector 4 -#define kScientificInferiorsSelector 4 -#define kStylisticAltEightOffSelector 17 -#define kStylisticAltEightOnSelector 16 -#define kStylisticAltEighteenOffSelector 37 -#define kStylisticAltEighteenOnSelector 36 -#define kStylisticAltElevenOffSelector 23 -#define kStylisticAltElevenOnSelector 22 -#define kStylisticAltFifteenOffSelector 31 -#define kStylisticAltFifteenOnSelector 30 -#define kStylisticAltFiveOffSelector 11 -#define kStylisticAltFiveOnSelector 10 -#define kStylisticAltFourOffSelector 9 -#define kStylisticAltFourOnSelector 8 -#define kStylisticAltFourteenOffSelector 29 -#define kStylisticAltFourteenOnSelector 28 -#define kStylisticAltNineOffSelector 19 -#define kStylisticAltNineOnSelector 18 -#define kStylisticAltNineteenOffSelector 39 -#define kStylisticAltNineteenOnSelector 38 -#define kStylisticAltOneOffSelector 3 -#define kStylisticAltOneOnSelector 2 -#define kStylisticAltSevenOffSelector 15 -#define kStylisticAltSevenOnSelector 14 -#define kStylisticAltSeventeenOffSelector 35 -#define kStylisticAltSeventeenOnSelector 34 -#define kStylisticAltSixOffSelector 13 -#define kStylisticAltSixOnSelector 12 -#define kStylisticAltSixteenOffSelector 33 -#define kStylisticAltSixteenOnSelector 32 -#define kStylisticAltTenOffSelector 21 -#define kStylisticAltTenOnSelector 20 -#define kStylisticAltThirteenOffSelector 27 -#define kStylisticAltThirteenOnSelector 26 -#define kStylisticAltThreeOffSelector 7 -#define kStylisticAltThreeOnSelector 6 -#define kStylisticAltTwelveOffSelector 25 -#define kStylisticAltTwelveOnSelector 24 -#define kStylisticAltTwentyOffSelector 41 -#define kStylisticAltTwentyOnSelector 40 -#define kStylisticAltTwoOffSelector 5 -#define kStylisticAltTwoOnSelector 4 -#define kStylisticAlternativesType 35 -#define kSwashAlternatesOffSelector 3 -#define kSwashAlternatesOnSelector 2 -#define kThirdWidthTextSelector 3 -#define kTraditionalNamesCharactersSelector 14 -#define kUpperCasePetiteCapsSelector 2 -#define kUpperCaseSmallCapsSelector 1 -#define kUpperCaseType 38 - -/* Table data courtesy of Apple. */ -static const struct feature_mapping_t { - FourCharCode otFeatureTag; - uint16_t aatFeatureType; - uint16_t selectorToEnable; - uint16_t selectorToDisable; -} feature_mappings[] = { - { 'c2pc', kUpperCaseType, kUpperCasePetiteCapsSelector, kDefaultUpperCaseSelector }, - { 'c2sc', kUpperCaseType, kUpperCaseSmallCapsSelector, kDefaultUpperCaseSelector }, - { 'calt', kContextualAlternatesType, kContextualAlternatesOnSelector, kContextualAlternatesOffSelector }, - { 'case', kCaseSensitiveLayoutType, kCaseSensitiveLayoutOnSelector, kCaseSensitiveLayoutOffSelector }, - { 'clig', kLigaturesType, kContextualLigaturesOnSelector, kContextualLigaturesOffSelector }, - { 'cpsp', kCaseSensitiveLayoutType, kCaseSensitiveSpacingOnSelector, kCaseSensitiveSpacingOffSelector }, - { 'cswh', kContextualAlternatesType, kContextualSwashAlternatesOnSelector, kContextualSwashAlternatesOffSelector }, - { 'dlig', kLigaturesType, kRareLigaturesOnSelector, kRareLigaturesOffSelector }, - { 'expt', kCharacterShapeType, kExpertCharactersSelector, 16 }, - { 'frac', kFractionsType, kDiagonalFractionsSelector, kNoFractionsSelector }, - { 'fwid', kTextSpacingType, kMonospacedTextSelector, 7 }, - { 'halt', kTextSpacingType, kAltHalfWidthTextSelector, 7 }, - { 'hist', kLigaturesType, kHistoricalLigaturesOnSelector, kHistoricalLigaturesOffSelector }, - { 'hkna', kAlternateKanaType, kAlternateHorizKanaOnSelector, kAlternateHorizKanaOffSelector, }, - { 'hlig', kLigaturesType, kHistoricalLigaturesOnSelector, kHistoricalLigaturesOffSelector }, - { 'hngl', kTransliterationType, kHanjaToHangulSelector, kNoTransliterationSelector }, - { 'hojo', kCharacterShapeType, kHojoCharactersSelector, 16 }, - { 'hwid', kTextSpacingType, kHalfWidthTextSelector, 7 }, - { 'ital', kItalicCJKRomanType, kCJKItalicRomanOnSelector, kCJKItalicRomanOffSelector }, - { 'jp04', kCharacterShapeType, kJIS2004CharactersSelector, 16 }, - { 'jp78', kCharacterShapeType, kJIS1978CharactersSelector, 16 }, - { 'jp83', kCharacterShapeType, kJIS1983CharactersSelector, 16 }, - { 'jp90', kCharacterShapeType, kJIS1990CharactersSelector, 16 }, - { 'liga', kLigaturesType, kCommonLigaturesOnSelector, kCommonLigaturesOffSelector }, - { 'lnum', kNumberCaseType, kUpperCaseNumbersSelector, 2 }, - { 'mgrk', kMathematicalExtrasType, kMathematicalGreekOnSelector, kMathematicalGreekOffSelector }, - { 'nlck', kCharacterShapeType, kNLCCharactersSelector, 16 }, - { 'onum', kNumberCaseType, kLowerCaseNumbersSelector, 2 }, - { 'ordn', kVerticalPositionType, kOrdinalsSelector, kNormalPositionSelector }, - { 'palt', kTextSpacingType, kAltProportionalTextSelector, 7 }, - { 'pcap', kLowerCaseType, kLowerCasePetiteCapsSelector, kDefaultLowerCaseSelector }, - { 'pkna', kTextSpacingType, kProportionalTextSelector, 7 }, - { 'pnum', kNumberSpacingType, kProportionalNumbersSelector, 4 }, - { 'pwid', kTextSpacingType, kProportionalTextSelector, 7 }, - { 'qwid', kTextSpacingType, kQuarterWidthTextSelector, 7 }, - { 'ruby', kRubyKanaType, kRubyKanaOnSelector, kRubyKanaOffSelector }, - { 'sinf', kVerticalPositionType, kScientificInferiorsSelector, kNormalPositionSelector }, - { 'smcp', kLowerCaseType, kLowerCaseSmallCapsSelector, kDefaultLowerCaseSelector }, - { 'smpl', kCharacterShapeType, kSimplifiedCharactersSelector, 16 }, - { 'ss01', kStylisticAlternativesType, kStylisticAltOneOnSelector, kStylisticAltOneOffSelector }, - { 'ss02', kStylisticAlternativesType, kStylisticAltTwoOnSelector, kStylisticAltTwoOffSelector }, - { 'ss03', kStylisticAlternativesType, kStylisticAltThreeOnSelector, kStylisticAltThreeOffSelector }, - { 'ss04', kStylisticAlternativesType, kStylisticAltFourOnSelector, kStylisticAltFourOffSelector }, - { 'ss05', kStylisticAlternativesType, kStylisticAltFiveOnSelector, kStylisticAltFiveOffSelector }, - { 'ss06', kStylisticAlternativesType, kStylisticAltSixOnSelector, kStylisticAltSixOffSelector }, - { 'ss07', kStylisticAlternativesType, kStylisticAltSevenOnSelector, kStylisticAltSevenOffSelector }, - { 'ss08', kStylisticAlternativesType, kStylisticAltEightOnSelector, kStylisticAltEightOffSelector }, - { 'ss09', kStylisticAlternativesType, kStylisticAltNineOnSelector, kStylisticAltNineOffSelector }, - { 'ss10', kStylisticAlternativesType, kStylisticAltTenOnSelector, kStylisticAltTenOffSelector }, - { 'ss11', kStylisticAlternativesType, kStylisticAltElevenOnSelector, kStylisticAltElevenOffSelector }, - { 'ss12', kStylisticAlternativesType, kStylisticAltTwelveOnSelector, kStylisticAltTwelveOffSelector }, - { 'ss13', kStylisticAlternativesType, kStylisticAltThirteenOnSelector, kStylisticAltThirteenOffSelector }, - { 'ss14', kStylisticAlternativesType, kStylisticAltFourteenOnSelector, kStylisticAltFourteenOffSelector }, - { 'ss15', kStylisticAlternativesType, kStylisticAltFifteenOnSelector, kStylisticAltFifteenOffSelector }, - { 'ss16', kStylisticAlternativesType, kStylisticAltSixteenOnSelector, kStylisticAltSixteenOffSelector }, - { 'ss17', kStylisticAlternativesType, kStylisticAltSeventeenOnSelector, kStylisticAltSeventeenOffSelector }, - { 'ss18', kStylisticAlternativesType, kStylisticAltEighteenOnSelector, kStylisticAltEighteenOffSelector }, - { 'ss19', kStylisticAlternativesType, kStylisticAltNineteenOnSelector, kStylisticAltNineteenOffSelector }, - { 'ss20', kStylisticAlternativesType, kStylisticAltTwentyOnSelector, kStylisticAltTwentyOffSelector }, - { 'subs', kVerticalPositionType, kInferiorsSelector, kNormalPositionSelector }, - { 'sups', kVerticalPositionType, kSuperiorsSelector, kNormalPositionSelector }, - { 'swsh', kContextualAlternatesType, kSwashAlternatesOnSelector, kSwashAlternatesOffSelector }, - { 'titl', kStyleOptionsType, kTitlingCapsSelector, kNoStyleOptionsSelector }, - { 'tnam', kCharacterShapeType, kTraditionalNamesCharactersSelector, 16 }, - { 'tnum', kNumberSpacingType, kMonospacedNumbersSelector, 4 }, - { 'trad', kCharacterShapeType, kTraditionalCharactersSelector, 16 }, - { 'twid', kTextSpacingType, kThirdWidthTextSelector, 7 }, - { 'unic', kLetterCaseType, 14, 15 }, - { 'valt', kTextSpacingType, kAltProportionalTextSelector, 7 }, - { 'vert', kVerticalSubstitutionType, kSubstituteVerticalFormsOnSelector, kSubstituteVerticalFormsOffSelector }, - { 'vhal', kTextSpacingType, kAltHalfWidthTextSelector, 7 }, - { 'vkna', kAlternateKanaType, kAlternateVertKanaOnSelector, kAlternateVertKanaOffSelector }, - { 'vpal', kTextSpacingType, kAltProportionalTextSelector, 7 }, - { 'vrt2', kVerticalSubstitutionType, kSubstituteVerticalFormsOnSelector, kSubstituteVerticalFormsOffSelector }, - { 'zero', kTypographicExtrasType, kSlashedZeroOnSelector, kSlashedZeroOffSelector }, -}; - -static int -_hb_feature_mapping_cmp (const void *key_, const void *entry_) -{ - unsigned int key = * (unsigned int *) key_; - const feature_mapping_t * entry = (const feature_mapping_t *) entry_; - return key < entry->otFeatureTag ? -1 : - key > entry->otFeatureTag ? 1 : - 0; -} - hb_bool_t _hb_coretext_shape (hb_shape_plan_t *shape_plan, hb_font_t *font, @@ -624,7 +448,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, CGFloat y_mult = (CGFloat) font->y_scale / ct_font_size; /* Attach marks to their bases, to match the 'ot' shaper. - * Adapted from hb-ot-shape:hb_form_clusters(). + * Adapted from a very old version of hb-ot-shape:hb_form_clusters(). * Note that this only makes us be closer to the 'ot' shaper, * but by no means the same. For example, if there's * B1 M1 B2 M2, and B1-B2 form a ligature, M2's cluster will @@ -653,11 +477,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, 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, - feature_mappings, - ARRAY_LENGTH (feature_mappings), - sizeof (feature_mappings[0]), - _hb_feature_mapping_cmp); + const hb_aat_feature_mapping_t * mapping = hb_aat_layout_find_feature_mapping (features[i].tag); if (!mapping) continue; @@ -766,7 +586,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, } else { active_feature_t *feature = active_features.find (&event->feature); if (feature) - active_features.remove (feature - active_features.arrayZ); + active_features.remove (feature - active_features.arrayZ()); } } } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh index 49663d215dc..58c190d275d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh @@ -43,9 +43,10 @@ struct hb_options_t { - unsigned int unused : 1; /* In-case sign bit is here. */ - unsigned int initialized : 1; - unsigned int uniscribe_bug_compatible : 1; + bool unused : 1; /* In-case sign bit is here. */ + bool initialized : 1; + bool uniscribe_bug_compatible : 1; + bool aat : 1; }; union hb_options_union_t { @@ -67,7 +68,10 @@ hb_options (void) u.i = _hb_options.get_relaxed (); if (unlikely (!u.i)) + { _hb_options_init (); + u.i = _hb_options.get_relaxed (); + } return u.opts; } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-deprecated.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-deprecated.h index eac7efb42f1..5af9bdbd85d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-deprecated.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-deprecated.h @@ -50,14 +50,191 @@ typedef hb_bool_t (*hb_font_get_glyph_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t *glyph, void *user_data); -HB_EXTERN void +HB_EXTERN HB_DEPRECATED_FOR(hb_font_funcs_set_nominal_glyph_func or hb_font_funcs_set_variation_glyph_func) void hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_func_t func, void *user_data, hb_destroy_func_t destroy); -HB_EXTERN void +HB_EXTERN HB_DEPRECATED void hb_set_invert (hb_set_t *set); +/** + * hb_unicode_eastasian_width_func_t: + * + * Deprecated: 2.0.0 + */ +typedef unsigned int (*hb_unicode_eastasian_width_func_t) (hb_unicode_funcs_t *ufuncs, + hb_codepoint_t unicode, + void *user_data); + +/** + * hb_unicode_funcs_set_eastasian_width_func: + * @ufuncs: a Unicode function structure + * @func: (closure user_data) (destroy destroy) (scope notified): + * @user_data: + * @destroy: + * + * + * + * Since: 0.9.2 + * Deprecated: 2.0.0 + **/ +HB_EXTERN HB_DEPRECATED void +hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs, + hb_unicode_eastasian_width_func_t func, + void *user_data, hb_destroy_func_t destroy); + +/** + * hb_unicode_eastasian_width: + * + * Since: 0.9.2 + * Deprecated: 2.0.0 + **/ +HB_EXTERN HB_DEPRECATED unsigned int +hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs, + hb_codepoint_t unicode); + + +/** + * hb_unicode_decompose_compatibility_func_t: + * @ufuncs: a Unicode function structure + * @u: codepoint to decompose + * @decomposed: address of codepoint array (of length %HB_UNICODE_MAX_DECOMPOSITION_LEN) to write decomposition into + * @user_data: user data pointer as passed to hb_unicode_funcs_set_decompose_compatibility_func() + * + * Fully decompose @u to its Unicode compatibility decomposition. The codepoints of the decomposition will be written to @decomposed. + * The complete length of the decomposition will be returned. + * + * If @u has no compatibility decomposition, zero should be returned. + * + * The Unicode standard guarantees that a buffer of length %HB_UNICODE_MAX_DECOMPOSITION_LEN codepoints will always be sufficient for any + * compatibility decomposition plus an terminating value of 0. Consequently, @decompose must be allocated by the caller to be at least this length. Implementations + * of this function type must ensure that they do not write past the provided array. + * + * Return value: number of codepoints in the full compatibility decomposition of @u, or 0 if no decomposition available. + * + * Deprecated: 2.0.0 + */ +typedef unsigned int (*hb_unicode_decompose_compatibility_func_t) (hb_unicode_funcs_t *ufuncs, + hb_codepoint_t u, + hb_codepoint_t *decomposed, + void *user_data); + +/** + * HB_UNICODE_MAX_DECOMPOSITION_LEN: + * + * See Unicode 6.1 for details on the maximum decomposition length. + * + * Deprecated: 2.0.0 + */ +#define HB_UNICODE_MAX_DECOMPOSITION_LEN (18+1) /* codepoints */ + +/** + * hb_unicode_funcs_set_decompose_compatibility_func: + * @ufuncs: a Unicode function structure + * @func: (closure user_data) (destroy destroy) (scope notified): + * @user_data: + * @destroy: + * + * + * + * Since: 0.9.2 + * Deprecated: 2.0.0 + **/ +HB_EXTERN HB_DEPRECATED void +hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs, + hb_unicode_decompose_compatibility_func_t func, + void *user_data, hb_destroy_func_t destroy); + +/** + * hb_unicode_decompose_compatibility: + * + * + * Deprecated: 2.0.0 + **/ +HB_EXTERN HB_DEPRECATED unsigned int +hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs, + hb_codepoint_t u, + hb_codepoint_t *decomposed); + + +typedef hb_position_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data, + hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, + void *user_data); +typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t; +typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_v_kerning_func_t; + +/** + * hb_font_funcs_set_glyph_h_kerning_func: + * @ffuncs: font functions. + * @func: (closure user_data) (destroy destroy) (scope notified): + * @user_data: + * @destroy: + * + * + * + * Since: 0.9.2 + * Deprecated: 2.0.0 + **/ +HB_EXTERN void +hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs, + hb_font_get_glyph_h_kerning_func_t func, + void *user_data, hb_destroy_func_t destroy); + +/** + * hb_font_funcs_set_glyph_v_kerning_func: + * @ffuncs: font functions. + * @func: (closure user_data) (destroy destroy) (scope notified): + * @user_data: + * @destroy: + * + * + * + * Since: 0.9.2 + * Deprecated: 2.0.0 + **/ +HB_EXTERN void +hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs, + hb_font_get_glyph_v_kerning_func_t func, + void *user_data, hb_destroy_func_t destroy); + +HB_EXTERN hb_position_t +hb_font_get_glyph_h_kerning (hb_font_t *font, + hb_codepoint_t left_glyph, hb_codepoint_t right_glyph); +HB_EXTERN hb_position_t +hb_font_get_glyph_v_kerning (hb_font_t *font, + hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph); + +HB_EXTERN void +hb_font_get_glyph_kerning_for_direction (hb_font_t *font, + hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, + hb_direction_t direction, + hb_position_t *x, hb_position_t *y); + +/* Like hb_ot_layout_table_find_script, but takes zero-terminated array of scripts to test */ +HB_EXTERN HB_DEPRECATED_FOR (hb_ot_layout_table_select_script) hb_bool_t +hb_ot_layout_table_choose_script (hb_face_t *face, + hb_tag_t table_tag, + const hb_tag_t *script_tags, + unsigned int *script_index, + hb_tag_t *chosen_script); + +HB_EXTERN HB_DEPRECATED_FOR (hb_ot_layout_script_select_language) hb_bool_t +hb_ot_layout_script_find_language (hb_face_t *face, + hb_tag_t table_tag, + unsigned int script_index, + hb_tag_t language_tag, + unsigned int *language_index); + +HB_EXTERN HB_DEPRECATED_FOR (hb_ot_tags_from_script_and_language) void +hb_ot_tags_from_script (hb_script_t script, + hb_tag_t *script_tag_1, + hb_tag_t *script_tag_2); + +HB_EXTERN HB_DEPRECATED_FOR (hb_ot_tags_from_script_and_language) hb_tag_t +hb_ot_tag_from_language (hb_language_t language); + + #endif HB_END_DECLS diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dsalgs.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dsalgs.hh index 7e06ff17010..eb15c089eb6 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dsalgs.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dsalgs.hh @@ -29,6 +29,8 @@ #include "hb.hh" +#include "hb-null.hh" + /* Void! For when we need a expression-type of void. */ typedef const struct _hb_void_t *hb_void_t; @@ -507,20 +509,40 @@ struct hb_auto_t : Type void fini (void) {} }; +template <typename T> +struct hb_array_t +{ + inline hb_array_t (void) : arrayZ (nullptr), len (0) {} + inline hb_array_t (const T *array_, unsigned int len_) : arrayZ (array_), len (len_) {} + + inline const T& operator [] (unsigned int i) const + { + if (unlikely (i >= len)) return Null(T); + return arrayZ[i]; + } + + inline void free (void) { ::free ((void *) arrayZ); arrayZ = nullptr; len = 0; } + + const T *arrayZ; + unsigned int len; +}; + struct hb_bytes_t { - inline hb_bytes_t (void) : bytes (nullptr), len (0) {} - inline hb_bytes_t (const char *bytes_, unsigned int len_) : bytes (bytes_), len (len_) {} - inline hb_bytes_t (const void *bytes_, unsigned int len_) : bytes ((const char *) bytes_), len (len_) {} + inline hb_bytes_t (void) : arrayZ (nullptr), len (0) {} + inline hb_bytes_t (const char *bytes_, unsigned int len_) : arrayZ (bytes_), len (len_) {} + inline hb_bytes_t (const void *bytes_, unsigned int len_) : arrayZ ((const char *) bytes_), len (len_) {} + template <typename T> + inline hb_bytes_t (const T& array) : arrayZ ((const char *) array.arrayZ), len (array.len) {} - inline void free (void) { ::free ((void *) bytes); bytes = nullptr; len = 0; } + inline void free (void) { ::free ((void *) arrayZ); arrayZ = nullptr; len = 0; } inline int cmp (const hb_bytes_t &a) const { if (len != a.len) return (int) a.len - (int) len; - return memcmp (a.bytes, bytes, len); + return memcmp (a.arrayZ, arrayZ, len); } static inline int cmp (const void *pa, const void *pb) { @@ -529,7 +551,7 @@ struct hb_bytes_t return b->cmp (*a); } - const char *bytes; + const char *arrayZ; unsigned int len; }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc index 92c34152335..bba1ee3fa0c 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc @@ -36,12 +36,12 @@ /** - * hb_face_count: Get number of faces on the blob - * @blob: - * + * hb_face_count: + * @blob: a blob. * + * Get number of faces in a blob. * - * Return value: Number of faces on the blob + * Return value: Number of faces in @blob * * Since: 1.7.7 **/ @@ -163,11 +163,12 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void return hb_blob_reference (data->blob); const OT::OpenTypeFontFile &ot_file = *data->blob->as<OT::OpenTypeFontFile> (); - const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index); + unsigned int base_offset; + const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index, &base_offset); const OT::OpenTypeTable &table = ot_face.get_table_by_tag (tag); - hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, table.offset, table.length); + hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, base_offset + table.offset, table.length); return blob; } @@ -324,6 +325,8 @@ hb_face_make_immutable (hb_face_t *face) { if (unlikely (hb_object_is_inert (face))) return; + if (face->immutable) + return; face->immutable = true; } @@ -487,6 +490,9 @@ hb_face_get_glyph_count (const hb_face_t *face) /** * hb_face_get_table_tags: * @face: a face. + * @start_offset: index of first tag to return. + * @table_count: input length of @table_tags array, output number of items written. + * @table_tags: array to write tags into. * * Retrieves table tags for a face, if possible. * @@ -628,7 +634,7 @@ _hb_face_builder_data_reference_blob (hb_face_builder_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.arrayZ[i].blob)); + face_length += hb_ceil_to_4 (hb_blob_get_length (data->tables[i].blob)); char *buf = (char *) malloc (face_length); if (unlikely (!buf)) @@ -682,7 +688,7 @@ _hb_face_builder_reference_table (hb_face_t *face, hb_tag_t tag, void *user_data * After tables are added to the face, it can be compiled to a binary * font file by calling hb_face_reference_blob(). * - * Return value: (transfer full) New face. + * Return value: (transfer full): New face. * * Since: 1.9.0 **/ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc index bc831dd53f2..7a430237c73 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc @@ -31,6 +31,8 @@ #include "hb-font.hh" #include "hb-machinery.hh" +#include "hb-ot.h" + /* * hb_font_funcs_t @@ -101,9 +103,42 @@ hb_font_get_nominal_glyph_default (hb_font_t *font, hb_codepoint_t *glyph, void *user_data HB_UNUSED) { + if (font->has_nominal_glyphs_func ()) + { + return font->get_nominal_glyphs (1, &unicode, 0, glyph, 0); + } return font->parent->get_nominal_glyph (unicode, glyph); } +#define hb_font_get_nominal_glyphs_nil hb_font_get_nominal_glyphs_default +static unsigned int +hb_font_get_nominal_glyphs_default (hb_font_t *font, + void *font_data HB_UNUSED, + unsigned int count, + const hb_codepoint_t *first_unicode, + unsigned int unicode_stride, + hb_codepoint_t *first_glyph, + unsigned int glyph_stride, + void *user_data HB_UNUSED) +{ + if (font->has_nominal_glyph_func ()) + { + for (unsigned int i = 0; i < count; i++) + { + if (!font->get_nominal_glyph (*first_unicode, first_glyph)) + return i; + + first_unicode = &StructAtOffset<hb_codepoint_t> (first_unicode, unicode_stride); + first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride); + } + return count; + } + + return font->parent->get_nominal_glyphs (count, + first_unicode, unicode_stride, + first_glyph, glyph_stride); +} + static hb_bool_t hb_font_get_variation_glyph_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, @@ -141,6 +176,12 @@ hb_font_get_glyph_h_advance_default (hb_font_t *font, hb_codepoint_t glyph, void *user_data HB_UNUSED) { + if (font->has_glyph_h_advances_func ()) + { + hb_position_t ret; + font->get_glyph_h_advances (1, &glyph, 0, &ret, 0); + return ret; + } return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph)); } @@ -159,6 +200,12 @@ hb_font_get_glyph_v_advance_default (hb_font_t *font, hb_codepoint_t glyph, void *user_data HB_UNUSED) { + if (font->has_glyph_v_advances_func ()) + { + hb_position_t ret; + font->get_glyph_v_advances (1, &glyph, 0, &ret, 0); + return ret; + } return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph)); } @@ -167,7 +214,7 @@ static void hb_font_get_glyph_h_advances_default (hb_font_t* font, void* font_data HB_UNUSED, unsigned int count, - hb_codepoint_t *first_glyph, + const hb_codepoint_t *first_glyph, unsigned int glyph_stride, hb_position_t *first_advance, unsigned int advance_stride, @@ -199,7 +246,7 @@ static void hb_font_get_glyph_v_advances_default (hb_font_t* font, void* font_data HB_UNUSED, unsigned int count, - hb_codepoint_t *first_glyph, + const hb_codepoint_t *first_glyph, unsigned int glyph_stride, hb_position_t *first_advance, unsigned int advance_stride, @@ -586,6 +633,8 @@ hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs) { if (unlikely (hb_object_is_inert (ffuncs))) return; + if (ffuncs->immutable) + return; ffuncs->immutable = true; } @@ -793,8 +842,8 @@ hb_font_get_glyph_v_advance (hb_font_t *font, **/ void hb_font_get_glyph_h_advances (hb_font_t* font, - unsigned count, - hb_codepoint_t *first_glyph, + unsigned int count, + const hb_codepoint_t *first_glyph, unsigned glyph_stride, hb_position_t *first_advance, unsigned advance_stride) @@ -811,8 +860,8 @@ hb_font_get_glyph_h_advances (hb_font_t* font, **/ void hb_font_get_glyph_v_advances (hb_font_t* font, - unsigned count, - hb_codepoint_t *first_glyph, + unsigned int count, + const hb_codepoint_t *first_glyph, unsigned glyph_stride, hb_position_t *first_advance, unsigned advance_stride) @@ -873,6 +922,7 @@ hb_font_get_glyph_v_origin (hb_font_t *font, * Return value: * * Since: 0.9.2 + * Deprecated: 2.0.0 **/ hb_position_t hb_font_get_glyph_h_kerning (hb_font_t *font, @@ -892,6 +942,7 @@ hb_font_get_glyph_h_kerning (hb_font_t *font, * Return value: * * Since: 0.9.2 + * Deprecated: 2.0.0 **/ hb_position_t hb_font_get_glyph_v_kerning (hb_font_t *font, @@ -991,7 +1042,7 @@ hb_font_get_glyph_from_name (hb_font_t *font, * hb_font_get_extents_for_direction: * @font: a font. * @direction: - * @extents: + * @extents: (out): * * * @@ -1036,8 +1087,8 @@ hb_font_get_glyph_advance_for_direction (hb_font_t *font, HB_EXTERN void hb_font_get_glyph_advances_for_direction (hb_font_t* font, hb_direction_t direction, - unsigned count, - hb_codepoint_t *first_glyph, + unsigned int count, + const hb_codepoint_t *first_glyph, unsigned glyph_stride, hb_position_t *first_advance, unsigned advance_stride) @@ -1120,6 +1171,7 @@ hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, * * * Since: 0.9.2 + * Deprecated: 2.0.0 **/ void hb_font_get_glyph_kerning_for_direction (hb_font_t *font, @@ -1254,18 +1306,8 @@ DEFINE_NULL_INSTANCE (hb_font_t) = }; -/** - * hb_font_create: (Xconstructor) - * @face: a face. - * - * - * - * Return value: (transfer full): - * - * Since: 0.9.2 - **/ -hb_font_t * -hb_font_create (hb_face_t *face) +static hb_font_t * +_hb_font_create (hb_face_t *face) { hb_font_t *font; @@ -1285,6 +1327,27 @@ hb_font_create (hb_face_t *face) } /** + * hb_font_create: (Xconstructor) + * @face: a face. + * + * + * + * Return value: (transfer full): + * + * Since: 0.9.2 + **/ +hb_font_t * +hb_font_create (hb_face_t *face) +{ + hb_font_t *font = _hb_font_create (face); + + /* Install our in-house, very lightweight, funcs. */ + hb_ot_font_set_funcs (font); + + return font; +} + +/** * hb_font_create_sub_font: * @parent: parent font. * @@ -1300,7 +1363,7 @@ hb_font_create_sub_font (hb_font_t *parent) if (unlikely (!parent)) parent = hb_font_get_empty (); - hb_font_t *font = hb_font_create (parent->face); + hb_font_t *font = _hb_font_create (parent->face); if (unlikely (hb_object_is_inert (font))) return font; @@ -1444,6 +1507,8 @@ hb_font_make_immutable (hb_font_t *font) { if (unlikely (hb_object_is_inert (font))) return; + if (font->immutable) + return; if (font->parent) hb_font_make_immutable (font->parent); @@ -1703,9 +1768,11 @@ hb_font_get_ppem (hb_font_t *font, /** * hb_font_set_ptem: * @font: a font. - * @ptem: + * @ptem: font size in points. * - * Sets "point size" of the font. + * Sets "point size" of the font. Set to 0 to unset. + * + * There are 72 points in an inch. * * Since: 1.6.0 **/ @@ -1843,8 +1910,6 @@ hb_font_get_var_coords_normalized (hb_font_t *font, } -#ifndef HB_DISABLE_DEPRECATED - /* * Deprecated get_glyph_func(): */ @@ -1931,9 +1996,9 @@ hb_font_get_variation_glyph_trampoline (hb_font_t *font, /** * hb_font_funcs_set_glyph_func: * @ffuncs: font functions. - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: + * @func: (closure user_data) (destroy destroy) (scope notified): callback function. + * @user_data: data to pass to @func. + * @destroy: function to call when @user_data is not needed anymore. * * Deprecated. Use hb_font_funcs_set_nominal_glyph_func() and * hb_font_funcs_set_variation_glyph_func() instead. @@ -1967,5 +2032,3 @@ hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, trampoline, trampoline_destroy); } - -#endif /* HB_DISABLE_DEPRECATED */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h index 6cd486979b0..74c61aba487 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h @@ -125,6 +125,14 @@ typedef hb_bool_t (*hb_font_get_variation_glyph_func_t) (hb_font_t *font, void * hb_codepoint_t *glyph, void *user_data); +typedef unsigned int (*hb_font_get_nominal_glyphs_func_t) (hb_font_t *font, void *font_data, + unsigned int count, + const hb_codepoint_t *first_unicode, + unsigned int unicode_stride, + hb_codepoint_t *first_glyph, + unsigned int glyph_stride, + void *user_data); + typedef hb_position_t (*hb_font_get_glyph_advance_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t glyph, @@ -133,8 +141,8 @@ typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_h_advance_func_t; typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_v_advance_func_t; typedef void (*hb_font_get_glyph_advances_func_t) (hb_font_t* font, void* font_data, - unsigned count, - hb_codepoint_t *first_glyph, + unsigned int count, + const hb_codepoint_t *first_glyph, unsigned glyph_stride, hb_position_t *first_advance, unsigned advance_stride, @@ -149,12 +157,6 @@ typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *fon typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_h_origin_func_t; typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_v_origin_func_t; -typedef hb_position_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data, - hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, - void *user_data); -typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t; -typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_v_kerning_func_t; - typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t glyph, @@ -227,6 +229,22 @@ hb_font_funcs_set_nominal_glyph_func (hb_font_funcs_t *ffuncs, void *user_data, hb_destroy_func_t destroy); /** + * hb_font_funcs_set_nominal_glyphs_func: + * @ffuncs: font functions. + * @func: (closure user_data) (destroy destroy) (scope notified): + * @user_data: + * @destroy: + * + * + * + * Since: 2.0.0 + **/ +HB_EXTERN void +hb_font_funcs_set_nominal_glyphs_func (hb_font_funcs_t *ffuncs, + hb_font_get_nominal_glyphs_func_t func, + void *user_data, hb_destroy_func_t destroy); + +/** * hb_font_funcs_set_variation_glyph_func: * @ffuncs: font functions. * @func: (closure user_data) (destroy destroy) (scope notified): @@ -339,38 +357,6 @@ hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs, void *user_data, hb_destroy_func_t destroy); /** - * hb_font_funcs_set_glyph_h_kerning_func: - * @ffuncs: font functions. - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * - * - * - * Since: 0.9.2 - **/ -HB_EXTERN void -hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs, - hb_font_get_glyph_h_kerning_func_t func, - void *user_data, hb_destroy_func_t destroy); - -/** - * hb_font_funcs_set_glyph_v_kerning_func: - * @ffuncs: font functions. - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * - * - * - * Since: 0.9.2 - **/ -HB_EXTERN void -hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs, - hb_font_get_glyph_v_kerning_func_t func, - void *user_data, hb_destroy_func_t destroy); - -/** * hb_font_funcs_set_glyph_extents_func: * @ffuncs: font functions. * @func: (closure user_data) (destroy destroy) (scope notified): @@ -461,15 +447,15 @@ hb_font_get_glyph_v_advance (hb_font_t *font, HB_EXTERN void hb_font_get_glyph_h_advances (hb_font_t* font, - unsigned count, - hb_codepoint_t *first_glyph, + unsigned int count, + const hb_codepoint_t *first_glyph, unsigned glyph_stride, hb_position_t *first_advance, unsigned advance_stride); HB_EXTERN void hb_font_get_glyph_v_advances (hb_font_t* font, - unsigned count, - hb_codepoint_t *first_glyph, + unsigned int count, + const hb_codepoint_t *first_glyph, unsigned glyph_stride, hb_position_t *first_advance, unsigned advance_stride); @@ -483,13 +469,6 @@ hb_font_get_glyph_v_origin (hb_font_t *font, hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y); -HB_EXTERN hb_position_t -hb_font_get_glyph_h_kerning (hb_font_t *font, - hb_codepoint_t left_glyph, hb_codepoint_t right_glyph); -HB_EXTERN hb_position_t -hb_font_get_glyph_v_kerning (hb_font_t *font, - hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph); - HB_EXTERN hb_bool_t hb_font_get_glyph_extents (hb_font_t *font, hb_codepoint_t glyph, @@ -531,8 +510,8 @@ hb_font_get_glyph_advance_for_direction (hb_font_t *font, HB_EXTERN void hb_font_get_glyph_advances_for_direction (hb_font_t* font, hb_direction_t direction, - unsigned count, - hb_codepoint_t *first_glyph, + unsigned int count, + const hb_codepoint_t *first_glyph, unsigned glyph_stride, hb_position_t *first_advance, unsigned advance_stride); @@ -552,12 +531,6 @@ hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, hb_direction_t direction, hb_position_t *x, hb_position_t *y); -HB_EXTERN void -hb_font_get_glyph_kerning_for_direction (hb_font_t *font, - hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, - hb_direction_t direction, - hb_position_t *x, hb_position_t *y); - HB_EXTERN hb_bool_t hb_font_get_glyph_extents_for_origin (hb_font_t *font, hb_codepoint_t glyph, diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh index 4c8d0aeec03..e10d56745fc 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh @@ -43,6 +43,7 @@ HB_FONT_FUNC_IMPLEMENT (font_h_extents) \ HB_FONT_FUNC_IMPLEMENT (font_v_extents) \ HB_FONT_FUNC_IMPLEMENT (nominal_glyph) \ + HB_FONT_FUNC_IMPLEMENT (nominal_glyphs) \ HB_FONT_FUNC_IMPLEMENT (variation_glyph) \ HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \ HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \ @@ -212,6 +213,18 @@ struct hb_font_t unicode, glyph, klass->user_data.nominal_glyph); } + inline unsigned int get_nominal_glyphs (unsigned int count, + const hb_codepoint_t *first_unicode, + unsigned int unicode_stride, + hb_codepoint_t *first_glyph, + unsigned int glyph_stride) + { + return klass->get.f.nominal_glyphs (this, user_data, + count, + first_unicode, unicode_stride, + first_glyph, glyph_stride, + klass->user_data.nominal_glyphs); + } inline hb_bool_t get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector, hb_codepoint_t *glyph) @@ -237,7 +250,7 @@ struct hb_font_t } inline void get_glyph_h_advances (unsigned int count, - hb_codepoint_t *first_glyph, + const hb_codepoint_t *first_glyph, unsigned int glyph_stride, hb_position_t *first_advance, unsigned int advance_stride) @@ -250,7 +263,7 @@ struct hb_font_t } inline void get_glyph_v_advances (unsigned int count, - hb_codepoint_t *first_glyph, + const hb_codepoint_t *first_glyph, unsigned int glyph_stride, hb_position_t *first_advance, unsigned int advance_stride) @@ -377,8 +390,8 @@ struct hb_font_t *y = get_glyph_v_advance (glyph); } inline void get_glyph_advances_for_direction (hb_direction_t direction, - unsigned count, - hb_codepoint_t *first_glyph, + unsigned int count, + const hb_codepoint_t *first_glyph, unsigned glyph_stride, hb_position_t *first_advance, unsigned advance_stride) @@ -502,8 +515,8 @@ struct hb_font_t hb_position_t *x, hb_position_t *y) { if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) { - *x = get_glyph_h_kerning (first_glyph, second_glyph); *y = 0; + *x = get_glyph_h_kerning (first_glyph, second_glyph); } else { *x = 0; *y = get_glyph_v_kerning (first_glyph, second_glyph); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc index 5d6abb29d16..18fb72a73cf 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc @@ -33,6 +33,7 @@ #include "hb-font.hh" #include "hb-machinery.hh" +#include "hb-cache.hh" #include FT_ADVANCES_H #include FT_MULTIPLE_MASTERS_H @@ -44,30 +45,29 @@ * In general, this file does a fine job of what it's supposed to do. * There are, however, things that need more work: * - * - I remember seeing FT_Get_Advance() without the NO_HINTING flag to be buggy. - * Have not investigated. - * * - FreeType works in 26.6 mode. Clients can decide to use that mode, and everything * would work fine. However, we also abuse this API for performing in font-space, * but don't pass the correct flags to FreeType. We just abuse the no-hinting mode * for that, such that no rounding etc happens. As such, we don't set ppem, and * pass NO_HINTING as load_flags. Would be much better to use NO_SCALE, and scale - * ourselves, like we do in uniscribe, etc. + * ourselves. * * - We don't handle / allow for emboldening / obliqueing. * * - In the future, we should add constructors to create fonts in font space? - * - * - FT_Load_Glyph() is extremely costly. Do something about it? */ struct hb_ft_font_t { + mutable hb_mutex_t lock; FT_Face ft_face; int load_flags; bool symbol; /* Whether selected cmap is symbol cmap. */ bool unref; /* Whether to destroy ft_face when done. */ + + mutable hb_atomic_int_t cached_x_scale; + mutable hb_advance_cache_t advance_cache; }; static hb_ft_font_t * @@ -78,12 +78,16 @@ _hb_ft_font_create (FT_Face ft_face, bool symbol, bool unref) if (unlikely (!ft_font)) return nullptr; + ft_font->lock.init (); ft_font->ft_face = ft_face; ft_font->symbol = symbol; ft_font->unref = unref; ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING; + ft_font->cached_x_scale.set (0); + ft_font->advance_cache.init (); + return ft_font; } @@ -98,9 +102,13 @@ _hb_ft_font_destroy (void *data) { hb_ft_font_t *ft_font = (hb_ft_font_t *) data; + ft_font->advance_cache.fini (); + if (ft_font->unref) _hb_ft_face_destroy (ft_font->ft_face); + ft_font->lock.fini (); + free (ft_font); } @@ -168,6 +176,7 @@ hb_ft_get_nominal_glyph (hb_font_t *font HB_UNUSED, void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + hb_lock_t lock (ft_font->lock); unsigned int g = FT_Get_Char_Index (ft_font->ft_face, unicode); if (unlikely (!g)) @@ -191,6 +200,32 @@ hb_ft_get_nominal_glyph (hb_font_t *font HB_UNUSED, return true; } +static unsigned int +hb_ft_get_nominal_glyphs (hb_font_t *font HB_UNUSED, + void *font_data, + unsigned int count, + const hb_codepoint_t *first_unicode, + unsigned int unicode_stride, + hb_codepoint_t *first_glyph, + unsigned int glyph_stride, + void *user_data HB_UNUSED) +{ + const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + hb_lock_t lock (ft_font->lock); + unsigned int done; + for (done = 0; + done < count && (*first_glyph = FT_Get_Char_Index (ft_font->ft_face, *first_unicode)); + done++) + { + first_unicode = &StructAtOffset<hb_codepoint_t> (first_unicode, unicode_stride); + first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride); + } + /* We don't need to do ft_font->symbol dance here, since HB calls the singular + * nominal_glyph() for what we don't handle here. */ + return done; +} + + static hb_bool_t hb_ft_get_variation_glyph (hb_font_t *font HB_UNUSED, void *font_data, @@ -200,6 +235,7 @@ hb_ft_get_variation_glyph (hb_font_t *font HB_UNUSED, void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + hb_lock_t lock (ft_font->lock); unsigned int g = FT_Face_GetCharVariantIndex (ft_font->ft_face, unicode, variation_selector); if (unlikely (!g)) @@ -209,22 +245,45 @@ hb_ft_get_variation_glyph (hb_font_t *font HB_UNUSED, return true; } -static hb_position_t -hb_ft_get_glyph_h_advance (hb_font_t *font, - void *font_data, - hb_codepoint_t glyph, - void *user_data HB_UNUSED) +static void +hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data, + unsigned count, + const hb_codepoint_t *first_glyph, + unsigned glyph_stride, + hb_position_t *first_advance, + unsigned advance_stride, + void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; - FT_Fixed v; + hb_lock_t lock (ft_font->lock); + FT_Face ft_face = ft_font->ft_face; + int load_flags = ft_font->load_flags; + int mult = font->x_scale < 0 ? -1 : +1; - if (unlikely (FT_Get_Advance (ft_font->ft_face, glyph, ft_font->load_flags, &v))) - return 0; + if (font->x_scale != ft_font->cached_x_scale.get ()) + { + ft_font->advance_cache.clear (); + ft_font->cached_x_scale.set (font->x_scale); + } - if (font->x_scale < 0) - v = -v; + for (unsigned int i = 0; i < count; i++) + { + FT_Fixed v = 0; + hb_codepoint_t glyph = *first_glyph; - return (v + (1<<9)) >> 10; + unsigned int cv; + if (ft_font->advance_cache.get (glyph, &cv)) + v = cv; + else + { + FT_Get_Advance (ft_face, glyph, load_flags, &v); + ft_font->advance_cache.set (glyph, v); + } + + *first_advance = (v * mult + (1<<9)) >> 10; + first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride); + first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride); + } } static hb_position_t @@ -234,6 +293,7 @@ hb_ft_get_glyph_v_advance (hb_font_t *font, void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + hb_lock_t lock (ft_font->lock); FT_Fixed v; if (unlikely (FT_Get_Advance (ft_font->ft_face, glyph, ft_font->load_flags | FT_LOAD_VERTICAL_LAYOUT, &v))) @@ -256,6 +316,7 @@ hb_ft_get_glyph_v_origin (hb_font_t *font, void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags))) @@ -274,23 +335,6 @@ hb_ft_get_glyph_v_origin (hb_font_t *font, return true; } -static hb_position_t -hb_ft_get_glyph_h_kerning (hb_font_t *font, - void *font_data, - hb_codepoint_t left_glyph, - hb_codepoint_t right_glyph, - void *user_data HB_UNUSED) -{ - const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; - FT_Vector kerningv; - - FT_Kerning_Mode mode = font->x_ppem ? FT_KERNING_DEFAULT : FT_KERNING_UNFITTED; - if (FT_Get_Kerning (ft_font->ft_face, left_glyph, right_glyph, mode, &kerningv)) - return 0; - - return kerningv.x; -} - static hb_bool_t hb_ft_get_glyph_extents (hb_font_t *font, void *font_data, @@ -299,6 +343,7 @@ hb_ft_get_glyph_extents (hb_font_t *font, void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags))) @@ -331,6 +376,7 @@ hb_ft_get_glyph_contour_point (hb_font_t *font HB_UNUSED, void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags))) @@ -356,8 +402,10 @@ hb_ft_get_glyph_name (hb_font_t *font HB_UNUSED, void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + hb_lock_t lock (ft_font->lock); + FT_Face ft_face = ft_font->ft_face; - hb_bool_t ret = !FT_Get_Glyph_Name (ft_font->ft_face, glyph, name, size); + hb_bool_t ret = !FT_Get_Glyph_Name (ft_face, glyph, name, size); if (ret && (size && !*name)) ret = false; @@ -372,6 +420,7 @@ hb_ft_get_glyph_from_name (hb_font_t *font HB_UNUSED, void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; if (len < 0) @@ -404,6 +453,7 @@ hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED, void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; metrics->ascender = ft_face->size->metrics.ascender; metrics->descender = ft_face->size->metrics.descender; @@ -430,13 +480,12 @@ static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ft hb_font_funcs_set_font_h_extents_func (funcs, hb_ft_get_font_h_extents, nullptr, nullptr); //hb_font_funcs_set_font_v_extents_func (funcs, hb_ft_get_font_v_extents, nullptr, nullptr); hb_font_funcs_set_nominal_glyph_func (funcs, hb_ft_get_nominal_glyph, nullptr, nullptr); + hb_font_funcs_set_nominal_glyphs_func (funcs, hb_ft_get_nominal_glyphs, nullptr, nullptr); hb_font_funcs_set_variation_glyph_func (funcs, hb_ft_get_variation_glyph, nullptr, nullptr); - hb_font_funcs_set_glyph_h_advance_func (funcs, hb_ft_get_glyph_h_advance, nullptr, nullptr); + hb_font_funcs_set_glyph_h_advances_func (funcs, hb_ft_get_glyph_h_advances, nullptr, nullptr); hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ft_get_glyph_v_advance, nullptr, nullptr); //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ft_get_glyph_h_origin, nullptr, nullptr); hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ft_get_glyph_v_origin, nullptr, nullptr); - hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ft_get_glyph_h_kerning, nullptr, nullptr); - //hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ft_get_glyph_v_kerning, nullptr, nullptr); hb_font_funcs_set_glyph_extents_func (funcs, hb_ft_get_glyph_extents, nullptr, nullptr); hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ft_get_glyph_contour_point, nullptr, nullptr); hb_font_funcs_set_glyph_name_func (funcs, hb_ft_get_glyph_name, nullptr, nullptr); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-glib.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-glib.cc index 18f3a81db64..a34acbba1d7 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-glib.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-glib.cc @@ -30,7 +30,6 @@ #include "hb-glib.h" -#include "hb-unicode.hh" #include "hb-machinery.hh" @@ -202,14 +201,6 @@ hb_glib_unicode_combining_class (hb_unicode_funcs_t *ufuncs HB_UNUSED, return (hb_unicode_combining_class_t) g_unichar_combining_class (unicode); } -static unsigned int -hb_glib_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs HB_UNUSED, - hb_codepoint_t unicode, - void *user_data HB_UNUSED) -{ - return g_unichar_iswide (unicode) ? 2 : 1; -} - static hb_unicode_general_category_t hb_glib_unicode_general_category (hb_unicode_funcs_t *ufuncs HB_UNUSED, hb_codepoint_t unicode, @@ -334,37 +325,6 @@ hb_glib_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED, return ret; } -static unsigned int -hb_glib_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs HB_UNUSED, - hb_codepoint_t u, - hb_codepoint_t *decomposed, - void *user_data HB_UNUSED) -{ -#if GLIB_CHECK_VERSION(2,29,12) - return g_unichar_fully_decompose (u, true, decomposed, HB_UNICODE_MAX_DECOMPOSITION_LEN); -#endif - - /* If the user doesn't have GLib >= 2.29.12 we have to perform - * a round trip to UTF-8 and the associated memory management dance. */ - gchar utf8[6]; - gchar *utf8_decomposed, *c; - gsize utf8_len, utf8_decomposed_len, i; - - /* Convert @u to UTF-8 and normalise it in NFKD mode. This performs the compatibility decomposition. */ - utf8_len = g_unichar_to_utf8 (u, utf8); - utf8_decomposed = g_utf8_normalize (utf8, utf8_len, G_NORMALIZE_NFKD); - utf8_decomposed_len = g_utf8_strlen (utf8_decomposed, -1); - - assert (utf8_decomposed_len <= HB_UNICODE_MAX_DECOMPOSITION_LEN); - - for (i = 0, c = utf8_decomposed; i < utf8_decomposed_len; i++, c = g_utf8_next_char (c)) - *decomposed++ = g_utf8_get_char (c); - - g_free (utf8_decomposed); - - return utf8_decomposed_len; -} - #ifdef HB_USE_ATEXIT static void free_static_glib_funcs (void); @@ -376,10 +336,12 @@ static struct hb_glib_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader { hb_unicode_funcs_t *funcs = hb_unicode_funcs_create (nullptr); -#define HB_UNICODE_FUNC_IMPLEMENT(name) \ - hb_unicode_funcs_set_##name##_func (funcs, hb_glib_unicode_##name, nullptr, nullptr); - HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS -#undef HB_UNICODE_FUNC_IMPLEMENT + hb_unicode_funcs_set_combining_class_func (funcs, hb_glib_unicode_combining_class, nullptr, nullptr); + hb_unicode_funcs_set_general_category_func (funcs, hb_glib_unicode_general_category, nullptr, nullptr); + hb_unicode_funcs_set_mirroring_func (funcs, hb_glib_unicode_mirroring, nullptr, nullptr); + hb_unicode_funcs_set_script_func (funcs, hb_glib_unicode_script, nullptr, nullptr); + hb_unicode_funcs_set_compose_func (funcs, hb_glib_unicode_compose, nullptr, nullptr); + hb_unicode_funcs_set_decompose_func (funcs, hb_glib_unicode_decompose, nullptr, nullptr); hb_unicode_funcs_make_immutable (funcs); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc index 817278f309b..6b2b6f19d45 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc @@ -33,6 +33,8 @@ #include <graphite2/Segment.h> +#include "hb-ot-tag.h" + HB_SHAPER_DATA_ENSURE_DEFINE(graphite2, face) HB_SHAPER_DATA_ENSURE_DEFINE(graphite2, font) @@ -95,6 +97,32 @@ retry: return d; } +static void hb_graphite2_release_table(const void *data, const void *table_buffer) +{ + hb_graphite2_face_data_t *face_data = (hb_graphite2_face_data_t *) data; + hb_graphite2_tablelist_t *tlist = face_data->tlist.get(); + + hb_graphite2_tablelist_t *prev = nullptr; + hb_graphite2_tablelist_t *curr = tlist; + while (curr) + { + if (hb_blob_get_data(curr->blob, nullptr) == table_buffer) + { + if (prev == nullptr) + face_data->tlist.cmpexch(tlist, curr->next); + else + prev->next = curr->next; + hb_blob_destroy(curr->blob); + free(curr); + break; + } + prev = curr; + curr = curr->next; + } +} + +static gr_face_ops hb_graphite2_face_ops = { sizeof(gr_face_ops), hb_graphite2_get_table, hb_graphite2_release_table }; + hb_graphite2_face_data_t * _hb_graphite2_shaper_face_data_create (hb_face_t *face) { @@ -113,7 +141,7 @@ _hb_graphite2_shaper_face_data_create (hb_face_t *face) return nullptr; data->face = face; - data->grface = gr_make_face (data, &hb_graphite2_get_table, gr_face_preloadAll); + data->grface = gr_make_face_with_ops (data, &hb_graphite2_face_ops, gr_face_preloadAll); if (unlikely (!data->grface)) { free (data); @@ -251,11 +279,16 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan, /* TODO ensure_native_direction. */ - hb_tag_t script_tag[2]; - hb_ot_tags_from_script (hb_buffer_get_script (buffer), &script_tag[0], &script_tag[1]); + hb_tag_t script_tag[HB_OT_MAX_TAGS_PER_SCRIPT]; + unsigned int count = HB_OT_MAX_TAGS_PER_SCRIPT; + hb_ot_tags_from_script_and_language (hb_buffer_get_script (buffer), + HB_LANGUAGE_INVALID, + &count, + script_tag, + nullptr, nullptr); seg = gr_make_seg (nullptr, grface, - script_tag[1] == HB_TAG_NONE ? script_tag[0] : script_tag[1], + count ? script_tag[count - 1] : HB_OT_TAG_DEFAULT_SCRIPT, feats, gr_utf32, chars, buffer->len, 2 | (hb_buffer_get_direction (buffer) == HB_DIRECTION_RTL ? 1 : 0)); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.h index 05c55debec9..1720191b42f 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.h @@ -41,7 +41,7 @@ hb_graphite2_face_get_gr_face (hb_face_t *face); #ifndef HB_DISABLE_DEPRECATED -HB_EXTERN gr_font * +HB_EXTERN HB_DEPRECATED_FOR (hb_graphite2_face_get_gr_face) gr_font * hb_graphite2_font_get_gr_font (hb_font_t *font); #endif diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-icu.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-icu.cc index 564f71fe2dc..e012314b507 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-icu.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-icu.cc @@ -31,7 +31,6 @@ #include "hb-icu.h" -#include "hb-unicode.hh" #include "hb-machinery.hh" #include <unicode/uchar.h> @@ -73,25 +72,6 @@ hb_icu_unicode_combining_class (hb_unicode_funcs_t *ufuncs HB_UNUSED, return (hb_unicode_combining_class_t) u_getCombiningClass (unicode); } -static unsigned int -hb_icu_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs HB_UNUSED, - hb_codepoint_t unicode, - void *user_data HB_UNUSED) -{ - switch (u_getIntPropertyValue(unicode, UCHAR_EAST_ASIAN_WIDTH)) - { - case U_EA_WIDE: - case U_EA_FULLWIDTH: - return 2; - case U_EA_NEUTRAL: - case U_EA_AMBIGUOUS: - case U_EA_HALFWIDTH: - case U_EA_NARROW: - return 1; - } - return 1; -} - static hb_unicode_general_category_t hb_icu_unicode_general_category (hb_unicode_funcs_t *ufuncs HB_UNUSED, hb_codepoint_t unicode, @@ -309,39 +289,6 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED, return ret; } -static unsigned int -hb_icu_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs HB_UNUSED, - hb_codepoint_t u, - hb_codepoint_t *decomposed, - void *user_data HB_UNUSED) -{ - UChar utf16[2], normalized[2 * HB_UNICODE_MAX_DECOMPOSITION_LEN + 1]; - unsigned int len; - int32_t utf32_len; - hb_bool_t err; - UErrorCode icu_err; - - /* Copy @u into a UTF-16 array to be passed to ICU. */ - len = 0; - err = false; - U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), u, err); - if (err) - return 0; - - /* Normalise the codepoint using NFKD mode. */ - icu_err = U_ZERO_ERROR; - len = unorm2_normalize (unorm2_getNFKDInstance (&icu_err), utf16, len, normalized, ARRAY_LENGTH (normalized), &icu_err); - if (U_FAILURE (icu_err)) - return 0; - - /* Convert the decomposed form from UTF-16 to UTF-32. */ - icu_err = U_ZERO_ERROR; - u_strToUTF32 ((UChar32*) decomposed, HB_UNICODE_MAX_DECOMPOSITION_LEN, &utf32_len, normalized, len, &icu_err); - if (U_FAILURE (icu_err)) - return 0; - - return utf32_len; -} #ifdef HB_USE_ATEXIT static void free_static_icu_funcs (void); @@ -360,10 +307,12 @@ static struct hb_icu_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader_ hb_unicode_funcs_t *funcs = hb_unicode_funcs_create (nullptr); -#define HB_UNICODE_FUNC_IMPLEMENT(name) \ - hb_unicode_funcs_set_##name##_func (funcs, hb_icu_unicode_##name, user_data, nullptr); - HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS -#undef HB_UNICODE_FUNC_IMPLEMENT + hb_unicode_funcs_set_combining_class_func (funcs, hb_icu_unicode_combining_class, nullptr, nullptr); + hb_unicode_funcs_set_general_category_func (funcs, hb_icu_unicode_general_category, nullptr, nullptr); + hb_unicode_funcs_set_mirroring_func (funcs, hb_icu_unicode_mirroring, nullptr, nullptr); + hb_unicode_funcs_set_script_func (funcs, hb_icu_unicode_script, nullptr, nullptr); + hb_unicode_funcs_set_compose_func (funcs, hb_icu_unicode_compose, user_data, nullptr); + hb_unicode_funcs_set_decompose_func (funcs, hb_icu_unicode_decompose, user_data, nullptr); hb_unicode_funcs_make_immutable (funcs); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh index 62f49072113..d836a94d629 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh @@ -217,6 +217,9 @@ struct hb_dispatch_context_t #ifndef HB_SANITIZE_MAX_OPS_MIN #define HB_SANITIZE_MAX_OPS_MIN 16384 #endif +#ifndef HB_SANITIZE_MAX_OPS_MAX +#define HB_SANITIZE_MAX_OPS_MAX 0x3FFFFFFF +#endif struct hb_sanitize_context_t : hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE> @@ -224,7 +227,8 @@ struct hb_sanitize_context_t : inline hb_sanitize_context_t (void) : debug_depth (0), start (nullptr), end (nullptr), - writable (false), edit_count (0), max_ops (0), + max_ops (0), + writable (false), edit_count (0), blob (nullptr), num_glyphs (65536), num_glyphs_set (false) {} @@ -252,6 +256,23 @@ struct hb_sanitize_context_t : } inline unsigned int get_num_glyphs (void) { return num_glyphs; } + inline void set_max_ops (int max_ops_) { max_ops = max_ops_; } + + /* TODO + * This set_object() thing is to use sanitize at runtime lookup + * application time. This is very distinct from the regular + * sanitizer operation, so, eventually, separate into another + * type and make hb_aat_apply_context_t use that one instead + * of abusing this one. + */ + template <typename T> + inline void set_object (const T& obj) + { + this->start = (const char *) &obj; + this->end = (const char *) &obj + obj.get_size (); + assert (this->start <= this->end); /* Must not overflow. */ + } + inline void start_processing (void) { this->start = this->blob->data; @@ -282,10 +303,10 @@ struct hb_sanitize_context_t : inline bool check_range (const void *base, unsigned int len) const { const char *p = (const char *) base; - bool ok = this->max_ops-- > 0 && - this->start <= p && + bool ok = this->start <= p && p <= this->end && - (unsigned int) (this->end - p) >= len; + (unsigned int) (this->end - p) >= len && + this->max_ops-- > 0; DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0, "check_range [%p..%p] (%d bytes) in [%p..%p] -> %s", @@ -296,7 +317,8 @@ struct hb_sanitize_context_t : return likely (ok); } - inline bool check_array (const void *base, unsigned int record_size, unsigned int len) const + template <typename T> + inline bool check_array (const T *base, unsigned int len, unsigned int record_size = T::static_size) const { const char *p = (const char *) base; bool overflows = hb_unsigned_mul_overflows (len, record_size); @@ -422,10 +444,10 @@ struct hb_sanitize_context_t : mutable unsigned int debug_depth; const char *start, *end; + mutable int max_ops; private: bool writable; unsigned int edit_count; - mutable int max_ops; hb_blob_t *blob; unsigned int num_glyphs; bool num_glyphs_set; @@ -590,7 +612,7 @@ struct Supplier } inline Supplier (const hb_vector_t<Type> *v) { - head = v->arrayZ; + head = v->arrayZ(); len = v->len; stride = sizeof (Type); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh index d8cdf4b64ac..75b89addb9a 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh @@ -137,5 +137,13 @@ struct hb_mutex_t inline void fini (void) { hb_mutex_impl_finish (&m); } }; +struct hb_lock_t +{ + inline hb_lock_t (hb_mutex_t &mutex_) : mutex (mutex_) { mutex.lock (); } + inline ~hb_lock_t (void) { mutex.unlock (); } + private: + hb_mutex_t &mutex; +}; + #endif /* HB_MUTEX_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-null.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-null.hh index 7128f0a94f3..bf01b3af741 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-null.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-null.hh @@ -36,7 +36,7 @@ /* Global nul-content Null pool. Enlarge as necessary. */ -#define HB_NULL_POOL_SIZE 264 +#define HB_NULL_POOL_SIZE 1024 extern HB_INTERNAL hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)]; @@ -73,19 +73,6 @@ static_assert (true, "Just so we take semicolon after.") #define DEFINE_NULL_INSTANCE(Type) \ const Type _hb_Null_##Type -/* Specializaiton to disallow Null objects. */ -#define DECLARE_NULL_DISALLOW(Type) \ - template <> inline const Type& Null<Type> (void) -#define DECLARE_NULL_NAMSPACE_DISALLOW(Namespace, Type) \ - } /* Close namespace. */ \ - template <> \ - /*static*/ inline const Namespace::Type& Null<Namespace::Type> (void) { \ - extern void *_hb_undefined; \ - return *reinterpret_cast<const Namespace::Type *> (_hb_undefined); \ - } \ - namespace Namespace { \ - static_assert (true, "Just so we take semicolon after.") - /* Global writable pool. Enlarge as necessary. */ /* To be fully correct, CrapPool must be thread_local. However, we do not rely on CrapPool diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file.hh index d3b748602ba..8772c79fa10 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file.hh @@ -287,188 +287,159 @@ struct TTCHeader /* * Mac Resource Fork + * + * http://mirror.informatimago.com/next/developer.apple.com/documentation/mac/MoreToolbox/MoreToolbox-99.html */ -struct ResourceRefItem +struct ResourceRecord { - inline bool sanitize (hb_sanitize_context_t *c) const + inline const OpenTypeFontFace & get_face (const void *data_base) const + { return CastR<OpenTypeFontFace> ((data_base+offset).arrayZ); } + + inline bool sanitize (hb_sanitize_context_t *c, + const void *data_base) const { TRACE_SANITIZE (this); - // actual data sanitization is done on ResourceForkHeader sanitizer - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this) && + offset.sanitize (c, data_base) && + get_face (data_base).sanitize (c)); } - HBINT16 id; /* Resource ID, is really should be signed? */ + protected: + HBUINT16 id; /* Resource ID. */ HBINT16 nameOffset; /* Offset from beginning of resource name list - * to resource name, minus means there is no */ - HBUINT8 attr; /* Resource attributes */ - HBUINT24 dataOffset; /* Offset from beginning of resource data to + * to resource name, -1 means there is none. */ + HBUINT8 attrs; /* Resource attributes */ + OffsetTo<LArrayOf<HBUINT8>, HBUINT24, false> + offset; /* Offset from beginning of data block to * data for this resource */ HBUINT32 reserved; /* Reserved for handle to resource */ public: DEFINE_SIZE_STATIC (12); }; -struct ResourceTypeItem +#define HB_TAG_sfnt HB_TAG ('s','f','n','t') + +struct ResourceTypeRecord { - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - // RefList sanitization is done on ResourceMap sanitizer - return_trace (likely (c->check_struct (this))); - } + inline unsigned int get_resource_count (void) const + { return tag == HB_TAG_sfnt ? resCountM1 + 1 : 0; } - inline unsigned int get_resource_count () const - { - return numRes + 1; - } + inline bool is_sfnt (void) const { return tag == HB_TAG_sfnt; } - inline bool is_sfnt () const + inline const ResourceRecord& get_resource_record (unsigned int i, + const void *type_base) const { - return type == HB_TAG ('s','f','n','t'); + return hb_array_t<ResourceRecord> ((type_base+resourcesZ).arrayZ, + get_resource_count ()) [i]; } - inline const ResourceRefItem& get_ref_item (const void *base, - unsigned int i) const + inline bool sanitize (hb_sanitize_context_t *c, + const void *type_base, + const void *data_base) const { - return (base+refList)[i]; + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + resourcesZ.sanitize (c, type_base, + get_resource_count (), + data_base)); } protected: - Tag type; /* Resource type */ - HBUINT16 numRes; /* Number of resource this type in map minus 1 */ - OffsetTo<UnsizedArrayOf<ResourceRefItem> > - refList; /* Offset from beginning of resource type list - * to reference list for this type */ + Tag tag; /* Resource type. */ + HBUINT16 resCountM1; /* Number of resources minus 1. */ + OffsetTo<UnsizedArrayOf<ResourceRecord>, HBUINT16, false> + resourcesZ; /* Offset from beginning of resource type list + * to reference item list for this type. */ public: DEFINE_SIZE_STATIC (8); }; struct ResourceMap { - inline bool sanitize (hb_sanitize_context_t *c) const + inline unsigned int get_face_count (void) const { - TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (this))) - return_trace (false); - for (unsigned int i = 0; i < get_types_count (); ++i) + unsigned int count = get_type_count (); + for (unsigned int i = 0; i < count; i++) { - const ResourceTypeItem& type = get_type (i); - if (unlikely (!type.sanitize (c))) - return_trace (false); - for (unsigned int j = 0; j < type.get_resource_count (); ++j) - if (unlikely (!get_ref_item (type, j).sanitize (c))) - return_trace (false); + const ResourceTypeRecord& type = get_type_record (i); + if (type.is_sfnt ()) + return type.get_resource_count (); } - return_trace (true); - } - - inline const ResourceTypeItem& get_type (unsigned int i) const - { - // Why offset from the second byte of the object? I'm not sure - return ((&reserved[2])+typeList)[i]; + return 0; } - inline unsigned int get_types_count () const + inline const OpenTypeFontFace& get_face (unsigned int idx, + const void *data_base) const { - return nTypes + 1; + unsigned int count = get_type_count (); + for (unsigned int i = 0; i < count; i++) + { + const ResourceTypeRecord& type = get_type_record (i); + /* The check for idx < count is here because ResourceRecord is NOT null-safe. + * Because an offset of 0 there does NOT mean null. */ + if (type.is_sfnt () && idx < type.get_resource_count ()) + return type.get_resource_record (idx, &(this+typeList)).get_face (data_base); + } + return Null (OpenTypeFontFace); } - inline const ResourceRefItem &get_ref_item (const ResourceTypeItem &type, - unsigned int i) const + inline bool sanitize (hb_sanitize_context_t *c, const void *data_base) const { - return type.get_ref_item (&(this+typeList), i); + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + typeList.sanitize (c, this, + &(this+typeList), + data_base)); } - inline const PString& get_name (const ResourceRefItem &item, - unsigned int i) const - { - if (item.nameOffset == -1) - return Null (PString); + private: + inline unsigned int get_type_count (void) const { return (this+typeList).lenM1 + 1; } - return StructAtOffset<PString> (this, nameList + item.nameOffset); - } + inline const ResourceTypeRecord& get_type_record (unsigned int i) const + { return (this+typeList)[i]; } protected: - HBUINT8 reserved[16]; /* Reserved for copy of resource header */ - LOffsetTo<ResourceMap> - reserved1; /* Reserved for handle to next resource map */ - HBUINT16 reserved2; /* Reserved for file reference number */ - HBUINT16 attr; /* Resource fork attribute */ - OffsetTo<UnsizedArrayOf<ResourceTypeItem> > + HBUINT8 reserved0[16]; /* Reserved for copy of resource header */ + HBUINT32 reserved1; /* Reserved for handle to next resource map */ + HBUINT16 resreved2; /* Reserved for file reference number */ + HBUINT16 attrs; /* Resource fork attribute */ + OffsetTo<ArrayOfM1<ResourceTypeRecord>, HBUINT16, false> typeList; /* Offset from beginning of map to * resource type list */ - HBUINT16 nameList; /* Offset from beginning of map to + Offset16 nameList; /* Offset from beginning of map to * resource name list */ - HBUINT16 nTypes; /* Number of types in the map minus 1 */ public: - DEFINE_SIZE_STATIC (30); + DEFINE_SIZE_STATIC (28); }; struct ResourceForkHeader { - inline unsigned int get_face_count () const - { - const ResourceMap &resource_map = this+map; - for (unsigned int i = 0; i < resource_map.get_types_count (); ++i) - { - const ResourceTypeItem& type = resource_map.get_type (i); - if (type.is_sfnt ()) - return type.get_resource_count (); - } - return 0; - } + inline unsigned int get_face_count (void) const + { return (this+map).get_face_count (); } - inline const LArrayOf<HBUINT8>& get_data (const ResourceTypeItem& type, - unsigned int idx) const + inline const OpenTypeFontFace& get_face (unsigned int idx, + unsigned int *base_offset = nullptr) const { - const ResourceMap &resource_map = this+map; - unsigned int offset = dataOffset; - offset += resource_map.get_ref_item (type, idx).dataOffset; - return StructAtOffset<LArrayOf<HBUINT8> > (this, offset); - } - - inline const OpenTypeFontFace& get_face (unsigned int idx) const - { - const ResourceMap &resource_map = this+map; - for (unsigned int i = 0; i < resource_map.get_types_count (); ++i) - { - const ResourceTypeItem& type = resource_map.get_type (i); - if (type.is_sfnt () && idx < type.get_resource_count ()) - return (OpenTypeFontFace&) get_data (type, idx).arrayZ; - } - return Null (OpenTypeFontFace); + const OpenTypeFontFace &face = (this+map).get_face (idx, &(this+data)); + if (base_offset) + *base_offset = (const char *) &face - (const char *) this; + return face; } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (this))) - return_trace (false); - - const ResourceMap &resource_map = this+map; - if (unlikely (!resource_map.sanitize (c))) - return_trace (false); - - for (unsigned int i = 0; i < resource_map.get_types_count (); ++i) - { - const ResourceTypeItem& type = resource_map.get_type (i); - for (unsigned int j = 0; j < type.get_resource_count (); ++j) - { - const LArrayOf<HBUINT8>& data = get_data (type, j); - if (unlikely (!(data.sanitize (c) && - ((OpenTypeFontFace&) data.arrayZ).sanitize (c)))) - return_trace (false); - } - } - - return_trace (true); + return_trace (c->check_struct (this) && + data.sanitize (c, this, dataLen) && + map.sanitize (c, this, &(this+data))); } protected: - HBUINT32 dataOffset; /* Offset from beginning of resource fork + LOffsetTo<UnsizedArrayOf<HBUINT8>, false> + data; /* Offset from beginning of resource fork * to resource data */ - LOffsetTo<ResourceMap> + LOffsetTo<ResourceMap, false> map; /* Offset from beginning of resource fork * to resource map */ HBUINT32 dataLen; /* Length of resource data */ @@ -485,7 +456,7 @@ struct OpenTypeFontFile { enum { CFFTag = HB_TAG ('O','T','T','O'), /* OpenType with Postscript outlines */ - TrueTypeTag = HB_TAG ( 0 , 1 , 0 , 0 ), /* OpenType with TrueType outlines */ + TrueTypeTag = HB_TAG ( 0 , 1 , 0 , 0 ), /* OpenType with TrueType outlines */ TTCTag = HB_TAG ('t','t','c','f'), /* TrueType Collection */ DFontTag = HB_TAG ( 0 , 0 , 1 , 0 ), /* DFont Mac Resource Fork */ TrueTag = HB_TAG ('t','r','u','e'), /* Obsolete Apple TrueType */ @@ -502,12 +473,14 @@ struct OpenTypeFontFile case Typ1Tag: case TrueTypeTag: return 1; case TTCTag: return u.ttcHeader.get_face_count (); -// case DFontTag: return u.rfHeader.get_face_count (); + case DFontTag: return u.rfHeader.get_face_count (); default: return 0; } } - inline const OpenTypeFontFace& get_face (unsigned int i) const + inline const OpenTypeFontFace& get_face (unsigned int i, unsigned int *base_offset = nullptr) const { + if (base_offset) + *base_offset = 0; switch (u.tag) { /* Note: for non-collection SFNT data we ignore index. This is because * Apple dfont container is a container of SFNT's. So each SFNT is a @@ -517,7 +490,7 @@ struct OpenTypeFontFile case Typ1Tag: case TrueTypeTag: return u.fontFace; case TTCTag: return u.ttcHeader.get_face (i); -// case DFontTag: return u.rfHeader.get_face (i); + case DFontTag: return u.rfHeader.get_face (i, base_offset); default: return Null(OpenTypeFontFace); } } @@ -544,7 +517,7 @@ struct OpenTypeFontFile case Typ1Tag: case TrueTypeTag: return_trace (u.fontFace.sanitize (c)); case TTCTag: return_trace (u.ttcHeader.sanitize (c)); -// case DFontTag: return_trace (u.rfHeader.sanitize (c)); + case DFontTag: return_trace (u.rfHeader.sanitize (c)); default: return_trace (true); } } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh index ef18163fa56..9d2e1fa7c1d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh @@ -92,6 +92,9 @@ typedef IntType<uint32_t, 3> HBUINT24; /* 24-bit unsigned integer. */ /* 16-bit signed integer (HBINT16) that describes a quantity in FUnits. */ typedef HBINT16 FWORD; +/* 32-bit signed integer (HBINT32) that describes a quantity in FUnits. */ +typedef HBINT32 FWORD32; + /* 16-bit unsigned integer (HBUINT16) that describes a quantity in FUnits. */ typedef HBUINT16 UFWORD; @@ -155,10 +158,10 @@ struct Index : HBUINT16 { DECLARE_NULL_NAMESPACE_BYTES (OT, Index); /* Offset, Null offset = 0 */ -template <typename Type> +template <typename Type, bool has_null=true> struct Offset : Type { - inline bool is_null (void) const { return 0 == *this; } + inline bool is_null (void) const { return has_null && 0 == *this; } inline void *serialize (hb_serialize_context_t *c, const void *base) { @@ -226,20 +229,23 @@ struct FixedVersion * Use: (base+offset) */ -template <typename Type, typename OffsetType=HBUINT16> -struct OffsetTo : Offset<OffsetType> +template <typename Type, bool has_null_> struct assert_has_min_size { static_assert (Type::min_size > 0, ""); }; +template <typename Type> struct assert_has_min_size<Type, false> {}; + +template <typename Type, typename OffsetType=HBUINT16, bool has_null=true> +struct OffsetTo : Offset<OffsetType, has_null> { + static_assert (sizeof (assert_has_min_size<Type, has_null>) || true, ""); + inline const Type& operator () (const void *base) const { - unsigned int offset = *this; - if (unlikely (!offset)) return Null(Type); - return StructAtOffset<const Type> (base, offset); + if (unlikely (this->is_null ())) return Null(Type); + return StructAtOffset<const Type> (base, *this); } inline Type& operator () (void *base) const { - unsigned int offset = *this; - if (unlikely (!offset)) return Crap(Type); - return StructAtOffset<Type> (base, offset); + if (unlikely (this->is_null ())) return Crap(Type); + return StructAtOffset<Type> (base, *this); } inline Type& serialize (hb_serialize_context_t *c, const void *base) @@ -260,46 +266,70 @@ struct OffsetTo : Offset<OffsetType> this->set (0); } - inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + inline bool sanitize_shallow (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); - unsigned int offset = *this; - if (unlikely (!offset)) return_trace (true); - if (unlikely (!c->check_range (base, offset))) return_trace (false); - const Type &obj = StructAtOffset<Type> (base, offset); - return_trace (likely (obj.sanitize (c)) || neuter (c)); + if (unlikely (this->is_null ())) return_trace (true); + if (unlikely (!c->check_range (base, *this))) return_trace (false); + return_trace (true); } - template <typename T> - inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const + + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (this))) return_trace (false); - unsigned int offset = *this; - if (unlikely (!offset)) return_trace (true); - if (unlikely (!c->check_range (base, offset))) return_trace (false); - const Type &obj = StructAtOffset<Type> (base, offset); - return_trace (likely (obj.sanitize (c, user_data)) || neuter (c)); + return_trace (sanitize_shallow (c, base) && + (this->is_null () || + StructAtOffset<Type> (base, *this).sanitize (c) || + neuter (c))); + } + template <typename T1> + inline bool sanitize (hb_sanitize_context_t *c, const void *base, T1 d1) const + { + TRACE_SANITIZE (this); + return_trace (sanitize_shallow (c, base) && + (this->is_null () || + StructAtOffset<Type> (base, *this).sanitize (c, d1) || + neuter (c))); + } + template <typename T1, typename T2> + inline bool sanitize (hb_sanitize_context_t *c, const void *base, T1 d1, T2 d2) const + { + TRACE_SANITIZE (this); + return_trace (sanitize_shallow (c, base) && + (this->is_null () || + StructAtOffset<Type> (base, *this).sanitize (c, d1, d2) || + neuter (c))); + } + template <typename T1, typename T2, typename T3> + inline bool sanitize (hb_sanitize_context_t *c, const void *base, T1 d1, T2 d2, T3 d3) const + { + TRACE_SANITIZE (this); + return_trace (sanitize_shallow (c, base) && + (this->is_null () || + StructAtOffset<Type> (base, *this).sanitize (c, d1, d2, d3) || + neuter (c))); } /* Set the offset to Null */ - inline bool neuter (hb_sanitize_context_t *c) const { + inline bool neuter (hb_sanitize_context_t *c) const + { + if (!has_null) return false; return c->try_set (this, 0); } DEFINE_SIZE_STATIC (sizeof(OffsetType)); }; -template <typename Type> struct LOffsetTo : OffsetTo<Type, HBUINT32> {}; -template <typename Base, typename OffsetType, typename Type> -static inline const Type& operator + (const Base &base, const OffsetTo<Type, OffsetType> &offset) { return offset (base); } -template <typename Base, typename OffsetType, typename Type> -static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType> &offset) { return offset (base); } +template <typename Type, bool has_null=true> struct LOffsetTo : OffsetTo<Type, HBUINT32, has_null> {}; +template <typename Base, typename OffsetType, bool has_null, typename Type> +static inline const Type& operator + (const Base &base, const OffsetTo<Type, OffsetType, has_null> &offset) { return offset (base); } +template <typename Base, typename OffsetType, bool has_null, typename Type> +static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType, has_null> &offset) { return offset (base); } /* * Array Types */ -/* TODO Use it in ArrayOf, HeadlessArrayOf, and other places around the code base?? */ template <typename Type> struct UnsizedArrayOf { @@ -345,22 +375,22 @@ struct UnsizedArrayOf 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)); + return_trace (c->check_array (arrayZ, count)); } public: - Type arrayZ[VAR]; + 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> > {}; +template <typename Type, typename OffsetType, bool has_null=true> +struct UnsizedOffsetArrayOf : UnsizedArrayOf<OffsetTo<Type, OffsetType, has_null> > {}; /* Unsized array of offsets relative to the beginning of the array itself. */ -template <typename Type, typename OffsetType> -struct UnsizedOffsetListOf : UnsizedOffsetArrayOf<Type, OffsetType> +template <typename Type, typename OffsetType, bool has_null=true> +struct UnsizedOffsetListOf : UnsizedOffsetArrayOf<Type, OffsetType, has_null> { inline const Type& operator [] (unsigned int i) const { @@ -370,13 +400,13 @@ struct UnsizedOffsetListOf : UnsizedOffsetArrayOf<Type, OffsetType> inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const { TRACE_SANITIZE (this); - return_trace ((UnsizedOffsetArrayOf<Type, OffsetType>::sanitize (c, count, this))); + return_trace ((UnsizedOffsetArrayOf<Type, OffsetType, has_null>::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))); + return_trace ((UnsizedOffsetArrayOf<Type, OffsetType, has_null>::sanitize (c, count, this, user_data))); } }; @@ -487,12 +517,12 @@ struct ArrayOf inline bool sanitize_shallow (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (len.sanitize (c) && c->check_array (arrayZ, Type::static_size, len)); + return_trace (len.sanitize (c) && c->check_array (arrayZ, len)); } public: - LenType len; - Type arrayZ[VAR]; + LenType len; + Type arrayZ[VAR]; public: DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ); }; @@ -548,16 +578,16 @@ struct HeadlessArrayOf { inline const Type& operator [] (unsigned int i) const { - if (unlikely (i >= len || !i)) return Null(Type); + if (unlikely (i >= lenP1 || !i)) return Null(Type); return arrayZ[i-1]; } inline Type& operator [] (unsigned int i) { - if (unlikely (i >= len || !i)) return Crap(Type); + if (unlikely (i >= lenP1 || !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; } + { return lenP1.static_size + (lenP1 ? lenP1 - 1 : 0) * Type::static_size; } inline bool serialize (hb_serialize_context_t *c, Supplier<Type> &items, @@ -565,7 +595,7 @@ struct HeadlessArrayOf { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); - len.set (items_len); /* TODO(serialize) Overflow? */ + lenP1.set (items_len); /* TODO(serialize) Overflow? */ 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++) @@ -595,13 +625,57 @@ struct HeadlessArrayOf inline bool sanitize_shallow (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (len.sanitize (c) && - (!len || c->check_array (arrayZ, Type::static_size, len - 1))); + return_trace (lenP1.sanitize (c) && + (!lenP1 || c->check_array (arrayZ, lenP1 - 1))); } public: - LenType len; - Type arrayZ[VAR]; + LenType lenP1; + Type arrayZ[VAR]; + public: + DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ); +}; + +/* An array storing length-1. */ +template <typename Type, typename LenType=HBUINT16> +struct ArrayOfM1 +{ + inline const Type& operator [] (unsigned int i) const + { + if (unlikely (i > lenM1)) return Null(Type); + return arrayZ[i]; + } + inline Type& operator [] (unsigned int i) + { + if (unlikely (i > lenM1)) return Crap(Type); + return arrayZ[i]; + } + inline unsigned int get_size (void) const + { return lenM1.static_size + (lenM1 + 1) * Type::static_size; } + + template <typename T> + inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const + { + TRACE_SANITIZE (this); + if (unlikely (!sanitize_shallow (c))) return_trace (false); + unsigned int count = lenM1 + 1; + 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) const + { + TRACE_SANITIZE (this); + return_trace (lenM1.sanitize (c) && + (c->check_array (arrayZ, lenM1 + 1))); + } + + public: + LenType lenM1; + Type arrayZ[VAR]; public: DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ); }; @@ -631,7 +705,11 @@ struct SortedArrayOf : ArrayOf<Type, LenType> } }; -/* Binary-search arrays */ +/* + * Binary-search arrays + */ + +template <typename LenType=HBUINT16> struct BinSearchHeader { inline operator uint32_t (void) const { return len; } @@ -654,17 +732,117 @@ struct BinSearchHeader } protected: - HBUINT16 len; - HBUINT16 searchRange; - HBUINT16 entrySelector; - HBUINT16 rangeShift; + LenType len; + LenType searchRange; + LenType entrySelector; + LenType rangeShift; public: DEFINE_SIZE_STATIC (8); }; +template <typename Type, typename LenType=HBUINT16> +struct BinSearchArrayOf : SortedArrayOf<Type, BinSearchHeader<LenType> > {}; + +struct VarSizedBinSearchHeader +{ + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + HBUINT16 unitSize; /* Size of a lookup unit for this search in bytes. */ + HBUINT16 nUnits; /* Number of units of the preceding size to be searched. */ + HBUINT16 searchRange; /* The value of unitSize times the largest power of 2 + * that is less than or equal to the value of nUnits. */ + HBUINT16 entrySelector; /* The log base 2 of the largest power of 2 less than + * or equal to the value of nUnits. */ + HBUINT16 rangeShift; /* The value of unitSize times the difference of the + * value of nUnits minus the largest power of 2 less + * than or equal to the value of nUnits. */ + public: + DEFINE_SIZE_STATIC (10); +}; + template <typename Type> -struct BinSearchArrayOf : SortedArrayOf<Type, BinSearchHeader> {}; +struct VarSizedBinSearchArrayOf +{ + inline const Type& operator [] (unsigned int i) const + { + if (unlikely (i >= header.nUnits)) return Null(Type); + return StructAtOffset<Type> (&bytesZ, i * header.unitSize); + } + inline Type& operator [] (unsigned int i) + { + return StructAtOffset<Type> (&bytesZ, i * header.unitSize); + } + inline unsigned int get_size (void) const + { return header.static_size + header.nUnits * header.unitSize; } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (unlikely (!sanitize_shallow (c))) 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 && StructAtOffset<Type> (&bytesZ, 0).sanitize (c)); + + return_trace (true); + } + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + if (unlikely (!sanitize_shallow (c))) return_trace (false); + unsigned int count = header.nUnits; + for (unsigned int i = 0; i < count; i++) + if (unlikely (!(*this)[i].sanitize (c, base))) + return_trace (false); + return_trace (true); + } + + template <typename T> + inline const Type *bsearch (const T &key) const + { + unsigned int size = header.unitSize; + int min = 0, max = (int) header.nUnits - 1; + while (min <= max) + { + int mid = (min + max) / 2; + const Type *p = (const Type *) (((const char *) &bytesZ) + (mid * size)); + int c = p->cmp (key); + if (c < 0) + max = mid - 1; + else if (c > 0) + min = mid + 1; + else + return p; + } + return nullptr; + } + + private: + inline bool sanitize_shallow (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (header.sanitize (c) && + Type::static_size <= header.unitSize && + c->check_array (bytesZ.arrayZ, header.nUnits, header.unitSize)); + } + + protected: + VarSizedBinSearchHeader header; + UnsizedArrayOf<HBUINT8> bytesZ; + public: + DEFINE_SIZE_ARRAY (10, bytesZ); +}; } /* namespace OT */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh index e6876d12cf6..e5793c387ea 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh @@ -231,7 +231,7 @@ struct CmapSubtableFormat4 inline void init (const CmapSubtableFormat4 *subtable) { segCount = subtable->segCountX2 / 2; - endCount = subtable->values; + endCount = subtable->values.arrayZ; startCount = endCount + segCount + 1; idDelta = startCount + segCount; idRangeOffset = idDelta + segCount; @@ -369,7 +369,8 @@ struct CmapSubtableFormat4 HBUINT16 entrySelector; /* log2(searchRange/2) */ HBUINT16 rangeShift; /* 2 x segCount - searchRange */ - HBUINT16 values[VAR]; + UnsizedArrayOf<HBUINT16> + values; #if 0 HBUINT16 endCount[segCount]; /* End characterCode for each segment, * last=0xFFFFu. */ @@ -377,7 +378,8 @@ struct CmapSubtableFormat4 HBUINT16 startCount[segCount]; /* Start character code for each segment. */ HBINT16 idDelta[segCount]; /* Delta for all character codes in segment. */ HBUINT16 idRangeOffset[segCount];/* Offsets into glyphIdArray or 0 */ - HBUINT16 glyphIdArray[VAR]; /* Glyph index array (arbitrary length) */ + UnsizedArrayOf<HBUINT16> + glyphIdArray; /* Glyph index array (arbitrary length) */ #endif public: @@ -493,7 +495,7 @@ struct CmapSubtableLongSegmented { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); - Supplier<CmapSubtableLongGroup> supplier (group_data.arrayZ, 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; } @@ -707,9 +709,9 @@ struct VariationSelectorRecord HBUINT24 varSelector; /* Variation selector. */ LOffsetTo<DefaultUVS> - defaultUVS; /* Offset to Default UVS Table. May be 0. */ + defaultUVS; /* Offset to Default UVS Table. May be 0. */ LOffsetTo<NonDefaultUVS> - nonDefaultUVS; /* Offset to Non-Default UVS Table. May be 0. */ + nonDefaultUVS; /* Offset to Non-Default UVS Table. May be 0. */ public: DEFINE_SIZE_STATIC (11); }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh index 8bedf2224a0..1e1fe095613 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh @@ -128,7 +128,7 @@ struct IndexSubtableFormat1Or3 { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && - c->check_array (offsetArrayZ, offsetArrayZ[0].static_size, glyph_count + 1)); + offsetArrayZ.sanitize (c, glyph_count + 1)); } bool get_image_data (unsigned int idx, @@ -144,7 +144,8 @@ struct IndexSubtableFormat1Or3 } IndexSubtableHeader header; - Offset<OffsetType> offsetArrayZ[VAR]; + UnsizedArrayOf<Offset<OffsetType> > + offsetArrayZ; public: DEFINE_SIZE_ARRAY(8, offsetArrayZ); }; @@ -205,24 +206,23 @@ struct IndexSubtableRecord TRACE_SANITIZE (this); return_trace (c->check_struct (this) && firstGlyphIndex <= lastGlyphIndex && - offsetToSubtable.sanitize (c, this, lastGlyphIndex - firstGlyphIndex + 1)); + offsetToSubtable.sanitize (c, base, lastGlyphIndex - firstGlyphIndex + 1)); } - inline bool get_extents (hb_glyph_extents_t *extents) const + inline bool get_extents (hb_glyph_extents_t *extents, + const void *base) const { - return (this+offsetToSubtable).get_extents (extents); + return (base+offsetToSubtable).get_extents (extents); } - bool get_image_data (unsigned int gid, + bool get_image_data (unsigned int gid, + const void *base, unsigned int *offset, unsigned int *length, unsigned int *format) const { - if (gid < firstGlyphIndex || gid > lastGlyphIndex) - { - return false; - } - return (this+offsetToSubtable).get_image_data (gid - firstGlyphIndex, + if (gid < firstGlyphIndex || gid > lastGlyphIndex) return false; + return (base+offsetToSubtable).get_image_data (gid - firstGlyphIndex, offset, length, format); } @@ -240,12 +240,7 @@ struct IndexSubtableArray inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const { TRACE_SANITIZE (this); - if (unlikely (!c->check_array (&indexSubtablesZ, indexSubtablesZ[0].static_size, count))) - return_trace (false); - for (unsigned int i = 0; i < count; i++) - if (unlikely (!indexSubtablesZ[i].sanitize (c, this))) - return_trace (false); - return_trace (true); + return_trace (indexSubtablesZ.sanitize (c, count, this)); } public: @@ -255,17 +250,14 @@ struct IndexSubtableArray { unsigned int firstGlyphIndex = indexSubtablesZ[i].firstGlyphIndex; unsigned int lastGlyphIndex = indexSubtablesZ[i].lastGlyphIndex; - if (firstGlyphIndex <= glyph && glyph <= lastGlyphIndex) { + if (firstGlyphIndex <= glyph && glyph <= lastGlyphIndex) return &indexSubtablesZ[i]; - } } return nullptr; } protected: - IndexSubtableRecord indexSubtablesZ[VAR]; - public: - DEFINE_SIZE_ARRAY(0, indexSubtablesZ); + UnsizedArrayOf<IndexSubtableRecord> indexSubtablesZ; }; struct BitmapSizeTable @@ -278,18 +270,20 @@ struct BitmapSizeTable TRACE_SANITIZE (this); return_trace (c->check_struct (this) && indexSubtableArrayOffset.sanitize (c, base, numberOfIndexSubtables) && - c->check_range (&(base+indexSubtableArrayOffset), indexTablesSize) && horizontal.sanitize (c) && vertical.sanitize (c)); } - const IndexSubtableRecord *find_table (hb_codepoint_t glyph, const void *base) const + const IndexSubtableRecord *find_table (hb_codepoint_t glyph, + const void *base, + const void **out_base) const { + *out_base = &(base+indexSubtableArrayOffset); return (base+indexSubtableArrayOffset).find_table (glyph, numberOfIndexSubtables); } protected: - LOffsetTo<IndexSubtableArray> + LOffsetTo<IndexSubtableArray, false> indexSubtableArrayOffset; HBUINT32 indexTablesSize; HBUINT32 numberOfIndexSubtables; @@ -350,7 +344,8 @@ struct CBLC protected: const IndexSubtableRecord *find_table (hb_codepoint_t glyph, - unsigned int *x_ppem, unsigned int *y_ppem) const + unsigned int *x_ppem, unsigned int *y_ppem, + const void **base) const { /* TODO: Make it possible to select strike. */ @@ -363,7 +358,7 @@ struct CBLC { *x_ppem = sizeTables[i].ppemX; *y_ppem = sizeTables[i].ppemY; - return sizeTables[i].find_table (glyph, this); + return sizeTables[i].find_table (glyph, this, base); } } @@ -421,15 +416,16 @@ struct CBDT if (!cblc) return false; // Not a color bitmap font. - const IndexSubtableRecord *subtable_record = this->cblc->find_table(glyph, &x_ppem, &y_ppem); + const void *base; + const IndexSubtableRecord *subtable_record = this->cblc->find_table (glyph, &x_ppem, &y_ppem, &base); if (!subtable_record || !x_ppem || !y_ppem) return false; - if (subtable_record->get_extents (extents)) + if (subtable_record->get_extents (extents, base)) return true; unsigned int image_offset = 0, image_length = 0, image_format = 0; - if (!subtable_record->get_image_data (glyph, &image_offset, &image_length, &image_format)) + if (!subtable_record->get_image_data (glyph, base, &image_offset, &image_length, &image_format)) return false; { @@ -480,7 +476,7 @@ struct CBDT { unsigned int image_offset = 0, image_length = 0, image_format = 0; - if (!subtable_record.get_image_data (gid, + if (!subtable_record.get_image_data (gid, &subtable_array, &image_offset, &image_length, &image_format)) continue; @@ -527,8 +523,8 @@ struct CBDT protected: - FixedVersion<> version; - HBUINT8 dataZ[VAR]; + FixedVersion<> version; + UnsizedArrayOf<HBUINT8> dataZ; public: DEFINE_SIZE_ARRAY(4, dataZ); }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh index 070226f18e2..a59d2bfa93e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh @@ -129,9 +129,9 @@ struct COLR protected: HBUINT16 version; /* Table version number */ HBUINT16 numBaseGlyphs; /* Number of Base Glyph Records */ - LOffsetTo<UnsizedArrayOf<BaseGlyphRecord> > + LOffsetTo<UnsizedArrayOf<BaseGlyphRecord>, false> baseGlyphsZ; /* Offset to Base Glyph records. */ - LOffsetTo<UnsizedArrayOf<LayerRecord> > + LOffsetTo<UnsizedArrayOf<LayerRecord>, false> layersZ; /* Offset to Layer Records */ HBUINT16 numLayers; /* Number of Layer Records */ public: diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh index 2c9fced093e..e354ced5c28 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh @@ -118,15 +118,15 @@ struct CPALV1Tail } protected: - LOffsetTo<UnsizedArrayOf<HBUINT32> > + LOffsetTo<UnsizedArrayOf<HBUINT32>, false> paletteFlagsZ; /* Offset from the beginning of CPAL table to * the Palette Type Array. Set to 0 if no array * is provided. */ - LOffsetTo<UnsizedArrayOf<HBUINT16> > + LOffsetTo<UnsizedArrayOf<HBUINT16>, false> paletteLabelZ; /* Offset from the beginning of CPAL table to * the Palette Labels Array. Set to 0 if no * array is provided. */ - LOffsetTo<UnsizedArrayOf<HBUINT16> > + LOffsetTo<UnsizedArrayOf<HBUINT16>, false> paletteEntryLabelZ; /* Offset from the beginning of CPAL table to * the Palette Entry Label Array. Set to 0 * if no array is provided. */ @@ -207,7 +207,7 @@ struct CPAL HBUINT16 numPalettes; /* Number of palettes in the table. */ HBUINT16 numColorRecords; /* Total number of color records, combined for * all palettes. */ - LOffsetTo<UnsizedArrayOf<BGRAColor> > + LOffsetTo<UnsizedArrayOf<BGRAColor>, false> colorRecordsZ; /* Offset from the beginning of CPAL table to * the first ColorRecord. */ UnsizedArrayOf<HBUINT16> diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh index ad9162f7c7d..53d466846a4 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh @@ -54,7 +54,7 @@ struct SVGDocumentIndexEntry * this index entry. */ HBUINT16 endGlyphID; /* The last glyph ID in the range described by * this index entry. Must be >= startGlyphID. */ - LOffsetTo<UnsizedArrayOf<HBUINT8> > + LOffsetTo<UnsizedArrayOf<HBUINT8>, false> svgDoc; /* Offset from the beginning of the SVG Document Index * to an SVG document. Must be non-zero. */ HBUINT32 svgDocLength; /* Length of the SVG document. diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.cc index 388a5972058..1bc68d36690 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.cc @@ -40,19 +40,19 @@ void hb_ot_face_data_t::init0 (hb_face_t *face) { this->face = face; -#define HB_OT_LAYOUT_TABLE(Namespace, Type) Type.init0 (); -#define HB_OT_LAYOUT_ACCELERATOR(Namespace, Type) HB_OT_LAYOUT_TABLE (Namespace, Type) - HB_OT_LAYOUT_TABLES -#undef HB_OT_LAYOUT_ACCELERATOR -#undef HB_OT_LAYOUT_TABLE +#define HB_OT_TABLE(Namespace, Type) Type.init0 (); +#define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type) + HB_OT_TABLES +#undef HB_OT_ACCELERATOR +#undef HB_OT_TABLE } void hb_ot_face_data_t::fini (void) { -#define HB_OT_LAYOUT_TABLE(Namespace, Type) Type.fini (); -#define HB_OT_LAYOUT_ACCELERATOR(Namespace, Type) HB_OT_LAYOUT_TABLE (Namespace, Type) - HB_OT_LAYOUT_TABLES -#undef HB_OT_LAYOUT_ACCELERATOR -#undef HB_OT_LAYOUT_TABLE +#define HB_OT_TABLE(Namespace, Type) Type.fini (); +#define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type) + HB_OT_TABLES +#undef HB_OT_ACCELERATOR +#undef HB_OT_TABLE } hb_ot_face_data_t * diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.hh index 5ac3538e44d..e3059221855 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.hh @@ -43,66 +43,66 @@ /* Most of these tables are NOT needed for shaping. But we need to hook them *somewhere*. * This is as good as any place. */ -#define HB_OT_LAYOUT_TABLES \ +#define HB_OT_TABLES \ /* OpenType shaping. */ \ - HB_OT_LAYOUT_TABLE(OT, JSTF) \ - HB_OT_LAYOUT_TABLE(OT, BASE) \ + HB_OT_TABLE(OT, JSTF) \ + HB_OT_TABLE(OT, BASE) \ /* AAT shaping. */ \ - HB_OT_LAYOUT_TABLE(AAT, morx) \ - HB_OT_LAYOUT_TABLE(AAT, kerx) \ - HB_OT_LAYOUT_TABLE(AAT, ankr) \ - HB_OT_LAYOUT_TABLE(AAT, trak) \ + HB_OT_TABLE(AAT, morx) \ + HB_OT_TABLE(AAT, kerx) \ + HB_OT_TABLE(AAT, ankr) \ + HB_OT_TABLE(AAT, trak) \ /* OpenType variations. */ \ - HB_OT_LAYOUT_TABLE(OT, fvar) \ - HB_OT_LAYOUT_TABLE(OT, avar) \ - HB_OT_LAYOUT_TABLE(OT, MVAR) \ + HB_OT_TABLE(OT, fvar) \ + HB_OT_TABLE(OT, avar) \ + HB_OT_TABLE(OT, MVAR) \ /* OpenType math. */ \ - HB_OT_LAYOUT_TABLE(OT, MATH) \ + HB_OT_TABLE(OT, MATH) \ /* OpenType fundamentals. */ \ - HB_OT_LAYOUT_ACCELERATOR(OT, GDEF) \ - HB_OT_LAYOUT_ACCELERATOR(OT, GSUB) \ - HB_OT_LAYOUT_ACCELERATOR(OT, GPOS) \ - HB_OT_LAYOUT_ACCELERATOR(OT, cmap) \ - HB_OT_LAYOUT_ACCELERATOR(OT, hmtx) \ - HB_OT_LAYOUT_ACCELERATOR(OT, vmtx) \ - HB_OT_LAYOUT_ACCELERATOR(OT, post) \ - HB_OT_LAYOUT_ACCELERATOR(OT, kern) \ - HB_OT_LAYOUT_ACCELERATOR(OT, glyf) \ - HB_OT_LAYOUT_ACCELERATOR(OT, CBDT) \ + HB_OT_ACCELERATOR(OT, GDEF) \ + HB_OT_ACCELERATOR(OT, GSUB) \ + HB_OT_ACCELERATOR(OT, GPOS) \ + HB_OT_ACCELERATOR(OT, cmap) \ + HB_OT_ACCELERATOR(OT, hmtx) \ + HB_OT_ACCELERATOR(OT, vmtx) \ + HB_OT_ACCELERATOR(OT, post) \ + HB_OT_ACCELERATOR(OT, kern) \ + HB_OT_ACCELERATOR(OT, glyf) \ + HB_OT_ACCELERATOR(OT, CBDT) \ /* */ /* Declare tables. */ -#define HB_OT_LAYOUT_TABLE(Namespace, Type) namespace Namespace { struct Type; } -#define HB_OT_LAYOUT_ACCELERATOR(Namespace, Type) HB_OT_LAYOUT_TABLE (Namespace, Type##_accelerator_t) -HB_OT_LAYOUT_TABLES -#undef HB_OT_LAYOUT_ACCELERATOR -#undef HB_OT_LAYOUT_TABLE +#define HB_OT_TABLE(Namespace, Type) namespace Namespace { struct Type; } +#define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type##_accelerator_t) +HB_OT_TABLES +#undef HB_OT_ACCELERATOR +#undef HB_OT_TABLE struct hb_ot_face_data_t { HB_INTERNAL void init0 (hb_face_t *face); HB_INTERNAL void fini (void); -#define HB_OT_LAYOUT_TABLE_ORDER(Namespace, Type) \ +#define HB_OT_TABLE_ORDER(Namespace, Type) \ HB_PASTE (ORDER_, HB_PASTE (Namespace, HB_PASTE (_, Type))) enum order_t { ORDER_ZERO, -#define HB_OT_LAYOUT_TABLE(Namespace, Type) HB_OT_LAYOUT_TABLE_ORDER (Namespace, Type), -#define HB_OT_LAYOUT_ACCELERATOR(Namespace, Type) HB_OT_LAYOUT_TABLE (Namespace, Type) - HB_OT_LAYOUT_TABLES -#undef HB_OT_LAYOUT_ACCELERATOR -#undef HB_OT_LAYOUT_TABLE +#define HB_OT_TABLE(Namespace, Type) HB_OT_TABLE_ORDER (Namespace, Type), +#define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type) + HB_OT_TABLES +#undef HB_OT_ACCELERATOR +#undef HB_OT_TABLE }; hb_face_t *face; /* MUST be JUST before the lazy loaders. */ -#define HB_OT_LAYOUT_TABLE(Namespace, Type) \ - hb_table_lazy_loader_t<Namespace::Type, HB_OT_LAYOUT_TABLE_ORDER (Namespace, Type)> Type; -#define HB_OT_LAYOUT_ACCELERATOR(Namespace, Type) \ - hb_face_lazy_loader_t<Namespace::Type##_accelerator_t, HB_OT_LAYOUT_TABLE_ORDER (Namespace, Type)> Type; - HB_OT_LAYOUT_TABLES -#undef HB_OT_LAYOUT_ACCELERATOR -#undef HB_OT_LAYOUT_TABLE +#define HB_OT_TABLE(Namespace, Type) \ + hb_table_lazy_loader_t<Namespace::Type, HB_OT_TABLE_ORDER (Namespace, Type)> Type; +#define HB_OT_ACCELERATOR(Namespace, Type) \ + hb_face_lazy_loader_t<Namespace::Type##_accelerator_t, HB_OT_TABLE_ORDER (Namespace, Type)> Type; + HB_OT_TABLES +#undef HB_OT_ACCELERATOR +#undef HB_OT_TABLE }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc index a4c5584fbd9..e6df038d322 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc @@ -46,10 +46,32 @@ hb_ot_get_nominal_glyph (hb_font_t *font HB_UNUSED, hb_codepoint_t unicode, hb_codepoint_t *glyph, void *user_data HB_UNUSED) +{ + const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; + return ot_face->cmap.get ()->get_nominal_glyph (unicode, glyph); +} +static unsigned int +hb_ot_get_nominal_glyphs (hb_font_t *font HB_UNUSED, + void *font_data, + unsigned int count, + const hb_codepoint_t *first_unicode, + unsigned int unicode_stride, + hb_codepoint_t *first_glyph, + unsigned int glyph_stride, + void *user_data HB_UNUSED) { - const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data; - return ot_font->cmap.get_relaxed()->get_nominal_glyph (unicode, glyph); + const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; + const OT::cmap_accelerator_t &cmap = *ot_face->cmap.get (); + unsigned int done; + for (done = 0; + done < count && cmap.get_nominal_glyph (*first_unicode, first_glyph); + done++) + { + first_unicode = &StructAtOffset<hb_codepoint_t> (first_unicode, unicode_stride); + first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride); + } + return done; } static hb_bool_t @@ -60,39 +82,77 @@ hb_ot_get_variation_glyph (hb_font_t *font HB_UNUSED, hb_codepoint_t *glyph, void *user_data HB_UNUSED) { - const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data; - return ot_font->cmap.get_relaxed ()->get_variation_glyph (unicode, variation_selector, glyph); + const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; + return ot_face->cmap.get ()->get_variation_glyph (unicode, variation_selector, glyph); } -static hb_position_t -hb_ot_get_glyph_h_advance (hb_font_t *font, - void *font_data, - hb_codepoint_t glyph, - void *user_data HB_UNUSED) +static void +hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, + unsigned count, + const hb_codepoint_t *first_glyph, + unsigned glyph_stride, + hb_position_t *first_advance, + unsigned advance_stride, + void *user_data HB_UNUSED) { - const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data; - return font->em_scale_x (ot_font->hmtx.get_relaxed ()->get_advance (glyph, font)); + const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; + const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx.get (); + + for (unsigned int i = 0; i < count; i++) + { + *first_advance = font->em_scale_x (hmtx.get_advance (*first_glyph, font)); + first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride); + first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride); + } } -static hb_position_t -hb_ot_get_glyph_v_advance (hb_font_t *font, - void *font_data, - hb_codepoint_t glyph, - void *user_data HB_UNUSED) +static void +hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, + unsigned count, + const hb_codepoint_t *first_glyph, + unsigned glyph_stride, + hb_position_t *first_advance, + unsigned advance_stride, + void *user_data HB_UNUSED) { - const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data; - return font->em_scale_y (-(int) ot_font->vmtx.get_relaxed ()->get_advance (glyph, font)); + const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; + const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx.get (); + + for (unsigned int i = 0; i < count; i++) + { + *first_advance = font->em_scale_y (-(int) vmtx.get_advance (*first_glyph, font)); + first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride); + first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride); + } } -static hb_position_t -hb_ot_get_glyph_h_kerning (hb_font_t *font, - void *font_data, - hb_codepoint_t left_glyph, - hb_codepoint_t right_glyph, - void *user_data HB_UNUSED) +static hb_bool_t +hb_ot_get_glyph_v_origin (hb_font_t *font, + void *font_data, + hb_codepoint_t glyph, + hb_position_t *x, + hb_position_t *y, + void *user_data HB_UNUSED) { - const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data; - return font->em_scale_x (ot_font->kern->get_h_kerning (left_glyph, right_glyph)); + const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; + + *x = font->get_glyph_h_advance (glyph) / 2; + + hb_glyph_extents_t extents = {0}; + bool ret = ot_face->glyf->get_extents (glyph, &extents); + if (ret) + { + const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx.get (); + hb_position_t tsb = vmtx.get_side_bearing (glyph); + *y = font->em_scale_y (extents.y_bearing + tsb); + return true; + } + + hb_font_extents_t font_extents; + font->get_h_extents_with_fallback (&font_extents); + *y = font_extents.ascender; + + return true; } static hb_bool_t @@ -102,10 +162,10 @@ hb_ot_get_glyph_extents (hb_font_t *font, hb_glyph_extents_t *extents, void *user_data HB_UNUSED) { - const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data; - bool ret = ot_font->glyf->get_extents (glyph, extents); + const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; + bool ret = ot_face->glyf->get_extents (glyph, extents); if (!ret) - ret = ot_font->CBDT->get_extents (glyph, extents); + ret = ot_face->CBDT->get_extents (glyph, extents); // TODO Hook up side-bearings variations. extents->x_bearing = font->em_scale_x (extents->x_bearing); extents->y_bearing = font->em_scale_y (extents->y_bearing); @@ -121,8 +181,8 @@ hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED, char *name, unsigned int size, void *user_data HB_UNUSED) { - const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data; - return ot_font->post->get_glyph_name (glyph, name, size); + const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; + return ot_face->post->get_glyph_name (glyph, name, size); } static hb_bool_t @@ -132,8 +192,8 @@ hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED, hb_codepoint_t *glyph, void *user_data HB_UNUSED) { - const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data; - return ot_font->post->get_glyph_from_name (name, len, glyph); + const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; + return ot_face->post->get_glyph_from_name (name, len, glyph); } static hb_bool_t @@ -142,12 +202,13 @@ hb_ot_get_font_h_extents (hb_font_t *font, hb_font_extents_t *metrics, void *user_data HB_UNUSED) { - const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data; - metrics->ascender = font->em_scale_y (ot_font->hmtx.get_relaxed ()->ascender); - metrics->descender = font->em_scale_y (ot_font->hmtx.get_relaxed ()->descender); - metrics->line_gap = font->em_scale_y (ot_font->hmtx.get_relaxed ()->line_gap); + const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; + const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx.get (); + metrics->ascender = font->em_scale_y (hmtx.ascender); + metrics->descender = font->em_scale_y (hmtx.descender); + metrics->line_gap = font->em_scale_y (hmtx.line_gap); // TODO Hook up variations. - return ot_font->hmtx.get_relaxed ()->has_font_extents; + return hmtx.has_font_extents; } static hb_bool_t @@ -156,12 +217,13 @@ hb_ot_get_font_v_extents (hb_font_t *font, hb_font_extents_t *metrics, void *user_data HB_UNUSED) { - const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data; - metrics->ascender = font->em_scale_x (ot_font->vmtx.get_relaxed ()->ascender); - metrics->descender = font->em_scale_x (ot_font->vmtx.get_relaxed ()->descender); - metrics->line_gap = font->em_scale_x (ot_font->vmtx.get_relaxed ()->line_gap); + const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; + const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx.get (); + metrics->ascender = font->em_scale_x (vmtx.ascender); + metrics->descender = font->em_scale_x (vmtx.descender); + metrics->line_gap = font->em_scale_x (vmtx.line_gap); // TODO Hook up variations. - return ot_font->vmtx.get_relaxed ()->has_font_extents; + return vmtx.has_font_extents; } #ifdef HB_USE_ATEXIT @@ -177,13 +239,12 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, nullptr, nullptr); hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, nullptr, nullptr); hb_font_funcs_set_nominal_glyph_func (funcs, hb_ot_get_nominal_glyph, nullptr, nullptr); + hb_font_funcs_set_nominal_glyphs_func (funcs, hb_ot_get_nominal_glyphs, nullptr, nullptr); hb_font_funcs_set_variation_glyph_func (funcs, hb_ot_get_variation_glyph, nullptr, nullptr); - hb_font_funcs_set_glyph_h_advance_func (funcs, hb_ot_get_glyph_h_advance, nullptr, nullptr); - hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ot_get_glyph_v_advance, nullptr, nullptr); + hb_font_funcs_set_glyph_h_advances_func (funcs, hb_ot_get_glyph_h_advances, nullptr, nullptr); + hb_font_funcs_set_glyph_v_advances_func (funcs, hb_ot_get_glyph_v_advances, nullptr, nullptr); //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, nullptr, nullptr); - //hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr); - hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ot_get_glyph_h_kerning, nullptr, nullptr); - //hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ot_get_glyph_v_kerning, nullptr, nullptr); + hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr); hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr); //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr); hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, nullptr, nullptr); @@ -223,15 +284,10 @@ void hb_ot_font_set_funcs (hb_font_t *font) { if (unlikely (!hb_ot_shaper_face_data_ensure (font->face))) return; - hb_ot_face_data_t *ot_font = hb_ot_face_data (font->face); - - /* Load them lazies. We access them with get_relaxed() for performance. */ - ot_font->cmap.get (); - ot_font->hmtx.get (); - ot_font->vmtx.get (); + hb_ot_face_data_t *ot_face = hb_ot_face_data (font->face); hb_font_set_funcs (font, _hb_ot_get_font_funcs (), - ot_font, + ot_face, nullptr); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh index 7c20983603f..2145ac02b2e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh @@ -54,7 +54,7 @@ struct loca } protected: - HBUINT8 dataZ[VAR]; /* Location data. */ + UnsizedArrayOf<HBUINT8> dataZ; /* Location data. */ DEFINE_SIZE_ARRAY (0, dataZ); }; @@ -375,13 +375,13 @@ struct glyf if (short_offset) { - const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataZ; + const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataZ.arrayZ; *start_offset = 2 * offsets[glyph]; *end_offset = 2 * offsets[glyph + 1]; } else { - const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataZ; + const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataZ.arrayZ; *start_offset = offsets[glyph]; *end_offset = offsets[glyph + 1]; @@ -418,7 +418,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->dataZ) + last->get_size(); + *instruction_start = ((char *) last - (char *) glyf_table->dataZ.arrayZ) + last->get_size(); else *instruction_start = end_offset; *instruction_end = end_offset; @@ -483,7 +483,7 @@ struct glyf }; protected: - HBUINT8 dataZ[VAR]; /* Glyphs data. */ + UnsizedArrayOf<HBUINT8> dataZ; /* Glyphs data. */ DEFINE_SIZE_ARRAY (0, dataZ); }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh index 87dd6d01822..04511b5d09e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh @@ -66,7 +66,7 @@ struct DeviceRecord if (unlikely (i >= len())) return nullptr; hb_codepoint_t gid = this->subset_plan->glyphs [i]; - const HBUINT8* width = &(this->source_device_record->widths[gid]); + const HBUINT8* width = &(this->source_device_record->widthsZ[gid]); if (width < ((const HBUINT8 *) this->source_device_record) + size_device_record) return width; @@ -77,11 +77,7 @@ struct DeviceRecord static inline unsigned int get_size (unsigned int count) { - unsigned int raw_size = min_size + count * HBUINT8::static_size; - if (raw_size % 4) - /* Align to 32 bits */ - return raw_size + (4 - (raw_size % 4)); - return raw_size; + return hb_ceil_to_4 (min_size + count * HBUINT8::static_size); } inline bool serialize (hb_serialize_context_t *c, const SubsetView &subset_view) @@ -107,7 +103,7 @@ struct DeviceRecord DEBUG_MSG(SUBSET, nullptr, "HDMX width for new gid %d is missing.", i); return_trace (false); } - widths[i].set (*width); + widthsZ[i].set (*width); } return_trace (true); @@ -120,11 +116,11 @@ struct DeviceRecord c->check_range (this, size_device_record))); } - HBUINT8 pixel_size; /* Pixel size for following widths (as ppem). */ - HBUINT8 max_width; /* Maximum width. */ - HBUINT8 widths[VAR]; /* Array of widths (numGlyphs is from the 'maxp' table). */ + HBUINT8 pixel_size; /* Pixel size for following widths (as ppem). */ + HBUINT8 max_width; /* Maximum width. */ + UnsizedArrayOf<HBUINT8> widthsZ; /* Array of widths (numGlyphs is from the 'maxp' table). */ public: - DEFINE_SIZE_ARRAY (2, widths); + DEFINE_SIZE_ARRAY (2, widthsZ); }; @@ -140,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->data, i * size_device_record); + return StructAtOffset<DeviceRecord> (&this->dataZ, i * size_device_record); } inline bool serialize (hb_serialize_context_t *c, const hdmx *source_hdmx, hb_subset_plan_t *plan) @@ -211,12 +207,12 @@ struct hdmx } protected: - HBUINT16 version; /* Table version number (0) */ - HBUINT16 num_records; /* Number of device records. */ - HBUINT32 size_device_record; /* Size of a device record, 32-bit aligned. */ - HBUINT8 data[VAR]; /* Array of device records. */ + HBUINT16 version; /* Table version number (0) */ + HBUINT16 num_records; /* Number of device records. */ + HBUINT32 size_device_record; /* Size of a device record, 32-bit aligned. */ + UnsizedArrayOf<HBUINT8> dataZ; /* Array of device records. */ public: - DEFINE_SIZE_ARRAY (8, data); + DEFINE_SIZE_ARRAY (8, dataZ); }; } /* namespace OT */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh index 3e4b3bdef5c..5293fdada1c 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh @@ -48,7 +48,7 @@ namespace OT { struct LongMetric { UFWORD advance; /* Advance width/height. */ - FWORD lsb; /* Leading (left/top) side bearing. */ + FWORD sb; /* Leading (left/top) side bearing. */ public: DEFINE_SIZE_STATIC (4); }; @@ -134,8 +134,8 @@ struct hmtxvmtx } else { - /* dest just lsb */ - *((FWORD *) dest_pos) = src_metric->lsb; + /* dest just sb */ + *((FWORD *) dest_pos) = src_metric->sb; } } else @@ -147,18 +147,18 @@ struct hmtxvmtx failed = true; break; } - FWORD src_lsb = *(lsbs + gids[i] - _mtx.num_advances); + FWORD src_sb = *(lsbs + gids[i] - _mtx.num_advances); if (i < num_advances) { /* dest needs a full LongMetric */ LongMetric *metric = (LongMetric *)dest_pos; metric->advance = src_metric->advance; - metric->lsb = src_lsb; + metric->sb = src_sb; } else { - /* dest just needs an lsb */ - *((FWORD *) dest_pos) = src_lsb; + /* dest just needs an sb */ + *((FWORD *) dest_pos) = src_sb; } } dest_pos += (i < num_advances ? 4 : 2); @@ -249,20 +249,33 @@ struct hmtxvmtx hb_blob_destroy (var_blob); } - inline unsigned int get_advance (hb_codepoint_t glyph) const + /* TODO Add variations version. */ + inline unsigned int get_side_bearing (hb_codepoint_t glyph) const + { + if (glyph < num_advances) + return table->longMetricZ[glyph].sb; + + if (unlikely (glyph > num_metrics)) + return 0; + + const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_advances]; + return bearings[glyph - num_advances]; + } + + inline unsigned int get_advance (hb_codepoint_t glyph) const { if (unlikely (glyph >= num_metrics)) { - /* If num_metrics is zero, it means we don't have the metrics table - * for this direction: return default advance. Otherwise, it means that the - * glyph index is out of bound: return zero. */ - if (num_metrics) - return 0; - else - return default_advance; + /* If num_metrics is zero, it means we don't have the metrics table + * for this direction: return default advance. Otherwise, it means that the + * glyph index is out of bound: return zero. */ + if (num_metrics) + return 0; + else + return default_advance; } - return table->longMetric[MIN (glyph, (uint32_t) num_advances - 1)].advance; + return table->longMetricZ[MIN (glyph, (uint32_t) num_advances - 1)].advance; } inline unsigned int get_advance (hb_codepoint_t glyph, @@ -271,7 +284,7 @@ struct hmtxvmtx unsigned int advance = get_advance (glyph); if (likely(glyph < num_metrics)) { - advance += (font->num_coords ? var_table->get_advance_var (glyph, font->coords, font->num_coords) : 0); // TODO Optimize?! + advance += (font->num_coords ? var_table->get_advance_var (glyph, font->coords, font->num_coords) : 0); // TODO Optimize?! } return advance; } @@ -295,7 +308,7 @@ struct hmtxvmtx }; protected: - LongMetric longMetric[VAR]; /* Paired advance width and leading + UnsizedArrayOf<LongMetric>longMetricZ;/* Paired advance width and leading * bearing values for each glyph. The * value numOfHMetrics comes from * the 'hhea' table. If the font is @@ -303,7 +316,7 @@ struct hmtxvmtx * be in the array, but that entry is * required. The last entry applies to * all subsequent glyphs. */ -/*FWORD leadingBearingX[VAR];*/ /* Here the advance is assumed +/*UnsizedArrayOf<FWORD> leadingBearingX;*//* Here the advance is assumed * to be the same as the advance * for the last entry above. The * number of entries in this array is @@ -317,7 +330,7 @@ struct hmtxvmtx * font to vary the side bearing * values for each glyph. */ public: - DEFINE_SIZE_ARRAY (0, longMetric); + DEFINE_SIZE_ARRAY (0, longMetricZ); }; struct hmtx : hmtxvmtx<hmtx, hhea> { diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh index 40f94be296f..63551d313cd 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh @@ -28,6 +28,88 @@ #define HB_OT_KERN_TABLE_HH #include "hb-open-type.hh" +#include "hb-ot-shape.hh" +#include "hb-ot-layout-gsubgpos.hh" + + +template <typename Driver> +struct hb_kern_machine_t +{ + hb_kern_machine_t (const Driver &driver_) : driver (driver_) {} + + HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW + inline void kern (hb_font_t *font, + hb_buffer_t *buffer, + hb_mask_t kern_mask, + bool scale = true) const + { + OT::hb_ot_apply_context_t c (1, font, buffer); + c.set_lookup_mask (kern_mask); + c.set_lookup_props (OT::LookupFlag::IgnoreMarks); + OT::hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c.iter_input; + skippy_iter.init (&c); + + bool horizontal = HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction); + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + hb_glyph_position_t *pos = buffer->pos; + for (unsigned int idx = 0; idx < count;) + { + if (!(info[idx].mask & kern_mask)) + { + idx++; + continue; + } + + skippy_iter.reset (idx, 1); + if (!skippy_iter.next ()) + { + idx++; + continue; + } + + unsigned int i = idx; + unsigned int j = skippy_iter.idx; + + hb_position_t kern = driver.get_kerning (info[i].codepoint, + info[j].codepoint); + + + if (likely (!kern)) + goto skip; + + + if (horizontal) + { + if (scale) + kern = font->em_scale_x (kern); + hb_position_t kern1 = kern >> 1; + hb_position_t kern2 = kern - kern1; + pos[i].x_advance += kern1; + pos[j].x_advance += kern2; + pos[j].x_offset += kern2; + } + else + { + if (scale) + kern = font->em_scale_y (kern); + hb_position_t kern1 = kern >> 1; + hb_position_t kern2 = kern - kern1; + pos[i].y_advance += kern1; + pos[j].y_advance += kern2; + pos[j].y_offset += kern2; + } + + buffer->unsafe_to_break (i, j + 1); + + skip: + idx = skippy_iter.idx; + } + } + + const Driver &driver; +}; + /* * kern -- Kerning @@ -116,14 +198,18 @@ struct KernSubTableFormat2 { inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const { + /* This subtable is disabled. It's not cleaer to me *exactly* where the offests are + * based from. I *think* they should be based from beginning of kern subtable wrapper, + * *NOT* "this". Since we know of no fonts that use this subtable, we are disabling + * it. Someday fix it and re-enable. Better yet, find fonts that use it... Meh, + * Windows doesn't implement it. Maybe just remove... */ + return 0; unsigned int l = (this+leftClassTable).get_class (left); unsigned int r = (this+rightClassTable).get_class (right); - unsigned int offset = l * rowWidth + r * sizeof (FWORD); - const FWORD *arr = &(this+array); - if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end)) - return 0; - const FWORD *v = &StructAtOffset<FWORD> (arr, offset); - if (unlikely ((const void *) v < (const void *) arr || (const void *) (v + 1) > (const void *) end)) + unsigned int offset = l + r; + const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset); + if (unlikely ((const char *) v < (const char *) &array || + (const char *) v > (const char *) end - 2)) return 0; return *v; } @@ -131,6 +217,7 @@ struct KernSubTableFormat2 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); + return_trace (true); /* Disabled. See above. */ return_trace (rowWidth.sanitize (c) && leftClassTable.sanitize (c, this) && rightClassTable.sanitize (c, this) && @@ -190,10 +277,10 @@ struct KernSubTableWrapper inline const T* thiz (void) const { return static_cast<const T *> (this); } inline bool is_horizontal (void) const - { return (thiz()->coverage & T::COVERAGE_CHECK_FLAGS) == T::COVERAGE_CHECK_HORIZONTAL; } + { return (thiz()->coverage & T::CheckFlags) == T::CheckHorizontal; } inline bool is_override (void) const - { return bool (thiz()->coverage & T::COVERAGE_OVERRIDE_FLAG); } + { return bool (thiz()->coverage & T::Override); } inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const { return thiz()->subtable.get_kerning (left, right, end, thiz()->format); } @@ -208,7 +295,7 @@ struct KernSubTableWrapper TRACE_SANITIZE (this); return_trace (c->check_struct (thiz()) && thiz()->length >= T::min_size && - c->check_array (thiz(), 1, thiz()->length) && + c->check_range (thiz(), thiz()->length) && thiz()->subtable.sanitize (c, thiz()->format)); } }; @@ -219,16 +306,16 @@ struct KernTable /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */ inline const T* thiz (void) const { return static_cast<const T *> (this); } - inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int table_length) const + inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const { int v = 0; - const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (thiz()->data); + const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ); unsigned int count = thiz()->nTables; for (unsigned int i = 0; i < count; i++) { if (st->is_override ()) v = 0; - v += st->get_h_kerning (left, right, table_length + (const char *) this); + v += st->get_h_kerning (left, right, st->length + (const char *) st); st = &StructAfter<typename T::SubTableWrapper> (*st); } return v; @@ -241,7 +328,7 @@ struct KernTable thiz()->version != T::VERSION)) return_trace (false); - const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (thiz()->data); + const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ); unsigned int count = thiz()->nTables; for (unsigned int i = 0; i < count; i++) { @@ -262,18 +349,20 @@ struct KernOT : KernTable<KernOT> struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper> { + friend struct KernTable<KernOT>; friend struct KernSubTableWrapper<SubTableWrapper>; - enum coverage_flags_t { - COVERAGE_DIRECTION_FLAG = 0x01u, - COVERAGE_MINIMUM_FLAG = 0x02u, - COVERAGE_CROSSSTREAM_FLAG = 0x04u, - COVERAGE_OVERRIDE_FLAG = 0x08u, + enum Coverage + { + Direction = 0x01u, + Minimum = 0x02u, + CrossStream = 0x04u, + Override = 0x08u, - COVERAGE_VARIATION_FLAG = 0x00u, /* Not supported. */ + Variation = 0x00u, /* Not supported. */ - COVERAGE_CHECK_FLAGS = 0x07u, - COVERAGE_CHECK_HORIZONTAL = 0x01u + CheckFlags = 0x07u, + CheckHorizontal = 0x01u }; protected: @@ -287,11 +376,11 @@ struct KernOT : KernTable<KernOT> }; protected: - HBUINT16 version; /* Version--0x0000u */ - HBUINT16 nTables; /* Number of subtables in the kerning table. */ - HBUINT8 data[VAR]; + HBUINT16 version; /* Version--0x0000u */ + HBUINT16 nTables; /* Number of subtables in the kerning table. */ + UnsizedArrayOf<HBUINT8> dataZ; public: - DEFINE_SIZE_ARRAY (4, data); + DEFINE_SIZE_ARRAY (4, dataZ); }; struct KernAAT : KernTable<KernAAT> @@ -302,17 +391,19 @@ struct KernAAT : KernTable<KernAAT> struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper> { + friend struct KernTable<KernAAT>; friend struct KernSubTableWrapper<SubTableWrapper>; - enum coverage_flags_t { - COVERAGE_DIRECTION_FLAG = 0x80u, - COVERAGE_CROSSSTREAM_FLAG = 0x40u, - COVERAGE_VARIATION_FLAG = 0x20u, + enum Coverage + { + Direction = 0x80u, + CrossStream = 0x40u, + Variation = 0x20u, - COVERAGE_OVERRIDE_FLAG = 0x00u, /* Not supported. */ + Override = 0x00u, /* Not supported. */ - COVERAGE_CHECK_FLAGS = 0xE0u, - COVERAGE_CHECK_HORIZONTAL = 0x00u + CheckFlags = 0xE0u, + CheckHorizontal = 0x00u }; protected: @@ -327,22 +418,25 @@ struct KernAAT : KernTable<KernAAT> }; protected: - HBUINT32 version; /* Version--0x00010000u */ - HBUINT32 nTables; /* Number of subtables in the kerning table. */ - HBUINT8 data[VAR]; + HBUINT32 version; /* Version--0x00010000u */ + HBUINT32 nTables; /* Number of subtables in the kerning table. */ + UnsizedArrayOf<HBUINT8> dataZ; public: - DEFINE_SIZE_ARRAY (8, data); + DEFINE_SIZE_ARRAY (8, dataZ); }; struct kern { static const hb_tag_t tableTag = HB_OT_TAG_kern; - inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int table_length) const + inline bool has_data (void) const + { return u.version32 != 0; } + + inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const { switch (u.major) { - case 0: return u.ot.get_h_kerning (left, right, table_length); - case 1: return u.aat.get_h_kerning (left, right, table_length); + case 0: return u.ot.get_h_kerning (left, right); + case 1: return u.aat.get_h_kerning (left, right); default:return 0; } } @@ -350,7 +444,7 @@ struct kern inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.major.sanitize (c)) return_trace (false); + if (!u.version32.sanitize (c)) return_trace (false); switch (u.major) { case 0: return_trace (u.ot.sanitize (c)); case 1: return_trace (u.aat.sanitize (c)); @@ -364,30 +458,48 @@ struct kern { blob = hb_sanitize_context_t().reference_table<kern> (face); table = blob->as<kern> (); - table_length = blob->length; } inline void fini (void) { hb_blob_destroy (blob); } + inline bool has_data (void) const + { return table->has_data (); } + inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { return table->get_h_kerning (left, right, table_length); } + { return table->get_h_kerning (left, right); } + + inline int get_kerning (hb_codepoint_t first, hb_codepoint_t second) const + { return get_h_kerning (first, second); } + + inline void apply (hb_font_t *font, + hb_buffer_t *buffer, + hb_mask_t kern_mask) const + { + /* We only apply horizontal kerning in this table. */ + if (!HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) + return; + + hb_kern_machine_t<accelerator_t> machine (*this); + + machine.kern (font, buffer, kern_mask); + } private: hb_blob_t *blob; const kern *table; - unsigned int table_length; }; protected: union { + HBUINT32 version32; HBUINT16 major; KernOT ot; KernAAT aat; } u; public: - DEFINE_SIZE_UNION (2, major); + DEFINE_SIZE_UNION (4, version32); }; struct kern_accelerator_t : kern::accelerator_t {}; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh index dd65f338494..0c60a1304e2 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh @@ -70,6 +70,11 @@ namespace OT { * Script, ScriptList, LangSys, Feature, FeatureList, Lookup, LookupList */ +struct Record_sanitize_closure_t { + hb_tag_t tag; + const void *list_base; +}; + template <typename Type> struct Record { @@ -77,14 +82,10 @@ struct Record return tag.cmp (a); } - struct sanitize_closure_t { - hb_tag_t tag; - const void *list_base; - }; inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - const sanitize_closure_t closure = {tag, base}; + const Record_sanitize_closure_t closure = {tag, base}; return_trace (c->check_struct (this) && offset.sanitize (c, base, &closure)); } @@ -240,7 +241,7 @@ struct LangSys } inline bool sanitize (hb_sanitize_context_t *c, - const Record<LangSys>::sanitize_closure_t * = nullptr) const + const Record_sanitize_closure_t * = nullptr) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && featureIndex.sanitize (c)); @@ -291,7 +292,7 @@ struct Script } inline bool sanitize (hb_sanitize_context_t *c, - const Record<Script>::sanitize_closure_t * = nullptr) const + const Record_sanitize_closure_t * = nullptr) const { TRACE_SANITIZE (this); return_trace (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this)); @@ -399,7 +400,7 @@ struct FeatureParamsSize * same subfamily value. If this value is * zero, the remaining fields in the array * will be ignored. */ - HBUINT16 subfamilyNameID;/* If the preceding value is non-zero, this + NameID subfamilyNameID;/* If the preceding value is non-zero, this * value must be set in the range 256 - 32767 * (inclusive). It records the value of a * field in the name table, which must @@ -472,7 +473,7 @@ struct FeatureParamsCharacterVariants * specifies a string (or strings, * for multiple languages) for a * user-interface label for this - * feature. (May be nullptr.) */ + * feature. (May be NULL.) */ NameID featUITooltipTextNameID;/* The ‘name’ table name ID that * specifies a string (or strings, * for multiple languages) that an @@ -482,7 +483,7 @@ struct FeatureParamsCharacterVariants NameID sampleTextNameID; /* The ‘name’ table name ID that * specifies sample text that * illustrates the effect of this - * feature. (May be nullptr.) */ + * feature. (May be NULL.) */ HBUINT16 numNamedParameters; /* Number of named parameters. (May * be zero.) */ NameID firstParamUILabelNameID;/* The first ‘name’ table name ID @@ -520,12 +521,27 @@ struct FeatureParams return Null(FeatureParamsSize); } + inline const FeatureParamsStylisticSet& get_stylistic_set_params (hb_tag_t tag) const + { + if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */ + return u.stylisticSet; + return Null(FeatureParamsStylisticSet); + } + + inline const FeatureParamsCharacterVariants& get_character_variants_params (hb_tag_t tag) const + { + if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */ + return u.characterVariants; + return Null(FeatureParamsCharacterVariants); + } + private: union { FeatureParamsSize size; FeatureParamsStylisticSet stylisticSet; FeatureParamsCharacterVariants characterVariants; } u; + public: DEFINE_SIZE_STATIC (17); }; @@ -553,7 +569,7 @@ struct Feature } inline bool sanitize (hb_sanitize_context_t *c, - const Record<Feature>::sanitize_closure_t *closure = nullptr) const + const Record_sanitize_closure_t *closure = nullptr) const { TRACE_SANITIZE (this); if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c)))) @@ -1542,14 +1558,14 @@ struct VarData regionIndices.sanitize(c) && shortCount <= regionIndices.len && c->check_array (&StructAfter<HBUINT8> (regionIndices), - get_row_size (), itemCount)); + itemCount, get_row_size ())); } protected: HBUINT16 itemCount; HBUINT16 shortCount; ArrayOf<HBUINT16> regionIndices; - HBUINT8 bytesX[VAR]; + UnsizedArrayOf<HBUINT8>bytesX; public: DEFINE_SIZE_ARRAY2 (6, regionIndices, bytesX); }; @@ -1844,7 +1860,7 @@ struct HintingDevice unsigned int s = ppem_size - startSize; - unsigned int byte = deltaValue[s >> (4 - f)]; + unsigned int byte = deltaValueZ[s >> (4 - f)]; unsigned int bits = (byte >> (16 - (((s & ((1 << (4 - f)) - 1)) + 1) << f))); unsigned int mask = (0xFFFFu >> (16 - (1 << f))); @@ -1864,9 +1880,10 @@ struct HintingDevice * 2 Signed 4-bit value, 4 values per uint16 * 3 Signed 8-bit value, 2 values per uint16 */ - HBUINT16 deltaValue[VAR]; /* Array of compressed data */ + UnsizedArrayOf<HBUINT16> + deltaValueZ; /* Array of compressed data */ public: - DEFINE_SIZE_ARRAY (6, deltaValue); + DEFINE_SIZE_ARRAY (6, deltaValueZ); }; struct VariationDevice diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh index 5847306d6e4..4f81b32785e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh @@ -199,7 +199,7 @@ struct ValueFormat : HBUINT16 TRACE_SANITIZE (this); unsigned int len = get_len (); - if (!c->check_array (values, get_size (), count)) return_trace (false); + if (!c->check_array (values, count, get_size ())) return_trace (false); if (!has_device ()) return_trace (true); @@ -376,7 +376,7 @@ struct AnchorMatrix if (!c->check_struct (this)) return_trace (false); if (unlikely (hb_unsigned_mul_overflows (rows, cols))) return_trace (false); unsigned int count = rows * cols; - if (!c->check_array (matrixZ, matrixZ[0].static_size, count)) return_trace (false); + if (!c->check_array (matrixZ.arrayZ, count)) return_trace (false); for (unsigned int i = 0; i < count; i++) if (!matrixZ[i].sanitize (c, this)) return_trace (false); return_trace (true); @@ -384,8 +384,8 @@ struct AnchorMatrix HBUINT16 rows; /* Number of rows */ protected: - OffsetTo<Anchor> - matrixZ[VAR]; /* Matrix of offsets to Anchor tables-- + UnsizedArrayOf<OffsetTo<Anchor> > + matrixZ; /* Matrix of offsets to Anchor tables-- * from beginning of AnchorMatrix table */ public: DEFINE_SIZE_ARRAY (2, matrixZ); @@ -621,7 +621,7 @@ struct PairSet unsigned int len2 = valueFormats[1].get_len (); unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2); - const PairValueRecord *record = CastP<PairValueRecord> (arrayZ); + const PairValueRecord *record = &firstPairValueRecord; unsigned int count = len; for (unsigned int i = 0; i < count; i++) { @@ -640,7 +640,7 @@ struct PairSet unsigned int len2 = valueFormats[1].get_len (); unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2); - const PairValueRecord *record = CastP<PairValueRecord> (arrayZ); + const PairValueRecord *record = &firstPairValueRecord; c->input->add_array (&record->secondGlyph, len, record_size); } @@ -654,7 +654,6 @@ struct PairSet unsigned int len2 = valueFormats[1].get_len (); unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2); - const PairValueRecord *record_array = CastP<PairValueRecord> (arrayZ); unsigned int count = len; /* Hand-coded bsearch. */ @@ -665,7 +664,7 @@ struct PairSet while (min <= max) { int mid = (min + max) / 2; - const PairValueRecord *record = &StructAtOffset<PairValueRecord> (record_array, record_size * mid); + const PairValueRecord *record = &StructAtOffset<PairValueRecord> (&firstPairValueRecord, record_size * mid); hb_codepoint_t mid_x = record->secondGlyph; if (x < mid_x) max = mid - 1; @@ -698,20 +697,21 @@ struct PairSet { TRACE_SANITIZE (this); if (!(c->check_struct (this) - && c->check_array (arrayZ, HBUINT16::static_size * closure->stride, len))) return_trace (false); + && c->check_array (&firstPairValueRecord, len, HBUINT16::static_size * closure->stride))) return_trace (false); unsigned int count = len; - const PairValueRecord *record = CastP<PairValueRecord> (arrayZ); + const PairValueRecord *record = &firstPairValueRecord; return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, closure->base, &record->values[0], count, closure->stride) && closure->valueFormats[1].sanitize_values_stride_unsafe (c, closure->base, &record->values[closure->len1], count, closure->stride)); } protected: - HBUINT16 len; /* Number of PairValueRecords */ - HBUINT16 arrayZ[VAR]; /* Array of PairValueRecords--ordered - * by GlyphID of the second glyph */ + HBUINT16 len; /* Number of PairValueRecords */ + PairValueRecord firstPairValueRecord; + /* Array of PairValueRecords--ordered + * by GlyphID of the second glyph */ public: - DEFINE_SIZE_ARRAY (2, arrayZ); + DEFINE_SIZE_MIN (2); }; struct PairPosFormat1 @@ -869,7 +869,7 @@ struct PairPosFormat2 unsigned int stride = len1 + len2; unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size (); unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count; - return_trace (c->check_array (values, record_size, count) && + return_trace (c->check_array (values, count, record_size) && valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], count, stride) && valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride)); } @@ -973,22 +973,22 @@ struct CursivePosFormat1 hb_buffer_t *buffer = c->buffer; const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)]; - if (!this_record.exitAnchor) return_trace (false); + if (!this_record.entryAnchor) return_trace (false); hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset (buffer->idx, 1); - if (!skippy_iter.next ()) return_trace (false); + if (!skippy_iter.prev ()) return_trace (false); - const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_coverage (buffer->info[skippy_iter.idx].codepoint)]; - if (!next_record.entryAnchor) return_trace (false); + const EntryExitRecord &prev_record = entryExitRecord[(this+coverage).get_coverage (buffer->info[skippy_iter.idx].codepoint)]; + if (!prev_record.exitAnchor) return_trace (false); - unsigned int i = buffer->idx; - unsigned int j = skippy_iter.idx; + unsigned int i = skippy_iter.idx; + unsigned int j = buffer->idx; buffer->unsafe_to_break (i, j); float entry_x, entry_y, exit_x, exit_y; - (this+this_record.exitAnchor).get_anchor (c, buffer->info[i].codepoint, &exit_x, &exit_y); - (this+next_record.entryAnchor).get_anchor (c, buffer->info[j].codepoint, &entry_x, &entry_y); + (this+prev_record.exitAnchor).get_anchor (c, buffer->info[i].codepoint, &exit_x, &exit_y); + (this+this_record.entryAnchor).get_anchor (c, buffer->info[j].codepoint, &entry_x, &entry_y); hb_glyph_position_t *pos = buffer->pos; @@ -1035,7 +1035,7 @@ struct CursivePosFormat1 * parent. * * Optimize things for the case of RightToLeft, as that's most common in - * Arabinc. */ + * Arabic. */ unsigned int child = i; unsigned int parent = j; hb_position_t x_offset = entry_x - exit_x; @@ -1064,7 +1064,7 @@ struct CursivePosFormat1 else pos[child].x_offset = x_offset; - buffer->idx = j; + buffer->idx++; return_trace (true); } @@ -1658,7 +1658,10 @@ reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direc pos[j].attach_type() = type; } static void -propagate_attachment_offsets (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction) +propagate_attachment_offsets (hb_glyph_position_t *pos, + unsigned int len, + unsigned int i, + hb_direction_t direction) { /* Adjusts offsets of attached glyphs (both cursive and mark) to accumulate * offset of glyph they are attached to. */ @@ -1666,11 +1669,14 @@ propagate_attachment_offsets (hb_glyph_position_t *pos, unsigned int i, hb_direc if (likely (!chain)) return; + pos[i].attach_chain() = 0; + unsigned int j = (int) i + chain; - pos[i].attach_chain() = 0; + if (unlikely (j >= len)) + return; - propagate_attachment_offsets (pos, j, direction); + propagate_attachment_offsets (pos, len, j, direction); assert (!!(type & ATTACH_TYPE_MARK) ^ !!(type & ATTACH_TYPE_CURSIVE)); @@ -1726,7 +1732,7 @@ GPOS::position_finish_offsets (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) /* Handle attachments */ if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT) for (unsigned int i = 0; i < len; i++) - propagate_attachment_offsets (pos, i, direction); + propagate_attachment_offsets (pos, len, i, direction); } @@ -1755,10 +1761,6 @@ template <typename context_t> struct GPOS_accelerator_t : GPOS::accelerator_t {}; -#undef attach_chain -#undef attach_type - - } /* namespace OT */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh index 76a0ea6d329..b664f15a617 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh @@ -541,6 +541,10 @@ struct AlternateSet unsigned int shift = hb_ctz (lookup_mask); unsigned int alt_index = ((lookup_mask & glyph_mask) >> shift); + /* If alt_index is MAX, randomize feature if it is the rand feature. */ + if (alt_index == HB_OT_MAP_MAX_VALUE && c->random) + alt_index = c->random_number () % count + 1; + if (unlikely (alt_index > count || alt_index == 0)) return_trace (false); c->replace_glyph (alternates[alt_index - 1]); @@ -706,7 +710,7 @@ struct Ligature { inline bool intersects (const hb_set_t *glyphs) const { - unsigned int count = component.len; + unsigned int count = component.lenP1; for (unsigned int i = 1; i < count; i++) if (!glyphs->has (component[i])) return false; @@ -716,7 +720,7 @@ struct Ligature inline void closure (hb_closure_context_t *c) const { TRACE_CLOSURE (this); - unsigned int count = component.len; + unsigned int count = component.lenP1; for (unsigned int i = 1; i < count; i++) if (!c->glyphs->has (component[i])) return; @@ -726,14 +730,14 @@ struct Ligature inline void collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); - c->input->add_array (component.arrayZ, component.len ? component.len - 1 : 0); + c->input->add_array (component.arrayZ, component.lenP1 ? component.lenP1 - 1 : 0); c->output->add (ligGlyph); } inline bool would_apply (hb_would_apply_context_t *c) const { TRACE_WOULD_APPLY (this); - if (c->len != component.len) + if (c->len != component.lenP1) return_trace (false); for (unsigned int i = 1; i < c->len; i++) @@ -746,7 +750,7 @@ struct Ligature inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); - unsigned int count = component.len; + unsigned int count = component.lenP1; if (unlikely (!count)) return_trace (false); @@ -758,7 +762,6 @@ struct Ligature return_trace (true); } - bool is_mark_ligature = false; unsigned int total_component_count = 0; unsigned int match_length = 0; @@ -770,7 +773,6 @@ struct Ligature nullptr, &match_length, match_positions, - &is_mark_ligature, &total_component_count))) return_trace (false); @@ -779,7 +781,6 @@ struct Ligature match_positions, match_length, ligGlyph, - is_mark_ligature, total_component_count); return_trace (true); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh index 315951a34f8..695a5df9957 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh @@ -33,6 +33,7 @@ #include "hb-buffer.hh" #include "hb-map.hh" #include "hb-set.hh" +#include "hb-ot-map.hh" #include "hb-ot-layout-common.hh" #include "hb-ot-layout-gdef-table.hh" @@ -213,10 +214,10 @@ struct hb_collect_glyphs_context_t : unsigned int debug_depth; hb_collect_glyphs_context_t (hb_face_t *face_, - hb_set_t *glyphs_before, /* OUT. May be nullptr */ - hb_set_t *glyphs_input, /* OUT. May be nullptr */ - hb_set_t *glyphs_after, /* OUT. May be nullptr */ - hb_set_t *glyphs_output, /* OUT. May be nullptr */ + hb_set_t *glyphs_before, /* OUT. May be NULL */ + hb_set_t *glyphs_input, /* OUT. May be NULL */ + hb_set_t *glyphs_after, /* OUT. May be NULL */ + hb_set_t *glyphs_output, /* OUT. May be NULL */ unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) : face (face_), before (glyphs_before ? glyphs_before : hb_set_get_empty ()), @@ -343,10 +344,10 @@ struct hb_ot_apply_context_t : match_glyph_data = nullptr; matcher.set_match_func (nullptr, nullptr); matcher.set_lookup_props (c->lookup_props); - /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */ + /* Ignore ZWNJ if we are matching GPOS, or matching GSUB context and asked to. */ matcher.set_ignore_zwnj (c->table_index == 1 || (context_match && c->auto_zwnj)); - /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */ - matcher.set_ignore_zwj (c->table_index == 1 || (context_match || c->auto_zwj)); + /* Ignore ZWJ if we are matching context, or asked to. */ + matcher.set_ignore_zwj (context_match || c->auto_zwj); matcher.set_mask (context_match ? -1 : c->lookup_mask); } inline void set_lookup_props (unsigned int lookup_props) @@ -478,9 +479,12 @@ struct hb_ot_apply_context_t : unsigned int nesting_level_left; unsigned int debug_depth; + bool has_glyph_classes; bool auto_zwnj; bool auto_zwj; - bool has_glyph_classes; + bool random; + + uint32_t random_state; hb_ot_apply_context_t (unsigned int table_index_, @@ -498,22 +502,33 @@ struct hb_ot_apply_context_t : lookup_props (0), nesting_level_left (HB_MAX_NESTING_LEVEL), debug_depth (0), + has_glyph_classes (gdef.has_glyph_classes ()), auto_zwnj (true), auto_zwj (true), - has_glyph_classes (gdef.has_glyph_classes ()) {} + random (false), + random_state (1) { init_iters (); } - inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; } - inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; } - inline void set_auto_zwnj (bool auto_zwnj_) { auto_zwnj = auto_zwnj_; } - inline void set_recurse_func (recurse_func_t func) { recurse_func = func; } - inline void set_lookup_index (unsigned int lookup_index_) { lookup_index = lookup_index_; } - inline void set_lookup_props (unsigned int lookup_props_) + inline void init_iters (void) { - lookup_props = lookup_props_; iter_input.init (this, false); iter_context.init (this, true); } + inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; init_iters (); } + inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; init_iters (); } + inline void set_auto_zwnj (bool auto_zwnj_) { auto_zwnj = auto_zwnj_; init_iters (); } + inline void set_random (bool random_) { random = random_; } + inline void set_recurse_func (recurse_func_t func) { recurse_func = func; } + inline void set_lookup_index (unsigned int lookup_index_) { lookup_index = lookup_index_; } + inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; init_iters (); } + + inline uint32_t random_number (void) + { + /* http://www.cplusplus.com/reference/random/minstd_rand/ */ + random_state = random_state * 48271 % 2147483647; + return random_state; + } + inline bool match_properties_mark (hb_codepoint_t glyph, unsigned int glyph_props, @@ -606,6 +621,64 @@ struct hb_ot_apply_context_t : }; +struct hb_get_subtables_context_t : + hb_dispatch_context_t<hb_get_subtables_context_t, hb_void_t, HB_DEBUG_APPLY> +{ + template <typename Type> + static inline bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c) + { + const Type *typed_obj = (const Type *) obj; + return typed_obj->apply (c); + } + + typedef bool (*hb_apply_func_t) (const void *obj, OT::hb_ot_apply_context_t *c); + + struct hb_applicable_t + { + template <typename T> + inline void init (const T &obj_, hb_apply_func_t apply_func_) + { + obj = &obj_; + apply_func = apply_func_; + digest.init (); + obj_.get_coverage ().add_coverage (&digest); + } + + inline bool apply (OT::hb_ot_apply_context_t *c) const + { + return digest.may_have (c->buffer->cur().codepoint) && apply_func (obj, c); + } + + private: + const void *obj; + hb_apply_func_t apply_func; + hb_set_digest_t digest; + }; + + typedef hb_vector_t<hb_applicable_t, 2> array_t; + + /* Dispatch interface. */ + inline const char *get_name (void) { return "GET_SUBTABLES"; } + template <typename T> + inline return_t dispatch (const T &obj) + { + hb_applicable_t *entry = array.push(); + entry->init (obj, apply_to<T>); + return HB_VOID; + } + static return_t default_return_value (void) { return HB_VOID; } + bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; } + + hb_get_subtables_context_t (array_t &array_) : + array (array_), + debug_depth (0) {} + + array_t &array; + unsigned int debug_depth; +}; + + + typedef bool (*intersects_func_t) (const hb_set_t *glyphs, const HBUINT16 &value, const void *data); typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const HBUINT16 &value, const void *data); @@ -716,7 +789,6 @@ static inline bool match_input (hb_ot_apply_context_t *c, const void *match_data, unsigned int *end_offset, unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], - bool *p_is_mark_ligature = nullptr, unsigned int *p_total_component_count = nullptr) { TRACE_APPLY (nullptr); @@ -753,8 +825,6 @@ static inline bool match_input (hb_ot_apply_context_t *c, * https://github.com/harfbuzz/harfbuzz/issues/545 */ - bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->cur()); - unsigned int total_component_count = 0; total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->cur()); @@ -821,15 +891,11 @@ static inline bool match_input (hb_ot_apply_context_t *c, return_trace (false); } - is_mark_ligature = is_mark_ligature && _hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]); total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->info[skippy_iter.idx]); } *end_offset = skippy_iter.idx - buffer->idx + 1; - if (p_is_mark_ligature) - *p_is_mark_ligature = is_mark_ligature; - if (p_total_component_count) *p_total_component_count = total_component_count; @@ -840,7 +906,6 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */ unsigned int match_length, hb_codepoint_t lig_glyph, - bool is_mark_ligature, unsigned int total_component_count) { TRACE_APPLY (nullptr); @@ -849,11 +914,15 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, buffer->merge_clusters (buffer->idx, buffer->idx + match_length); - /* - * - If it *is* a mark ligature, we don't allocate a new ligature id, and leave + /* - If a base and one or more marks ligate, consider that as a base, NOT + * ligature, such that all following marks can still attach to it. + * https://github.com/harfbuzz/harfbuzz/issues/1109 + * + * - If all components of the ligature were marks, we call this a mark ligature. + * If it *is* a mark ligature, we don't allocate a new ligature id, and leave * the ligature to keep its old ligature id. This will allow it to attach to * a base ligature in GPOS. Eg. if the sequence is: LAM,LAM,SHADDA,FATHA,HEH, - * and LAM,LAM,HEH for a ligature, they will leave SHADDA and FATHA wit a + * and LAM,LAM,HEH for a ligature, they will leave SHADDA and FATHA with a * ligature id and component value of 2. Then if SHADDA,FATHA form a ligature * later, we don't want them to lose their ligature id/component, otherwise * GPOS will fail to correctly position the mark ligature on top of the @@ -877,13 +946,24 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, * https://bugzilla.gnome.org/show_bug.cgi?id=437633 */ - unsigned int klass = is_mark_ligature ? 0 : HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE; - unsigned int lig_id = is_mark_ligature ? 0 : _hb_allocate_lig_id (buffer); + bool is_base_ligature = _hb_glyph_info_is_base_glyph (&buffer->info[match_positions[0]]); + bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->info[match_positions[0]]); + for (unsigned int i = 1; i < count; i++) + if (!_hb_glyph_info_is_mark (&buffer->info[match_positions[i]])) + { + is_base_ligature = false; + is_mark_ligature = false; + break; + } + bool is_ligature = !is_base_ligature && !is_mark_ligature; + + unsigned int klass = is_ligature ? HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE : 0; + unsigned int lig_id = is_ligature ? _hb_allocate_lig_id (buffer) : 0; unsigned int last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur()); unsigned int last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer->cur()); unsigned int components_so_far = last_num_components; - if (!is_mark_ligature) + if (is_ligature) { _hb_glyph_info_set_lig_props_for_ligature (&buffer->cur(), lig_id, total_component_count); if (_hb_glyph_info_get_general_category (&buffer->cur()) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) @@ -897,7 +977,8 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, { while (buffer->idx < match_positions[i] && buffer->successful) { - if (!is_mark_ligature) { + if (is_ligature) + { unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->cur()); if (this_comp == 0) this_comp = last_num_components; @@ -1222,42 +1303,42 @@ struct Rule inline bool intersects (const hb_set_t *glyphs, ContextClosureLookupContext &lookup_context) const { return context_intersects (glyphs, - inputCount, inputZ, + inputCount, inputZ.arrayZ, lookup_context); } inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const { TRACE_CLOSURE (this); - const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); + const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAtOffset<UnsizedArrayOf<LookupRecord> > (inputZ.arrayZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); context_closure_lookup (c, - inputCount, inputZ, - lookupCount, lookupRecord, + inputCount, inputZ.arrayZ, + lookupCount, lookupRecord.arrayZ, lookup_context); } inline void collect_glyphs (hb_collect_glyphs_context_t *c, ContextCollectGlyphsLookupContext &lookup_context) const { TRACE_COLLECT_GLYPHS (this); - const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); + const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAtOffset<UnsizedArrayOf<LookupRecord> > (inputZ.arrayZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); context_collect_glyphs_lookup (c, - inputCount, inputZ, - lookupCount, lookupRecord, + inputCount, inputZ.arrayZ, + lookupCount, lookupRecord.arrayZ, lookup_context); } inline bool would_apply (hb_would_apply_context_t *c, ContextApplyLookupContext &lookup_context) const { TRACE_WOULD_APPLY (this); - const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); - return_trace (context_would_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context)); + const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAtOffset<UnsizedArrayOf<LookupRecord> > (inputZ.arrayZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); + return_trace (context_would_apply_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, lookup_context)); } inline bool apply (hb_ot_apply_context_t *c, ContextApplyLookupContext &lookup_context) const { TRACE_APPLY (this); - const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); - return_trace (context_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context)); + const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAtOffset<UnsizedArrayOf<LookupRecord> > (inputZ.arrayZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); + return_trace (context_apply_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, lookup_context)); } public: @@ -1266,8 +1347,8 @@ struct Rule TRACE_SANITIZE (this); return_trace (inputCount.sanitize (c) && lookupCount.sanitize (c) && - c->check_range (inputZ, - inputZ[0].static_size * inputCount + + c->check_range (inputZ.arrayZ, + inputZ[0].static_size * (inputCount ? inputCount - 1 : 0) + LookupRecord::static_size * lookupCount)); } @@ -1276,9 +1357,11 @@ struct Rule * glyph sequence--includes the first * glyph */ HBUINT16 lookupCount; /* Number of LookupRecords */ - HBUINT16 inputZ[VAR]; /* Array of match inputs--start with + UnsizedArrayOf<HBUINT16> + inputZ; /* Array of match inputs--start with * second glyph */ -/*LookupRecord lookupRecordX[VAR];*/ /* Array of LookupRecords--in +/*UnsizedArrayOf<LookupRecord> + lookupRecordX;*/ /* Array of LookupRecords--in * design order */ public: DEFINE_SIZE_ARRAY (4, inputZ); @@ -1595,7 +1678,7 @@ struct ContextFormat3 this }; return context_intersects (glyphs, - glyphCount, (const HBUINT16 *) (coverageZ + 1), + glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1), lookup_context); } @@ -1605,13 +1688,13 @@ struct ContextFormat3 if (!(this+coverageZ[0]).intersects (c->glyphs)) return; - const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount); + const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ.arrayZ, coverageZ[0].static_size * glyphCount); struct ContextClosureLookupContext lookup_context = { {intersects_coverage}, this }; context_closure_lookup (c, - glyphCount, (const HBUINT16 *) (coverageZ + 1), + glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1), lookupCount, lookupRecord, lookup_context); } @@ -1621,14 +1704,14 @@ struct ContextFormat3 TRACE_COLLECT_GLYPHS (this); (this+coverageZ[0]).add_coverage (c->input); - const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount); + const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ.arrayZ, coverageZ[0].static_size * glyphCount); struct ContextCollectGlyphsLookupContext lookup_context = { {collect_coverage}, this }; context_collect_glyphs_lookup (c, - glyphCount, (const HBUINT16 *) (coverageZ + 1), + glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1), lookupCount, lookupRecord, lookup_context); } @@ -1637,12 +1720,12 @@ struct ContextFormat3 { TRACE_WOULD_APPLY (this); - const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount); + const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ.arrayZ, coverageZ[0].static_size * glyphCount); struct ContextApplyLookupContext lookup_context = { {match_coverage}, this }; - return_trace (context_would_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); + return_trace (context_would_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1), lookupCount, lookupRecord, lookup_context)); } inline const Coverage &get_coverage (void) const @@ -1654,12 +1737,12 @@ struct ContextFormat3 unsigned int index = (this+coverageZ[0]).get_coverage (c->buffer->cur().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); - const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount); + const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ.arrayZ, coverageZ[0].static_size * glyphCount); struct ContextApplyLookupContext lookup_context = { {match_coverage}, this }; - return_trace (context_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); + return_trace (context_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1), lookupCount, lookupRecord, lookup_context)); } inline bool subset (hb_subset_context_t *c) const @@ -1675,11 +1758,11 @@ struct ContextFormat3 if (!c->check_struct (this)) return_trace (false); unsigned int count = glyphCount; if (!count) return_trace (false); /* We want to access coverageZ[0] freely. */ - if (!c->check_array (coverageZ, coverageZ[0].static_size, count)) return_trace (false); + if (!c->check_array (coverageZ.arrayZ, count)) return_trace (false); for (unsigned int i = 0; i < count; i++) if (!coverageZ[i].sanitize (c, this)) return_trace (false); - const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * count); - return_trace (c->check_array (lookupRecord, lookupRecord[0].static_size, lookupCount)); + const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ.arrayZ, coverageZ[0].static_size * count); + return_trace (c->check_array (lookupRecord, lookupCount)); } protected: @@ -1687,10 +1770,11 @@ struct ContextFormat3 HBUINT16 glyphCount; /* Number of glyphs in the input glyph * sequence */ HBUINT16 lookupCount; /* Number of LookupRecords */ - OffsetTo<Coverage> - coverageZ[VAR]; /* Array of offsets to Coverage + UnsizedArrayOf<OffsetTo<Coverage> > + coverageZ; /* Array of offsets to Coverage * table in glyph sequence order */ -/*LookupRecord lookupRecordX[VAR];*/ /* Array of LookupRecords--in +/*UnsizedArrayOf<LookupRecord> + lookupRecordX;*/ /* Array of LookupRecords--in * design order */ public: DEFINE_SIZE_ARRAY (6, coverageZ); @@ -1862,7 +1946,7 @@ struct ChainRule const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input); return chain_context_intersects (glyphs, backtrack.len, backtrack.arrayZ, - input.len, input.arrayZ, + input.lenP1, input.arrayZ, lookahead.len, lookahead.arrayZ, lookup_context); } @@ -1875,7 +1959,7 @@ struct ChainRule const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); chain_context_closure_lookup (c, backtrack.len, backtrack.arrayZ, - input.len, input.arrayZ, + input.lenP1, input.arrayZ, lookahead.len, lookahead.arrayZ, lookup.len, lookup.arrayZ, lookup_context); @@ -1889,7 +1973,7 @@ struct ChainRule const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); chain_context_collect_glyphs_lookup (c, backtrack.len, backtrack.arrayZ, - input.len, input.arrayZ, + input.lenP1, input.arrayZ, lookahead.len, lookahead.arrayZ, lookup.len, lookup.arrayZ, lookup_context); @@ -1903,7 +1987,7 @@ struct ChainRule const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); return_trace (chain_context_would_apply_lookup (c, backtrack.len, backtrack.arrayZ, - input.len, input.arrayZ, + input.lenP1, input.arrayZ, lookahead.len, lookahead.arrayZ, lookup.len, lookup.arrayZ, lookup_context)); } @@ -1916,7 +2000,7 @@ struct ChainRule const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); return_trace (chain_context_apply_lookup (c, backtrack.len, backtrack.arrayZ, - input.len, input.arrayZ, + input.lenP1, input.arrayZ, lookahead.len, lookahead.arrayZ, lookup.len, lookup.arrayZ, lookup_context)); } @@ -2536,6 +2620,39 @@ struct Extension * GSUB/GPOS Common */ +struct hb_ot_layout_lookup_accelerator_t +{ + template <typename TLookup> + inline void init (const TLookup &lookup) + { + digest.init (); + lookup.add_coverage (&digest); + + subtables.init (); + OT::hb_get_subtables_context_t c_get_subtables (subtables); + lookup.dispatch (&c_get_subtables); + } + inline void fini (void) + { + subtables.fini (); + } + + inline bool may_have (hb_codepoint_t g) const + { return digest.may_have (g); } + + inline bool apply (hb_ot_apply_context_t *c) const + { + for (unsigned int i = 0; i < subtables.len; i++) + if (subtables[i].apply (c)) + return true; + return false; + } + + private: + hb_set_digest_t digest; + hb_get_subtables_context_t::array_t subtables; +}; + struct GSUBGPOS { inline bool has_data (void) const { return version.to_int () != 0; } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-jstf-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-jstf-table.hh index e718c319f0e..2fb23cbc32d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-jstf-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-jstf-table.hh @@ -124,7 +124,7 @@ struct JstfPriority struct JstfLangSys : OffsetListOf<JstfPriority> { inline bool sanitize (hb_sanitize_context_t *c, - const Record<JstfLangSys>::sanitize_closure_t * = nullptr) const + const Record_sanitize_closure_t * = nullptr) const { TRACE_SANITIZE (this); return_trace (OffsetListOf<JstfPriority>::sanitize (c)); @@ -165,7 +165,7 @@ struct JstfScript inline const JstfLangSys& get_default_lang_sys (void) const { return this+defaultLangSys; } inline bool sanitize (hb_sanitize_context_t *c, - const Record<JstfScript>::sanitize_closure_t * = nullptr) const + const Record_sanitize_closure_t * = nullptr) const { TRACE_SANITIZE (this); return_trace (extenderGlyphs.sanitize (c, this) && diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc index a1220f4dd3b..fb1d9b11f25 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc @@ -45,17 +45,15 @@ #include "hb-ot-color-cpal-table.hh" #include "hb-ot-color-sbix-table.hh" #include "hb-ot-color-svg-table.hh" +#include "hb-ot-kern-table.hh" #include "hb-ot-name-table.hh" -// static inline const OT::BASE& -// _get_base (hb_face_t *face) -// { -// if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::BASE); -// hb_ot_face_data_t *data = hb_ot_face_data (face); -// return *(data->base.get ()); -// } - +static const OT::kern::accelerator_t& _get_kern (hb_face_t *face) +{ + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::kern::accelerator_t); + return *hb_ot_face_data (face)->kern; +} const OT::GDEF& _get_gdef (hb_face_t *face) { if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::GDEF); @@ -92,6 +90,25 @@ const OT::GPOS& _get_gpos_relaxed (hb_face_t *face) /* + * kern + */ + +hb_bool_t +hb_ot_layout_has_kerning (hb_face_t *face) +{ + return _get_kern (face).has_data (); +} + +void +hb_ot_layout_kern (hb_font_t *font, + hb_buffer_t *buffer, + hb_mask_t kern_mask) +{ + _get_kern (font->face).apply (font, buffer, kern_mask); +} + + +/* * GDEF */ @@ -305,7 +322,7 @@ hb_ot_layout_table_get_script_tags (hb_face_t *face, hb_tag_t table_tag, unsigned int start_offset, unsigned int *script_count /* IN/OUT */, - hb_tag_t *script_tags /* OUT */) + hb_tag_t *script_tags /* OUT */) { const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); @@ -351,17 +368,36 @@ hb_ot_layout_table_choose_script (hb_face_t *face, unsigned int *script_index, hb_tag_t *chosen_script) { + const hb_tag_t *t; + for (t = script_tags; *t; t++); + return hb_ot_layout_table_select_script (face, table_tag, t - script_tags, script_tags, script_index, chosen_script); +} + +/** + * hb_ot_layout_table_select_script: + * + * Since: 2.0.0 + **/ +hb_bool_t +hb_ot_layout_table_select_script (hb_face_t *face, + hb_tag_t table_tag, + unsigned int script_count, + const hb_tag_t *script_tags, + unsigned int *script_index /* OUT */, + hb_tag_t *chosen_script /* OUT */) +{ static_assert ((OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX), ""); const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); + unsigned int i; - while (*script_tags) + for (i = 0; i < script_count; i++) { - if (g.find_script_index (*script_tags, script_index)) { + if (g.find_script_index (script_tags[i], script_index)) + { if (chosen_script) - *chosen_script = *script_tags; + *chosen_script = script_tags[i]; return true; } - script_tags++; } /* try finding 'DFLT' */ @@ -397,7 +433,7 @@ hb_ot_layout_table_get_feature_tags (hb_face_t *face, hb_tag_t table_tag, unsigned int start_offset, unsigned int *feature_count /* IN/OUT */, - hb_tag_t *feature_tags /* OUT */) + hb_tag_t *feature_tags /* OUT */) { const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); @@ -433,7 +469,7 @@ hb_ot_layout_script_get_language_tags (hb_face_t *face, unsigned int script_index, unsigned int start_offset, unsigned int *language_count /* IN/OUT */, - hb_tag_t *language_tags /* OUT */) + hb_tag_t *language_tags /* OUT */) { const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index); @@ -447,13 +483,33 @@ hb_ot_layout_script_find_language (hb_face_t *face, hb_tag_t language_tag, unsigned int *language_index) { + return hb_ot_layout_script_select_language (face, table_tag, script_index, 1, &language_tag, language_index); +} + +/** + * hb_ot_layout_script_select_language: + * + * Since: 2.0.0 + **/ +hb_bool_t +hb_ot_layout_script_select_language (hb_face_t *face, + hb_tag_t table_tag, + unsigned int script_index, + unsigned int language_count, + const hb_tag_t *language_tags, + unsigned int *language_index /* OUT */) +{ static_assert ((OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX), ""); const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index); + unsigned int i; - if (s.find_lang_sys_index (language_tag, language_index)) - return true; + for (i = 0; i < language_count; i++) + { + if (s.find_lang_sys_index (language_tags[i], language_index)) + return true; + } - /* try with 'dflt'; MS site has had typos and many fonts use it now :( */ + /* try finding 'dflt' */ if (s.find_lang_sys_index (HB_OT_TAG_DEFAULT_LANGUAGE, language_index)) return false; @@ -518,7 +574,7 @@ hb_ot_layout_language_get_feature_indexes (hb_face_t *face, unsigned int script_index, unsigned int language_index, unsigned int start_offset, - unsigned int *feature_count /* IN/OUT */, + unsigned int *feature_count /* IN/OUT */, unsigned int *feature_indexes /* OUT */) { const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); @@ -534,7 +590,7 @@ hb_ot_layout_language_get_feature_tags (hb_face_t *face, unsigned int language_index, unsigned int start_offset, unsigned int *feature_count /* IN/OUT */, - hb_tag_t *feature_tags /* OUT */) + hb_tag_t *feature_tags /* OUT */) { const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index); @@ -588,7 +644,7 @@ hb_ot_layout_feature_get_lookups (hb_face_t *face, hb_tag_t table_tag, unsigned int feature_index, unsigned int start_offset, - unsigned int *lookup_count /* IN/OUT */, + unsigned int *lookup_count /* IN/OUT */, unsigned int *lookup_indexes /* OUT */) { return hb_ot_layout_feature_with_variations_get_lookups (face, @@ -726,11 +782,12 @@ _hb_ot_layout_collect_features_languages (hb_face_t *face, for (; *languages; languages++) { unsigned int language_index; - if (hb_ot_layout_script_find_language (face, - table_tag, - script_index, - *languages, - &language_index)) + if (hb_ot_layout_script_select_language (face, + table_tag, + script_index, + 1, + languages, + &language_index)) _hb_ot_layout_collect_features_features (face, table_tag, script_index, @@ -815,10 +872,10 @@ void hb_ot_layout_lookup_collect_glyphs (hb_face_t *face, hb_tag_t table_tag, unsigned int lookup_index, - hb_set_t *glyphs_before, /* OUT. May be nullptr */ - hb_set_t *glyphs_input, /* OUT. May be nullptr */ - hb_set_t *glyphs_after, /* OUT. May be nullptr */ - hb_set_t *glyphs_output /* OUT. May be nullptr */) + hb_set_t *glyphs_before, /* OUT. May be NULL */ + hb_set_t *glyphs_input, /* OUT. May be NULL */ + hb_set_t *glyphs_after, /* OUT. May be NULL */ + hb_set_t *glyphs_output /* OUT. May be NULL */) { if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return; @@ -1016,11 +1073,11 @@ hb_ot_layout_position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer) **/ hb_bool_t hb_ot_layout_get_size_params (hb_face_t *face, - unsigned int *design_size, /* OUT. May be nullptr */ - unsigned int *subfamily_id, /* OUT. May be nullptr */ - unsigned int *subfamily_name_id, /* OUT. May be nullptr */ - unsigned int *range_start, /* OUT. May be nullptr */ - unsigned int *range_end /* OUT. May be nullptr */) + unsigned int *design_size, /* OUT. May be NULL */ + unsigned int *subfamily_id, /* OUT. May be NULL */ + unsigned int *subfamily_name_id, /* OUT. May be NULL */ + unsigned int *range_start, /* OUT. May be NULL */ + unsigned int *range_end /* OUT. May be NULL */) { const OT::GPOS &gpos = _get_gpos (face); const hb_tag_t tag = HB_TAG ('s','i','z','e'); @@ -1035,30 +1092,152 @@ hb_ot_layout_get_size_params (hb_face_t *face, if (params.designSize) { -#define PARAM(a, A) if (a) *a = params.A - PARAM (design_size, designSize); - PARAM (subfamily_id, subfamilyID); - PARAM (subfamily_name_id, subfamilyNameID); - PARAM (range_start, rangeStart); - PARAM (range_end, rangeEnd); -#undef PARAM + if (design_size) *design_size = params.designSize; + if (subfamily_id) *subfamily_id = params.subfamilyID; + if (subfamily_name_id) *subfamily_name_id = params.subfamilyNameID; + if (range_start) *range_start = params.rangeStart; + if (range_end) *range_end = params.rangeEnd; return true; } } } -#define PARAM(a, A) if (a) *a = 0 - PARAM (design_size, designSize); - PARAM (subfamily_id, subfamilyID); - PARAM (subfamily_name_id, subfamilyNameID); - PARAM (range_start, rangeStart); - PARAM (range_end, rangeEnd); -#undef PARAM + if (design_size) *design_size = 0; + if (subfamily_id) *subfamily_id = 0; + if (subfamily_name_id) *subfamily_name_id = 0; + if (range_start) *range_start = 0; + if (range_end) *range_end = 0; + + return false; +} + +/** + * hb_ot_layout_feature_get_name_ids: + * @face: #hb_face_t to work upon + * @table_tag: + * @feature_index: + * @label_id: (out) (allow-none): The ‘name’ table name ID that specifies a string + * for a user-interface label for this feature. (May be NULL.) + * @tooltip_id: (out) (allow-none): The ‘name’ table name ID that specifies a string + * that an application can use for tooltip text for this + * feature. (May be NULL.) + * @sample_id: (out) (allow-none): The ‘name’ table name ID that specifies sample text + * that illustrates the effect of this feature. (May be NULL.) + * @num_named_parameters: (out) (allow-none): Number of named parameters. (May be zero.) + * @first_param_id: (out) (allow-none): 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.) + * + * Fetches name indices from feature parameters for "Stylistic Set" ('ssXX') or + * "Character Variant" ('cvXX') features. + * + * Return value: true if data found, false otherwise + * + * Since: 2.0.0 + **/ +hb_bool_t +hb_ot_layout_feature_get_name_ids (hb_face_t *face, + hb_tag_t table_tag, + unsigned int feature_index, + hb_name_id_t *label_id, /* OUT. May be NULL */ + hb_name_id_t *tooltip_id, /* OUT. May be NULL */ + hb_name_id_t *sample_id, /* OUT. May be NULL */ + unsigned int *num_named_parameters, /* OUT. May be NULL */ + hb_name_id_t *first_param_id /* OUT. May be NULL */) +{ + const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); + + hb_tag_t feature_tag = g.get_feature_tag (feature_index); + const OT::Feature &f = g.get_feature (feature_index); + + const OT::FeatureParams &feature_params = f.get_feature_params (); + if (&feature_params != &Null (OT::FeatureParams)) + { + const OT::FeatureParamsStylisticSet& ss_params = + feature_params.get_stylistic_set_params (feature_tag); + if (&ss_params != &Null (OT::FeatureParamsStylisticSet)) /* ssXX */ + { + if (label_id) *label_id = ss_params.uiNameID; + // ssXX features don't have the rest + if (tooltip_id) *tooltip_id = HB_NAME_ID_INVALID; + if (sample_id) *sample_id = HB_NAME_ID_INVALID; + if (num_named_parameters) *num_named_parameters = 0; + if (first_param_id) *first_param_id = HB_NAME_ID_INVALID; + return true; + } + const OT::FeatureParamsCharacterVariants& cv_params = + feature_params.get_character_variants_params (feature_tag); + if (&cv_params != &Null (OT::FeatureParamsCharacterVariants)) /* cvXX */ + { + if (label_id) *label_id = cv_params.featUILableNameID; + if (tooltip_id) *tooltip_id = cv_params.featUITooltipTextNameID; + if (sample_id) *sample_id = cv_params.sampleTextNameID; + if (num_named_parameters) *num_named_parameters = cv_params.numNamedParameters; + if (first_param_id) *first_param_id = cv_params.firstParamUILabelNameID; + return true; + } + } + if (label_id) *label_id = HB_NAME_ID_INVALID; + if (tooltip_id) *tooltip_id = HB_NAME_ID_INVALID; + if (sample_id) *sample_id = HB_NAME_ID_INVALID; + if (num_named_parameters) *num_named_parameters = 0; + if (first_param_id) *first_param_id = HB_NAME_ID_INVALID; return false; } +/** + * hb_ot_layout_feature_get_characters:: + * @face: #hb_face_t to work upon + * @table_tag: + * @feature_index: + * @start_offset: In case the resulting char_count was equal to its input value, there + * is a chance there were more characters on the tag so this API can be + * called with an offset till resulting char_count gets to a number + * lower than input buffer (or consider using just a bigger buffer for + * one shot copying). + * @char_count: (inout) (allow-none): The count of characters for which this feature + * provides glyph variants. (May be zero.) + * @characters: (out) (allow-none): A buffer pointer. The Unicode Scalar Value + * of the characters for which this feature provides glyph variants. + * + * Fetches characters listed by designer under feature parameters for "Character + * Variant" ("cvXX") features. + * + * Return value: Number of total sample characters in the cvXX feature. + * + * Since: 2.0.0 + **/ +unsigned int +hb_ot_layout_feature_get_characters (hb_face_t *face, + hb_tag_t table_tag, + unsigned int feature_index, + unsigned int start_offset, + unsigned int *char_count, /* IN/OUT. May be NULL */ + hb_codepoint_t *characters /* OUT. May be NULL */) +{ + const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); + + hb_tag_t feature_tag = g.get_feature_tag (feature_index); + const OT::Feature &f = g.get_feature (feature_index); + + const OT::FeatureParams &feature_params = f.get_feature_params (); + + const OT::FeatureParamsCharacterVariants& cv_params = + feature_params.get_character_variants_params(feature_tag); + + unsigned int len = 0; + if (char_count && characters && start_offset < cv_params.characters.len) + { + len = MIN (cv_params.characters.len - start_offset, *char_count); + for (unsigned int i = 0; i < len; ++i) + characters[i] = cv_params.characters[start_offset + i]; + } + if (char_count) *char_count = len; + return cv_params.characters.len; +} + /* * Parts of different types are implemented here such that they have direct @@ -1077,7 +1256,7 @@ struct GSUBProxy accels (hb_ot_face_data (face)->GSUB->accels) {} const OT::GSUB &table; - const hb_ot_layout_lookup_accelerator_t *accels; + const OT::hb_ot_layout_lookup_accelerator_t *accels; }; struct GPOSProxy @@ -1091,63 +1270,13 @@ struct GPOSProxy accels (hb_ot_face_data (face)->GPOS->accels) {} const OT::GPOS &table; - const hb_ot_layout_lookup_accelerator_t *accels; + const OT::hb_ot_layout_lookup_accelerator_t *accels; }; -struct hb_get_subtables_context_t : - hb_dispatch_context_t<hb_get_subtables_context_t, hb_void_t, HB_DEBUG_APPLY> -{ - template <typename Type> - static inline bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c) - { - const Type *typed_obj = (const Type *) obj; - return typed_obj->apply (c); - } - - typedef bool (*hb_apply_func_t) (const void *obj, OT::hb_ot_apply_context_t *c); - - struct hb_applicable_t - { - inline void init (const void *obj_, hb_apply_func_t apply_func_) - { - obj = obj_; - apply_func = apply_func_; - } - - inline bool apply (OT::hb_ot_apply_context_t *c) const { return apply_func (obj, c); } - - private: - const void *obj; - hb_apply_func_t apply_func; - }; - - typedef hb_auto_t<hb_vector_t<hb_applicable_t> > array_t; - - /* Dispatch interface. */ - inline const char *get_name (void) { return "GET_SUBTABLES"; } - template <typename T> - inline return_t dispatch (const T &obj) - { - hb_applicable_t *entry = array.push(); - entry->init (&obj, apply_to<T>); - return HB_VOID; - } - static return_t default_return_value (void) { return HB_VOID; } - bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; } - - hb_get_subtables_context_t (array_t &array_) : - array (array_), - debug_depth (0) {} - - array_t &array; - unsigned int debug_depth; -}; - static inline bool apply_forward (OT::hb_ot_apply_context_t *c, - const hb_ot_layout_lookup_accelerator_t &accel, - const hb_get_subtables_context_t::array_t &subtables) + const OT::hb_ot_layout_lookup_accelerator_t &accel) { bool ret = false; hb_buffer_t *buffer = c->buffer; @@ -1158,12 +1287,7 @@ apply_forward (OT::hb_ot_apply_context_t *c, (buffer->cur().mask & c->lookup_mask) && c->check_glyph_property (&buffer->cur(), c->lookup_props)) { - for (unsigned int i = 0; i < subtables.len; i++) - if (subtables[i].apply (c)) - { - applied = true; - break; - } + applied = accel.apply (c); } if (applied) @@ -1176,8 +1300,7 @@ apply_forward (OT::hb_ot_apply_context_t *c, static inline bool apply_backward (OT::hb_ot_apply_context_t *c, - const hb_ot_layout_lookup_accelerator_t &accel, - const hb_get_subtables_context_t::array_t &subtables) + const OT::hb_ot_layout_lookup_accelerator_t &accel) { bool ret = false; hb_buffer_t *buffer = c->buffer; @@ -1187,12 +1310,8 @@ apply_backward (OT::hb_ot_apply_context_t *c, (buffer->cur().mask & c->lookup_mask) && c->check_glyph_property (&buffer->cur(), c->lookup_props)) { - for (unsigned int i = 0; i < subtables.len; i++) - if (subtables[i].apply (c)) - { - ret = true; - break; - } + if (accel.apply (c)) + ret = true; } /* The reverse lookup doesn't "advance" cursor (for good reason). */ buffer->idx--; @@ -1206,7 +1325,7 @@ template <typename Proxy> static inline void apply_string (OT::hb_ot_apply_context_t *c, const typename Proxy::Lookup &lookup, - const hb_ot_layout_lookup_accelerator_t &accel) + const OT::hb_ot_layout_lookup_accelerator_t &accel) { hb_buffer_t *buffer = c->buffer; @@ -1215,10 +1334,6 @@ apply_string (OT::hb_ot_apply_context_t *c, c->set_lookup_props (lookup.get_props ()); - hb_get_subtables_context_t::array_t subtables; - hb_get_subtables_context_t c_get_subtables (subtables); - lookup.dispatch (&c_get_subtables); - if (likely (!lookup.is_reverse ())) { /* in/out forward substitution/positioning */ @@ -1227,7 +1342,7 @@ apply_string (OT::hb_ot_apply_context_t *c, buffer->idx = 0; bool ret; - ret = apply_forward (c, accel, subtables); + ret = apply_forward (c, accel); if (ret) { if (!Proxy::inplace) @@ -1243,7 +1358,7 @@ apply_string (OT::hb_ot_apply_context_t *c, buffer->remove_output (); buffer->idx = buffer->len - 1; - apply_backward (c, accel, subtables); + apply_backward (c, accel); } } @@ -1268,6 +1383,11 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, c.set_lookup_mask (lookups[table_index][i].mask); c.set_auto_zwj (lookups[table_index][i].auto_zwj); c.set_auto_zwnj (lookups[table_index][i].auto_zwnj); + if (lookups[table_index][i].random) + { + c.set_random (true); + buffer->unsafe_to_break_all (); + } apply_string<Proxy> (&c, proxy.table.get_lookup (lookup_index), proxy.accels[lookup_index]); @@ -1297,31 +1417,7 @@ void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_ void hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c, const OT::SubstLookup &lookup, - const hb_ot_layout_lookup_accelerator_t &accel) + const OT::hb_ot_layout_lookup_accelerator_t &accel) { apply_string<GSUBProxy> (c, lookup, accel); } - - - - -/* - * OT::BASE - */ - -// /** -// * hb_ot_base_has_data: -// * @face: #hb_face_t to test -// * -// * This function allows to verify the presence of an OpenType BASE table on the -// * face. -// * -// * Return value: true if face has a BASE table, false otherwise -// * -// * Since: XXX -// **/ -// hb_bool_t -// hb_ot_base_has_data (hb_face_t *face) -// { -// return _get_base (face).has_data (); -// } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h index 586fb151751..9bd18c8af6d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h @@ -34,6 +34,7 @@ #include "hb.h" #include "hb-ot-tag.h" +#include "hb-ot-name.h" HB_BEGIN_DECLS @@ -111,13 +112,13 @@ hb_ot_layout_table_find_script (hb_face_t *face, hb_tag_t script_tag, unsigned int *script_index); -/* Like find_script, but takes zero-terminated array of scripts to test */ HB_EXTERN hb_bool_t -hb_ot_layout_table_choose_script (hb_face_t *face, +hb_ot_layout_table_select_script (hb_face_t *face, hb_tag_t table_tag, + unsigned int script_count, const hb_tag_t *script_tags, - unsigned int *script_index, - hb_tag_t *chosen_script); + unsigned int *script_index /* OUT */, + hb_tag_t *chosen_script /* OUT */); HB_EXTERN unsigned int hb_ot_layout_table_get_feature_tags (hb_face_t *face, @@ -135,11 +136,12 @@ hb_ot_layout_script_get_language_tags (hb_face_t *face, hb_tag_t *language_tags /* OUT */); HB_EXTERN hb_bool_t -hb_ot_layout_script_find_language (hb_face_t *face, - hb_tag_t table_tag, - unsigned int script_index, - hb_tag_t language_tag, - unsigned int *language_index); +hb_ot_layout_script_select_language (hb_face_t *face, + hb_tag_t table_tag, + unsigned int script_index, + unsigned int language_count, + const hb_tag_t *language_tags, + unsigned int *language_index /* OUT */); HB_EXTERN hb_bool_t hb_ot_layout_language_get_required_feature_index (hb_face_t *face, @@ -214,10 +216,10 @@ HB_EXTERN void hb_ot_layout_lookup_collect_glyphs (hb_face_t *face, hb_tag_t table_tag, unsigned int lookup_index, - hb_set_t *glyphs_before, /* OUT. May be NULL */ - hb_set_t *glyphs_input, /* OUT. May be NULL */ - hb_set_t *glyphs_after, /* OUT. May be NULL */ - hb_set_t *glyphs_output /* OUT. May be NULL */); + hb_set_t *glyphs_before, /* OUT. May be NULL */ + hb_set_t *glyphs_input, /* OUT. May be NULL */ + hb_set_t *glyphs_after, /* OUT. May be NULL */ + hb_set_t *glyphs_output /* OUT. May be NULL */); #ifdef HB_NOT_IMPLEMENTED typedef struct @@ -325,11 +327,30 @@ HB_EXTERN hb_bool_t hb_ot_layout_get_size_params (hb_face_t *face, unsigned int *design_size, /* OUT. May be NULL */ unsigned int *subfamily_id, /* OUT. May be NULL */ - unsigned int *subfamily_name_id, /* OUT. May be NULL */ + hb_name_id_t *subfamily_name_id, /* OUT. May be NULL */ unsigned int *range_start, /* OUT. May be NULL */ unsigned int *range_end /* OUT. May be NULL */); +HB_EXTERN hb_bool_t +hb_ot_layout_feature_get_name_ids (hb_face_t *face, + hb_tag_t table_tag, + unsigned int feature_index, + hb_name_id_t *label_id /* OUT. May be NULL */, + hb_name_id_t *tooltip_id /* OUT. May be NULL */, + hb_name_id_t *sample_id /* OUT. May be NULL */, + unsigned int *num_named_parameters /* OUT. May be NULL */, + hb_name_id_t *first_param_id /* OUT. May be NULL */); + + +HB_EXTERN unsigned int +hb_ot_layout_feature_get_characters (hb_face_t *face, + hb_tag_t table_tag, + unsigned int feature_index, + unsigned int start_offset, + unsigned int *char_count /* IN/OUT. May be NULL */, + hb_codepoint_t *characters /* OUT. May be NULL */); + /* * BASE */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh index 84981391cb5..64b3d7480d6 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh @@ -49,6 +49,19 @@ HB_INTERNAL const OT::GSUB& _get_gsub_relaxed (hb_face_t *face); HB_INTERNAL const OT::GPOS& _get_gpos_relaxed (hb_face_t *face); +/* + * kern + */ + +HB_INTERNAL hb_bool_t +hb_ot_layout_has_kerning (hb_face_t *face); + +HB_INTERNAL void +hb_ot_layout_kern (hb_font_t *font, + hb_buffer_t *buffer, + hb_mask_t kern_mask); + + /* Private API corresponding to hb-ot-layout.h: */ HB_INTERNAL hb_bool_t @@ -99,32 +112,16 @@ hb_ot_layout_substitute_start (hb_font_t *font, hb_buffer_t *buffer); -struct hb_ot_layout_lookup_accelerator_t -{ - template <typename TLookup> - inline void init (const TLookup &lookup) - { - digest.init (); - lookup.add_coverage (&digest); - } - inline void fini (void) {} - - inline bool may_have (hb_codepoint_t g) const - { return digest.may_have (g); } - - private: - hb_set_digest_t digest; -}; - namespace OT { struct hb_ot_apply_context_t; struct SubstLookup; + struct hb_ot_layout_lookup_accelerator_t; } HB_INTERNAL void hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c, const OT::SubstLookup &lookup, - const hb_ot_layout_lookup_accelerator_t &accel); + const OT::hb_ot_layout_lookup_accelerator_t &accel); /* Should be called before all the position_lookup's are done. */ @@ -160,12 +157,12 @@ hb_ot_layout_position_finish_offsets (hb_font_t *font, #define foreach_syllable(buffer, start, end) \ for (unsigned int \ _count = buffer->len, \ - start = 0, end = _count ? _next_syllable (buffer, 0) : 0; \ + start = 0, end = _count ? _hb_next_syllable (buffer, 0) : 0; \ start < _count; \ - start = end, end = _next_syllable (buffer, start)) + start = end, end = _hb_next_syllable (buffer, start)) static inline unsigned int -_next_syllable (hb_buffer_t *buffer, unsigned int start) +_hb_next_syllable (hb_buffer_t *buffer, unsigned int start) { hb_glyph_info_t *info = buffer->info; unsigned int count = buffer->len; @@ -188,7 +185,7 @@ _next_syllable (hb_buffer_t *buffer, unsigned int start) * * Whether it's one of the three Mongolian Free Variation Selectors, * CGJ, or other characters that are hidden but should not be ignored * like most other Default_Ignorable()s do during matching. - * * One free bit right now. + * * Whether it's a grapheme continuation. * * The high-byte has different meanings, switched by the Gen-Cat: * - For Mn,Mc,Me: the modified Combining_Class. @@ -200,8 +197,8 @@ _next_syllable (hb_buffer_t *buffer, unsigned int start) enum hb_unicode_props_flags_t { UPROPS_MASK_GEN_CAT = 0x001Fu, UPROPS_MASK_IGNORABLE = 0x0020u, - UPROPS_MASK_HIDDEN = 0x0040u, /* MONGOLIAN FREE VARIATION SELECTOR 1..3, - * or TAG characters */ + UPROPS_MASK_HIDDEN = 0x0040u, /* MONGOLIAN FREE VARIATION SELECTOR 1..3, or TAG characters */ + UPROPS_MASK_CONTINUATION=0x0080u, /* If GEN_CAT=FORMAT, top byte masks: */ UPROPS_MASK_Cf_ZWJ = 0x0100u, @@ -220,6 +217,7 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer) if (u >= 0x80) { buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII; + if (unlikely (unicode->is_default_ignorable (u))) { buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES; @@ -245,35 +243,11 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer) props |= UPROPS_MASK_HIDDEN; } } - else if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK_OR_MODIFIER_SYMBOL (gen_cat))) + + if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (gen_cat))) { - /* The above check is just an optimization to let in only things we need further - * processing on. */ - - /* Only Mn and Mc can have non-zero ccc: - * https://unicode.org/policies/stability_policy.html#Property_Value - * """ - * Canonical_Combining_Class, General_Category - * All characters other than those with General_Category property values - * Spacing_Mark (Mc) and Nonspacing_Mark (Mn) have the Canonical_Combining_Class - * property value 0. - * 1.1.5+ - * """ - * - * Also, all Mn's that are Default_Ignorable, have ccc=0, hence - * the "else if". - */ - props |= unicode->modified_combining_class (info->codepoint)<<8; - - /* Recategorize emoji skin-tone modifiers as Unicode mark, so they - * behave correctly in non-native directionality. They originally - * are MODIFIER_SYMBOL. Fixes: - * https://github.com/harfbuzz/harfbuzz/issues/169 - */ - if (unlikely (hb_in_range (u, 0x1F3FBu, 0x1F3FFu))) - { - props = gen_cat = HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK; - } + props |= UPROPS_MASK_CONTINUATION; + props |= unicode->modified_combining_class (u)<<8; } } @@ -312,29 +286,6 @@ _hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info) { return _hb_glyph_info_is_unicode_mark (info) ? info->unicode_props()>>8 : 0; } - - -/* Loop over grapheme. Based on foreach_cluster(). */ -#define foreach_grapheme(buffer, start, end) \ - for (unsigned int \ - _count = buffer->len, \ - start = 0, end = _count ? _next_grapheme (buffer, 0) : 0; \ - start < _count; \ - start = end, end = _next_grapheme (buffer, start)) - -static inline unsigned int -_next_grapheme (hb_buffer_t *buffer, unsigned int start) -{ - hb_glyph_info_t *info = buffer->info; - unsigned int count = buffer->len; - - while (++start < count && _hb_glyph_info_is_unicode_mark (&info[start])) - ; - - return start; -} - - #define info_cc(info) (_hb_glyph_info_get_modified_combining_class (&(info))) static inline bool @@ -379,6 +330,41 @@ _hb_glyph_info_unhide (hb_glyph_info_t *info) info->unicode_props() &= ~ UPROPS_MASK_HIDDEN; } +static inline void +_hb_glyph_info_set_continuation (hb_glyph_info_t *info) +{ + info->unicode_props() |= UPROPS_MASK_CONTINUATION; +} +static inline void +_hb_glyph_info_reset_continuation (hb_glyph_info_t *info) +{ + info->unicode_props() &= ~ UPROPS_MASK_CONTINUATION; +} +static inline bool +_hb_glyph_info_is_continuation (const hb_glyph_info_t *info) +{ + return info->unicode_props() & UPROPS_MASK_CONTINUATION; +} +/* Loop over grapheme. Based on foreach_cluster(). */ +#define foreach_grapheme(buffer, start, end) \ + for (unsigned int \ + _count = buffer->len, \ + start = 0, end = _count ? _hb_next_grapheme (buffer, 0) : 0; \ + start < _count; \ + start = end, end = _hb_next_grapheme (buffer, start)) + +static inline unsigned int +_hb_next_grapheme (hb_buffer_t *buffer, unsigned int start) +{ + hb_glyph_info_t *info = buffer->info; + unsigned int count = buffer->len; + + while (++start < count && _hb_glyph_info_is_continuation (&info[start])) + ; + + return start; +} + static inline bool _hb_glyph_info_is_unicode_format (const hb_glyph_info_t *info) { diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc index 29f52dcc28d..45d7dbdcfa7 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc @@ -54,16 +54,17 @@ hb_ot_map_builder_t::hb_ot_map_builder_t (hb_face_t *face_, /* Fetch script/language indices for GSUB/GPOS. We need these later to skip * features not available in either table and not waste precious bits for them. */ - hb_tag_t script_tags[3] = {HB_TAG_NONE, HB_TAG_NONE, HB_TAG_NONE}; - hb_tag_t language_tag; + unsigned int script_count = HB_OT_MAX_TAGS_PER_SCRIPT; + unsigned int language_count = HB_OT_MAX_TAGS_PER_LANGUAGE; + hb_tag_t script_tags[HB_OT_MAX_TAGS_PER_SCRIPT]; + hb_tag_t language_tags[HB_OT_MAX_TAGS_PER_LANGUAGE]; - hb_ot_tags_from_script (props.script, &script_tags[0], &script_tags[1]); - language_tag = hb_ot_tag_from_language (props.language); + hb_ot_tags_from_script_and_language (props.script, props.language, &script_count, script_tags, &language_count, language_tags); for (unsigned int table_index = 0; table_index < 2; table_index++) { hb_tag_t table_tag = table_tags[table_index]; - found_script[table_index] = (bool) hb_ot_layout_table_choose_script (face, table_tag, script_tags, &script_index[table_index], &chosen_script[table_index]); - hb_ot_layout_script_find_language (face, table_tag, script_index[table_index], language_tag, &language_index[table_index]); + found_script[table_index] = (bool) hb_ot_layout_table_select_script (face, table_tag, script_count, script_tags, &script_index[table_index], &chosen_script[table_index]); + hb_ot_layout_script_select_language (face, table_tag, script_index[table_index], language_count, language_tags, &language_index[table_index]); } } @@ -74,8 +75,9 @@ hb_ot_map_builder_t::~hb_ot_map_builder_t (void) 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) +void hb_ot_map_builder_t::add_feature (hb_tag_t tag, + hb_ot_map_feature_flags_t flags, + unsigned int value) { feature_info_t *info = feature_infos.push(); if (unlikely (!tag)) return; @@ -95,7 +97,8 @@ hb_ot_map_builder_t::add_lookups (hb_ot_map_t &m, unsigned int variations_index, hb_mask_t mask, bool auto_zwnj, - bool auto_zwj) + bool auto_zwj, + bool random) { unsigned int lookup_indices[32]; unsigned int offset, len; @@ -122,6 +125,7 @@ hb_ot_map_builder_t::add_lookups (hb_ot_map_t &m, lookup->index = lookup_indices[i]; lookup->auto_zwnj = auto_zwnj; lookup->auto_zwj = auto_zwj; + lookup->random = random; } offset += len; @@ -208,8 +212,8 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, /* Uses the global bit */ bits_needed = 0; else - /* Limit to 8 bits per feature. */ - bits_needed = MIN(8u, hb_bit_storage (info->max_value)); + /* Limit bits per feature. */ + bits_needed = MIN(HB_OT_MAP_MAX_BITS, hb_bit_storage (info->max_value)); if (!info->max_value || next_bit + bits_needed > 8 * sizeof (hb_mask_t)) continue; /* Feature disabled, or not enough bits. */ @@ -252,6 +256,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, map->stage[1] = info->stage[1]; map->auto_zwnj = !(info->flags & F_MANUAL_ZWNJ); map->auto_zwj = !(info->flags & F_MANUAL_ZWJ); + map->random = !!(info->flags & F_RANDOM); if ((info->flags & F_GLOBAL) && info->max_value == 1) { /* Uses the global bit */ map->shift = global_bit_shift; @@ -301,7 +306,8 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, variations_index, m.features[i].mask, m.features[i].auto_zwnj, - m.features[i].auto_zwj); + m.features[i].auto_zwj, + m.features[i].random); /* Sort lookups and merge duplicates */ if (last_num_lookups < m.lookups[table_index].len) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh index 32a9e7e003d..40b9921fd30 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh @@ -32,6 +32,9 @@ #include "hb-buffer.hh" +#define HB_OT_MAP_MAX_BITS 8u +#define HB_OT_MAP_MAX_VALUE ((1u << HB_OT_MAP_MAX_BITS) - 1u) + struct hb_ot_shape_plan_t; static const hb_tag_t table_tags[2] = {HB_OT_TAG_GSUB, HB_OT_TAG_GPOS}; @@ -52,6 +55,7 @@ struct hb_ot_map_t unsigned int needs_fallback : 1; unsigned int auto_zwnj : 1; unsigned int auto_zwj : 1; + unsigned int random : 1; inline int cmp (const hb_tag_t *tag_) const { return *tag_ < tag ? -1 : *tag_ > tag ? 1 : 0; } @@ -61,6 +65,7 @@ struct hb_ot_map_t unsigned short index; unsigned short auto_zwnj : 1; unsigned short auto_zwj : 1; + unsigned short random : 1; hb_mask_t mask; static int cmp (const void *pa, const void *pb) @@ -161,17 +166,27 @@ struct hb_ot_map_t hb_vector_t<stage_map_t, 4> stages[2]; /* GSUB/GPOS */ }; -enum hb_ot_map_feature_flags_t { +enum hb_ot_map_feature_flags_t +{ F_NONE = 0x0000u, F_GLOBAL = 0x0001u, /* Feature applies to all characters; results in no mask allocated for it. */ F_HAS_FALLBACK = 0x0002u, /* Has fallback implementation, so include mask bit even if feature not found. */ F_MANUAL_ZWNJ = 0x0004u, /* Don't skip over ZWNJ when matching **context**. */ F_MANUAL_ZWJ = 0x0008u, /* Don't skip over ZWJ when matching **input**. */ - F_GLOBAL_SEARCH = 0x0010u /* If feature not found in LangSys, look for it in global feature list and pick one. */ + F_MANUAL_JOINERS = F_MANUAL_ZWNJ | F_MANUAL_ZWJ, + F_GLOBAL_MANUAL_JOINERS= F_GLOBAL | F_MANUAL_JOINERS, + F_GLOBAL_HAS_FALLBACK = F_GLOBAL | F_HAS_FALLBACK, + F_GLOBAL_SEARCH = 0x0010u, /* If feature not found in LangSys, look for it in global feature list and pick one. */ + F_RANDOM = 0x0020u /* Randomly select a glyph from an AlternateSubstFormat1 subtable. */ }; HB_MARK_AS_FLAG_T (hb_ot_map_feature_flags_t); -/* Macro version for where const is desired. */ -#define F_COMBINE(l,r) (hb_ot_map_feature_flags_t ((unsigned int) (l) | (unsigned int) (r))) + + +struct hb_ot_map_feature_t +{ + hb_tag_t tag; + hb_ot_map_feature_flags_t flags; +}; struct hb_ot_map_builder_t @@ -183,11 +198,20 @@ struct hb_ot_map_builder_t 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); + HB_INTERNAL void add_feature (hb_tag_t tag, + hb_ot_map_feature_flags_t flags=F_NONE, + unsigned int value=1); + + inline void add_feature (const hb_ot_map_feature_t &feat) + { add_feature (feat.tag, feat.flags); } + + inline void enable_feature (hb_tag_t tag, + hb_ot_map_feature_flags_t flags=F_NONE, + unsigned int value=1) + { add_feature (tag, F_GLOBAL | flags, value); } - inline void add_global_bool_feature (hb_tag_t tag) - { add_feature (tag, 1, F_GLOBAL); } + inline void disable_feature (hb_tag_t tag) + { add_feature (tag, F_GLOBAL, 0); } inline void add_gsub_pause (hb_ot_map_t::pause_func_t pause_func) { add_pause (0, pause_func); } @@ -206,7 +230,8 @@ struct hb_ot_map_builder_t unsigned int variations_index, hb_mask_t mask, bool auto_zwnj = true, - bool auto_zwj = true); + bool auto_zwj = true, + bool random = false); struct feature_info_t { hb_tag_t tag; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh index b7ca167b179..2f871124cd1 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh @@ -50,7 +50,7 @@ struct MathValueRecord protected: HBINT16 value; /* The X or Y value in design units */ OffsetTo<Device> deviceTable; /* Offset to the device table - from the - * beginning of parent table. May be nullptr. + * beginning of parent table. May be NULL. * Suggested format for device table is 1. */ public: @@ -234,7 +234,7 @@ struct MathKern TRACE_SANITIZE (this); unsigned int count = 2 * heightCount + 1; for (unsigned int i = 0; i < count; i++) - if (!mathValueRecords[i].sanitize (c, this)) return_trace (false); + if (!mathValueRecordsZ.arrayZ[i].sanitize (c, this)) return_trace (false); return_trace (true); } @@ -242,16 +242,14 @@ struct MathKern { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && - c->check_array (mathValueRecords, - mathValueRecords[0].static_size, - 2 * heightCount + 1) && + c->check_array (mathValueRecordsZ.arrayZ, 2 * heightCount + 1) && sanitize_math_value_records (c)); } inline hb_position_t get_value (hb_position_t correction_height, hb_font_t *font) const { - const MathValueRecord* correctionHeight = mathValueRecords; - const MathValueRecord* kernValue = mathValueRecords + heightCount; + const MathValueRecord* correctionHeight = mathValueRecordsZ.arrayZ; + const MathValueRecord* kernValue = mathValueRecordsZ.arrayZ + heightCount; int sign = font->y_scale < 0 ? -1 : +1; /* The description of the MathKern table is a ambiguous, but interpreting @@ -279,18 +277,19 @@ struct MathKern } protected: - HBUINT16 heightCount; - MathValueRecord mathValueRecords[VAR]; /* Array of correction heights at - * which the kern value changes. - * Sorted by the height value in - * design units (heightCount entries), - * Followed by: - * Array of kern values corresponding - * to heights. (heightCount+1 entries). - */ + HBUINT16 heightCount; + UnsizedArrayOf<MathValueRecord> + mathValueRecordsZ; /* Array of correction heights at + * which the kern value changes. + * Sorted by the height value in + * design units (heightCount entries), + * Followed by: + * Array of kern values corresponding + * to heights. (heightCount+1 entries). + */ public: - DEFINE_SIZE_ARRAY (2, mathValueRecords); + DEFINE_SIZE_ARRAY (2, mathValueRecordsZ); }; struct MathKernInfoRecord @@ -319,7 +318,7 @@ struct MathKernInfoRecord protected: /* Offset to MathKern table for each corner - - * from the beginning of MathKernInfo table. May be nullptr. */ + * from the beginning of MathKernInfo table. May be NULL. */ OffsetTo<MathKern> mathKern[4]; public: @@ -402,7 +401,7 @@ struct MathGlyphInfo * from the beginning of MathGlyphInfo table. When the left or right glyph of * a box is an extended shape variant, the (ink) box (and not the default * position defined by values in MathConstants table) should be used for - * vertical positioning purposes. May be nullptr.. */ + * vertical positioning purposes. May be NULL.. */ OffsetTo<Coverage> extendedShapeCoverage; /* Offset to MathKernInfo table - @@ -571,7 +570,7 @@ struct MathGlyphConstruction protected: /* Offset to MathGlyphAssembly table for this shape - from the beginning of - MathGlyphConstruction table. May be nullptr. */ + MathGlyphConstruction table. May be NULL. */ OffsetTo<MathGlyphAssembly> glyphAssembly; /* MathGlyphVariantRecords for alternative variants of the glyphs. */ @@ -588,7 +587,7 @@ struct MathVariants TRACE_SANITIZE (this); unsigned int count = vertGlyphCount + horizGlyphCount; for (unsigned int i = 0; i < count; i++) - if (!glyphConstruction[i].sanitize (c, this)) return_trace (false); + if (!glyphConstruction.arrayZ[i].sanitize (c, this)) return_trace (false); return_trace (true); } @@ -598,9 +597,7 @@ struct MathVariants return_trace (c->check_struct (this) && vertGlyphCoverage.sanitize (c, this) && horizGlyphCoverage.sanitize (c, this) && - c->check_array (glyphConstruction, - glyphConstruction[0].static_size, - vertGlyphCount + horizGlyphCount) && + c->check_array (glyphConstruction.arrayZ, vertGlyphCount + horizGlyphCount) && sanitize_offsets (c)); } @@ -670,7 +667,8 @@ struct MathVariants /* Array of offsets to MathGlyphConstruction tables - from the beginning of the MathVariants table, for shapes growing in vertical/horizontal direction. */ - OffsetTo<MathGlyphConstruction> glyphConstruction[VAR]; + UnsizedArrayOf<OffsetTo<MathGlyphConstruction> > + glyphConstruction; public: DEFINE_SIZE_ARRAY (10, glyphConstruction); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh index efcf593e956..2572ad288f5 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh @@ -136,7 +136,7 @@ struct maxp FixedVersion<>version; /* Version of the maxp table (0.5 or 1.0), * 0x00005000u or 0x00010000u. */ HBUINT16 numGlyphs; /* The number of glyphs in the font. */ -/*maxpV1Tail v1Tail[VAR]; */ +/*maxpV1Tail v1Tail[VAR]; */ public: DEFINE_SIZE_STATIC (6); }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh index a1de1193f00..bb49c2cb0d2 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh @@ -91,7 +91,7 @@ struct name key.encodingID.set (encoding_id); key.languageID.set (language_id); key.nameID.set (name_id); - NameRecord *match = (NameRecord *) bsearch (&key, nameRecord, count, sizeof (nameRecord[0]), NameRecord::cmp); + NameRecord *match = (NameRecord *) bsearch (&key, nameRecordZ.arrayZ, count, sizeof (nameRecordZ[0]), NameRecord::cmp); if (!match) return 0; @@ -102,14 +102,14 @@ struct name } inline unsigned int get_size (void) const - { return min_size + count * nameRecord[0].min_size; } + { return min_size + count * nameRecordZ[0].min_size; } inline bool sanitize_records (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); char *string_pool = (char *) this + stringOffset; unsigned int _count = count; for (unsigned int i = 0; i < _count; i++) - if (!nameRecord[i].sanitize (c, string_pool)) return_trace (false); + if (!nameRecordZ[i].sanitize (c, string_pool)) return_trace (false); return_trace (true); } @@ -118,7 +118,7 @@ struct name TRACE_SANITIZE (this); return_trace (c->check_struct (this) && likely (format == 0 || format == 1) && - c->check_array (nameRecord, nameRecord[0].static_size, count) && + c->check_array (nameRecordZ.arrayZ, count) && sanitize_records (c)); } @@ -126,9 +126,10 @@ struct name HBUINT16 format; /* Format selector (=0/1). */ HBUINT16 count; /* Number of name records. */ Offset16 stringOffset; /* Offset to start of string storage (from start of table). */ - NameRecord nameRecord[VAR]; /* The name records where count is the number of records. */ + UnsizedArrayOf<NameRecord> + nameRecordZ; /* The name records where count is the number of records. */ public: - DEFINE_SIZE_ARRAY (6, nameRecord); + DEFINE_SIZE_ARRAY (6, nameRecordZ); }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-tibetan.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.h index 9982ebc29f0..49423e87cc8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-tibetan.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.h @@ -1,5 +1,5 @@ /* - * Copyright © 2010,2012 Google, Inc. + * Copyright © 2018 Ebrahim Byagowi. * * This is part of HarfBuzz, a text shaping library. * @@ -20,44 +20,34 @@ * 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_H_IN +#error "Include <hb-ot.h> instead." +#endif + +#ifndef HB_OT_NAME_H +#define HB_OT_NAME_H + +#include "hb.h" + +HB_BEGIN_DECLS + + +/** + * hb_name_id_t: * - * Google Author(s): Behdad Esfahbod + * Since: 2.0.0 */ +typedef unsigned int hb_name_id_t; + +/** + * HB_NAME_ID_INVALID + * + * Since: 2.0.0 + **/ +#define HB_NAME_ID_INVALID 0xFFFF + +HB_END_DECLS -#include "hb-ot-shape-complex.hh" - - -static const hb_tag_t tibetan_features[] = -{ - HB_TAG('a','b','v','s'), - HB_TAG('b','l','w','s'), - HB_TAG('a','b','v','m'), - HB_TAG('b','l','w','m'), - HB_TAG_NONE -}; - -static void -collect_features_tibetan (hb_ot_shape_planner_t *plan) -{ - for (const hb_tag_t *script_features = tibetan_features; script_features && *script_features; script_features++) - plan->map.add_global_bool_feature (*script_features); -} - - -const hb_ot_complex_shaper_t _hb_ot_complex_shaper_tibetan = -{ - collect_features_tibetan, - nullptr, /* override_features */ - nullptr, /* data_create */ - nullptr, /* data_destroy */ - nullptr, /* preprocess_text */ - nullptr, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, - nullptr, /* decompose */ - nullptr, /* compose */ - nullptr, /* setup_masks */ - nullptr, /* disable_otl */ - nullptr, /* reorder_marks */ - HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, - true, /* fallback_position */ -}; +#endif /* HB_OT_NAME_H */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh index f28858c592b..71d2bf59d66 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh @@ -81,7 +81,7 @@ struct os2 hb_codepoint_t cp = HB_SET_VALUE_INVALID; while (codepoints->next (&cp)) { - unsigned int bit = hb_get_unicode_range_bit (cp); + unsigned int bit = _hb_ot_os2_get_unicode_range_bit (cp); if (bit < 128) { unsigned int block = bit / 32; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-unicode-ranges.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-unicode-ranges.hh index 42dfa490680..19780088a7a 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-unicode-ranges.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-unicode-ranges.hh @@ -31,14 +31,29 @@ namespace OT { -struct Range { +struct OS2Range +{ + static int + cmp (const void *_key, const void *_item, void *_arg) + { + hb_codepoint_t cp = *((hb_codepoint_t *) _key); + const OS2Range *range = (OS2Range *) _item; + + if (cp < range->start) + return -1; + else if (cp <= range->end) + return 0; + else + return +1; + } + hb_codepoint_t start; hb_codepoint_t end; unsigned int bit; }; -/* Note: The contents of this array was generated using src/gen-unicode-ranges.py. */ -static Range os2UnicodeRangesSorted[] = +/* Note: The contents of this array was generated using gen-os2-unicode-ranges.py. */ +static const OS2Range _hb_os2_unicode_ranges[] = { { 0x0, 0x7F, 0}, // Basic Latin { 0x80, 0xFF, 1}, // Latin-1 Supplement @@ -211,31 +226,17 @@ static Range os2UnicodeRangesSorted[] = {0x100000, 0x10FFFD, 90}, // Private Use (plane 16) }; -static int -_compare_range (const void *_key, const void *_item, void *_arg) -{ - hb_codepoint_t cp = *((hb_codepoint_t *) _key); - const Range *range = (Range *) _item; - - if (cp < range->start) - return -1; - else if (cp <= range->end) - return 0; - else - return 1; -} - /** - * hb_get_unicode_range_bit: - * Returns the bit to be set in os/2 ulUnicodeRange for a given codepoint. + * _hb_ot_os2_get_unicode_range_bit: + * Returns the bit to be set in os/2 ulUnicodeOS2Range for a given codepoint. **/ static unsigned int -hb_get_unicode_range_bit (hb_codepoint_t cp) +_hb_ot_os2_get_unicode_range_bit (hb_codepoint_t cp) { - Range *range = (Range*) hb_bsearch_r (&cp, os2UnicodeRangesSorted, - sizeof (os2UnicodeRangesSorted) / sizeof(Range), - sizeof(Range), - _compare_range, nullptr); + OS2Range *range = (OS2Range*) hb_bsearch_r (&cp, _hb_os2_unicode_ranges, + ARRAY_LENGTH (_hb_os2_unicode_ranges), + sizeof (OS2Range), + OS2Range::cmp, nullptr); if (range != nullptr) return range->bit; return -1; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh index d0265d056dd..bd049f9ab97 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh @@ -55,10 +55,11 @@ struct postV2Tail return_trace (glyphNameIndex.sanitize (c)); } - ArrayOf<HBUINT16>glyphNameIndex; /* This is not an offset, but is the + ArrayOf<HBUINT16> glyphNameIndex; /* This is not an offset, but is the * ordinal number of the glyph in 'post' * string tables. */ - HBUINT8 namesX[VAR]; /* Glyph names with length bytes [variable] + UnsizedArrayOf<HBUINT8> + namesX; /* Glyph names with length bytes [variable] * (a Pascal string). */ DEFINE_SIZE_ARRAY2 (2, glyphNameIndex, namesX); @@ -130,6 +131,7 @@ struct post { index_to_offset.fini (); free (gids_sorted_by_name.get ()); + hb_blob_destroy (blob); } inline bool get_glyph_name (hb_codepoint_t glyph, @@ -142,7 +144,7 @@ struct post return true; if (buf_len <= s.len) /* What to do with truncation? Returning false for now. */ return false; - strncpy (buf, s.bytes, s.len); + strncpy (buf, s.arrayZ, s.len); buf[s.len] = '\0'; return true; } @@ -240,7 +242,7 @@ struct post if (index >= index_to_offset.len) return hb_bytes_t (); - unsigned int offset = index_to_offset.arrayZ[index]; + unsigned int offset = index_to_offset[index]; const uint8_t *data = pool + offset; unsigned int name_length = *data; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh index 0ef60f64347..2aa0367280a 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh @@ -201,7 +201,7 @@ struct arabic_fallback_plan_t hb_mask_t mask_array[ARABIC_FALLBACK_MAX_LOOKUPS]; OT::SubstLookup *lookup_array[ARABIC_FALLBACK_MAX_LOOKUPS]; - hb_ot_layout_lookup_accelerator_t accel_array[ARABIC_FALLBACK_MAX_LOOKUPS]; + OT::hb_ot_layout_lookup_accelerator_t accel_array[ARABIC_FALLBACK_MAX_LOOKUPS]; }; #if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(HB_NO_WIN1256) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc index ebc1d3d5fd0..b56443910de 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc @@ -159,11 +159,6 @@ static const struct arabic_state_table_entry { static void -nuke_joiners (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer); - -static void arabic_fallback_shape (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); @@ -200,32 +195,38 @@ collect_features_arabic (hb_ot_shape_planner_t *plan) * work correctly. See https://github.com/harfbuzz/harfbuzz/issues/505 */ - map->add_gsub_pause (nuke_joiners); - map->add_global_bool_feature (HB_TAG('s','t','c','h')); + map->enable_feature (HB_TAG('s','t','c','h')); map->add_gsub_pause (record_stch); - map->add_global_bool_feature (HB_TAG('c','c','m','p')); - map->add_global_bool_feature (HB_TAG('l','o','c','l')); + map->enable_feature (HB_TAG('c','c','m','p')); + map->enable_feature (HB_TAG('l','o','c','l')); map->add_gsub_pause (nullptr); for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++) { bool has_fallback = plan->props.script == HB_SCRIPT_ARABIC && !FEATURE_IS_SYRIAC (arabic_features[i]); - map->add_feature (arabic_features[i], 1, has_fallback ? F_HAS_FALLBACK : F_NONE); + map->add_feature (arabic_features[i], has_fallback ? F_HAS_FALLBACK : F_NONE); map->add_gsub_pause (nullptr); } - map->add_feature (HB_TAG('r','l','i','g'), 1, F_GLOBAL|F_HAS_FALLBACK); + /* Normally, Unicode says a ZWNJ means "don't ligate". In Arabic script + * however, it says a ZWJ should also mean "don't ligate". So we run + * the main ligating features as MANUAL_ZWJ. */ + + map->enable_feature (HB_TAG('r','l','i','g'), F_MANUAL_ZWJ | F_HAS_FALLBACK); + if (plan->props.script == HB_SCRIPT_ARABIC) map->add_gsub_pause (arabic_fallback_shape); /* No pause after rclt. See 98460779bae19e4d64d29461ff154b3527bf8420. */ - map->add_global_bool_feature (HB_TAG('r','c','l','t')); - map->add_global_bool_feature (HB_TAG('c','a','l','t')); + map->enable_feature (HB_TAG('r','c','l','t'), F_MANUAL_ZWJ); + map->enable_feature (HB_TAG('c','a','l','t'), F_MANUAL_ZWJ); map->add_gsub_pause (nullptr); + /* And undo here. */ + /* The spec includes 'cswh'. Earlier versions of Windows * used to enable this by default, but testing suggests * that Windows 8 and later do not enable it by default, @@ -234,8 +235,8 @@ collect_features_arabic (hb_ot_shape_planner_t *plan) * Note that IranNastaliq uses this feature extensively * to fixup broken glyph sequences. Oh well... * Test case: U+0643,U+0640,U+0631. */ - //map->add_global_bool_feature (HB_TAG('c','s','w','h')); - map->add_global_bool_feature (HB_TAG('m','s','e','t')); + //map->enable_feature (HB_TAG('c','s','w','h')); + map->enable_feature (HB_TAG('m','s','e','t')); } #include "hb-ot-shape-complex-arabic-fallback.hh" @@ -379,19 +380,6 @@ setup_masks_arabic (const hb_ot_shape_plan_t *plan, setup_masks_arabic_plan (arabic_plan, buffer, plan->props.script); } - -static void -nuke_joiners (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_font_t *font HB_UNUSED, - hb_buffer_t *buffer) -{ - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 0; i < count; i++) - if (_hb_glyph_info_is_zwj (&info[i])) - _hb_glyph_info_flip_joiners (&info[i]); -} - static void arabic_fallback_shape (const hb_ot_shape_plan_t *plan, hb_font_t *font, @@ -470,9 +458,9 @@ apply_stch (const hb_ot_shape_plan_t *plan, int sign = font->x_scale < 0 ? -1 : +1; unsigned int extra_glyphs_needed = 0; // Set during MEASURE, used during CUT - typedef enum { MEASURE, CUT } step_t; + enum { MEASURE, CUT } /* step_t */; - for (step_t step = MEASURE; step <= CUT; step = (step_t) (step + 1)) + for (unsigned int step = MEASURE; step <= CUT; step = step + 1) { unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; @@ -611,7 +599,7 @@ postprocess_glyphs_arabic (const hb_ot_shape_plan_t *plan, HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action); } -/* https://unicode.org/reports/tr53/tr53-1.pdf */ +/* http://www.unicode.org/reports/tr53/ */ static hb_codepoint_t modifier_combining_marks[] = @@ -623,6 +611,7 @@ modifier_combining_marks[] = 0x06E3u, /* ARABIC SMALL LOW SEEN */ 0x06E7u, /* ARABIC SMALL HIGH YEH */ 0x06E8u, /* ARABIC SMALL HIGH NOON */ + 0x08D3u, /* ARABIC SMALL LOW WAW */ 0x08F3u, /* ARABIC SMALL HIGH WAW */ }; @@ -714,7 +703,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic = nullptr, /* decompose */ nullptr, /* compose */ setup_masks_arabic, - nullptr, /* disable_otl */ + HB_TAG_NONE, /* gpos_tag */ reorder_marks_arabic, HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, true, /* fallback_position */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-default.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-default.cc index 45d5f434673..97923ecf692 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-default.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-default.cc @@ -39,7 +39,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default = nullptr, /* decompose */ nullptr, /* compose */ nullptr, /* setup_masks */ - nullptr, /* disable_otl */ + HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, true, /* fallback_position */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hangul.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hangul.cc index ea731114a88..9595402582e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hangul.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hangul.cc @@ -56,7 +56,7 @@ collect_features_hangul (hb_ot_shape_planner_t *plan) hb_ot_map_builder_t *map = &plan->map; for (unsigned int i = FIRST_HANGUL_FEATURE; i < HANGUL_FEATURE_COUNT; i++) - map->add_feature (hangul_features[i], 1, F_NONE); + map->add_feature (hangul_features[i]); } static void @@ -65,7 +65,7 @@ override_features_hangul (hb_ot_shape_planner_t *plan) /* Uniscribe does not apply 'calt' for Hangul, and certain fonts * (Noto Sans CJK, Source Sans Han, etc) apply all of jamo lookups * in calt, which is not desirable. */ - plan->map.add_feature (HB_TAG('c','a','l','t'), 0, F_GLOBAL); + plan->map.disable_feature (HB_TAG('c','a','l','t')); } struct hangul_shape_plan_t @@ -345,13 +345,6 @@ 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->successful)) - return; - - /* We decomposed S: apply jamo features to the individual glyphs - * that are now in buffer->out_info. - */ - hb_glyph_info_t *info = buffer->out_info; /* If we decomposed an LV because of a non-combining T following, * we want to include this T in the syllable. @@ -361,6 +354,14 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan, buffer->next_glyph (); s_len++; } + + if (unlikely (!buffer->successful)) + return; + + /* We decomposed S: apply jamo features to the individual glyphs + * that are now in buffer->out_info. + */ + hb_glyph_info_t *info = buffer->out_info; end = start + s_len; unsigned int i = start; @@ -368,6 +369,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan, info[i++].hangul_shaping_feature() = VJMO; if (i < end) info[i++].hangul_shaping_feature() = TJMO; + if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) buffer->merge_out_clusters (start, end); continue; @@ -424,7 +426,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hangul = nullptr, /* decompose */ nullptr, /* compose */ setup_masks_hangul, - nullptr, /* disable_otl */ + HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, false, /* fallback_position */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hebrew.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hebrew.cc index ba25258a33b..90c36c023a4 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hebrew.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hebrew.cc @@ -70,7 +70,7 @@ compose_hebrew (const hb_ot_shape_normalize_context_t *c, bool found = (bool) c->unicode->compose (a, b, ab); - if (!found && !c->plan->has_mark) + if (!found && !c->plan->has_gpos_mark) { /* Special-case Hebrew presentation forms that are excluded from * standard normalization, but wanted for old fonts. */ @@ -154,18 +154,6 @@ compose_hebrew (const hb_ot_shape_normalize_context_t *c, return found; } -static bool -disable_otl_hebrew (const hb_ot_shape_plan_t *plan) -{ - /* For Hebrew shaper, use fallback if GPOS does not have 'hebr' - * script. This matches Uniscribe better, and makes fonts like - * Arial that have GSUB/GPOS/GDEF but no data for Hebrew work. - * See: - * https://github.com/harfbuzz/harfbuzz/issues/347#issuecomment-267838368 - */ - return plan->map.chosen_script[1] != HB_TAG ('h','e','b','r'); -} - const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hebrew = { @@ -179,7 +167,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hebrew = nullptr, /* decompose */ compose_hebrew, nullptr, /* setup_masks */ - disable_otl_hebrew, + HB_TAG ('h','e','b','r'), /* gpos_tag. https://github.com/harfbuzz/harfbuzz/issues/347#issuecomment-267838368 */ nullptr, /* reorder_marks */ HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, true, /* fallback_position */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.hh index f67a525c5aa..e2ecfb89ca2 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.hh @@ -34,887 +34,709 @@ #line 36 "hb-ot-shape-complex-indic-machine.hh" static const unsigned char _indic_syllable_machine_trans_keys[] = { - 8u, 8u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, + 8u, 8u, 4u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, - 16u, 16u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, - 4u, 13u, 4u, 8u, 4u, 13u, 8u, 8u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, - 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, - 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, - 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, - 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 8u, 8u, 5u, 8u, - 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, - 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, - 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, - 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, - 8u, 8u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, - 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, - 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, - 16u, 16u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, - 4u, 13u, 4u, 8u, 4u, 13u, 4u, 13u, 5u, 8u, 5u, 8u, 5u, 7u, 5u, 8u, - 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, - 8u, 8u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, - 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 8u, 8u, 1u, 19u, 3u, 17u, - 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, - 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, - 3u, 17u, 4u, 17u, 5u, 10u, 5u, 10u, 5u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, - 5u, 10u, 3u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, - 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, - 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, - 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, - 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, - 3u, 17u, 3u, 17u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, - 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, - 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 5u, 10u, 5u, 10u, 5u, 10u, - 10u, 10u, 10u, 10u, 10u, 10u, 5u, 10u, 3u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, - 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, - 5u, 10u, 3u, 10u, 4u, 10u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, - 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, - 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, - 1u, 16u, 1u, 16u, 1u, 16u, 4u, 8u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, - 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, - 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 5u, 10u, - 5u, 10u, 5u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 5u, 10u, 3u, 10u, 3u, 10u, + 16u, 16u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, + 4u, 8u, 4u, 13u, 8u, 8u, 4u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, + 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u, + 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, + 4u, 8u, 6u, 6u, 16u, 16u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, + 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 8u, 8u, 4u, 8u, 5u, 7u, 7u, 7u, + 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, + 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, + 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 13u, 4u, 8u, 4u, 13u, + 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 8u, 8u, 4u, 8u, 5u, 7u, + 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, + 5u, 7u, 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, + 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 13u, 4u, 8u, + 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 13u, + 5u, 8u, 8u, 8u, 1u, 19u, 3u, 13u, 3u, 10u, 4u, 10u, 1u, 16u, 3u, 13u, + 3u, 10u, 4u, 10u, 1u, 16u, 3u, 13u, 3u, 10u, 4u, 10u, 1u, 16u, 3u, 13u, + 3u, 10u, 4u, 10u, 1u, 16u, 3u, 13u, 3u, 10u, 4u, 10u, 5u, 10u, 5u, 10u, + 5u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 5u, 10u, 3u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, - 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 3u, 17u, 3u, 17u, 1u, 16u, - 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, - 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, - 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 4u, 13u, 3u, 17u, 4u, 8u, - 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, - 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, - 3u, 17u, 3u, 17u, 4u, 17u, 5u, 10u, 5u, 10u, 5u, 10u, 10u, 10u, 10u, 10u, - 10u, 10u, 5u, 10u, 3u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, + 3u, 10u, 4u, 10u, 3u, 10u, 3u, 13u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 10u, + 3u, 13u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 10u, 3u, 13u, 1u, 16u, 1u, 16u, + 1u, 16u, 3u, 10u, 3u, 13u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 10u, 3u, 13u, + 3u, 13u, 3u, 10u, 4u, 10u, 1u, 16u, 3u, 13u, 3u, 10u, 4u, 10u, 1u, 16u, + 3u, 13u, 3u, 10u, 4u, 10u, 1u, 16u, 3u, 13u, 3u, 10u, 4u, 10u, 1u, 16u, + 3u, 13u, 3u, 10u, 4u, 10u, 5u, 10u, 5u, 10u, 5u, 10u, 10u, 10u, 10u, 10u, + 10u, 10u, 5u, 10u, 3u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, + 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 3u, 10u, + 3u, 13u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 10u, 3u, 13u, 1u, 16u, 1u, 16u, + 1u, 16u, 3u, 10u, 3u, 13u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 10u, 3u, 13u, + 1u, 16u, 1u, 16u, 1u, 16u, 4u, 8u, 3u, 10u, 3u, 10u, 4u, 10u, 1u, 16u, + 3u, 13u, 3u, 10u, 4u, 10u, 1u, 16u, 3u, 13u, 3u, 10u, 4u, 10u, 1u, 16u, + 3u, 13u, 3u, 10u, 4u, 10u, 1u, 16u, 3u, 13u, 3u, 10u, 4u, 10u, 5u, 10u, + 5u, 10u, 5u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 5u, 10u, 3u, 10u, 5u, 10u, + 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, + 5u, 10u, 3u, 10u, 4u, 10u, 3u, 10u, 3u, 13u, 1u, 16u, 1u, 16u, 1u, 16u, + 3u, 10u, 3u, 13u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 10u, 3u, 13u, 1u, 16u, + 1u, 16u, 1u, 16u, 3u, 10u, 3u, 13u, 1u, 16u, 1u, 16u, 1u, 16u, 4u, 13u, + 3u, 10u, 4u, 8u, 3u, 13u, 3u, 10u, 4u, 10u, 1u, 16u, 3u, 13u, 3u, 10u, + 4u, 10u, 1u, 16u, 3u, 13u, 3u, 10u, 4u, 10u, 1u, 16u, 3u, 13u, 3u, 10u, + 4u, 10u, 1u, 16u, 3u, 13u, 3u, 10u, 4u, 10u, 5u, 10u, 5u, 10u, 5u, 10u, + 10u, 10u, 10u, 10u, 10u, 10u, 5u, 10u, 3u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, - 4u, 10u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, - 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, - 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, - 1u, 16u, 3u, 17u, 1u, 17u, 3u, 17u, 1u, 17u, 4u, 13u, 5u, 10u, 10u, 10u, - 10u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, - 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, + 4u, 10u, 3u, 10u, 3u, 13u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 10u, 3u, 13u, + 1u, 16u, 1u, 16u, 1u, 16u, 3u, 10u, 3u, 13u, 1u, 16u, 1u, 16u, 1u, 16u, + 3u, 10u, 3u, 13u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 10u, 1u, 16u, 3u, 13u, + 1u, 16u, 4u, 13u, 5u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 3u, 10u, 5u, 10u, 5u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 0 }; static const char _indic_syllable_machine_key_spans[] = { - 1, 4, 3, 1, 4, 3, 1, 4, + 1, 5, 3, 1, 4, 3, 1, 4, 3, 1, 4, 3, 1, 5, 1, 1, 5, 1, 1, 5, 1, 1, 5, 1, - 1, 5, 10, 5, 10, 5, 10, 5, - 10, 5, 10, 1, 4, 3, 1, 4, - 3, 1, 4, 3, 1, 4, 3, 1, - 5, 1, 1, 5, 1, 1, 5, 1, - 1, 5, 1, 1, 5, 10, 5, 10, - 5, 10, 5, 10, 5, 10, 1, 4, - 3, 1, 4, 3, 1, 4, 3, 1, - 4, 3, 1, 5, 1, 1, 5, 1, + 1, 10, 5, 10, 5, 10, 5, 10, + 5, 10, 1, 5, 3, 1, 4, 3, + 1, 4, 3, 1, 4, 3, 1, 5, + 1, 1, 5, 1, 1, 5, 1, 1, + 5, 1, 1, 10, 5, 10, 5, 10, + 5, 10, 5, 10, 1, 5, 3, 1, + 4, 3, 1, 4, 3, 1, 4, 3, 1, 5, 1, 1, 5, 1, 1, 5, - 10, 5, 10, 5, 10, 5, 10, 5, + 1, 1, 5, 1, 1, 10, 5, 10, + 5, 10, 5, 10, 5, 1, 5, 3, 1, 4, 3, 1, 4, 3, 1, 4, - 3, 1, 4, 3, 1, 5, 1, 1, - 5, 1, 1, 5, 1, 1, 5, 1, - 1, 5, 10, 5, 10, 5, 10, 5, - 10, 5, 10, 10, 4, 4, 3, 4, - 3, 1, 4, 3, 1, 4, 3, 1, - 1, 5, 1, 1, 5, 1, 1, 5, - 1, 1, 5, 1, 1, 1, 19, 15, - 15, 14, 16, 15, 15, 14, 16, 15, - 15, 14, 16, 15, 15, 14, 16, 15, - 15, 14, 6, 6, 6, 1, 1, 1, - 6, 8, 8, 7, 6, 8, 7, 6, - 8, 7, 6, 8, 7, 6, 8, 7, - 15, 15, 16, 16, 16, 16, 15, 15, - 16, 16, 16, 16, 15, 15, 16, 16, - 16, 16, 15, 15, 16, 16, 16, 16, - 15, 15, 15, 15, 14, 16, 15, 15, - 14, 16, 15, 15, 14, 16, 15, 15, - 14, 16, 15, 15, 14, 6, 6, 6, - 1, 1, 1, 6, 8, 8, 7, 6, - 8, 7, 6, 8, 7, 6, 8, 7, - 6, 8, 7, 15, 15, 16, 16, 16, - 16, 15, 15, 16, 16, 16, 16, 15, - 15, 16, 16, 16, 16, 15, 15, 16, - 16, 16, 16, 5, 15, 15, 14, 16, - 15, 15, 14, 16, 15, 15, 14, 16, - 15, 15, 14, 16, 15, 15, 14, 6, - 6, 6, 1, 1, 1, 6, 8, 8, + 3, 1, 5, 1, 1, 5, 1, 1, + 5, 1, 1, 5, 1, 1, 10, 5, + 10, 5, 10, 5, 10, 5, 10, 10, + 4, 1, 19, 11, 8, 7, 16, 11, + 8, 7, 16, 11, 8, 7, 16, 11, + 8, 7, 16, 11, 8, 7, 6, 6, + 6, 1, 1, 1, 6, 8, 6, 8, 7, 6, 8, 7, 6, 8, 7, 6, - 8, 7, 6, 8, 7, 15, 15, 16, - 16, 16, 16, 15, 15, 16, 16, 16, - 16, 15, 15, 16, 16, 16, 16, 15, - 15, 16, 16, 16, 16, 10, 15, 5, - 15, 15, 14, 16, 15, 15, 14, 16, - 15, 15, 14, 16, 15, 15, 14, 16, - 15, 15, 14, 6, 6, 6, 1, 1, - 1, 6, 8, 8, 7, 6, 8, 7, + 8, 7, 8, 11, 16, 16, 16, 8, + 11, 16, 16, 16, 8, 11, 16, 16, + 16, 8, 11, 16, 16, 16, 8, 11, + 11, 8, 7, 16, 11, 8, 7, 16, + 11, 8, 7, 16, 11, 8, 7, 16, + 11, 8, 7, 6, 6, 6, 1, 1, + 1, 6, 8, 6, 8, 7, 6, 8, + 7, 6, 8, 7, 6, 8, 7, 8, + 11, 16, 16, 16, 8, 11, 16, 16, + 16, 8, 11, 16, 16, 16, 8, 11, + 16, 16, 16, 5, 8, 8, 7, 16, + 11, 8, 7, 16, 11, 8, 7, 16, + 11, 8, 7, 16, 11, 8, 7, 6, + 6, 6, 1, 1, 1, 6, 8, 6, + 8, 7, 6, 8, 7, 6, 8, 7, + 6, 8, 7, 8, 11, 16, 16, 16, + 8, 11, 16, 16, 16, 8, 11, 16, + 16, 16, 8, 11, 16, 16, 16, 10, + 8, 5, 11, 8, 7, 16, 11, 8, + 7, 16, 11, 8, 7, 16, 11, 8, + 7, 16, 11, 8, 7, 6, 6, 6, + 1, 1, 1, 6, 8, 6, 8, 7, 6, 8, 7, 6, 8, 7, 6, 8, - 7, 15, 15, 16, 16, 16, 16, 15, - 15, 16, 16, 16, 16, 15, 15, 16, - 16, 16, 16, 15, 15, 16, 16, 16, - 16, 15, 17, 15, 17, 10, 6, 1, - 1, 1, 6, 16, 8, 7, 6, 8, - 7, 6, 8, 7, 6, 8, 7, 6, + 7, 8, 11, 16, 16, 16, 8, 11, + 16, 16, 16, 8, 11, 16, 16, 16, + 8, 11, 16, 16, 16, 8, 16, 11, + 16, 10, 6, 1, 1, 1, 6, 16, 8, 6, 6, 1, 1, 1, 6, 16 }; static const short _indic_syllable_machine_index_offsets[] = { - 0, 2, 7, 11, 13, 18, 22, 24, - 29, 33, 35, 40, 44, 46, 52, 54, - 56, 62, 64, 66, 72, 74, 76, 82, - 84, 86, 92, 103, 109, 120, 126, 137, - 143, 154, 160, 171, 173, 178, 182, 184, - 189, 193, 195, 200, 204, 206, 211, 215, - 217, 223, 225, 227, 233, 235, 237, 243, - 245, 247, 253, 255, 257, 263, 274, 280, - 291, 297, 308, 314, 325, 331, 342, 344, - 349, 353, 355, 360, 364, 366, 371, 375, - 377, 382, 386, 388, 394, 396, 398, 404, - 406, 408, 414, 416, 418, 424, 426, 428, - 434, 445, 451, 462, 468, 479, 485, 496, - 502, 504, 509, 513, 515, 520, 524, 526, - 531, 535, 537, 542, 546, 548, 554, 556, - 558, 564, 566, 568, 574, 576, 578, 584, - 586, 588, 594, 605, 611, 622, 628, 639, - 645, 656, 662, 673, 684, 689, 694, 698, - 703, 707, 709, 714, 718, 720, 725, 729, - 731, 733, 739, 741, 743, 749, 751, 753, - 759, 761, 763, 769, 771, 773, 775, 795, - 811, 827, 842, 859, 875, 891, 906, 923, - 939, 955, 970, 987, 1003, 1019, 1034, 1051, - 1067, 1083, 1098, 1105, 1112, 1119, 1121, 1123, - 1125, 1132, 1141, 1150, 1158, 1165, 1174, 1182, - 1189, 1198, 1206, 1213, 1222, 1230, 1237, 1246, - 1254, 1270, 1286, 1303, 1320, 1337, 1354, 1370, - 1386, 1403, 1420, 1437, 1454, 1470, 1486, 1503, - 1520, 1537, 1554, 1570, 1586, 1603, 1620, 1637, - 1654, 1670, 1686, 1702, 1718, 1733, 1750, 1766, - 1782, 1797, 1814, 1830, 1846, 1861, 1878, 1894, - 1910, 1925, 1942, 1958, 1974, 1989, 1996, 2003, - 2010, 2012, 2014, 2016, 2023, 2032, 2041, 2049, - 2056, 2065, 2073, 2080, 2089, 2097, 2104, 2113, - 2121, 2128, 2137, 2145, 2161, 2177, 2194, 2211, - 2228, 2245, 2261, 2277, 2294, 2311, 2328, 2345, - 2361, 2377, 2394, 2411, 2428, 2445, 2461, 2477, - 2494, 2511, 2528, 2545, 2551, 2567, 2583, 2598, - 2615, 2631, 2647, 2662, 2679, 2695, 2711, 2726, - 2743, 2759, 2775, 2790, 2807, 2823, 2839, 2854, - 2861, 2868, 2875, 2877, 2879, 2881, 2888, 2897, - 2906, 2914, 2921, 2930, 2938, 2945, 2954, 2962, - 2969, 2978, 2986, 2993, 3002, 3010, 3026, 3042, - 3059, 3076, 3093, 3110, 3126, 3142, 3159, 3176, - 3193, 3210, 3226, 3242, 3259, 3276, 3293, 3310, - 3326, 3342, 3359, 3376, 3393, 3410, 3421, 3437, - 3443, 3459, 3475, 3490, 3507, 3523, 3539, 3554, - 3571, 3587, 3603, 3618, 3635, 3651, 3667, 3682, - 3699, 3715, 3731, 3746, 3753, 3760, 3767, 3769, - 3771, 3773, 3780, 3789, 3798, 3806, 3813, 3822, - 3830, 3837, 3846, 3854, 3861, 3870, 3878, 3885, - 3894, 3902, 3918, 3934, 3951, 3968, 3985, 4002, - 4018, 4034, 4051, 4068, 4085, 4102, 4118, 4134, - 4151, 4168, 4185, 4202, 4218, 4234, 4251, 4268, - 4285, 4302, 4318, 4336, 4352, 4370, 4381, 4388, - 4390, 4392, 4394, 4401, 4418, 4427, 4435, 4442, - 4451, 4459, 4466, 4475, 4483, 4490, 4499, 4507, - 4514, 4523, 4530, 4537, 4539, 4541, 4543, 4550 + 0, 2, 8, 12, 14, 19, 23, 25, + 30, 34, 36, 41, 45, 47, 53, 55, + 57, 63, 65, 67, 73, 75, 77, 83, + 85, 87, 98, 104, 115, 121, 132, 138, + 149, 155, 166, 168, 174, 178, 180, 185, + 189, 191, 196, 200, 202, 207, 211, 213, + 219, 221, 223, 229, 231, 233, 239, 241, + 243, 249, 251, 253, 264, 270, 281, 287, + 298, 304, 315, 321, 332, 334, 340, 344, + 346, 351, 355, 357, 362, 366, 368, 373, + 377, 379, 385, 387, 389, 395, 397, 399, + 405, 407, 409, 415, 417, 419, 430, 436, + 447, 453, 464, 470, 481, 487, 489, 495, + 499, 501, 506, 510, 512, 517, 521, 523, + 528, 532, 534, 540, 542, 544, 550, 552, + 554, 560, 562, 564, 570, 572, 574, 585, + 591, 602, 608, 619, 625, 636, 642, 653, + 664, 669, 671, 691, 703, 712, 720, 737, + 749, 758, 766, 783, 795, 804, 812, 829, + 841, 850, 858, 875, 887, 896, 904, 911, + 918, 925, 927, 929, 931, 938, 947, 954, + 963, 971, 978, 987, 995, 1002, 1011, 1019, + 1026, 1035, 1043, 1052, 1064, 1081, 1098, 1115, + 1124, 1136, 1153, 1170, 1187, 1196, 1208, 1225, + 1242, 1259, 1268, 1280, 1297, 1314, 1331, 1340, + 1352, 1364, 1373, 1381, 1398, 1410, 1419, 1427, + 1444, 1456, 1465, 1473, 1490, 1502, 1511, 1519, + 1536, 1548, 1557, 1565, 1572, 1579, 1586, 1588, + 1590, 1592, 1599, 1608, 1615, 1624, 1632, 1639, + 1648, 1656, 1663, 1672, 1680, 1687, 1696, 1704, + 1713, 1725, 1742, 1759, 1776, 1785, 1797, 1814, + 1831, 1848, 1857, 1869, 1886, 1903, 1920, 1929, + 1941, 1958, 1975, 1992, 1998, 2007, 2016, 2024, + 2041, 2053, 2062, 2070, 2087, 2099, 2108, 2116, + 2133, 2145, 2154, 2162, 2179, 2191, 2200, 2208, + 2215, 2222, 2229, 2231, 2233, 2235, 2242, 2251, + 2258, 2267, 2275, 2282, 2291, 2299, 2306, 2315, + 2323, 2330, 2339, 2347, 2356, 2368, 2385, 2402, + 2419, 2428, 2440, 2457, 2474, 2491, 2500, 2512, + 2529, 2546, 2563, 2572, 2584, 2601, 2618, 2635, + 2646, 2655, 2661, 2673, 2682, 2690, 2707, 2719, + 2728, 2736, 2753, 2765, 2774, 2782, 2799, 2811, + 2820, 2828, 2845, 2857, 2866, 2874, 2881, 2888, + 2895, 2897, 2899, 2901, 2908, 2917, 2924, 2933, + 2941, 2948, 2957, 2965, 2972, 2981, 2989, 2996, + 3005, 3013, 3022, 3034, 3051, 3068, 3085, 3094, + 3106, 3123, 3140, 3157, 3166, 3178, 3195, 3212, + 3229, 3238, 3250, 3267, 3284, 3301, 3310, 3327, + 3339, 3356, 3367, 3374, 3376, 3378, 3380, 3387, + 3404, 3413, 3420, 3427, 3429, 3431, 3433, 3440 }; static const short _indic_syllable_machine_indicies[] = { - 1, 0, 2, 2, 3, 1, 0, 4, - 4, 3, 0, 3, 0, 5, 5, 6, - 1, 0, 7, 7, 6, 0, 6, 0, - 8, 8, 9, 1, 0, 10, 10, 9, - 0, 9, 0, 11, 11, 12, 1, 0, - 13, 13, 12, 0, 12, 0, 14, 0, - 0, 0, 1, 0, 15, 0, 16, 0, - 17, 11, 11, 12, 1, 0, 18, 0, - 19, 0, 20, 8, 8, 9, 1, 0, - 21, 0, 22, 0, 23, 5, 5, 6, - 1, 0, 24, 0, 25, 0, 26, 2, - 2, 3, 1, 0, 26, 2, 2, 3, - 1, 0, 0, 0, 0, 27, 0, 28, - 2, 2, 3, 1, 0, 28, 2, 2, - 3, 1, 0, 0, 0, 0, 29, 0, - 30, 2, 2, 3, 1, 0, 30, 2, - 2, 3, 1, 0, 0, 0, 0, 31, - 0, 32, 2, 2, 3, 1, 0, 32, - 2, 2, 3, 1, 0, 0, 0, 0, - 33, 0, 34, 2, 2, 3, 1, 0, - 34, 2, 2, 3, 1, 0, 0, 0, - 0, 35, 0, 37, 36, 38, 38, 39, - 37, 36, 40, 40, 39, 36, 39, 36, - 41, 41, 42, 37, 36, 43, 43, 42, - 36, 42, 36, 44, 44, 45, 37, 36, - 46, 46, 45, 36, 45, 36, 47, 47, - 48, 37, 36, 49, 49, 48, 36, 48, - 36, 50, 36, 36, 36, 37, 36, 51, - 36, 52, 36, 53, 47, 47, 48, 37, - 36, 54, 36, 55, 36, 56, 44, 44, - 45, 37, 36, 57, 36, 58, 36, 59, - 41, 41, 42, 37, 36, 60, 36, 61, - 36, 62, 38, 38, 39, 37, 36, 62, - 38, 38, 39, 37, 36, 36, 36, 36, - 63, 36, 64, 38, 38, 39, 37, 36, - 64, 38, 38, 39, 37, 36, 36, 36, - 36, 65, 36, 66, 38, 38, 39, 37, - 36, 66, 38, 38, 39, 37, 36, 36, - 36, 36, 67, 36, 68, 38, 38, 39, - 37, 36, 68, 38, 38, 39, 37, 36, - 36, 36, 36, 69, 36, 70, 38, 38, - 39, 37, 36, 70, 38, 38, 39, 37, - 36, 36, 36, 36, 71, 36, 73, 72, - 74, 74, 75, 73, 72, 77, 77, 75, - 76, 75, 76, 78, 78, 79, 73, 72, - 80, 80, 79, 72, 79, 72, 81, 81, - 82, 73, 72, 83, 83, 82, 72, 82, - 72, 84, 84, 85, 73, 72, 86, 86, - 85, 72, 85, 72, 87, 72, 72, 72, - 73, 72, 88, 72, 89, 72, 90, 84, - 84, 85, 73, 72, 91, 72, 92, 72, - 93, 81, 81, 82, 73, 72, 94, 72, - 95, 72, 96, 78, 78, 79, 73, 72, - 97, 72, 98, 72, 99, 74, 74, 75, - 73, 72, 99, 74, 74, 75, 73, 72, - 72, 72, 72, 100, 72, 101, 74, 74, - 75, 73, 72, 101, 74, 74, 75, 73, - 72, 72, 72, 72, 102, 72, 103, 74, - 74, 75, 73, 72, 103, 74, 74, 75, - 73, 72, 72, 72, 72, 104, 72, 105, - 74, 74, 75, 73, 72, 105, 74, 74, - 75, 73, 72, 72, 72, 72, 106, 72, - 107, 74, 74, 75, 73, 72, 109, 108, - 110, 110, 111, 109, 108, 112, 112, 111, - 108, 111, 108, 113, 113, 114, 109, 108, - 115, 115, 114, 108, 114, 108, 116, 116, - 117, 109, 108, 118, 118, 117, 108, 117, - 108, 119, 119, 120, 109, 108, 121, 121, - 120, 108, 120, 108, 122, 108, 108, 108, - 109, 108, 123, 108, 124, 108, 125, 119, - 119, 120, 109, 108, 126, 108, 127, 108, - 128, 116, 116, 117, 109, 108, 129, 108, - 130, 108, 131, 113, 113, 114, 109, 108, - 132, 108, 133, 108, 134, 110, 110, 111, - 109, 108, 134, 110, 110, 111, 109, 108, - 108, 108, 108, 135, 108, 136, 110, 110, - 111, 109, 108, 136, 110, 110, 111, 109, - 108, 108, 108, 108, 137, 108, 138, 110, - 110, 111, 109, 108, 138, 110, 110, 111, - 109, 108, 108, 108, 108, 139, 108, 140, - 110, 110, 111, 109, 108, 140, 110, 110, - 111, 109, 108, 108, 108, 108, 141, 108, - 142, 110, 110, 111, 109, 108, 142, 110, - 110, 111, 109, 108, 108, 108, 108, 143, - 108, 107, 74, 74, 75, 73, 72, 72, - 72, 72, 144, 72, 77, 77, 75, 1, - 0, 145, 145, 146, 1, 0, 4, 4, - 146, 0, 147, 147, 148, 149, 0, 150, - 150, 148, 0, 148, 0, 151, 151, 152, - 149, 0, 153, 153, 152, 0, 152, 0, - 154, 154, 155, 149, 0, 156, 156, 155, - 0, 155, 0, 149, 0, 157, 0, 0, - 0, 149, 0, 158, 0, 159, 0, 160, - 154, 154, 155, 149, 0, 161, 0, 162, - 0, 163, 151, 151, 152, 149, 0, 164, - 0, 165, 0, 166, 147, 147, 148, 149, - 0, 167, 0, 168, 0, 170, 169, 172, - 173, 174, 175, 176, 177, 75, 73, 171, - 178, 179, 179, 144, 171, 180, 181, 182, - 183, 184, 171, 186, 187, 188, 189, 3, - 1, 185, 190, 185, 185, 35, 185, 185, - 185, 191, 185, 192, 187, 193, 193, 3, - 1, 185, 190, 185, 185, 185, 185, 185, - 185, 191, 185, 187, 193, 193, 3, 1, - 185, 190, 185, 185, 185, 185, 185, 185, - 191, 185, 194, 185, 185, 185, 16, 195, - 185, 1, 185, 190, 185, 185, 185, 185, - 185, 194, 185, 196, 197, 198, 199, 3, - 1, 185, 190, 185, 185, 33, 185, 185, - 185, 191, 185, 200, 197, 201, 201, 3, - 1, 185, 190, 185, 185, 185, 185, 185, - 185, 191, 185, 197, 201, 201, 3, 1, - 185, 190, 185, 185, 185, 185, 185, 185, - 191, 185, 202, 185, 185, 185, 16, 203, - 185, 1, 185, 190, 185, 185, 185, 185, - 185, 202, 185, 204, 205, 206, 207, 3, - 1, 185, 190, 185, 185, 31, 185, 185, - 185, 191, 185, 208, 205, 209, 209, 3, - 1, 185, 190, 185, 185, 185, 185, 185, - 185, 191, 185, 205, 209, 209, 3, 1, - 185, 190, 185, 185, 185, 185, 185, 185, - 191, 185, 210, 185, 185, 185, 16, 211, - 185, 1, 185, 190, 185, 185, 185, 185, - 185, 210, 185, 212, 213, 214, 215, 3, - 1, 185, 190, 185, 185, 29, 185, 185, - 185, 191, 185, 216, 213, 217, 217, 3, - 1, 185, 190, 185, 185, 185, 185, 185, - 185, 191, 185, 213, 217, 217, 3, 1, - 185, 190, 185, 185, 185, 185, 185, 185, - 191, 185, 218, 185, 185, 185, 16, 219, - 185, 1, 185, 190, 185, 185, 185, 185, - 185, 218, 185, 220, 221, 222, 223, 3, - 1, 185, 190, 185, 185, 27, 185, 185, - 185, 191, 185, 224, 221, 225, 225, 3, - 1, 185, 190, 185, 185, 185, 185, 185, - 185, 191, 185, 221, 225, 225, 3, 1, - 185, 190, 185, 185, 185, 185, 185, 185, - 191, 185, 16, 226, 185, 1, 185, 190, - 185, 227, 227, 185, 1, 185, 190, 185, - 228, 185, 185, 229, 185, 190, 185, 190, - 185, 230, 185, 231, 185, 228, 185, 185, - 185, 185, 190, 185, 16, 185, 232, 232, - 3, 1, 185, 190, 185, 233, 25, 234, - 235, 6, 1, 185, 190, 185, 25, 234, - 235, 6, 1, 185, 190, 185, 234, 234, - 6, 1, 185, 190, 185, 236, 22, 237, - 238, 9, 1, 185, 190, 185, 22, 237, - 238, 9, 1, 185, 190, 185, 237, 237, - 9, 1, 185, 190, 185, 239, 19, 240, - 241, 12, 1, 185, 190, 185, 19, 240, - 241, 12, 1, 185, 190, 185, 240, 240, - 12, 1, 185, 190, 185, 242, 16, 227, - 243, 185, 1, 185, 190, 185, 16, 227, - 243, 185, 1, 185, 190, 185, 227, 244, - 185, 1, 185, 190, 185, 16, 185, 227, - 227, 185, 1, 185, 190, 185, 221, 225, - 225, 3, 1, 185, 190, 185, 220, 221, - 225, 225, 3, 1, 185, 190, 185, 185, - 185, 185, 185, 185, 191, 185, 220, 221, - 222, 225, 3, 1, 185, 190, 185, 185, - 27, 185, 185, 185, 191, 185, 218, 185, - 245, 185, 232, 232, 3, 1, 185, 190, - 185, 185, 185, 185, 185, 218, 185, 218, - 185, 185, 185, 227, 227, 185, 1, 185, - 190, 185, 185, 185, 185, 185, 218, 185, - 218, 185, 185, 185, 227, 246, 185, 1, - 185, 190, 185, 185, 185, 185, 185, 218, - 185, 218, 185, 245, 185, 227, 227, 185, - 1, 185, 190, 185, 185, 185, 185, 185, - 218, 185, 212, 213, 217, 217, 3, 1, - 185, 190, 185, 185, 185, 185, 185, 185, - 191, 185, 212, 213, 214, 217, 3, 1, - 185, 190, 185, 185, 29, 185, 185, 185, - 191, 185, 210, 185, 247, 185, 232, 232, - 3, 1, 185, 190, 185, 185, 185, 185, - 185, 210, 185, 210, 185, 185, 185, 227, - 227, 185, 1, 185, 190, 185, 185, 185, - 185, 185, 210, 185, 210, 185, 185, 185, - 227, 248, 185, 1, 185, 190, 185, 185, - 185, 185, 185, 210, 185, 210, 185, 247, - 185, 227, 227, 185, 1, 185, 190, 185, - 185, 185, 185, 185, 210, 185, 204, 205, - 209, 209, 3, 1, 185, 190, 185, 185, - 185, 185, 185, 185, 191, 185, 204, 205, - 206, 209, 3, 1, 185, 190, 185, 185, - 31, 185, 185, 185, 191, 185, 202, 185, - 249, 185, 232, 232, 3, 1, 185, 190, - 185, 185, 185, 185, 185, 202, 185, 202, - 185, 185, 185, 227, 227, 185, 1, 185, - 190, 185, 185, 185, 185, 185, 202, 185, - 202, 185, 185, 185, 227, 250, 185, 1, - 185, 190, 185, 185, 185, 185, 185, 202, - 185, 202, 185, 249, 185, 227, 227, 185, - 1, 185, 190, 185, 185, 185, 185, 185, - 202, 185, 196, 197, 201, 201, 3, 1, - 185, 190, 185, 185, 185, 185, 185, 185, - 191, 185, 196, 197, 198, 201, 3, 1, - 185, 190, 185, 185, 33, 185, 185, 185, - 191, 185, 194, 185, 251, 185, 232, 232, - 3, 1, 185, 190, 185, 185, 185, 185, - 185, 194, 185, 194, 185, 185, 185, 227, - 227, 185, 1, 185, 190, 185, 185, 185, - 185, 185, 194, 185, 194, 185, 185, 185, - 227, 252, 185, 1, 185, 190, 185, 185, - 185, 185, 185, 194, 185, 194, 185, 251, - 185, 227, 227, 185, 1, 185, 190, 185, - 185, 185, 185, 185, 194, 185, 186, 187, - 193, 193, 3, 1, 185, 190, 185, 185, - 185, 185, 185, 185, 191, 185, 186, 187, - 188, 193, 3, 1, 185, 190, 185, 185, - 35, 185, 185, 185, 191, 185, 254, 255, - 256, 257, 39, 37, 253, 258, 253, 253, - 71, 253, 253, 253, 259, 253, 260, 255, - 261, 257, 39, 37, 253, 258, 253, 253, - 253, 253, 253, 253, 259, 253, 255, 261, - 257, 39, 37, 253, 258, 253, 253, 253, - 253, 253, 253, 259, 253, 262, 253, 253, - 253, 52, 263, 253, 37, 253, 258, 253, - 253, 253, 253, 253, 262, 253, 264, 265, - 266, 267, 39, 37, 253, 258, 253, 253, - 69, 253, 253, 253, 259, 253, 268, 265, - 269, 269, 39, 37, 253, 258, 253, 253, - 253, 253, 253, 253, 259, 253, 265, 269, - 269, 39, 37, 253, 258, 253, 253, 253, - 253, 253, 253, 259, 253, 270, 253, 253, - 253, 52, 271, 253, 37, 253, 258, 253, - 253, 253, 253, 253, 270, 253, 272, 273, - 274, 275, 39, 37, 253, 258, 253, 253, - 67, 253, 253, 253, 259, 253, 276, 273, - 277, 277, 39, 37, 253, 258, 253, 253, - 253, 253, 253, 253, 259, 253, 273, 277, - 277, 39, 37, 253, 258, 253, 253, 253, - 253, 253, 253, 259, 253, 278, 253, 253, - 253, 52, 279, 253, 37, 253, 258, 253, - 253, 253, 253, 253, 278, 253, 280, 281, - 282, 283, 39, 37, 253, 258, 253, 253, - 65, 253, 253, 253, 259, 253, 284, 281, - 285, 285, 39, 37, 253, 258, 253, 253, - 253, 253, 253, 253, 259, 253, 281, 285, - 285, 39, 37, 253, 258, 253, 253, 253, - 253, 253, 253, 259, 253, 286, 253, 253, - 253, 52, 287, 253, 37, 253, 258, 253, - 253, 253, 253, 253, 286, 253, 288, 289, - 290, 291, 39, 37, 253, 258, 253, 253, - 63, 253, 253, 253, 259, 253, 292, 289, - 293, 293, 39, 37, 253, 258, 253, 253, - 253, 253, 253, 253, 259, 253, 289, 293, - 293, 39, 37, 253, 258, 253, 253, 253, - 253, 253, 253, 259, 253, 52, 294, 253, - 37, 253, 258, 253, 295, 295, 253, 37, - 253, 258, 253, 296, 253, 253, 297, 253, - 258, 253, 258, 253, 298, 253, 299, 253, - 296, 253, 253, 253, 253, 258, 253, 52, - 253, 300, 300, 39, 37, 253, 258, 253, - 301, 61, 302, 303, 42, 37, 253, 258, - 253, 61, 302, 303, 42, 37, 253, 258, - 253, 302, 302, 42, 37, 253, 258, 253, - 304, 58, 305, 306, 45, 37, 253, 258, - 253, 58, 305, 306, 45, 37, 253, 258, - 253, 305, 305, 45, 37, 253, 258, 253, - 307, 55, 308, 309, 48, 37, 253, 258, - 253, 55, 308, 309, 48, 37, 253, 258, - 253, 308, 308, 48, 37, 253, 258, 253, - 310, 52, 295, 311, 253, 37, 253, 258, - 253, 52, 295, 311, 253, 37, 253, 258, - 253, 295, 312, 253, 37, 253, 258, 253, - 52, 253, 295, 295, 253, 37, 253, 258, - 253, 289, 293, 293, 39, 37, 253, 258, - 253, 288, 289, 293, 293, 39, 37, 253, - 258, 253, 253, 253, 253, 253, 253, 259, - 253, 288, 289, 290, 293, 39, 37, 253, - 258, 253, 253, 63, 253, 253, 253, 259, - 253, 286, 253, 313, 253, 300, 300, 39, - 37, 253, 258, 253, 253, 253, 253, 253, - 286, 253, 286, 253, 253, 253, 295, 295, - 253, 37, 253, 258, 253, 253, 253, 253, - 253, 286, 253, 286, 253, 253, 253, 295, - 314, 253, 37, 253, 258, 253, 253, 253, - 253, 253, 286, 253, 286, 253, 313, 253, - 295, 295, 253, 37, 253, 258, 253, 253, - 253, 253, 253, 286, 253, 280, 281, 285, - 285, 39, 37, 253, 258, 253, 253, 253, - 253, 253, 253, 259, 253, 280, 281, 282, - 285, 39, 37, 253, 258, 253, 253, 65, - 253, 253, 253, 259, 253, 278, 253, 315, - 253, 300, 300, 39, 37, 253, 258, 253, - 253, 253, 253, 253, 278, 253, 278, 253, - 253, 253, 295, 295, 253, 37, 253, 258, - 253, 253, 253, 253, 253, 278, 253, 278, - 253, 253, 253, 295, 316, 253, 37, 253, - 258, 253, 253, 253, 253, 253, 278, 253, - 278, 253, 315, 253, 295, 295, 253, 37, - 253, 258, 253, 253, 253, 253, 253, 278, - 253, 272, 273, 277, 277, 39, 37, 253, - 258, 253, 253, 253, 253, 253, 253, 259, - 253, 272, 273, 274, 277, 39, 37, 253, - 258, 253, 253, 67, 253, 253, 253, 259, - 253, 270, 253, 317, 253, 300, 300, 39, - 37, 253, 258, 253, 253, 253, 253, 253, - 270, 253, 270, 253, 253, 253, 295, 295, - 253, 37, 253, 258, 253, 253, 253, 253, - 253, 270, 253, 270, 253, 253, 253, 295, - 318, 253, 37, 253, 258, 253, 253, 253, - 253, 253, 270, 253, 270, 253, 317, 253, - 295, 295, 253, 37, 253, 258, 253, 253, - 253, 253, 253, 270, 253, 264, 265, 269, - 269, 39, 37, 253, 258, 253, 253, 253, - 253, 253, 253, 259, 253, 264, 265, 266, - 269, 39, 37, 253, 258, 253, 253, 69, - 253, 253, 253, 259, 253, 262, 253, 319, - 253, 300, 300, 39, 37, 253, 258, 253, - 253, 253, 253, 253, 262, 253, 262, 253, - 253, 253, 295, 295, 253, 37, 253, 258, - 253, 253, 253, 253, 253, 262, 253, 262, - 253, 253, 253, 295, 320, 253, 37, 253, - 258, 253, 253, 253, 253, 253, 262, 253, - 262, 253, 319, 253, 295, 295, 253, 37, - 253, 258, 253, 253, 253, 253, 253, 262, - 253, 70, 38, 38, 39, 37, 253, 254, - 255, 261, 257, 39, 37, 253, 258, 253, - 253, 253, 253, 253, 253, 259, 253, 322, - 175, 323, 323, 75, 73, 321, 178, 321, - 321, 321, 321, 321, 321, 182, 321, 175, - 323, 323, 75, 73, 321, 178, 321, 321, - 321, 321, 321, 321, 182, 321, 324, 321, - 321, 321, 89, 325, 321, 73, 321, 178, - 321, 321, 321, 321, 321, 324, 321, 326, - 327, 328, 329, 75, 73, 321, 178, 321, - 321, 106, 321, 321, 321, 182, 321, 330, - 327, 331, 331, 75, 73, 321, 178, 321, - 321, 321, 321, 321, 321, 182, 321, 327, - 331, 331, 75, 73, 321, 178, 321, 321, - 321, 321, 321, 321, 182, 321, 332, 321, - 321, 321, 89, 333, 321, 73, 321, 178, - 321, 321, 321, 321, 321, 332, 321, 334, - 335, 336, 337, 75, 73, 321, 178, 321, - 321, 104, 321, 321, 321, 182, 321, 338, - 335, 339, 339, 75, 73, 321, 178, 321, - 321, 321, 321, 321, 321, 182, 321, 335, - 339, 339, 75, 73, 321, 178, 321, 321, - 321, 321, 321, 321, 182, 321, 340, 321, - 321, 321, 89, 341, 321, 73, 321, 178, - 321, 321, 321, 321, 321, 340, 321, 342, - 343, 344, 345, 75, 73, 321, 178, 321, - 321, 102, 321, 321, 321, 182, 321, 346, - 343, 347, 347, 75, 73, 321, 178, 321, - 321, 321, 321, 321, 321, 182, 321, 343, - 347, 347, 75, 73, 321, 178, 321, 321, - 321, 321, 321, 321, 182, 321, 348, 321, - 321, 321, 89, 349, 321, 73, 321, 178, - 321, 321, 321, 321, 321, 348, 321, 350, - 351, 352, 353, 75, 73, 321, 178, 321, - 321, 100, 321, 321, 321, 182, 321, 354, - 351, 355, 355, 75, 73, 321, 178, 321, - 321, 321, 321, 321, 321, 182, 321, 351, - 355, 355, 75, 73, 321, 178, 321, 321, - 321, 321, 321, 321, 182, 321, 89, 356, - 321, 73, 321, 178, 321, 357, 357, 321, - 73, 321, 178, 321, 358, 321, 321, 359, - 321, 178, 321, 178, 321, 360, 321, 361, - 321, 358, 321, 321, 321, 321, 178, 321, - 89, 321, 362, 362, 75, 73, 321, 178, - 321, 363, 98, 364, 365, 79, 73, 321, - 178, 321, 98, 364, 365, 79, 73, 321, - 178, 321, 364, 364, 79, 73, 321, 178, - 321, 366, 95, 367, 368, 82, 73, 321, - 178, 321, 95, 367, 368, 82, 73, 321, - 178, 321, 367, 367, 82, 73, 321, 178, - 321, 369, 92, 370, 371, 85, 73, 321, - 178, 321, 92, 370, 371, 85, 73, 321, - 178, 321, 370, 370, 85, 73, 321, 178, - 321, 372, 89, 357, 373, 321, 73, 321, - 178, 321, 89, 357, 373, 321, 73, 321, - 178, 321, 357, 374, 321, 73, 321, 178, - 321, 89, 321, 357, 357, 321, 73, 321, - 178, 321, 351, 355, 355, 75, 73, 321, - 178, 321, 350, 351, 355, 355, 75, 73, - 321, 178, 321, 321, 321, 321, 321, 321, - 182, 321, 350, 351, 352, 355, 75, 73, - 321, 178, 321, 321, 100, 321, 321, 321, - 182, 321, 348, 321, 375, 321, 362, 362, - 75, 73, 321, 178, 321, 321, 321, 321, - 321, 348, 321, 348, 321, 321, 321, 357, - 357, 321, 73, 321, 178, 321, 321, 321, - 321, 321, 348, 321, 348, 321, 321, 321, - 357, 376, 321, 73, 321, 178, 321, 321, - 321, 321, 321, 348, 321, 348, 321, 375, - 321, 357, 357, 321, 73, 321, 178, 321, - 321, 321, 321, 321, 348, 321, 342, 343, - 347, 347, 75, 73, 321, 178, 321, 321, - 321, 321, 321, 321, 182, 321, 342, 343, - 344, 347, 75, 73, 321, 178, 321, 321, - 102, 321, 321, 321, 182, 321, 340, 321, - 377, 321, 362, 362, 75, 73, 321, 178, - 321, 321, 321, 321, 321, 340, 321, 340, - 321, 321, 321, 357, 357, 321, 73, 321, - 178, 321, 321, 321, 321, 321, 340, 321, - 340, 321, 321, 321, 357, 378, 321, 73, - 321, 178, 321, 321, 321, 321, 321, 340, - 321, 340, 321, 377, 321, 357, 357, 321, - 73, 321, 178, 321, 321, 321, 321, 321, - 340, 321, 334, 335, 339, 339, 75, 73, - 321, 178, 321, 321, 321, 321, 321, 321, - 182, 321, 334, 335, 336, 339, 75, 73, - 321, 178, 321, 321, 104, 321, 321, 321, - 182, 321, 332, 321, 379, 321, 362, 362, - 75, 73, 321, 178, 321, 321, 321, 321, - 321, 332, 321, 332, 321, 321, 321, 357, - 357, 321, 73, 321, 178, 321, 321, 321, - 321, 321, 332, 321, 332, 321, 321, 321, - 357, 380, 321, 73, 321, 178, 321, 321, - 321, 321, 321, 332, 321, 332, 321, 379, - 321, 357, 357, 321, 73, 321, 178, 321, - 321, 321, 321, 321, 332, 321, 326, 327, - 331, 331, 75, 73, 321, 178, 321, 321, - 321, 321, 321, 321, 182, 321, 326, 327, - 328, 331, 75, 73, 321, 178, 321, 321, - 106, 321, 321, 321, 182, 321, 324, 321, - 381, 321, 362, 362, 75, 73, 321, 178, - 321, 321, 321, 321, 321, 324, 321, 324, - 321, 321, 321, 357, 357, 321, 73, 321, - 178, 321, 321, 321, 321, 321, 324, 321, - 324, 321, 321, 321, 357, 382, 321, 73, - 321, 178, 321, 321, 321, 321, 321, 324, - 321, 324, 321, 381, 321, 357, 357, 321, - 73, 321, 178, 321, 321, 321, 321, 321, - 324, 321, 107, 74, 74, 75, 73, 383, - 383, 383, 383, 144, 383, 174, 175, 323, - 323, 75, 73, 321, 178, 321, 321, 321, - 321, 321, 321, 182, 321, 107, 74, 74, - 75, 73, 383, 385, 386, 387, 388, 111, - 109, 384, 389, 384, 384, 143, 384, 384, - 384, 390, 384, 391, 386, 388, 388, 111, - 109, 384, 389, 384, 384, 384, 384, 384, - 384, 390, 384, 386, 388, 388, 111, 109, - 384, 389, 384, 384, 384, 384, 384, 384, - 390, 384, 392, 384, 384, 384, 124, 393, - 384, 109, 384, 389, 384, 384, 384, 384, - 384, 392, 384, 394, 395, 396, 397, 111, - 109, 384, 389, 384, 384, 141, 384, 384, - 384, 390, 384, 398, 395, 399, 399, 111, - 109, 384, 389, 384, 384, 384, 384, 384, - 384, 390, 384, 395, 399, 399, 111, 109, - 384, 389, 384, 384, 384, 384, 384, 384, - 390, 384, 400, 384, 384, 384, 124, 401, - 384, 109, 384, 389, 384, 384, 384, 384, - 384, 400, 384, 402, 403, 404, 405, 111, - 109, 384, 389, 384, 384, 139, 384, 384, - 384, 390, 384, 406, 403, 407, 407, 111, - 109, 384, 389, 384, 384, 384, 384, 384, - 384, 390, 384, 403, 407, 407, 111, 109, - 384, 389, 384, 384, 384, 384, 384, 384, - 390, 384, 408, 384, 384, 384, 124, 409, - 384, 109, 384, 389, 384, 384, 384, 384, - 384, 408, 384, 410, 411, 412, 413, 111, - 109, 384, 389, 384, 384, 137, 384, 384, - 384, 390, 384, 414, 411, 415, 415, 111, - 109, 384, 389, 384, 384, 384, 384, 384, - 384, 390, 384, 411, 415, 415, 111, 109, - 384, 389, 384, 384, 384, 384, 384, 384, - 390, 384, 416, 384, 384, 384, 124, 417, - 384, 109, 384, 389, 384, 384, 384, 384, - 384, 416, 384, 418, 419, 420, 421, 111, - 109, 384, 389, 384, 384, 135, 384, 384, - 384, 390, 384, 422, 419, 423, 423, 111, - 109, 384, 389, 384, 384, 384, 384, 384, - 384, 390, 384, 419, 423, 423, 111, 109, - 384, 389, 384, 384, 384, 384, 384, 384, - 390, 384, 124, 424, 384, 109, 384, 389, - 384, 425, 425, 384, 109, 384, 389, 384, - 426, 384, 384, 427, 384, 389, 384, 389, - 384, 428, 384, 429, 384, 426, 384, 384, - 384, 384, 389, 384, 124, 384, 430, 430, - 111, 109, 384, 389, 384, 431, 133, 432, - 433, 114, 109, 384, 389, 384, 133, 432, - 433, 114, 109, 384, 389, 384, 432, 432, - 114, 109, 384, 389, 384, 434, 130, 435, - 436, 117, 109, 384, 389, 384, 130, 435, - 436, 117, 109, 384, 389, 384, 435, 435, - 117, 109, 384, 389, 384, 437, 127, 438, - 439, 120, 109, 384, 389, 384, 127, 438, - 439, 120, 109, 384, 389, 384, 438, 438, - 120, 109, 384, 389, 384, 440, 124, 425, - 441, 384, 109, 384, 389, 384, 124, 425, - 441, 384, 109, 384, 389, 384, 425, 442, - 384, 109, 384, 389, 384, 124, 384, 425, - 425, 384, 109, 384, 389, 384, 419, 423, - 423, 111, 109, 384, 389, 384, 418, 419, - 423, 423, 111, 109, 384, 389, 384, 384, - 384, 384, 384, 384, 390, 384, 418, 419, - 420, 423, 111, 109, 384, 389, 384, 384, - 135, 384, 384, 384, 390, 384, 416, 384, - 443, 384, 430, 430, 111, 109, 384, 389, - 384, 384, 384, 384, 384, 416, 384, 416, - 384, 384, 384, 425, 425, 384, 109, 384, - 389, 384, 384, 384, 384, 384, 416, 384, - 416, 384, 384, 384, 425, 444, 384, 109, - 384, 389, 384, 384, 384, 384, 384, 416, - 384, 416, 384, 443, 384, 425, 425, 384, - 109, 384, 389, 384, 384, 384, 384, 384, - 416, 384, 410, 411, 415, 415, 111, 109, - 384, 389, 384, 384, 384, 384, 384, 384, - 390, 384, 410, 411, 412, 415, 111, 109, - 384, 389, 384, 384, 137, 384, 384, 384, - 390, 384, 408, 384, 445, 384, 430, 430, - 111, 109, 384, 389, 384, 384, 384, 384, - 384, 408, 384, 408, 384, 384, 384, 425, - 425, 384, 109, 384, 389, 384, 384, 384, - 384, 384, 408, 384, 408, 384, 384, 384, - 425, 446, 384, 109, 384, 389, 384, 384, - 384, 384, 384, 408, 384, 408, 384, 445, - 384, 425, 425, 384, 109, 384, 389, 384, - 384, 384, 384, 384, 408, 384, 402, 403, - 407, 407, 111, 109, 384, 389, 384, 384, - 384, 384, 384, 384, 390, 384, 402, 403, - 404, 407, 111, 109, 384, 389, 384, 384, - 139, 384, 384, 384, 390, 384, 400, 384, - 447, 384, 430, 430, 111, 109, 384, 389, - 384, 384, 384, 384, 384, 400, 384, 400, - 384, 384, 384, 425, 425, 384, 109, 384, - 389, 384, 384, 384, 384, 384, 400, 384, - 400, 384, 384, 384, 425, 448, 384, 109, - 384, 389, 384, 384, 384, 384, 384, 400, - 384, 400, 384, 447, 384, 425, 425, 384, - 109, 384, 389, 384, 384, 384, 384, 384, - 400, 384, 394, 395, 399, 399, 111, 109, - 384, 389, 384, 384, 384, 384, 384, 384, - 390, 384, 394, 395, 396, 399, 111, 109, - 384, 389, 384, 384, 141, 384, 384, 384, - 390, 384, 392, 384, 449, 384, 430, 430, - 111, 109, 384, 389, 384, 384, 384, 384, - 384, 392, 384, 392, 384, 384, 384, 425, - 425, 384, 109, 384, 389, 384, 384, 384, - 384, 384, 392, 384, 392, 384, 384, 384, - 425, 450, 384, 109, 384, 389, 384, 384, - 384, 384, 384, 392, 384, 392, 384, 449, - 384, 425, 425, 384, 109, 384, 389, 384, - 384, 384, 384, 384, 392, 384, 385, 386, - 388, 388, 111, 109, 384, 389, 384, 384, - 384, 384, 384, 384, 390, 384, 172, 173, - 174, 175, 451, 323, 75, 73, 321, 178, - 179, 179, 144, 321, 321, 172, 182, 321, - 186, 452, 188, 189, 3, 1, 185, 190, - 185, 185, 35, 185, 185, 185, 191, 185, - 194, 173, 174, 175, 453, 454, 75, 149, - 185, 455, 185, 179, 144, 185, 185, 194, - 182, 185, 107, 456, 456, 75, 149, 185, - 190, 185, 185, 144, 185, 457, 185, 185, - 458, 185, 455, 185, 455, 185, 459, 185, - 231, 185, 457, 185, 185, 185, 185, 455, - 185, 194, 185, 251, 107, 460, 460, 146, - 149, 185, 190, 185, 185, 185, 185, 185, - 194, 185, 461, 168, 462, 463, 148, 149, - 185, 455, 185, 168, 462, 463, 148, 149, - 185, 455, 185, 462, 462, 148, 149, 185, - 455, 185, 464, 165, 465, 466, 152, 149, - 185, 455, 185, 165, 465, 466, 152, 149, - 185, 455, 185, 465, 465, 152, 149, 185, - 455, 185, 467, 162, 468, 469, 155, 149, - 185, 455, 185, 162, 468, 469, 155, 149, - 185, 455, 185, 468, 468, 155, 149, 185, - 455, 185, 470, 159, 471, 472, 185, 149, - 185, 455, 185, 159, 471, 472, 185, 149, - 185, 455, 185, 471, 471, 185, 149, 185, - 455, 185, 474, 473, 475, 475, 473, 170, - 473, 476, 473, 475, 475, 473, 170, 473, - 476, 473, 477, 473, 473, 478, 473, 476, - 473, 476, 473, 479, 473, 480, 473, 477, - 473, 473, 473, 473, 476, 473, 172, 383, - 383, 383, 383, 383, 383, 383, 383, 383, - 179, 383, 383, 383, 383, 172, 383, 0 + 1, 0, 2, 3, 3, 4, 1, 0, + 5, 5, 4, 0, 4, 0, 6, 6, + 7, 1, 0, 8, 8, 7, 0, 7, + 0, 9, 9, 10, 1, 0, 11, 11, + 10, 0, 10, 0, 12, 12, 13, 1, + 0, 14, 14, 13, 0, 13, 0, 15, + 0, 0, 0, 1, 0, 16, 0, 17, + 0, 18, 12, 12, 13, 1, 0, 19, + 0, 20, 0, 21, 9, 9, 10, 1, + 0, 22, 0, 23, 0, 24, 6, 6, + 7, 1, 0, 25, 0, 26, 0, 2, + 3, 3, 4, 1, 0, 0, 0, 0, + 27, 0, 28, 3, 3, 4, 1, 0, + 28, 3, 3, 4, 1, 0, 0, 0, + 0, 29, 0, 30, 3, 3, 4, 1, + 0, 30, 3, 3, 4, 1, 0, 0, + 0, 0, 31, 0, 32, 3, 3, 4, + 1, 0, 32, 3, 3, 4, 1, 0, + 0, 0, 0, 33, 0, 34, 3, 3, + 4, 1, 0, 34, 3, 3, 4, 1, + 0, 0, 0, 0, 35, 0, 37, 36, + 38, 39, 39, 40, 37, 36, 41, 41, + 40, 36, 40, 36, 42, 42, 43, 37, + 36, 44, 44, 43, 36, 43, 36, 45, + 45, 46, 37, 36, 47, 47, 46, 36, + 46, 36, 48, 48, 49, 37, 36, 50, + 50, 49, 36, 49, 36, 51, 36, 36, + 36, 37, 36, 52, 36, 53, 36, 54, + 48, 48, 49, 37, 36, 55, 36, 56, + 36, 57, 45, 45, 46, 37, 36, 58, + 36, 59, 36, 60, 42, 42, 43, 37, + 36, 61, 36, 62, 36, 38, 39, 39, + 40, 37, 36, 36, 36, 36, 63, 36, + 64, 39, 39, 40, 37, 36, 64, 39, + 39, 40, 37, 36, 36, 36, 36, 65, + 36, 66, 39, 39, 40, 37, 36, 66, + 39, 39, 40, 37, 36, 36, 36, 36, + 67, 36, 68, 39, 39, 40, 37, 36, + 68, 39, 39, 40, 37, 36, 36, 36, + 36, 69, 36, 70, 39, 39, 40, 37, + 36, 70, 39, 39, 40, 37, 36, 36, + 36, 36, 71, 36, 73, 72, 74, 75, + 75, 76, 73, 72, 78, 78, 76, 77, + 76, 77, 79, 79, 80, 73, 72, 81, + 81, 80, 72, 80, 72, 82, 82, 83, + 73, 72, 84, 84, 83, 72, 83, 72, + 85, 85, 86, 73, 72, 87, 87, 86, + 72, 86, 72, 88, 72, 72, 72, 73, + 72, 89, 72, 90, 72, 91, 85, 85, + 86, 73, 72, 92, 72, 93, 72, 94, + 82, 82, 83, 73, 72, 95, 72, 96, + 72, 97, 79, 79, 80, 73, 72, 98, + 72, 99, 72, 74, 75, 75, 76, 73, + 72, 72, 72, 72, 100, 72, 101, 75, + 75, 76, 73, 72, 101, 75, 75, 76, + 73, 72, 72, 72, 72, 102, 72, 103, + 75, 75, 76, 73, 72, 103, 75, 75, + 76, 73, 72, 72, 72, 72, 104, 72, + 105, 75, 75, 76, 73, 72, 105, 75, + 75, 76, 73, 72, 72, 72, 72, 106, + 72, 107, 75, 75, 76, 73, 72, 109, + 108, 110, 111, 111, 112, 109, 108, 113, + 113, 112, 108, 112, 108, 114, 114, 115, + 109, 108, 116, 116, 115, 108, 115, 108, + 117, 117, 118, 109, 108, 119, 119, 118, + 108, 118, 108, 120, 120, 121, 109, 108, + 122, 122, 121, 108, 121, 108, 123, 108, + 108, 108, 109, 108, 124, 108, 125, 108, + 126, 120, 120, 121, 109, 108, 127, 108, + 128, 108, 129, 117, 117, 118, 109, 108, + 130, 108, 131, 108, 132, 114, 114, 115, + 109, 108, 133, 108, 134, 108, 110, 111, + 111, 112, 109, 108, 108, 108, 108, 135, + 108, 136, 111, 111, 112, 109, 108, 136, + 111, 111, 112, 109, 108, 108, 108, 108, + 137, 108, 138, 111, 111, 112, 109, 108, + 138, 111, 111, 112, 109, 108, 108, 108, + 108, 139, 108, 140, 111, 111, 112, 109, + 108, 140, 111, 111, 112, 109, 108, 108, + 108, 108, 141, 108, 142, 111, 111, 112, + 109, 108, 142, 111, 111, 112, 109, 108, + 108, 108, 108, 143, 108, 107, 75, 75, + 76, 73, 72, 72, 72, 72, 144, 72, + 78, 78, 76, 1, 0, 146, 145, 148, + 149, 150, 151, 152, 153, 76, 73, 147, + 154, 155, 155, 144, 147, 156, 157, 147, + 158, 159, 147, 161, 162, 163, 164, 4, + 1, 160, 165, 160, 160, 35, 160, 166, + 162, 167, 167, 4, 1, 160, 165, 160, + 162, 167, 167, 4, 1, 160, 165, 160, + 168, 160, 160, 160, 17, 169, 160, 1, + 160, 165, 160, 160, 160, 160, 160, 168, + 160, 170, 171, 172, 173, 4, 1, 160, + 165, 160, 160, 33, 160, 174, 171, 175, + 175, 4, 1, 160, 165, 160, 171, 175, + 175, 4, 1, 160, 165, 160, 176, 160, + 160, 160, 17, 177, 160, 1, 160, 165, + 160, 160, 160, 160, 160, 176, 160, 178, + 179, 180, 181, 4, 1, 160, 165, 160, + 160, 31, 160, 182, 179, 183, 183, 4, + 1, 160, 165, 160, 179, 183, 183, 4, + 1, 160, 165, 160, 184, 160, 160, 160, + 17, 185, 160, 1, 160, 165, 160, 160, + 160, 160, 160, 184, 160, 186, 187, 188, + 189, 4, 1, 160, 165, 160, 160, 29, + 160, 190, 187, 191, 191, 4, 1, 160, + 165, 160, 187, 191, 191, 4, 1, 160, + 165, 160, 192, 160, 160, 160, 17, 193, + 160, 1, 160, 165, 160, 160, 160, 160, + 160, 192, 160, 194, 195, 196, 197, 4, + 1, 160, 165, 160, 160, 27, 160, 198, + 195, 199, 199, 4, 1, 160, 165, 160, + 195, 199, 199, 4, 1, 160, 165, 160, + 17, 200, 160, 1, 160, 165, 160, 201, + 201, 160, 1, 160, 165, 160, 202, 160, + 160, 203, 160, 165, 160, 165, 160, 204, + 160, 205, 160, 202, 160, 160, 160, 160, + 165, 160, 17, 160, 201, 201, 160, 1, + 160, 165, 160, 201, 200, 160, 1, 160, + 165, 160, 206, 26, 207, 208, 7, 1, + 160, 165, 160, 26, 207, 208, 7, 1, + 160, 165, 160, 207, 207, 7, 1, 160, + 165, 160, 209, 23, 210, 211, 10, 1, + 160, 165, 160, 23, 210, 211, 10, 1, + 160, 165, 160, 210, 210, 10, 1, 160, + 165, 160, 212, 20, 213, 214, 13, 1, + 160, 165, 160, 20, 213, 214, 13, 1, + 160, 165, 160, 213, 213, 13, 1, 160, + 165, 160, 215, 17, 201, 216, 160, 1, + 160, 165, 160, 17, 201, 216, 160, 1, + 160, 165, 160, 194, 195, 199, 199, 4, + 1, 160, 165, 160, 194, 195, 196, 199, + 4, 1, 160, 165, 160, 160, 27, 160, + 192, 160, 217, 160, 201, 201, 160, 1, + 160, 165, 160, 160, 160, 160, 160, 192, + 160, 192, 160, 160, 160, 201, 201, 160, + 1, 160, 165, 160, 160, 160, 160, 160, + 192, 160, 192, 160, 160, 160, 201, 193, + 160, 1, 160, 165, 160, 160, 160, 160, + 160, 192, 160, 186, 187, 191, 191, 4, + 1, 160, 165, 160, 186, 187, 188, 191, + 4, 1, 160, 165, 160, 160, 29, 160, + 184, 160, 218, 160, 201, 201, 160, 1, + 160, 165, 160, 160, 160, 160, 160, 184, + 160, 184, 160, 160, 160, 201, 201, 160, + 1, 160, 165, 160, 160, 160, 160, 160, + 184, 160, 184, 160, 160, 160, 201, 185, + 160, 1, 160, 165, 160, 160, 160, 160, + 160, 184, 160, 178, 179, 183, 183, 4, + 1, 160, 165, 160, 178, 179, 180, 183, + 4, 1, 160, 165, 160, 160, 31, 160, + 176, 160, 219, 160, 201, 201, 160, 1, + 160, 165, 160, 160, 160, 160, 160, 176, + 160, 176, 160, 160, 160, 201, 201, 160, + 1, 160, 165, 160, 160, 160, 160, 160, + 176, 160, 176, 160, 160, 160, 201, 177, + 160, 1, 160, 165, 160, 160, 160, 160, + 160, 176, 160, 170, 171, 175, 175, 4, + 1, 160, 165, 160, 170, 171, 172, 175, + 4, 1, 160, 165, 160, 160, 33, 160, + 168, 160, 220, 160, 201, 201, 160, 1, + 160, 165, 160, 160, 160, 160, 160, 168, + 160, 168, 160, 160, 160, 201, 201, 160, + 1, 160, 165, 160, 160, 160, 160, 160, + 168, 160, 168, 160, 160, 160, 201, 169, + 160, 1, 160, 165, 160, 160, 160, 160, + 160, 168, 160, 161, 162, 167, 167, 4, + 1, 160, 165, 160, 161, 162, 163, 167, + 4, 1, 160, 165, 160, 160, 35, 160, + 222, 223, 224, 225, 40, 37, 221, 226, + 221, 221, 71, 221, 227, 223, 228, 225, + 40, 37, 221, 226, 221, 223, 228, 225, + 40, 37, 221, 226, 221, 229, 221, 221, + 221, 53, 230, 221, 37, 221, 226, 221, + 221, 221, 221, 221, 229, 221, 231, 232, + 233, 234, 40, 37, 221, 226, 221, 221, + 69, 221, 235, 232, 236, 236, 40, 37, + 221, 226, 221, 232, 236, 236, 40, 37, + 221, 226, 221, 237, 221, 221, 221, 53, + 238, 221, 37, 221, 226, 221, 221, 221, + 221, 221, 237, 221, 239, 240, 241, 242, + 40, 37, 221, 226, 221, 221, 67, 221, + 243, 240, 244, 244, 40, 37, 221, 226, + 221, 240, 244, 244, 40, 37, 221, 226, + 221, 245, 221, 221, 221, 53, 246, 221, + 37, 221, 226, 221, 221, 221, 221, 221, + 245, 221, 247, 248, 249, 250, 40, 37, + 221, 226, 221, 221, 65, 221, 251, 248, + 252, 252, 40, 37, 221, 226, 221, 248, + 252, 252, 40, 37, 221, 226, 221, 253, + 221, 221, 221, 53, 254, 221, 37, 221, + 226, 221, 221, 221, 221, 221, 253, 221, + 255, 256, 257, 258, 40, 37, 221, 226, + 221, 221, 63, 221, 259, 256, 260, 260, + 40, 37, 221, 226, 221, 256, 260, 260, + 40, 37, 221, 226, 221, 53, 261, 221, + 37, 221, 226, 221, 262, 262, 221, 37, + 221, 226, 221, 263, 221, 221, 264, 221, + 226, 221, 226, 221, 265, 221, 266, 221, + 263, 221, 221, 221, 221, 226, 221, 53, + 221, 262, 262, 221, 37, 221, 226, 221, + 262, 261, 221, 37, 221, 226, 221, 267, + 62, 268, 269, 43, 37, 221, 226, 221, + 62, 268, 269, 43, 37, 221, 226, 221, + 268, 268, 43, 37, 221, 226, 221, 270, + 59, 271, 272, 46, 37, 221, 226, 221, + 59, 271, 272, 46, 37, 221, 226, 221, + 271, 271, 46, 37, 221, 226, 221, 273, + 56, 274, 275, 49, 37, 221, 226, 221, + 56, 274, 275, 49, 37, 221, 226, 221, + 274, 274, 49, 37, 221, 226, 221, 276, + 53, 262, 277, 221, 37, 221, 226, 221, + 53, 262, 277, 221, 37, 221, 226, 221, + 255, 256, 260, 260, 40, 37, 221, 226, + 221, 255, 256, 257, 260, 40, 37, 221, + 226, 221, 221, 63, 221, 253, 221, 278, + 221, 262, 262, 221, 37, 221, 226, 221, + 221, 221, 221, 221, 253, 221, 253, 221, + 221, 221, 262, 262, 221, 37, 221, 226, + 221, 221, 221, 221, 221, 253, 221, 253, + 221, 221, 221, 262, 254, 221, 37, 221, + 226, 221, 221, 221, 221, 221, 253, 221, + 247, 248, 252, 252, 40, 37, 221, 226, + 221, 247, 248, 249, 252, 40, 37, 221, + 226, 221, 221, 65, 221, 245, 221, 279, + 221, 262, 262, 221, 37, 221, 226, 221, + 221, 221, 221, 221, 245, 221, 245, 221, + 221, 221, 262, 262, 221, 37, 221, 226, + 221, 221, 221, 221, 221, 245, 221, 245, + 221, 221, 221, 262, 246, 221, 37, 221, + 226, 221, 221, 221, 221, 221, 245, 221, + 239, 240, 244, 244, 40, 37, 221, 226, + 221, 239, 240, 241, 244, 40, 37, 221, + 226, 221, 221, 67, 221, 237, 221, 280, + 221, 262, 262, 221, 37, 221, 226, 221, + 221, 221, 221, 221, 237, 221, 237, 221, + 221, 221, 262, 262, 221, 37, 221, 226, + 221, 221, 221, 221, 221, 237, 221, 237, + 221, 221, 221, 262, 238, 221, 37, 221, + 226, 221, 221, 221, 221, 221, 237, 221, + 231, 232, 236, 236, 40, 37, 221, 226, + 221, 231, 232, 233, 236, 40, 37, 221, + 226, 221, 221, 69, 221, 229, 221, 281, + 221, 262, 262, 221, 37, 221, 226, 221, + 221, 221, 221, 221, 229, 221, 229, 221, + 221, 221, 262, 262, 221, 37, 221, 226, + 221, 221, 221, 221, 221, 229, 221, 229, + 221, 221, 221, 262, 230, 221, 37, 221, + 226, 221, 221, 221, 221, 221, 229, 221, + 70, 39, 39, 40, 37, 221, 222, 223, + 228, 225, 40, 37, 221, 226, 221, 283, + 151, 284, 284, 76, 73, 282, 154, 282, + 151, 284, 284, 76, 73, 282, 154, 282, + 285, 282, 282, 282, 90, 286, 282, 73, + 282, 154, 282, 282, 282, 282, 282, 285, + 282, 287, 288, 289, 290, 76, 73, 282, + 154, 282, 282, 106, 282, 291, 288, 292, + 292, 76, 73, 282, 154, 282, 288, 292, + 292, 76, 73, 282, 154, 282, 293, 282, + 282, 282, 90, 294, 282, 73, 282, 154, + 282, 282, 282, 282, 282, 293, 282, 295, + 296, 297, 298, 76, 73, 282, 154, 282, + 282, 104, 282, 299, 296, 300, 300, 76, + 73, 282, 154, 282, 296, 300, 300, 76, + 73, 282, 154, 282, 301, 282, 282, 282, + 90, 302, 282, 73, 282, 154, 282, 282, + 282, 282, 282, 301, 282, 303, 304, 305, + 306, 76, 73, 282, 154, 282, 282, 102, + 282, 307, 304, 308, 308, 76, 73, 282, + 154, 282, 304, 308, 308, 76, 73, 282, + 154, 282, 309, 282, 282, 282, 90, 310, + 282, 73, 282, 154, 282, 282, 282, 282, + 282, 309, 282, 311, 312, 313, 314, 76, + 73, 282, 154, 282, 282, 100, 282, 315, + 312, 316, 316, 76, 73, 282, 154, 282, + 312, 316, 316, 76, 73, 282, 154, 282, + 90, 317, 282, 73, 282, 154, 282, 318, + 318, 282, 73, 282, 154, 282, 319, 282, + 282, 320, 282, 154, 282, 154, 282, 321, + 282, 322, 282, 319, 282, 282, 282, 282, + 154, 282, 90, 282, 318, 318, 282, 73, + 282, 154, 282, 318, 317, 282, 73, 282, + 154, 282, 323, 99, 324, 325, 80, 73, + 282, 154, 282, 99, 324, 325, 80, 73, + 282, 154, 282, 324, 324, 80, 73, 282, + 154, 282, 326, 96, 327, 328, 83, 73, + 282, 154, 282, 96, 327, 328, 83, 73, + 282, 154, 282, 327, 327, 83, 73, 282, + 154, 282, 329, 93, 330, 331, 86, 73, + 282, 154, 282, 93, 330, 331, 86, 73, + 282, 154, 282, 330, 330, 86, 73, 282, + 154, 282, 332, 90, 318, 333, 282, 73, + 282, 154, 282, 90, 318, 333, 282, 73, + 282, 154, 282, 311, 312, 316, 316, 76, + 73, 282, 154, 282, 311, 312, 313, 316, + 76, 73, 282, 154, 282, 282, 100, 282, + 309, 282, 334, 282, 318, 318, 282, 73, + 282, 154, 282, 282, 282, 282, 282, 309, + 282, 309, 282, 282, 282, 318, 318, 282, + 73, 282, 154, 282, 282, 282, 282, 282, + 309, 282, 309, 282, 282, 282, 318, 310, + 282, 73, 282, 154, 282, 282, 282, 282, + 282, 309, 282, 303, 304, 308, 308, 76, + 73, 282, 154, 282, 303, 304, 305, 308, + 76, 73, 282, 154, 282, 282, 102, 282, + 301, 282, 335, 282, 318, 318, 282, 73, + 282, 154, 282, 282, 282, 282, 282, 301, + 282, 301, 282, 282, 282, 318, 318, 282, + 73, 282, 154, 282, 282, 282, 282, 282, + 301, 282, 301, 282, 282, 282, 318, 302, + 282, 73, 282, 154, 282, 282, 282, 282, + 282, 301, 282, 295, 296, 300, 300, 76, + 73, 282, 154, 282, 295, 296, 297, 300, + 76, 73, 282, 154, 282, 282, 104, 282, + 293, 282, 336, 282, 318, 318, 282, 73, + 282, 154, 282, 282, 282, 282, 282, 293, + 282, 293, 282, 282, 282, 318, 318, 282, + 73, 282, 154, 282, 282, 282, 282, 282, + 293, 282, 293, 282, 282, 282, 318, 294, + 282, 73, 282, 154, 282, 282, 282, 282, + 282, 293, 282, 287, 288, 292, 292, 76, + 73, 282, 154, 282, 287, 288, 289, 292, + 76, 73, 282, 154, 282, 282, 106, 282, + 285, 282, 337, 282, 318, 318, 282, 73, + 282, 154, 282, 282, 282, 282, 282, 285, + 282, 285, 282, 282, 282, 318, 318, 282, + 73, 282, 154, 282, 282, 282, 282, 282, + 285, 282, 285, 282, 282, 282, 318, 286, + 282, 73, 282, 154, 282, 282, 282, 282, + 282, 285, 282, 107, 75, 75, 76, 73, + 338, 338, 338, 338, 144, 338, 150, 151, + 284, 284, 76, 73, 282, 154, 282, 107, + 75, 75, 76, 73, 338, 340, 341, 342, + 343, 112, 109, 339, 344, 339, 339, 143, + 339, 345, 341, 343, 343, 112, 109, 339, + 344, 339, 341, 343, 343, 112, 109, 339, + 344, 339, 346, 339, 339, 339, 125, 347, + 339, 109, 339, 344, 339, 339, 339, 339, + 339, 346, 339, 348, 349, 350, 351, 112, + 109, 339, 344, 339, 339, 141, 339, 352, + 349, 353, 353, 112, 109, 339, 344, 339, + 349, 353, 353, 112, 109, 339, 344, 339, + 354, 339, 339, 339, 125, 355, 339, 109, + 339, 344, 339, 339, 339, 339, 339, 354, + 339, 356, 357, 358, 359, 112, 109, 339, + 344, 339, 339, 139, 339, 360, 357, 361, + 361, 112, 109, 339, 344, 339, 357, 361, + 361, 112, 109, 339, 344, 339, 362, 339, + 339, 339, 125, 363, 339, 109, 339, 344, + 339, 339, 339, 339, 339, 362, 339, 364, + 365, 366, 367, 112, 109, 339, 344, 339, + 339, 137, 339, 368, 365, 369, 369, 112, + 109, 339, 344, 339, 365, 369, 369, 112, + 109, 339, 344, 339, 370, 339, 339, 339, + 125, 371, 339, 109, 339, 344, 339, 339, + 339, 339, 339, 370, 339, 372, 373, 374, + 375, 112, 109, 339, 344, 339, 339, 135, + 339, 376, 373, 377, 377, 112, 109, 339, + 344, 339, 373, 377, 377, 112, 109, 339, + 344, 339, 125, 378, 339, 109, 339, 344, + 339, 379, 379, 339, 109, 339, 344, 339, + 380, 339, 339, 381, 339, 344, 339, 344, + 339, 382, 339, 383, 339, 380, 339, 339, + 339, 339, 344, 339, 125, 339, 379, 379, + 339, 109, 339, 344, 339, 379, 378, 339, + 109, 339, 344, 339, 384, 134, 385, 386, + 115, 109, 339, 344, 339, 134, 385, 386, + 115, 109, 339, 344, 339, 385, 385, 115, + 109, 339, 344, 339, 387, 131, 388, 389, + 118, 109, 339, 344, 339, 131, 388, 389, + 118, 109, 339, 344, 339, 388, 388, 118, + 109, 339, 344, 339, 390, 128, 391, 392, + 121, 109, 339, 344, 339, 128, 391, 392, + 121, 109, 339, 344, 339, 391, 391, 121, + 109, 339, 344, 339, 393, 125, 379, 394, + 339, 109, 339, 344, 339, 125, 379, 394, + 339, 109, 339, 344, 339, 372, 373, 377, + 377, 112, 109, 339, 344, 339, 372, 373, + 374, 377, 112, 109, 339, 344, 339, 339, + 135, 339, 370, 339, 395, 339, 379, 379, + 339, 109, 339, 344, 339, 339, 339, 339, + 339, 370, 339, 370, 339, 339, 339, 379, + 379, 339, 109, 339, 344, 339, 339, 339, + 339, 339, 370, 339, 370, 339, 339, 339, + 379, 371, 339, 109, 339, 344, 339, 339, + 339, 339, 339, 370, 339, 364, 365, 369, + 369, 112, 109, 339, 344, 339, 364, 365, + 366, 369, 112, 109, 339, 344, 339, 339, + 137, 339, 362, 339, 396, 339, 379, 379, + 339, 109, 339, 344, 339, 339, 339, 339, + 339, 362, 339, 362, 339, 339, 339, 379, + 379, 339, 109, 339, 344, 339, 339, 339, + 339, 339, 362, 339, 362, 339, 339, 339, + 379, 363, 339, 109, 339, 344, 339, 339, + 339, 339, 339, 362, 339, 356, 357, 361, + 361, 112, 109, 339, 344, 339, 356, 357, + 358, 361, 112, 109, 339, 344, 339, 339, + 139, 339, 354, 339, 397, 339, 379, 379, + 339, 109, 339, 344, 339, 339, 339, 339, + 339, 354, 339, 354, 339, 339, 339, 379, + 379, 339, 109, 339, 344, 339, 339, 339, + 339, 339, 354, 339, 354, 339, 339, 339, + 379, 355, 339, 109, 339, 344, 339, 339, + 339, 339, 339, 354, 339, 348, 349, 353, + 353, 112, 109, 339, 344, 339, 348, 349, + 350, 353, 112, 109, 339, 344, 339, 339, + 141, 339, 346, 339, 398, 339, 379, 379, + 339, 109, 339, 344, 339, 339, 339, 339, + 339, 346, 339, 346, 339, 339, 339, 379, + 379, 339, 109, 339, 344, 339, 339, 339, + 339, 339, 346, 339, 346, 339, 339, 339, + 379, 347, 339, 109, 339, 344, 339, 339, + 339, 339, 339, 346, 339, 340, 341, 343, + 343, 112, 109, 339, 344, 339, 148, 149, + 150, 151, 399, 284, 76, 73, 282, 154, + 155, 155, 144, 282, 282, 148, 282, 161, + 400, 163, 164, 4, 1, 160, 165, 160, + 160, 35, 160, 168, 149, 150, 151, 401, + 402, 76, 403, 160, 404, 160, 155, 144, + 160, 160, 168, 160, 107, 405, 405, 76, + 403, 160, 165, 160, 160, 144, 160, 406, + 160, 160, 407, 160, 404, 160, 404, 160, + 408, 160, 205, 160, 406, 160, 160, 160, + 160, 404, 160, 168, 160, 220, 107, 405, + 405, 76, 403, 160, 165, 160, 160, 160, + 160, 160, 168, 160, 410, 409, 411, 411, + 409, 146, 409, 412, 409, 411, 411, 409, + 146, 409, 412, 409, 413, 409, 409, 414, + 409, 412, 409, 412, 409, 415, 409, 416, + 409, 413, 409, 409, 409, 409, 412, 409, + 148, 338, 338, 338, 338, 338, 338, 338, + 338, 338, 155, 338, 338, 338, 338, 148, + 338, 0 }; static const short _indic_syllable_machine_trans_targs[] = { - 166, 188, 2, 194, 3, 5, 197, 6, - 8, 200, 9, 11, 203, 12, 14, 15, - 187, 17, 18, 202, 20, 21, 199, 23, - 24, 196, 205, 208, 212, 214, 218, 220, - 224, 226, 230, 232, 166, 255, 37, 261, - 38, 40, 264, 41, 43, 267, 44, 46, - 270, 47, 49, 50, 254, 52, 53, 269, - 55, 56, 266, 58, 59, 263, 272, 275, - 279, 281, 285, 287, 291, 293, 297, 300, - 166, 321, 72, 327, 166, 73, 75, 330, - 76, 78, 333, 79, 81, 336, 82, 84, - 85, 320, 87, 88, 335, 90, 91, 332, - 93, 94, 329, 338, 341, 345, 347, 351, - 353, 357, 359, 363, 166, 389, 106, 395, - 107, 109, 398, 110, 112, 401, 113, 115, - 404, 116, 118, 119, 388, 121, 122, 403, - 124, 125, 400, 127, 128, 397, 406, 409, - 413, 415, 419, 421, 425, 427, 431, 433, - 366, 142, 444, 144, 447, 438, 145, 147, - 450, 148, 150, 453, 151, 154, 155, 455, - 157, 158, 452, 160, 161, 449, 163, 164, - 446, 166, 458, 166, 167, 234, 301, 303, - 365, 367, 323, 368, 434, 435, 340, 456, - 463, 166, 168, 170, 34, 233, 190, 207, - 169, 33, 171, 228, 172, 174, 32, 227, - 173, 31, 175, 222, 176, 178, 30, 221, - 177, 29, 179, 216, 180, 182, 28, 215, - 181, 27, 183, 210, 184, 186, 26, 209, - 185, 25, 193, 0, 189, 192, 191, 166, - 1, 195, 4, 22, 198, 7, 19, 201, - 10, 16, 204, 13, 206, 211, 213, 217, - 219, 223, 225, 229, 231, 166, 235, 237, - 69, 299, 257, 274, 236, 68, 238, 295, - 239, 241, 67, 294, 240, 66, 242, 289, - 243, 245, 65, 288, 244, 64, 246, 283, - 247, 249, 63, 282, 248, 62, 250, 277, - 251, 253, 61, 276, 252, 60, 260, 35, - 256, 259, 258, 166, 36, 262, 39, 57, - 265, 42, 54, 268, 45, 51, 271, 48, - 273, 278, 280, 284, 286, 290, 292, 296, - 298, 166, 302, 103, 304, 361, 305, 307, - 102, 360, 306, 101, 308, 355, 309, 311, - 100, 354, 310, 99, 312, 349, 313, 315, - 98, 348, 314, 97, 316, 343, 317, 319, - 96, 342, 318, 95, 326, 70, 322, 325, - 324, 166, 71, 328, 74, 92, 331, 77, - 89, 334, 80, 86, 337, 83, 339, 344, - 346, 350, 352, 356, 358, 362, 364, 166, - 166, 369, 371, 138, 137, 391, 408, 370, - 372, 429, 373, 375, 136, 428, 374, 135, - 376, 423, 377, 379, 134, 422, 378, 133, - 380, 417, 381, 383, 132, 416, 382, 131, - 384, 411, 385, 387, 130, 410, 386, 129, - 394, 104, 390, 393, 392, 166, 105, 396, - 108, 126, 399, 111, 123, 402, 114, 120, - 405, 117, 407, 412, 414, 418, 420, 424, - 426, 430, 432, 139, 436, 437, 443, 440, - 140, 439, 442, 441, 141, 445, 143, 162, - 448, 146, 159, 451, 149, 156, 454, 152, - 153, 166, 457, 165, 460, 459, 462, 461, - 166 + 138, 160, 166, 2, 167, 3, 5, 170, + 6, 8, 173, 9, 11, 176, 12, 14, + 15, 159, 17, 18, 175, 20, 21, 172, + 23, 24, 169, 178, 182, 183, 187, 188, + 192, 193, 197, 198, 138, 221, 227, 36, + 228, 37, 39, 231, 40, 42, 234, 43, + 45, 237, 46, 48, 49, 220, 51, 52, + 236, 54, 55, 233, 57, 58, 230, 239, + 243, 244, 248, 249, 253, 254, 258, 260, + 138, 281, 287, 70, 288, 138, 71, 73, + 291, 74, 76, 294, 77, 79, 297, 80, + 82, 83, 280, 85, 86, 296, 88, 89, + 293, 91, 92, 290, 299, 303, 304, 308, + 309, 313, 314, 318, 138, 343, 349, 103, + 350, 104, 106, 353, 107, 109, 356, 110, + 112, 359, 113, 115, 116, 342, 118, 119, + 358, 121, 122, 355, 124, 125, 352, 361, + 365, 366, 370, 371, 375, 376, 380, 381, + 320, 138, 394, 138, 139, 200, 261, 263, + 319, 321, 283, 322, 382, 383, 392, 399, + 138, 140, 142, 33, 199, 162, 141, 32, + 143, 195, 144, 146, 31, 194, 145, 30, + 147, 190, 148, 150, 29, 189, 149, 28, + 151, 185, 152, 154, 27, 184, 153, 26, + 155, 180, 156, 158, 25, 179, 157, 1, + 165, 0, 161, 164, 163, 138, 168, 4, + 22, 171, 7, 19, 174, 10, 16, 177, + 13, 181, 186, 191, 196, 138, 201, 203, + 67, 259, 223, 202, 66, 204, 256, 205, + 207, 65, 255, 206, 64, 208, 251, 209, + 211, 63, 250, 210, 62, 212, 246, 213, + 215, 61, 245, 214, 60, 216, 241, 217, + 219, 59, 240, 218, 35, 226, 34, 222, + 225, 224, 138, 229, 38, 56, 232, 41, + 53, 235, 44, 50, 238, 47, 242, 247, + 252, 257, 138, 262, 100, 264, 316, 265, + 267, 99, 315, 266, 98, 268, 311, 269, + 271, 97, 310, 270, 96, 272, 306, 273, + 275, 95, 305, 274, 94, 276, 301, 277, + 279, 93, 300, 278, 69, 286, 68, 282, + 285, 284, 138, 289, 72, 90, 292, 75, + 87, 295, 78, 84, 298, 81, 302, 307, + 312, 317, 138, 138, 323, 325, 134, 133, + 345, 324, 326, 378, 327, 329, 132, 377, + 328, 131, 330, 373, 331, 333, 130, 372, + 332, 129, 334, 368, 335, 337, 128, 367, + 336, 127, 338, 363, 339, 341, 126, 362, + 340, 102, 348, 101, 344, 347, 346, 138, + 351, 105, 123, 354, 108, 120, 357, 111, + 117, 360, 114, 364, 369, 374, 379, 135, + 384, 385, 391, 386, 388, 136, 387, 390, + 389, 138, 393, 137, 396, 395, 398, 397, + 138 }; static const char _indic_syllable_machine_trans_actions[] = { - 1, 0, 0, 2, 0, 0, 2, 0, - 0, 2, 0, 0, 2, 0, 0, 0, - 2, 0, 0, 2, 0, 0, 2, 0, - 0, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 3, 0, 0, 2, - 0, 0, 2, 0, 0, 2, 0, 0, - 2, 0, 0, 0, 2, 0, 0, 2, - 0, 0, 2, 0, 0, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 4, 0, 0, 2, 5, 0, 0, 2, + 1, 0, 2, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 0, 2, 0, 0, 2, 0, 0, 2, - 0, 0, 2, 2, 6, 2, 6, 2, - 6, 2, 6, 2, 7, 0, 0, 2, - 0, 0, 2, 0, 0, 2, 0, 0, - 2, 0, 0, 0, 2, 0, 0, 2, - 0, 0, 2, 0, 0, 2, 2, 2, + 0, 0, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 3, 0, 2, 0, + 2, 0, 0, 2, 0, 0, 2, 0, + 0, 2, 0, 0, 0, 2, 0, 0, + 2, 0, 0, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 6, 0, 2, 0, 2, 0, 0, 0, - 2, 0, 0, 2, 0, 0, 0, 2, + 4, 0, 2, 0, 2, 5, 0, 0, + 2, 0, 0, 2, 0, 0, 2, 0, 0, 0, 2, 0, 0, 2, 0, 0, - 2, 8, 0, 11, 2, 2, 6, 0, - 12, 12, 0, 2, 6, 2, 6, 2, - 0, 13, 2, 0, 0, 2, 0, 2, - 2, 0, 2, 2, 2, 0, 0, 2, - 2, 0, 2, 2, 2, 0, 0, 2, - 2, 0, 2, 2, 2, 0, 0, 2, - 2, 0, 2, 2, 2, 0, 0, 2, - 2, 0, 2, 0, 0, 0, 0, 14, - 0, 2, 0, 0, 2, 0, 0, 2, - 0, 0, 2, 0, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 15, 2, 0, - 0, 2, 0, 2, 2, 0, 2, 2, - 2, 0, 0, 2, 2, 0, 2, 2, - 2, 0, 0, 2, 2, 0, 2, 2, - 2, 0, 0, 2, 2, 0, 2, 2, - 2, 0, 0, 2, 2, 0, 2, 0, - 0, 0, 0, 16, 0, 2, 0, 0, + 2, 0, 0, 2, 6, 2, 6, 2, + 6, 2, 6, 2, 7, 0, 2, 0, 2, 0, 0, 2, 0, 0, 2, 0, + 0, 2, 0, 0, 0, 2, 0, 0, + 2, 0, 0, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 17, 6, 0, 6, 6, 6, 0, - 0, 6, 6, 0, 6, 6, 6, 0, - 0, 6, 6, 0, 6, 6, 6, 0, - 0, 6, 6, 0, 6, 6, 6, 0, - 0, 6, 6, 0, 6, 0, 0, 0, - 0, 18, 0, 2, 0, 0, 2, 0, - 0, 2, 0, 0, 2, 0, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 19, - 20, 2, 0, 0, 0, 0, 2, 2, + 6, 8, 0, 11, 2, 2, 6, 0, + 12, 12, 0, 2, 6, 2, 2, 0, + 13, 2, 0, 0, 2, 0, 2, 0, 2, 2, 2, 0, 0, 2, 2, 0, 2, 2, 2, 0, 0, 2, 2, 0, 2, 2, 2, 0, 0, 2, 2, 0, 2, 2, 2, 0, 0, 2, 2, 0, - 2, 0, 0, 0, 0, 21, 0, 2, - 0, 0, 2, 0, 0, 2, 0, 0, - 2, 0, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 0, 0, 22, 2, 0, - 0, 0, 0, 0, 0, 2, 0, 0, + 2, 0, 0, 0, 0, 14, 2, 0, + 0, 2, 0, 0, 2, 0, 0, 2, + 0, 2, 2, 2, 2, 15, 2, 0, + 0, 2, 0, 2, 0, 2, 2, 2, + 0, 0, 2, 2, 0, 2, 2, 2, + 0, 0, 2, 2, 0, 2, 2, 2, + 0, 0, 2, 2, 0, 2, 2, 2, + 0, 0, 2, 2, 0, 2, 0, 0, + 0, 0, 16, 2, 0, 0, 2, 0, + 0, 2, 0, 0, 2, 0, 2, 2, + 2, 2, 17, 6, 0, 6, 2, 6, + 0, 0, 6, 6, 0, 6, 2, 6, + 0, 0, 6, 6, 0, 6, 2, 6, + 0, 0, 6, 6, 0, 6, 2, 6, + 0, 0, 6, 6, 0, 2, 0, 0, + 0, 0, 18, 2, 0, 0, 2, 0, + 0, 2, 0, 0, 2, 0, 2, 2, + 2, 2, 19, 20, 2, 0, 0, 0, + 0, 2, 2, 2, 2, 0, 0, 2, + 2, 0, 2, 2, 2, 0, 0, 2, + 2, 0, 2, 2, 2, 0, 0, 2, + 2, 0, 2, 2, 2, 0, 0, 2, + 2, 0, 2, 0, 0, 0, 0, 21, 2, 0, 0, 2, 0, 0, 2, 0, + 0, 2, 0, 2, 2, 2, 2, 0, + 0, 22, 22, 0, 0, 0, 0, 0, 0, 23, 2, 0, 0, 0, 0, 0, 24 }; @@ -937,15 +759,7 @@ static const char _indic_syllable_machine_to_state_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -998,15 +812,7 @@ static const char _indic_syllable_machine_from_state_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 10, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1046,67 +852,59 @@ static const short _indic_syllable_machine_eof_trans[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 37, 37, 37, 37, 37, + 1, 1, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 73, 73, - 77, 77, 73, 73, 73, 73, 73, 73, + 37, 37, 37, 37, 73, 73, 78, 78, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 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, 170, 0, 186, - 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 384, 322, 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, 322, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, - 474, 474, 474, 474, 474, 474, 474, 384 + 109, 109, 109, 109, 109, 109, 109, 73, + 1, 146, 0, 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, + 222, 222, 222, 222, 222, 222, 222, 222, + 222, 222, 222, 222, 222, 222, 222, 222, + 222, 222, 222, 222, 222, 222, 222, 222, + 222, 222, 222, 222, 222, 222, 222, 222, + 222, 222, 222, 222, 222, 222, 222, 222, + 222, 222, 222, 222, 222, 222, 222, 222, + 222, 222, 222, 222, 222, 222, 222, 222, + 222, 222, 222, 222, 222, 283, 283, 283, + 283, 283, 283, 283, 283, 283, 283, 283, + 283, 283, 283, 283, 283, 283, 283, 283, + 283, 283, 283, 283, 283, 283, 283, 283, + 283, 283, 283, 283, 283, 283, 283, 283, + 283, 283, 283, 283, 283, 283, 283, 283, + 283, 283, 283, 283, 283, 283, 283, 283, + 283, 283, 283, 283, 283, 283, 283, 339, + 283, 339, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 283, 161, + 161, 161, 161, 161, 161, 161, 161, 161, + 410, 410, 410, 410, 410, 410, 410, 339 }; -static const int indic_syllable_machine_start = 166; -static const int indic_syllable_machine_first_final = 166; +static const int indic_syllable_machine_start = 138; +static const int indic_syllable_machine_first_final = 138; static const int indic_syllable_machine_error = -1; -static const int indic_syllable_machine_en_main = 166; +static const int indic_syllable_machine_en_main = 138; #line 36 "hb-ot-shape-complex-indic-machine.rl" @@ -1118,10 +916,9 @@ static const int indic_syllable_machine_en_main = 166; #define found_syllable(syllable_type) \ HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \ - for (unsigned int i = last; i < p+1; i++) \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ + for (unsigned int i = ts; i < te; i++) \ info[i].syllable() = (syllable_serial << 4) | syllable_type; \ - last = p+1; \ syllable_serial++; \ if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ } HB_STMT_END @@ -1129,11 +926,11 @@ 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, act; + unsigned int p, pe, eof, ts, te, act; int cs; hb_glyph_info_t *info = buffer->info; -#line 1137 "hb-ot-shape-complex-indic-machine.hh" +#line 934 "hb-ot-shape-complex-indic-machine.hh" { cs = indic_syllable_machine_start; ts = 0; @@ -1141,16 +938,15 @@ find_syllables (hb_buffer_t *buffer) act = 0; } -#line 113 "hb-ot-shape-complex-indic-machine.rl" +#line 112 "hb-ot-shape-complex-indic-machine.rl" p = 0; pe = eof = buffer->len; - unsigned int last = 0; unsigned int syllable_serial = 1; -#line 1154 "hb-ot-shape-complex-indic-machine.hh" +#line 950 "hb-ot-shape-complex-indic-machine.hh" { int _slen; int _trans; @@ -1164,7 +960,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 1168 "hb-ot-shape-complex-indic-machine.hh" +#line 964 "hb-ot-shape-complex-indic-machine.hh" } _keys = _indic_syllable_machine_trans_keys + (cs<<1); @@ -1287,7 +1083,7 @@ _eof_trans: #line 88 "hb-ot-shape-complex-indic-machine.rl" {act = 6;} break; -#line 1291 "hb-ot-shape-complex-indic-machine.hh" +#line 1087 "hb-ot-shape-complex-indic-machine.hh" } _again: @@ -1296,7 +1092,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 1300 "hb-ot-shape-complex-indic-machine.hh" +#line 1096 "hb-ot-shape-complex-indic-machine.hh" } if ( ++p != pe ) @@ -1312,7 +1108,7 @@ _again: } -#line 122 "hb-ot-shape-complex-indic-machine.rl" +#line 120 "hb-ot-shape-complex-indic-machine.rl" } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.rl b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.rl index d384a68c35e..c5d945d4ecd 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.rl +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.rl @@ -52,7 +52,6 @@ DOTTEDCIRCLE = 12; RS = 13; Repha = 15; Ra = 16; -CM = 17; Symbol= 18; CS = 19; @@ -68,15 +67,16 @@ matra_group = z{0,3}.M.N?.(H | forced_rakar)?; syllable_tail = (z?.SM.SM?.ZWNJ?)? A{0,3}?; halant_group = (z?.H.(ZWJ.N?)?); final_halant_group = halant_group | H.ZWNJ; -medial_group = CM?; -halant_or_matra_group = (final_halant_group | (H.ZWJ)? matra_group{0,4}); +halant_or_matra_group = (final_halant_group | matra_group{0,4}); +complex_syllable_tail = (halant_group.cn){0,4} halant_or_matra_group syllable_tail; -consonant_syllable = (Repha|CS)? (cn.halant_group){0,4} cn medial_group halant_or_matra_group syllable_tail; -vowel_syllable = reph? V.n? (ZWJ | (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail); -standalone_cluster = ((Repha|CS)? PLACEHOLDER | reph? DOTTEDCIRCLE).n? (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail; + +consonant_syllable = (Repha|CS)? cn complex_syllable_tail; +vowel_syllable = reph? V.n? (ZWJ | complex_syllable_tail); +standalone_cluster = ((Repha|CS)? PLACEHOLDER | reph? DOTTEDCIRCLE).n? complex_syllable_tail; symbol_cluster = symbol syllable_tail; -broken_cluster = reph? n? (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail; +broken_cluster = reph? n? complex_syllable_tail; other = any; main := |* @@ -93,10 +93,9 @@ main := |* #define found_syllable(syllable_type) \ HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \ - for (unsigned int i = last; i < p+1; i++) \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ + for (unsigned int i = ts; i < te; i++) \ info[i].syllable() = (syllable_serial << 4) | syllable_type; \ - last = p+1; \ syllable_serial++; \ if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ } HB_STMT_END @@ -104,7 +103,7 @@ main := |* static void find_syllables (hb_buffer_t *buffer) { - unsigned int p, pe, eof, ts HB_UNUSED, te, act; + unsigned int p, pe, eof, ts, te, act; int cs; hb_glyph_info_t *info = buffer->info; %%{ @@ -115,7 +114,6 @@ find_syllables (hb_buffer_t *buffer) p = 0; pe = eof = buffer->len; - unsigned int last = 0; unsigned int syllable_serial = 1; %%{ write exec; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc index d4541bb18ab..f1ae303adcc 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc @@ -95,42 +95,40 @@ static const indic_config_t indic_configs[] = * Indic shaper. */ -struct feature_list_t { - hb_tag_t tag; - hb_ot_map_feature_flags_t flags; -}; - -static const feature_list_t +static const hb_ot_map_feature_t indic_features[] = { /* * Basic features. * These features are applied in order, one at a time, after initial_reordering. */ - {HB_TAG('n','u','k','t'), F_GLOBAL}, - {HB_TAG('a','k','h','n'), F_GLOBAL}, - {HB_TAG('r','p','h','f'), F_NONE}, - {HB_TAG('r','k','r','f'), F_GLOBAL}, - {HB_TAG('p','r','e','f'), F_NONE}, - {HB_TAG('b','l','w','f'), F_NONE}, - {HB_TAG('a','b','v','f'), F_NONE}, - {HB_TAG('h','a','l','f'), F_NONE}, - {HB_TAG('p','s','t','f'), F_NONE}, - {HB_TAG('v','a','t','u'), F_GLOBAL}, - {HB_TAG('c','j','c','t'), F_GLOBAL}, + {HB_TAG('n','u','k','t'), F_GLOBAL_MANUAL_JOINERS}, + {HB_TAG('a','k','h','n'), F_GLOBAL_MANUAL_JOINERS}, + {HB_TAG('r','p','h','f'), F_MANUAL_JOINERS}, + {HB_TAG('r','k','r','f'), F_GLOBAL_MANUAL_JOINERS}, + {HB_TAG('p','r','e','f'), F_MANUAL_JOINERS}, + {HB_TAG('b','l','w','f'), F_MANUAL_JOINERS}, + {HB_TAG('a','b','v','f'), F_MANUAL_JOINERS}, + {HB_TAG('h','a','l','f'), F_MANUAL_JOINERS}, + {HB_TAG('p','s','t','f'), F_MANUAL_JOINERS}, + {HB_TAG('v','a','t','u'), F_GLOBAL_MANUAL_JOINERS}, + {HB_TAG('c','j','c','t'), F_GLOBAL_MANUAL_JOINERS}, /* * Other features. * These features are applied all at once, after final_reordering. * Default Bengali font in Windows for example has intermixed * lookups for init,pres,abvs,blws features. */ - {HB_TAG('i','n','i','t'), F_NONE}, - {HB_TAG('p','r','e','s'), F_GLOBAL}, - {HB_TAG('a','b','v','s'), F_GLOBAL}, - {HB_TAG('b','l','w','s'), F_GLOBAL}, - {HB_TAG('p','s','t','s'), F_GLOBAL}, - {HB_TAG('h','a','l','n'), F_GLOBAL}, - /* Positioning features, though we don't care about the types. */ + {HB_TAG('i','n','i','t'), F_MANUAL_JOINERS}, + {HB_TAG('p','r','e','s'), F_GLOBAL_MANUAL_JOINERS}, + {HB_TAG('a','b','v','s'), F_GLOBAL_MANUAL_JOINERS}, + {HB_TAG('b','l','w','s'), F_GLOBAL_MANUAL_JOINERS}, + {HB_TAG('p','s','t','s'), F_GLOBAL_MANUAL_JOINERS}, + {HB_TAG('h','a','l','n'), F_GLOBAL_MANUAL_JOINERS}, + /* + * Positioning features. + * We don't care about the types. + */ {HB_TAG('d','i','s','t'), F_GLOBAL}, {HB_TAG('a','b','v','m'), F_GLOBAL}, {HB_TAG('b','l','w','m'), F_GLOBAL}, @@ -158,12 +156,13 @@ enum { _BLWS, _PSTS, _HALN, + _DIST, _ABVM, _BLWM, INDIC_NUM_FEATURES, - INDIC_BASIC_FEATURES = INIT /* Don't forget to update this! */ + INDIC_BASIC_FEATURES = INIT, /* Don't forget to update this! */ }; static void @@ -191,25 +190,27 @@ collect_features_indic (hb_ot_shape_planner_t *plan) /* Do this before any lookups have been applied. */ map->add_gsub_pause (setup_syllables); - map->add_global_bool_feature (HB_TAG('l','o','c','l')); + map->enable_feature (HB_TAG('l','o','c','l')); /* The Indic specs do not require ccmp, but we apply it here since if * there is a use of it, it's typically at the beginning. */ - map->add_global_bool_feature (HB_TAG('c','c','m','p')); + map->enable_feature (HB_TAG('c','c','m','p')); unsigned int i = 0; map->add_gsub_pause (initial_reordering); + for (; i < INDIC_BASIC_FEATURES; i++) { - map->add_feature (indic_features[i].tag, 1, indic_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ); + map->add_feature (indic_features[i]); map->add_gsub_pause (nullptr); } + map->add_gsub_pause (final_reordering); - for (; i < INDIC_NUM_FEATURES; i++) { - map->add_feature (indic_features[i].tag, 1, indic_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ); - } - map->add_global_bool_feature (HB_TAG('c','a','l','t')); - map->add_global_bool_feature (HB_TAG('c','l','i','g')); + for (; i < INDIC_NUM_FEATURES; i++) + map->add_feature (indic_features[i]); + + map->enable_feature (HB_TAG('c','a','l','t')); + map->enable_feature (HB_TAG('c','l','i','g')); map->add_gsub_pause (clear_syllables); } @@ -217,7 +218,7 @@ collect_features_indic (hb_ot_shape_planner_t *plan) static void override_features_indic (hb_ot_shape_planner_t *plan) { - plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL); + plan->map.disable_feature (HB_TAG('l','i','g','a')); } @@ -273,6 +274,7 @@ struct indic_shape_plan_t const indic_config_t *config; bool is_old_spec; + bool uniscribe_bug_compatible; mutable hb_atomic_int_t virama_glyph; would_substitute_feature_t rphf; @@ -298,6 +300,7 @@ data_create_indic (const hb_ot_shape_plan_t *plan) } indic_plan->is_old_spec = indic_plan->config->has_old_spec && ((plan->map.chosen_script[0] & 0x000000FFu) != '2'); + indic_plan->uniscribe_bug_compatible = hb_options ().uniscribe_bug_compatible; indic_plan->virama_glyph.set_relaxed (-1); /* Use zero-context would_substitute() matching for new-spec of the main @@ -328,6 +331,275 @@ data_destroy_indic (void *data) free (data); } +static void +_output_with_dotted_circle (hb_buffer_t *buffer) +{ + hb_glyph_info_t &dottedcircle = buffer->output_glyph (0x25CCu); + _hb_glyph_info_reset_continuation (&dottedcircle); + + buffer->next_glyph (); +} + +static void +preprocess_text_indic (const hb_ot_shape_plan_t *plan, + hb_buffer_t *buffer, + hb_font_t *font) +{ + /* UGLY UGLY UGLY business of adding dotted-circle in the middle of + * vowel-sequences that look like another vowel. Data for each script + * collected from Unicode 11 book, tables named "Vowel Letters" with + * "Use" and "Do Not Use" columns. + * + * https://github.com/harfbuzz/harfbuzz/issues/1019 + */ + bool processed = false; + buffer->clear_output (); + unsigned int count = buffer->len; + switch ((unsigned) buffer->props.script) + { + case HB_SCRIPT_DEVANAGARI: + for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;) + { + bool matched = false; + switch (buffer->cur().codepoint) + { + case 0x0905u: + switch (buffer->cur(1).codepoint) + { + case 0x093Au: case 0x093Bu: case 0x093Eu: case 0x0945u: + case 0x0946u: case 0x0949u: case 0x094Au: case 0x094Bu: + case 0x094Cu: case 0x094Fu: case 0x0956u: case 0x0957u: + matched = true; + break; + } + break; + case 0x0906u: + switch (buffer->cur(1).codepoint) + { + case 0x093Au: case 0x0945u: case 0x0946u: case 0x0947u: + case 0x0948u: + matched = true; + break; + } + break; + case 0x0909u: + switch (buffer->cur(1).codepoint) + { + case 0x0941u: + matched = true; + break; + } + break; + case 0x090Fu: + switch (buffer->cur(1).codepoint) + { + case 0x0945u: case 0x0946u: case 0x0947u: + matched = true; + break; + } + break; + case 0x0930u: + if (0x094Du == buffer->cur(1).codepoint && + buffer->idx + 2 < count && + 0x0907u == buffer->cur(2).codepoint) + { + buffer->next_glyph (); + buffer->next_glyph (); + buffer->output_glyph (0x25CCu); + } + break; + } + buffer->next_glyph (); + if (matched) _output_with_dotted_circle (buffer); + } + processed = true; + break; + + case HB_SCRIPT_BENGALI: + for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;) + { + bool matched = false; + switch (buffer->cur().codepoint) + { + case 0x0985u: + matched = 0x09BE == buffer->cur(1).codepoint; + break; + case 0x098Bu: + matched = 0x09C3 == buffer->cur(1).codepoint; + break; + case 0x098Cu: + matched = 0x09E2 == buffer->cur(1).codepoint; + break; + } + buffer->next_glyph (); + if (matched) _output_with_dotted_circle (buffer); + } + processed = true; + break; + + case HB_SCRIPT_GURMUKHI: + for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;) + { + bool matched = false; + switch (buffer->cur().codepoint) + { + case 0x0A05u: + switch (buffer->cur(1).codepoint) + { + case 0x0A3Eu: case 0x0A48u: case 0x0A4Cu: + matched = true; + break; + } + break; + case 0x0A72u: + switch (buffer->cur(1).codepoint) + { + case 0x0A3Fu: case 0x0A40u: case 0x0A47u: + matched = true; + break; + } + break; + case 0x0A73u: + switch (buffer->cur(1).codepoint) + { + case 0x0A41u: case 0x0A42u: case 0x0A4Bu: + matched = true; + break; + } + break; + } + buffer->next_glyph (); + if (matched) _output_with_dotted_circle (buffer); + } + processed = true; + break; + + case HB_SCRIPT_GUJARATI: + for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;) + { + bool matched = false; + switch (buffer->cur().codepoint) + { + case 0x0A85u: + switch (buffer->cur(1).codepoint) + { + case 0x0ABEu: case 0x0AC5u: case 0x0AC7u: case 0x0AC8u: + case 0x0AC9u: case 0x0ACBu: case 0x0ACCu: + matched = true; + break; + } + break; + case 0x0AC5u: + matched = 0x0ABE == buffer->cur(1).codepoint; + break; + } + buffer->next_glyph (); + if (matched) _output_with_dotted_circle (buffer); + } + processed = true; + break; + + case HB_SCRIPT_ORIYA: + for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;) + { + bool matched = false; + switch (buffer->cur().codepoint) + { + case 0x0B05u: + matched = 0x0B3E == buffer->cur(1).codepoint; + break; + case 0x0B0Fu: case 0x0B13u: + matched = 0x0B57 == buffer->cur(1).codepoint; + break; + } + buffer->next_glyph (); + if (matched) _output_with_dotted_circle (buffer); + } + processed = true; + break; + + case HB_SCRIPT_TELUGU: + for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;) + { + bool matched = false; + switch (buffer->cur().codepoint) + { + case 0x0C12u: + switch (buffer->cur(1).codepoint) + { + case 0x0C4Cu: case 0x0C55u: + matched = true; + break; + } + break; + case 0x0C3Fu: case 0x0C46u: case 0xC4Au: + matched = 0x0C55 == buffer->cur(1).codepoint; + break; + } + buffer->next_glyph (); + if (matched) _output_with_dotted_circle (buffer); + } + processed = true; + break; + + case HB_SCRIPT_KANNADA: + for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;) + { + bool matched = false; + switch (buffer->cur().codepoint) + { + case 0x0C89u: case 0x0C8Bu: + matched = 0x0CBE == buffer->cur(1).codepoint; + break; + case 0x0C92u: + matched = 0x0CCC == buffer->cur(1).codepoint; + break; + } + buffer->next_glyph (); + if (matched) _output_with_dotted_circle (buffer); + } + processed = true; + break; + + case HB_SCRIPT_MALAYALAM: + for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;) + { + bool matched = false; + switch (buffer->cur().codepoint) + { + case 0x0D07u: case 0x0D09u: + matched = 0x0D57 == buffer->cur(1).codepoint; + break; + case 0x0D0Eu: + matched = 0x0D46 == buffer->cur(1).codepoint; + break; + case 0x0D12u: + switch (buffer->cur(1).codepoint) + { + case 0x0D3Eu: case 0x0D57u: + matched = true; + break; + } + break; + } + buffer->next_glyph (); + if (matched) _output_with_dotted_circle (buffer); + } + processed = true; + break; + + default: + break; + } + if (processed) + { + if (buffer->idx < count) + buffer->next_glyph (); + if (likely (buffer->successful)) + buffer->swap_buffers (); + } +} + static indic_position_t consonant_position_from_face (const indic_shape_plan_t *indic_plan, const hb_codepoint_t consonant, @@ -717,7 +989,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, indic_position_t last_pos = POS_START; for (unsigned int i = start; i < end; i++) { - if ((FLAG_UNSAFE (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | FLAG (OT_H)))) + if ((FLAG_UNSAFE (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | FLAG (OT_H)))) { info[i].indic_position() = last_pos; if (unlikely (info[i].indic_category() == OT_H && @@ -913,10 +1185,12 @@ initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, unsigned int start, unsigned int end) { + const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data; + /* We treat placeholder/dotted-circle as if they are consonants, so we * should just chain. Only if not in compatibility mode that is... */ - if (hb_options ().uniscribe_bug_compatible) + if (indic_plan->uniscribe_bug_compatible) { /* For dotted-circle, this is what Uniscribe does: * If dotted-circle is the last glyph, it just does nothing. @@ -958,7 +1232,8 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_font_t *font, hb_buffer_t *buffer) { - /* Note: This loop is extra overhead, but should not be measurable. */ + /* Note: This loop is extra overhead, but should not be measurable. + * TODO Use a buffer scratch flag to remove the loop. */ bool has_broken_syllables = false; unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; @@ -1356,7 +1631,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, * Uniscribe doesn't do this. * TEST: U+0930,U+094D,U+0915,U+094B,U+094D */ - if (!hb_options ().uniscribe_bug_compatible && + if (!indic_plan->uniscribe_bug_compatible && unlikely (is_halant (info[new_reph_pos]))) { for (unsigned int i = base + 1; i < new_reph_pos; i++) if (info[i].indic_category() == OT_M) { @@ -1462,7 +1737,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, /* * Finish off the clusters and go home! */ - if (hb_options ().uniscribe_bug_compatible) + if (indic_plan->uniscribe_bug_compatible) { switch ((hb_tag_t) plan->props.script) { @@ -1609,13 +1884,13 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic = override_features_indic, data_create_indic, data_destroy_indic, - nullptr, /* preprocess_text */ + preprocess_text_indic, nullptr, /* postprocess_glyphs */ HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, decompose_indic, compose_indic, setup_masks_indic, - nullptr, /* disable_otl */ + HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, false, /* fallback_position */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.hh index 9e597797c88..dcc2a7a6c5f 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.hh @@ -29,9 +29,7 @@ #include "hb.hh" - #include "hb-ot-shape-complex.hh" -#include "hb-ot-shape.hh" /* XXX Remove */ /* buffer var allocations */ @@ -64,19 +62,17 @@ enum indic_category_t { OT_Coeng = 14, /* Khmer-style Virama. */ OT_Repha = 15, /* Atomically-encoded logical or visual repha. */ OT_Ra = 16, - OT_CM = 17, /* Consonant-Medial. */ + OT_CM = 17, /* Consonant-Medial; Unused by Indic shaper. */ OT_Symbol = 18, /* Avagraha, etc that take marks (SM,A,VD). */ OT_CS = 19 }; -#define MEDIAL_FLAGS (FLAG (OT_CM)) - /* Note: * * We treat Vowels and placeholders as if they were consonants. This is safe because Vowels * cannot happen in a consonant syllable. The plus side however is, we can call the * consonant syllable logic from the vowel syllable function and get it all right! */ -#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_CS) | FLAG (OT_Ra) | MEDIAL_FLAGS | FLAG (OT_V) | FLAG (OT_PLACEHOLDER) | FLAG (OT_DOTTEDCIRCLE)) +#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_CS) | FLAG (OT_Ra) | FLAG (OT_V) | FLAG (OT_PLACEHOLDER) | FLAG (OT_DOTTEDCIRCLE)) #define JOINER_FLAGS (FLAG (OT_ZWJ) | FLAG (OT_ZWNJ)) @@ -125,7 +121,7 @@ enum indic_syllabic_category_t { INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA = OT_Repha, INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED = OT_X, /* Don't care. */ INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED = OT_CM, - INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA = OT_N, + INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA = OT_CM, INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER = OT_CS, INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK = OT_SM, /* https://github.com/harfbuzz/harfbuzz/issues/552 */ INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER = OT_Coeng, diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer-machine.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer-machine.hh index a7e1711eb09..2bc8ca650a4 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer-machine.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer-machine.hh @@ -34,138 +34,207 @@ #line 36 "hb-ot-shape-complex-khmer-machine.hh" static const unsigned char _khmer_syllable_machine_trans_keys[] = { - 7u, 7u, 1u, 16u, 13u, 13u, 1u, 16u, 7u, 13u, 7u, 7u, 1u, 16u, 13u, 13u, - 1u, 16u, 7u, 13u, 1u, 16u, 3u, 14u, 3u, 14u, 5u, 14u, 3u, 14u, 5u, 14u, - 8u, 8u, 3u, 13u, 3u, 8u, 8u, 8u, 3u, 8u, 3u, 14u, 3u, 14u, 5u, 14u, - 3u, 14u, 5u, 14u, 8u, 8u, 3u, 13u, 3u, 8u, 8u, 8u, 3u, 8u, 3u, 14u, - 3u, 14u, 7u, 13u, 7u, 7u, 1u, 16u, 0 + 5u, 26u, 5u, 21u, 5u, 26u, 5u, 21u, 1u, 16u, 5u, 21u, 5u, 26u, 5u, 21u, + 5u, 26u, 5u, 21u, 1u, 16u, 5u, 21u, 5u, 26u, 5u, 21u, 1u, 16u, 5u, 21u, + 5u, 26u, 5u, 21u, 5u, 26u, 5u, 21u, 5u, 26u, 1u, 16u, 1u, 29u, 5u, 29u, + 5u, 29u, 5u, 29u, 22u, 22u, 5u, 22u, 5u, 29u, 5u, 29u, 5u, 29u, 5u, 26u, + 5u, 29u, 5u, 29u, 22u, 22u, 5u, 22u, 5u, 29u, 5u, 29u, 1u, 16u, 5u, 29u, + 5u, 29u, 0 }; static const char _khmer_syllable_machine_key_spans[] = { - 1, 16, 1, 16, 7, 1, 16, 1, - 16, 7, 16, 12, 12, 10, 12, 10, - 1, 11, 6, 1, 6, 12, 12, 10, - 12, 10, 1, 11, 6, 1, 6, 12, - 12, 7, 1, 16 + 22, 17, 22, 17, 16, 17, 22, 17, + 22, 17, 16, 17, 22, 17, 16, 17, + 22, 17, 22, 17, 22, 16, 29, 25, + 25, 25, 1, 18, 25, 25, 25, 22, + 25, 25, 1, 18, 25, 25, 16, 25, + 25 }; static const short _khmer_syllable_machine_index_offsets[] = { - 0, 2, 19, 21, 38, 46, 48, 65, - 67, 84, 92, 109, 122, 135, 146, 159, - 170, 172, 184, 191, 193, 200, 213, 226, - 237, 250, 261, 263, 275, 282, 284, 291, - 304, 317, 325, 327 + 0, 23, 41, 64, 82, 99, 117, 140, + 158, 181, 199, 216, 234, 257, 275, 292, + 310, 333, 351, 374, 392, 415, 432, 462, + 488, 514, 540, 542, 561, 587, 613, 639, + 662, 688, 714, 716, 735, 761, 787, 804, + 830 }; static const char _khmer_syllable_machine_indicies[] = { - 1, 0, 2, 2, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, + 3, 0, 0, 0, 0, 4, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3, + 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 0, 3, 0, 4, 4, 0, + 0, 3, 0, 0, 0, 0, 4, 0, + 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 4, 0, 1, 0, - 0, 0, 0, 0, 5, 0, 7, 6, - 8, 8, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 8, - 6, 9, 6, 10, 10, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 10, 6, 7, 6, 6, 6, - 6, 6, 11, 6, 4, 4, 13, 12, - 14, 15, 7, 16, 12, 12, 4, 4, - 11, 17, 12, 4, 12, 19, 18, 20, - 21, 1, 22, 18, 18, 18, 18, 5, - 23, 18, 24, 18, 21, 21, 1, 22, - 18, 18, 18, 18, 18, 23, 18, 21, - 21, 1, 22, 18, 18, 18, 18, 18, - 23, 18, 25, 18, 21, 21, 1, 22, - 18, 18, 18, 18, 18, 26, 18, 21, - 21, 1, 22, 18, 18, 18, 18, 18, - 26, 18, 27, 18, 28, 18, 29, 18, - 18, 22, 18, 18, 18, 18, 3, 18, - 30, 18, 18, 18, 18, 22, 18, 22, - 18, 28, 18, 18, 18, 18, 22, 18, - 19, 18, 21, 21, 1, 22, 18, 18, - 18, 18, 18, 23, 18, 32, 31, 33, - 33, 7, 16, 31, 31, 31, 31, 31, - 34, 31, 33, 33, 7, 16, 31, 31, - 31, 31, 31, 34, 31, 35, 31, 33, - 33, 7, 16, 31, 31, 31, 31, 31, - 36, 31, 33, 33, 7, 16, 31, 31, - 31, 31, 31, 36, 31, 37, 31, 38, - 31, 39, 31, 31, 16, 31, 31, 31, - 31, 9, 31, 40, 31, 31, 31, 31, - 16, 31, 16, 31, 38, 31, 31, 31, - 31, 16, 31, 13, 31, 41, 33, 7, - 16, 31, 31, 31, 31, 11, 34, 31, - 13, 31, 33, 33, 7, 16, 31, 31, - 31, 31, 31, 34, 31, 7, 42, 42, - 42, 42, 42, 11, 42, 7, 42, 10, - 10, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 10, 42, + 4, 0, 6, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6, 0, 7, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 8, 0, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 10, 0, 0, + 0, 0, 4, 0, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 10, 0, 11, 11, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 12, 0, + 0, 0, 0, 4, 0, 11, 11, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 12, 0, 13, + 13, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 13, 0, + 15, 15, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 16, 14, 15, 15, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 16, 17, 17, 17, 17, 18, + 17, 19, 19, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 18, 17, 20, 20, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 20, 17, 21, 21, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 22, 17, 23, 23, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 24, 17, + 17, 17, 17, 18, 17, 23, 23, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 24, 17, 25, + 25, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 26, + 17, 17, 17, 17, 18, 17, 25, 25, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 26, 17, + 15, 15, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 27, + 16, 17, 17, 17, 17, 18, 17, 28, + 28, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 28, 17, + 13, 13, 29, 29, 30, 30, 29, 29, + 29, 29, 2, 2, 29, 31, 29, 13, + 29, 29, 29, 29, 16, 20, 29, 29, + 29, 18, 24, 26, 22, 29, 33, 33, + 32, 32, 32, 32, 32, 32, 32, 34, + 32, 32, 32, 32, 32, 2, 3, 6, + 32, 32, 32, 4, 10, 12, 8, 32, + 35, 35, 32, 32, 32, 32, 32, 32, + 32, 36, 32, 32, 32, 32, 32, 32, + 3, 6, 32, 32, 32, 4, 10, 12, + 8, 32, 5, 5, 32, 32, 32, 32, + 32, 32, 32, 36, 32, 32, 32, 32, + 32, 32, 4, 6, 32, 32, 32, 32, + 32, 32, 8, 32, 6, 32, 7, 7, + 32, 32, 32, 32, 32, 32, 32, 36, + 32, 32, 32, 32, 32, 32, 8, 6, + 32, 37, 37, 32, 32, 32, 32, 32, + 32, 32, 36, 32, 32, 32, 32, 32, + 32, 10, 6, 32, 32, 32, 4, 32, + 32, 8, 32, 38, 38, 32, 32, 32, + 32, 32, 32, 32, 36, 32, 32, 32, + 32, 32, 32, 12, 6, 32, 32, 32, + 4, 10, 32, 8, 32, 35, 35, 32, + 32, 32, 32, 32, 32, 32, 34, 32, + 32, 32, 32, 32, 32, 3, 6, 32, + 32, 32, 4, 10, 12, 8, 32, 15, + 15, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 16, + 39, 39, 39, 39, 18, 39, 41, 41, + 40, 40, 40, 40, 40, 40, 40, 42, + 40, 40, 40, 40, 40, 40, 16, 20, + 40, 40, 40, 18, 24, 26, 22, 40, + 19, 19, 40, 40, 40, 40, 40, 40, + 40, 42, 40, 40, 40, 40, 40, 40, + 18, 20, 40, 40, 40, 40, 40, 40, + 22, 40, 20, 40, 21, 21, 40, 40, + 40, 40, 40, 40, 40, 42, 40, 40, + 40, 40, 40, 40, 22, 20, 40, 43, + 43, 40, 40, 40, 40, 40, 40, 40, + 42, 40, 40, 40, 40, 40, 40, 24, + 20, 40, 40, 40, 18, 40, 40, 22, + 40, 44, 44, 40, 40, 40, 40, 40, + 40, 40, 42, 40, 40, 40, 40, 40, + 40, 26, 20, 40, 40, 40, 18, 24, + 40, 22, 40, 28, 28, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 28, 39, 45, 45, 40, 40, + 40, 40, 40, 40, 40, 46, 40, 40, + 40, 40, 40, 27, 16, 20, 40, 40, + 40, 18, 24, 26, 22, 40, 41, 41, + 40, 40, 40, 40, 40, 40, 40, 46, + 40, 40, 40, 40, 40, 40, 16, 20, + 40, 40, 40, 18, 24, 26, 22, 40, 0 }; static const char _khmer_syllable_machine_trans_targs[] = { - 10, 14, 17, 20, 11, 21, 10, 24, - 27, 30, 31, 32, 10, 22, 33, 34, - 26, 35, 10, 12, 4, 0, 16, 3, - 13, 15, 1, 10, 18, 2, 19, 10, - 23, 5, 8, 25, 6, 10, 28, 7, - 29, 9, 10 + 22, 1, 30, 24, 25, 3, 26, 5, + 27, 7, 28, 9, 29, 23, 22, 11, + 32, 22, 33, 13, 34, 15, 35, 17, + 36, 19, 37, 40, 39, 22, 31, 38, + 22, 0, 10, 2, 4, 6, 8, 22, + 22, 12, 14, 16, 18, 20, 21 }; static const char _khmer_syllable_machine_trans_actions[] = { - 1, 2, 2, 0, 2, 2, 3, 2, - 2, 0, 2, 2, 6, 2, 0, 0, - 0, 0, 7, 2, 0, 0, 0, 0, - 2, 2, 0, 8, 0, 0, 0, 9, - 2, 0, 0, 2, 0, 10, 0, 0, - 0, 0, 11 + 1, 0, 2, 2, 2, 0, 0, 0, + 2, 0, 2, 0, 2, 2, 3, 0, + 4, 5, 2, 0, 0, 0, 2, 0, + 2, 0, 2, 4, 4, 8, 9, 0, + 10, 0, 0, 0, 0, 0, 0, 11, + 12, 0, 0, 0, 0, 0, 0 }; static const char _khmer_syllable_machine_to_state_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, + 0 }; static const char _khmer_syllable_machine_from_state_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0 + 0 }; static const unsigned char _khmer_syllable_machine_eof_trans[] = { - 1, 1, 1, 1, 1, 7, 7, 7, - 7, 7, 0, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 43, 43, 43 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 15, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 0, 33, + 33, 33, 33, 33, 33, 33, 33, 40, + 41, 41, 41, 41, 41, 41, 40, 41, + 41 }; -static const int khmer_syllable_machine_start = 10; -static const int khmer_syllable_machine_first_final = 10; +static const int khmer_syllable_machine_start = 22; +static const int khmer_syllable_machine_first_final = 22; static const int khmer_syllable_machine_error = -1; -static const int khmer_syllable_machine_en_main = 10; +static const int khmer_syllable_machine_en_main = 22; #line 36 "hb-ot-shape-complex-khmer-machine.rl" -#line 74 "hb-ot-shape-complex-khmer-machine.rl" +#line 80 "hb-ot-shape-complex-khmer-machine.rl" #define found_syllable(syllable_type) \ HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \ - for (unsigned int i = last; i < p+1; i++) \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ + for (unsigned int i = ts; i < te; i++) \ info[i].syllable() = (syllable_serial << 4) | syllable_type; \ - last = p+1; \ syllable_serial++; \ if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ } HB_STMT_END @@ -173,11 +242,11 @@ 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, act HB_UNUSED; + unsigned int p, pe, eof, ts, te, act HB_UNUSED; int cs; hb_glyph_info_t *info = buffer->info; -#line 181 "hb-ot-shape-complex-khmer-machine.hh" +#line 250 "hb-ot-shape-complex-khmer-machine.hh" { cs = khmer_syllable_machine_start; ts = 0; @@ -185,16 +254,15 @@ find_syllables (hb_buffer_t *buffer) act = 0; } -#line 95 "hb-ot-shape-complex-khmer-machine.rl" +#line 100 "hb-ot-shape-complex-khmer-machine.rl" p = 0; pe = eof = buffer->len; - unsigned int last = 0; unsigned int syllable_serial = 1; -#line 198 "hb-ot-shape-complex-khmer-machine.hh" +#line 266 "hb-ot-shape-complex-khmer-machine.hh" { int _slen; int _trans; @@ -204,11 +272,11 @@ find_syllables (hb_buffer_t *buffer) goto _test_eof; _resume: switch ( _khmer_syllable_machine_from_state_actions[cs] ) { - case 5: + case 7: #line 1 "NONE" {ts = p;} break; -#line 212 "hb-ot-shape-complex-khmer-machine.hh" +#line 280 "hb-ot-shape-complex-khmer-machine.hh" } _keys = _khmer_syllable_machine_trans_keys + (cs<<1); @@ -231,47 +299,63 @@ _eof_trans: {te = p+1;} break; case 8: -#line 68 "hb-ot-shape-complex-khmer-machine.rl" - {te = p+1;{ found_syllable (consonant_syllable); }} - break; - case 10: -#line 69 "hb-ot-shape-complex-khmer-machine.rl" - {te = p+1;{ found_syllable (broken_cluster); }} - break; - case 6: -#line 70 "hb-ot-shape-complex-khmer-machine.rl" +#line 76 "hb-ot-shape-complex-khmer-machine.rl" {te = p+1;{ found_syllable (non_khmer_cluster); }} break; - case 7: -#line 68 "hb-ot-shape-complex-khmer-machine.rl" + case 10: +#line 74 "hb-ot-shape-complex-khmer-machine.rl" {te = p;p--;{ found_syllable (consonant_syllable); }} break; - case 9: -#line 69 "hb-ot-shape-complex-khmer-machine.rl" + case 12: +#line 75 "hb-ot-shape-complex-khmer-machine.rl" {te = p;p--;{ found_syllable (broken_cluster); }} break; case 11: -#line 70 "hb-ot-shape-complex-khmer-machine.rl" +#line 76 "hb-ot-shape-complex-khmer-machine.rl" {te = p;p--;{ found_syllable (non_khmer_cluster); }} break; case 1: -#line 68 "hb-ot-shape-complex-khmer-machine.rl" +#line 74 "hb-ot-shape-complex-khmer-machine.rl" {{p = ((te))-1;}{ found_syllable (consonant_syllable); }} break; - case 3: -#line 69 "hb-ot-shape-complex-khmer-machine.rl" + case 5: +#line 75 "hb-ot-shape-complex-khmer-machine.rl" {{p = ((te))-1;}{ found_syllable (broken_cluster); }} break; -#line 266 "hb-ot-shape-complex-khmer-machine.hh" + case 3: +#line 1 "NONE" + { switch( act ) { + case 2: + {{p = ((te))-1;} found_syllable (broken_cluster); } + break; + case 3: + {{p = ((te))-1;} found_syllable (non_khmer_cluster); } + break; + } + } + break; + case 4: +#line 1 "NONE" + {te = p+1;} +#line 75 "hb-ot-shape-complex-khmer-machine.rl" + {act = 2;} + break; + case 9: +#line 1 "NONE" + {te = p+1;} +#line 76 "hb-ot-shape-complex-khmer-machine.rl" + {act = 3;} + break; +#line 350 "hb-ot-shape-complex-khmer-machine.hh" } _again: switch ( _khmer_syllable_machine_to_state_actions[cs] ) { - case 4: + case 6: #line 1 "NONE" {ts = 0;} break; -#line 275 "hb-ot-shape-complex-khmer-machine.hh" +#line 359 "hb-ot-shape-complex-khmer-machine.hh" } if ( ++p != pe ) @@ -287,7 +371,7 @@ _again: } -#line 104 "hb-ot-shape-complex-khmer-machine.rl" +#line 108 "hb-ot-shape-complex-khmer-machine.rl" } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer-machine.rl b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer-machine.rl index 7c7951629cc..4c596ab6425 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer-machine.rl +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer-machine.rl @@ -40,28 +40,34 @@ # Same order as enum khmer_category_t. Not sure how to avoid duplication. C = 1; V = 2; -N = 3; ZWNJ = 5; ZWJ = 6; -M = 7; -SM = 8; PLACEHOLDER = 11; DOTTEDCIRCLE = 12; -RS = 13; -Coeng = 14; -Ra = 16; - -c = (C | Ra | V); # is_consonant -n = ((ZWNJ?.RS)? (N.N?)?); # is_consonant_modifier -z = ZWJ|ZWNJ; # is_joiner - -cn = c.n?; -matra_group = z?.M.N?; -syllable_tail = (SM.SM?)?; - - -broken_cluster = n? (Coeng.cn)* matra_group* (Coeng.cn)? syllable_tail; -consonant_syllable = (c|PLACEHOLDER|DOTTEDCIRCLE) broken_cluster; +Coeng= 14; +Ra = 16; +Robatic = 20; +Xgroup = 21; +Ygroup = 22; +VAbv = 26; +VBlw = 27; +VPre = 28; +VPst = 29; + +c = (C | Ra | V); +cn = c.((ZWJ|ZWNJ)?.Robatic)?; +joiner = (ZWJ | ZWNJ); +xgroup = (joiner*.Xgroup)*; +ygroup = Ygroup*; + +# This grammar was experimentally extracted from what Uniscribe allows. + +matra_group = VPre? xgroup VBlw? xgroup (joiner?.VAbv)? xgroup VPst?; +syllable_tail = xgroup matra_group xgroup (Coeng.c)? ygroup; + + +broken_cluster = (Coeng.cn)* syllable_tail; +consonant_syllable = (cn|PLACEHOLDER|DOTTEDCIRCLE) broken_cluster; other = any; main := |* @@ -75,10 +81,9 @@ main := |* #define found_syllable(syllable_type) \ HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \ - for (unsigned int i = last; i < p+1; i++) \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ + for (unsigned int i = ts; i < te; i++) \ info[i].syllable() = (syllable_serial << 4) | syllable_type; \ - last = p+1; \ syllable_serial++; \ if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ } HB_STMT_END @@ -86,7 +91,7 @@ main := |* static void find_syllables (hb_buffer_t *buffer) { - unsigned int p, pe, eof, ts HB_UNUSED, te, act HB_UNUSED; + unsigned int p, pe, eof, ts, te, act HB_UNUSED; int cs; hb_glyph_info_t *info = buffer->info; %%{ @@ -97,7 +102,6 @@ find_syllables (hb_buffer_t *buffer) p = 0; pe = eof = buffer->len; - unsigned int last = 0; unsigned int syllable_serial = 1; %%{ write exec; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.cc index 0b5b50a972e..88d16267b39 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.cc @@ -32,32 +32,30 @@ * Khmer shaper. */ -struct feature_list_t { - hb_tag_t tag; - hb_ot_map_feature_flags_t flags; -}; - -static const feature_list_t +static const hb_ot_map_feature_t khmer_features[] = { /* * Basic features. * These features are applied in order, one at a time, after reordering. */ - {HB_TAG('p','r','e','f'), F_NONE}, - {HB_TAG('b','l','w','f'), F_NONE}, - {HB_TAG('a','b','v','f'), F_NONE}, - {HB_TAG('p','s','t','f'), F_NONE}, - {HB_TAG('c','f','a','r'), F_NONE}, + {HB_TAG('p','r','e','f'), F_MANUAL_JOINERS}, + {HB_TAG('b','l','w','f'), F_MANUAL_JOINERS}, + {HB_TAG('a','b','v','f'), F_MANUAL_JOINERS}, + {HB_TAG('p','s','t','f'), F_MANUAL_JOINERS}, + {HB_TAG('c','f','a','r'), F_MANUAL_JOINERS}, /* * Other features. * These features are applied all at once. */ - {HB_TAG('p','r','e','s'), F_GLOBAL}, - {HB_TAG('a','b','v','s'), F_GLOBAL}, - {HB_TAG('b','l','w','s'), F_GLOBAL}, - {HB_TAG('p','s','t','s'), F_GLOBAL}, - /* Positioning features, though we don't care about the types. */ + {HB_TAG('p','r','e','s'), F_GLOBAL_MANUAL_JOINERS}, + {HB_TAG('a','b','v','s'), F_GLOBAL_MANUAL_JOINERS}, + {HB_TAG('b','l','w','s'), F_GLOBAL_MANUAL_JOINERS}, + {HB_TAG('p','s','t','s'), F_GLOBAL_MANUAL_JOINERS}, + /* + * Positioning features. + * We don't care about the types. + */ {HB_TAG('d','i','s','t'), F_GLOBAL}, {HB_TAG('a','b','v','m'), F_GLOBAL}, {HB_TAG('b','l','w','m'), F_GLOBAL}, @@ -77,12 +75,13 @@ enum { _ABVS, _BLWS, _PSTS, + _DIST, _ABVM, _BLWM, KHMER_NUM_FEATURES, - KHMER_BASIC_FEATURES = _PRES /* Don't forget to update this! */ + KHMER_BASIC_FEATURES = _PRES, /* Don't forget to update this! */ }; static void @@ -117,22 +116,20 @@ collect_features_khmer (hb_ot_shape_planner_t *plan) * * https://github.com/harfbuzz/harfbuzz/issues/974 */ - map->add_global_bool_feature (HB_TAG('l','o','c','l')); - map->add_global_bool_feature (HB_TAG('c','c','m','p')); + map->enable_feature (HB_TAG('l','o','c','l')); + map->enable_feature (HB_TAG('c','c','m','p')); unsigned int i = 0; - for (; i < KHMER_BASIC_FEATURES; i++) { - map->add_feature (khmer_features[i].tag, 1, khmer_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ); - } + for (; i < KHMER_BASIC_FEATURES; i++) + map->add_feature (khmer_features[i]); map->add_gsub_pause (clear_syllables); - for (; i < KHMER_NUM_FEATURES; i++) { - map->add_feature (khmer_features[i].tag, 1, khmer_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ); - } + for (; i < KHMER_NUM_FEATURES; i++) + map->add_feature (khmer_features[i]); - map->add_global_bool_feature (HB_TAG('c','a','l','t')); - map->add_global_bool_feature (HB_TAG('c','l','i','g')); + map->enable_feature (HB_TAG('c','a','l','t')); + map->enable_feature (HB_TAG('c','l','i','g')); } @@ -142,10 +139,10 @@ override_features_khmer (hb_ot_shape_planner_t *plan) /* Uniscribe does not apply 'kern' in Khmer. */ if (hb_options ().uniscribe_bug_compatible) { - plan->map.add_feature (HB_TAG('k','e','r','n'), 0, F_GLOBAL); + plan->map.disable_feature (HB_TAG('k','e','r','n')); } - plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL); + plan->map.disable_feature (HB_TAG('l','i','g','a')); } @@ -244,7 +241,6 @@ setup_masks_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_font_t *font HB_UNUSED) { HB_BUFFER_ALLOCATE_VAR (buffer, khmer_category); - HB_BUFFER_ALLOCATE_VAR (buffer, khmer_position); /* We cannot setup masks here. We save information about characters * and setup masks later on in a pause-callback. */ @@ -333,7 +329,7 @@ reorder_consonant_syllable (const hb_ot_shape_plan_t *plan, } /* Reorder left matra piece. */ - else if (info[i].khmer_position() == POS_PRE_M) + else if (info[i].khmer_category() == OT_VPre) { /* Move to the start. */ buffer->merge_clusters (start, i + 1); @@ -435,7 +431,6 @@ reorder (const hb_ot_shape_plan_t *plan, initial_reordering_syllable (plan, font->face, buffer, start, end); HB_BUFFER_DEALLOCATE_VAR (buffer, khmer_category); - HB_BUFFER_DEALLOCATE_VAR (buffer, khmer_position); } static void @@ -501,7 +496,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_khmer = decompose_khmer, compose_khmer, setup_masks_khmer, - nullptr, /* disable_otl */ + HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, false, /* fallback_position */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.hh index 3371c130216..622294588b2 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.hh @@ -34,42 +34,21 @@ /* buffer var allocations */ #define khmer_category() indic_category() /* khmer_category_t */ -#define khmer_position() indic_position() /* khmer_position_t */ -typedef indic_category_t khmer_category_t; -typedef indic_position_t khmer_position_t; - - -static inline khmer_position_t -matra_position_khmer (khmer_position_t side) -{ - switch ((int) side) - { - case POS_PRE_C: - return POS_PRE_M; - - case POS_POST_C: - case POS_ABOVE_C: - case POS_BELOW_C: - return POS_AFTER_POST; - - default: - return side; - }; -} - -static inline bool -is_consonant_or_vowel (const hb_glyph_info_t &info) +/* Note: This enum is duplicated in the -machine.rl source file. + * Not sure how to avoid duplication. */ +enum khmer_category_t { - return is_one_of (info, CONSONANT_FLAGS | FLAG (OT_V)); -} + OT_Robatic = 20, + OT_Xgroup = 21, + OT_Ygroup = 22, -static inline bool -is_coeng (const hb_glyph_info_t &info) -{ - return is_one_of (info, FLAG (OT_Coeng)); -} + OT_VAbv = 26, + OT_VBlw = 27, + OT_VPre = 28, + OT_VPst = 29, +}; static inline void set_khmer_properties (hb_glyph_info_t &info) @@ -77,47 +56,58 @@ set_khmer_properties (hb_glyph_info_t &info) hb_codepoint_t u = info.codepoint; unsigned int type = hb_indic_get_categories (u); khmer_category_t cat = (khmer_category_t) (type & 0x7Fu); - khmer_position_t pos = (khmer_position_t) (type >> 8); + indic_position_t pos = (indic_position_t) (type >> 8); /* * Re-assign category + * + * These categories are experimentally extracted from what Uniscribe allows. */ - - if (unlikely (u == 0x17C6u)) cat = OT_N; /* Khmer Bindu doesn't like to be repositioned. */ - else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x17CDu, 0x17D1u) || - u == 0x17CBu || u == 0x17D3u || u == 0x17DDu)) /* Khmer Various signs */ + switch (u) { - /* These can occur mid-syllable (eg. before matras), even though Unicode marks them as Syllable_Modifier. - * https://github.com/roozbehp/unicode-data/issues/5 */ - cat = OT_M; - pos = POS_ABOVE_C; + case 0x179Au: + cat = (khmer_category_t) OT_Ra; + break; + + case 0x17CCu: + case 0x17C9u: + case 0x17CAu: + cat = OT_Robatic; + break; + + case 0x17C6u: + case 0x17CBu: + case 0x17CDu: + case 0x17CEu: + case 0x17CFu: + case 0x17D0u: + case 0x17D1u: + cat = OT_Xgroup; + break; + + case 0x17C7u: + case 0x17C8u: + case 0x17DDu: + case 0x17D3u: /* Just guessing. Uniscribe doesn't categorize it. */ + cat = OT_Ygroup; + break; } - else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x2010u, 0x2011u))) cat = OT_PLACEHOLDER; - else if (unlikely (u == 0x25CCu)) cat = OT_DOTTEDCIRCLE; - /* * Re-assign position. */ - - if ((FLAG_UNSAFE (cat) & CONSONANT_FLAGS)) - { - pos = POS_BASE_C; - if (u == 0x179Au) - cat = OT_Ra; - } - else if (cat == OT_M) - { - pos = matra_position_khmer (pos); - } - else if ((FLAG_UNSAFE (cat) & (FLAG (OT_SM) | FLAG (OT_A) | FLAG (OT_Symbol)))) - { - pos = POS_SMVD; - } + if (cat == (khmer_category_t) OT_M) + switch ((int) pos) + { + case POS_PRE_C: cat = OT_VPre; break; + case POS_BELOW_C: cat = OT_VBlw; break; + case POS_ABOVE_C: cat = OT_VAbv; break; + case POS_POST_C: cat = OT_VPst; break; + default: assert (0); + }; info.khmer_category() = cat; - info.khmer_position() = pos; } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.hh index 7fa23517807..0c19e4f687f 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.hh @@ -283,10 +283,9 @@ static const int myanmar_syllable_machine_en_main = 0; #define found_syllable(syllable_type) \ HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \ - for (unsigned int i = last; i < p+1; i++) \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ + for (unsigned int i = ts; i < te; i++) \ info[i].syllable() = (syllable_serial << 4) | syllable_type; \ - last = p+1; \ syllable_serial++; \ if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ } HB_STMT_END @@ -294,11 +293,11 @@ static const int myanmar_syllable_machine_en_main = 0; 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, te, act HB_UNUSED; int cs; hb_glyph_info_t *info = buffer->info; -#line 302 "hb-ot-shape-complex-myanmar-machine.hh" +#line 301 "hb-ot-shape-complex-myanmar-machine.hh" { cs = myanmar_syllable_machine_start; ts = 0; @@ -306,16 +305,15 @@ find_syllables (hb_buffer_t *buffer) act = 0; } -#line 115 "hb-ot-shape-complex-myanmar-machine.rl" +#line 114 "hb-ot-shape-complex-myanmar-machine.rl" p = 0; pe = eof = buffer->len; - unsigned int last = 0; unsigned int syllable_serial = 1; -#line 319 "hb-ot-shape-complex-myanmar-machine.hh" +#line 317 "hb-ot-shape-complex-myanmar-machine.hh" { int _slen; int _trans; @@ -329,7 +327,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 333 "hb-ot-shape-complex-myanmar-machine.hh" +#line 331 "hb-ot-shape-complex-myanmar-machine.hh" } _keys = _myanmar_syllable_machine_trans_keys + (cs<<1); @@ -379,7 +377,7 @@ _eof_trans: #line 90 "hb-ot-shape-complex-myanmar-machine.rl" {te = p;p--;{ found_syllable (non_myanmar_cluster); }} break; -#line 383 "hb-ot-shape-complex-myanmar-machine.hh" +#line 381 "hb-ot-shape-complex-myanmar-machine.hh" } _again: @@ -388,7 +386,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 392 "hb-ot-shape-complex-myanmar-machine.hh" +#line 390 "hb-ot-shape-complex-myanmar-machine.hh" } if ( ++p != pe ) @@ -404,7 +402,7 @@ _again: } -#line 124 "hb-ot-shape-complex-myanmar-machine.rl" +#line 122 "hb-ot-shape-complex-myanmar-machine.rl" } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.rl b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.rl index 62f51d1e9e8..7845a86d41f 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.rl +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.rl @@ -95,10 +95,9 @@ main := |* #define found_syllable(syllable_type) \ HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \ - for (unsigned int i = last; i < p+1; i++) \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ + for (unsigned int i = ts; i < te; i++) \ info[i].syllable() = (syllable_serial << 4) | syllable_type; \ - last = p+1; \ syllable_serial++; \ if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ } HB_STMT_END @@ -106,7 +105,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, te, act HB_UNUSED; int cs; hb_glyph_info_t *info = buffer->info; %%{ @@ -117,7 +116,6 @@ find_syllables (hb_buffer_t *buffer) p = 0; pe = eof = buffer->len; - unsigned int last = 0; unsigned int syllable_serial = 1; %%{ write exec; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc index 8466f8129d5..e201a230938 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc @@ -54,7 +54,14 @@ other_features[] = HB_TAG('a','b','v','s'), HB_TAG('b','l','w','s'), HB_TAG('p','s','t','s'), - /* Positioning features, though we don't care about the types. */ +}; +static const hb_tag_t +positioning_features[] = +{ + /* + * Positioning features. + * We don't care about the types. + */ HB_TAG('d','i','s','t'), /* Pre-release version of Windows 8 Myanmar font had abvm,blwm * features. The released Windows 8 version of the font (as well @@ -89,27 +96,33 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan) /* Do this before any lookups have been applied. */ map->add_gsub_pause (setup_syllables); - map->add_global_bool_feature (HB_TAG('l','o','c','l')); + map->enable_feature (HB_TAG('l','o','c','l')); /* The Indic specs do not require ccmp, but we apply it here since if * there is a use of it, it's typically at the beginning. */ - map->add_global_bool_feature (HB_TAG('c','c','m','p')); + map->enable_feature (HB_TAG('c','c','m','p')); map->add_gsub_pause (initial_reordering); + for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++) { - map->add_feature (basic_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ); + map->enable_feature (basic_features[i], F_MANUAL_ZWJ); map->add_gsub_pause (nullptr); } + map->add_gsub_pause (final_reordering); + for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++) - map->add_feature (other_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ); + map->enable_feature (other_features[i], F_MANUAL_ZWJ); + + for (unsigned int i = 0; i < ARRAY_LENGTH (positioning_features); i++) + map->enable_feature (positioning_features[i]); } static void override_features_myanmar (hb_ot_shape_planner_t *plan) { - plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL); + plan->map.disable_feature (HB_TAG('l','i','g','a')); } @@ -362,6 +375,25 @@ final_reordering (const hb_ot_shape_plan_t *plan, } +const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar = +{ + collect_features_myanmar, + override_features_myanmar, + nullptr, /* data_create */ + nullptr, /* data_destroy */ + nullptr, /* preprocess_text */ + nullptr, /* postprocess_glyphs */ + HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, + nullptr, /* decompose */ + nullptr, /* compose */ + setup_masks_myanmar, + HB_TAG_NONE, /* gpos_tag */ + nullptr, /* reorder_marks */ + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY, + false, /* fallback_position */ +}; + + /* Uniscribe seems to have a shaper for 'mymr' that is like the * generic shaper, except that it zeros mark advances GDEF_LATE. */ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar_old = @@ -376,26 +408,30 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar_old = nullptr, /* decompose */ nullptr, /* compose */ nullptr, /* setup_masks */ - nullptr, /* disable_otl */ + HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, true, /* fallback_position */ }; -const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar = + +/* Ugly Zawgyi encoding. + * Disable all auto processing. + * https://github.com/harfbuzz/harfbuzz/issues/1162 */ +const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar_zawgyi = { - collect_features_myanmar, - override_features_myanmar, + nullptr, /* collect_features */ + nullptr, /* override_features */ nullptr, /* data_create */ nullptr, /* data_destroy */ nullptr, /* preprocess_text */ nullptr, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, + HB_OT_SHAPE_NORMALIZATION_MODE_NONE, nullptr, /* decompose */ nullptr, /* compose */ - setup_masks_myanmar, - nullptr, /* disable_otl */ + nullptr, /* setup_masks */ + HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ - HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY, + HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, false, /* fallback_position */ }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.hh index 7b6fd4837c7..3e9537a6447 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.hh @@ -64,42 +64,42 @@ set_myanmar_properties (hb_glyph_info_t &info) { hb_codepoint_t u = info.codepoint; unsigned int type = hb_indic_get_categories (u); - indic_category_t cat = (indic_category_t) (type & 0x7Fu); + unsigned int cat = type & 0x7Fu; indic_position_t pos = (indic_position_t) (type >> 8); /* Myanmar * 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; + cat = OT_VS; switch (u) { case 0x104Eu: - cat = (indic_category_t) OT_C; /* The spec says C, IndicSyllableCategory doesn't have. */ + cat = OT_C; /* The spec says C, IndicSyllableCategory doesn't have. */ break; case 0x002Du: case 0x00A0u: case 0x00D7u: case 0x2012u: case 0x2013u: case 0x2014u: case 0x2015u: case 0x2022u: case 0x25CCu: case 0x25FBu: case 0x25FCu: case 0x25FDu: case 0x25FEu: - cat = (indic_category_t) OT_GB; + cat = OT_GB; break; case 0x1004u: case 0x101Bu: case 0x105Au: - cat = (indic_category_t) OT_Ra; + cat = OT_Ra; break; case 0x1032u: case 0x1036u: - cat = (indic_category_t) OT_A; + cat = OT_A; break; case 0x1039u: - cat = (indic_category_t) OT_H; + cat = OT_H; break; case 0x103Au: - cat = (indic_category_t) OT_As; + cat = OT_As; break; case 0x1041u: case 0x1042u: case 0x1043u: case 0x1044u: @@ -107,47 +107,47 @@ set_myanmar_properties (hb_glyph_info_t &info) case 0x1049u: case 0x1090u: case 0x1091u: case 0x1092u: case 0x1093u: case 0x1094u: case 0x1095u: case 0x1096u: case 0x1097u: case 0x1098u: case 0x1099u: - cat = (indic_category_t) OT_D; + cat = OT_D; break; case 0x1040u: - cat = (indic_category_t) OT_D; /* XXX The spec says D0, but Uniscribe doesn't seem to do. */ + cat = OT_D; /* XXX The spec says D0, but Uniscribe doesn't seem to do. */ break; case 0x103Eu: case 0x1060u: - cat = (indic_category_t) OT_MH; + cat = OT_MH; break; case 0x103Cu: - cat = (indic_category_t) OT_MR; + cat = OT_MR; break; case 0x103Du: case 0x1082u: - cat = (indic_category_t) OT_MW; + cat = OT_MW; break; case 0x103Bu: case 0x105Eu: case 0x105Fu: - cat = (indic_category_t) OT_MY; + cat = OT_MY; break; case 0x1063u: case 0x1064u: case 0x1069u: case 0x106Au: case 0x106Bu: case 0x106Cu: case 0x106Du: case 0xAA7Bu: - cat = (indic_category_t) OT_PT; + cat = OT_PT; break; case 0x1038u: case 0x1087u: case 0x1088u: case 0x1089u: case 0x108Au: case 0x108Bu: case 0x108Cu: case 0x108Du: case 0x108Fu: case 0x109Au: case 0x109Bu: case 0x109Cu: - cat = (indic_category_t) OT_SM; + cat = OT_SM; break; case 0x104Au: case 0x104Bu: - cat = (indic_category_t) OT_P; + cat = OT_P; break; case 0xAA74u: case 0xAA75u: case 0xAA76u: /* https://github.com/roozbehp/unicode-data/issues/3 */ - cat = (indic_category_t) OT_C; + cat = OT_C; break; } @@ -155,15 +155,15 @@ set_myanmar_properties (hb_glyph_info_t &info) { switch ((int) pos) { - case POS_PRE_C: cat = (indic_category_t) OT_VPre; - pos = POS_PRE_M; break; - case POS_ABOVE_C: cat = (indic_category_t) OT_VAbv; break; - case POS_BELOW_C: cat = (indic_category_t) OT_VBlw; break; - case POS_POST_C: cat = (indic_category_t) OT_VPst; break; + case POS_PRE_C: cat = OT_VPre; + pos = POS_PRE_M; break; + case POS_ABOVE_C: cat = OT_VAbv; break; + case POS_BELOW_C: cat = OT_VBlw; break; + case POS_POST_C: cat = OT_VPst; break; } } - info.myanmar_category() = (myanmar_category_t) cat; + info.myanmar_category() = cat; info.myanmar_position() = pos; } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-thai.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-thai.cc index 1d18760e4da..b687fe61e3d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-thai.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-thai.cc @@ -324,9 +324,9 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan, } /* Is SARA AM. Decompose and reorder. */ - 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); + hb_glyph_info_t &nikhahit = buffer->output_glyph (NIKHAHIT_FROM_SARA_AM (u)); + _hb_glyph_info_set_continuation (&nikhahit); + buffer->replace_glyph (SARA_AA_FROM_SARA_AM (u)); if (unlikely (!buffer->successful)) return; @@ -357,7 +357,8 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan, buffer->merge_out_clusters (start - 1, end); } } - buffer->swap_buffers (); + if (likely (buffer->successful)) + buffer->swap_buffers (); /* If font has Thai GSUB, we are done. */ if (plan->props.script == HB_SCRIPT_THAI && !plan->map.found_script[0]) @@ -376,7 +377,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai = nullptr, /* decompose */ nullptr, /* compose */ nullptr, /* setup_masks */ - nullptr, /* disable_otl */ + HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, false,/* fallback_position */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.hh index 77ca3aeb52a..c9410e4e581 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.hh @@ -36,227 +36,266 @@ #line 38 "hb-ot-shape-complex-use-machine.hh" static const unsigned char _use_syllable_machine_trans_keys[] = { - 12u, 12u, 1u, 15u, 1u, 1u, 12u, 12u, 0u, 43u, 21u, 21u, 8u, 39u, 8u, 39u, - 1u, 15u, 1u, 1u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 26u, 8u, 26u, 8u, 26u, - 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, - 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 13u, 21u, 4u, 4u, 13u, 13u, 8u, 39u, - 8u, 39u, 8u, 39u, 8u, 39u, 8u, 26u, 8u, 26u, 8u, 26u, 8u, 39u, 8u, 39u, - 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, - 8u, 39u, 1u, 15u, 12u, 12u, 1u, 39u, 8u, 39u, 21u, 42u, 41u, 42u, 42u, 42u, - 1u, 5u, 0 + 12u, 44u, 1u, 15u, 1u, 1u, 12u, 44u, 0u, 44u, 21u, 21u, 8u, 44u, 8u, 44u, + 1u, 15u, 1u, 1u, 8u, 44u, 8u, 44u, 8u, 39u, 8u, 26u, 8u, 26u, 8u, 26u, + 8u, 39u, 8u, 39u, 8u, 39u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u, + 8u, 44u, 8u, 44u, 8u, 44u, 1u, 39u, 8u, 44u, 13u, 21u, 4u, 4u, 13u, 13u, + 8u, 44u, 8u, 44u, 8u, 44u, 8u, 39u, 8u, 26u, 8u, 26u, 8u, 26u, 8u, 39u, + 8u, 39u, 8u, 39u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u, + 8u, 44u, 8u, 44u, 1u, 39u, 1u, 15u, 12u, 44u, 1u, 44u, 8u, 44u, 21u, 42u, + 41u, 42u, 42u, 42u, 1u, 5u, 0 }; static const char _use_syllable_machine_key_spans[] = { - 1, 15, 1, 1, 44, 1, 32, 32, - 15, 1, 32, 32, 32, 19, 19, 19, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 9, 1, 1, 32, - 32, 32, 32, 19, 19, 19, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 15, 1, 39, 32, 22, 2, 1, - 5 + 33, 15, 1, 33, 45, 1, 37, 37, + 15, 1, 37, 37, 32, 19, 19, 19, + 32, 32, 32, 37, 37, 37, 37, 37, + 37, 37, 37, 39, 37, 9, 1, 1, + 37, 37, 37, 32, 19, 19, 19, 32, + 32, 32, 37, 37, 37, 37, 37, 37, + 37, 37, 39, 15, 33, 44, 37, 22, + 2, 1, 5 }; static const short _use_syllable_machine_index_offsets[] = { - 0, 2, 18, 20, 22, 67, 69, 102, - 135, 151, 153, 186, 219, 252, 272, 292, - 312, 345, 378, 411, 444, 477, 510, 543, - 576, 609, 642, 675, 708, 718, 720, 722, - 755, 788, 821, 854, 874, 894, 914, 947, - 980, 1013, 1046, 1079, 1112, 1145, 1178, 1211, - 1244, 1277, 1293, 1295, 1335, 1368, 1391, 1394, - 1396 + 0, 34, 50, 52, 86, 132, 134, 172, + 210, 226, 228, 266, 304, 337, 357, 377, + 397, 430, 463, 496, 534, 572, 610, 648, + 686, 724, 762, 800, 840, 878, 888, 890, + 892, 930, 968, 1006, 1039, 1059, 1079, 1099, + 1132, 1165, 1198, 1236, 1274, 1312, 1350, 1388, + 1426, 1464, 1502, 1542, 1558, 1592, 1637, 1675, + 1698, 1701, 1703 }; static const char _use_syllable_machine_indicies[] = { + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 4, 2, 3, 2, 6, 5, 7, 8, + 4, 2, 3, 2, 6, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 6, 5, 7, 8, 9, 7, 10, 8, 9, 9, 11, 9, 9, 3, 12, 9, 9, 13, 7, 7, 14, 15, 9, 9, 16, 17, 18, 19, 20, 21, 22, 16, 23, 24, 25, 26, 27, 28, 9, 29, 30, 31, 9, 9, - 9, 32, 9, 34, 33, 36, 35, 35, - 37, 1, 35, 35, 38, 35, 35, 35, - 35, 35, 39, 40, 41, 42, 43, 44, - 45, 46, 40, 47, 39, 48, 49, 50, - 51, 35, 52, 53, 54, 35, 36, 35, - 35, 37, 1, 35, 35, 38, 35, 35, - 35, 35, 35, 55, 40, 41, 42, 43, - 44, 45, 46, 40, 47, 48, 48, 49, - 50, 51, 35, 52, 53, 54, 35, 37, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 57, 56, 37, - 56, 36, 35, 35, 37, 1, 35, 35, - 38, 35, 35, 35, 35, 35, 35, 40, - 41, 42, 43, 44, 45, 46, 40, 47, - 48, 48, 49, 50, 51, 35, 52, 53, - 54, 35, 36, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 40, 41, 42, 43, 44, 35, 35, 35, - 35, 35, 35, 49, 50, 51, 35, 52, - 53, 54, 35, 36, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 41, 42, 43, 44, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 52, 53, 54, 35, 36, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 42, 43, 44, 35, - 36, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 43, 44, 35, 36, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 44, 35, - 36, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 42, 43, 44, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 52, 53, 54, - 35, 36, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 42, 43, 44, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 53, - 54, 35, 36, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 42, 43, 44, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 54, 35, 36, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 41, 42, 43, 44, 35, 35, - 35, 35, 35, 35, 49, 50, 51, 35, - 52, 53, 54, 35, 36, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 41, 42, 43, 44, 35, - 35, 35, 35, 35, 35, 35, 50, 51, - 35, 52, 53, 54, 35, 36, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 41, 42, 43, 44, - 35, 35, 35, 35, 35, 35, 35, 35, - 51, 35, 52, 53, 54, 35, 36, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 40, 41, 42, 43, - 44, 35, 46, 40, 35, 35, 35, 49, - 50, 51, 35, 52, 53, 54, 35, 36, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 40, 41, 42, - 43, 44, 35, 58, 40, 35, 35, 35, - 49, 50, 51, 35, 52, 53, 54, 35, - 36, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 40, 41, - 42, 43, 44, 35, 35, 40, 35, 35, - 35, 49, 50, 51, 35, 52, 53, 54, - 35, 36, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 40, - 41, 42, 43, 44, 45, 46, 40, 35, - 35, 35, 49, 50, 51, 35, 52, 53, - 54, 35, 36, 35, 35, 37, 1, 35, - 35, 38, 35, 35, 35, 35, 35, 35, - 40, 41, 42, 43, 44, 45, 46, 40, - 47, 35, 48, 49, 50, 51, 35, 52, - 53, 54, 35, 36, 35, 35, 37, 1, - 35, 35, 38, 35, 35, 35, 35, 35, - 35, 40, 41, 42, 43, 44, 45, 46, - 40, 47, 39, 48, 49, 50, 51, 35, - 52, 53, 54, 35, 60, 59, 59, 59, - 59, 59, 59, 59, 61, 59, 10, 62, - 60, 59, 11, 63, 63, 3, 6, 63, - 63, 64, 63, 63, 63, 63, 63, 65, + 9, 32, 33, 9, 35, 34, 37, 36, + 36, 38, 1, 36, 36, 39, 36, 36, + 36, 36, 36, 40, 41, 42, 43, 44, + 45, 46, 47, 41, 48, 40, 49, 50, + 51, 52, 36, 53, 54, 55, 36, 36, + 36, 36, 56, 36, 37, 36, 36, 38, + 1, 36, 36, 39, 36, 36, 36, 36, + 36, 57, 41, 42, 43, 44, 45, 46, + 47, 41, 48, 49, 49, 50, 51, 52, + 36, 53, 54, 55, 36, 36, 36, 36, + 56, 36, 38, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, + 59, 58, 38, 58, 37, 36, 36, 38, + 1, 36, 36, 39, 36, 36, 36, 36, + 36, 36, 41, 42, 43, 44, 45, 46, + 47, 41, 48, 49, 49, 50, 51, 52, + 36, 53, 54, 55, 36, 36, 36, 36, + 56, 36, 37, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 41, 42, 43, 44, 45, 36, 36, 36, + 36, 36, 36, 50, 51, 52, 36, 53, + 54, 55, 36, 36, 36, 36, 42, 36, + 37, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 42, + 43, 44, 45, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 53, 54, 55, + 36, 37, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 43, 44, 45, 36, 37, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 44, 45, + 36, 37, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 45, 36, 37, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 43, 44, 45, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 53, 54, 55, 36, 37, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 43, 44, + 45, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 54, 55, 36, 37, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 43, + 44, 45, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 55, 36, + 37, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 42, + 43, 44, 45, 36, 36, 36, 36, 36, + 36, 50, 51, 52, 36, 53, 54, 55, + 36, 36, 36, 36, 42, 36, 37, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 42, 43, 44, + 45, 36, 36, 36, 36, 36, 36, 36, + 51, 52, 36, 53, 54, 55, 36, 36, + 36, 36, 42, 36, 37, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 42, 43, 44, 45, 36, + 36, 36, 36, 36, 36, 36, 36, 52, + 36, 53, 54, 55, 36, 36, 36, 36, + 42, 36, 37, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 41, 42, 43, 44, 45, 36, 47, 41, + 36, 36, 36, 50, 51, 52, 36, 53, + 54, 55, 36, 36, 36, 36, 42, 36, + 37, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 41, 42, + 43, 44, 45, 36, 60, 41, 36, 36, + 36, 50, 51, 52, 36, 53, 54, 55, + 36, 36, 36, 36, 42, 36, 37, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 41, 42, 43, 44, + 45, 36, 36, 41, 36, 36, 36, 50, + 51, 52, 36, 53, 54, 55, 36, 36, + 36, 36, 42, 36, 37, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 41, 42, 43, 44, 45, 46, + 47, 41, 36, 36, 36, 50, 51, 52, + 36, 53, 54, 55, 36, 36, 36, 36, + 42, 36, 37, 36, 36, 38, 1, 36, + 36, 39, 36, 36, 36, 36, 36, 36, + 41, 42, 43, 44, 45, 46, 47, 41, + 48, 36, 49, 50, 51, 52, 36, 53, + 54, 55, 36, 36, 36, 36, 56, 36, + 38, 58, 58, 58, 58, 58, 58, 37, + 58, 58, 58, 58, 58, 58, 59, 58, + 58, 58, 58, 58, 58, 58, 42, 43, + 44, 45, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 53, 54, 55, 58, + 37, 36, 36, 38, 1, 36, 36, 39, + 36, 36, 36, 36, 36, 36, 41, 42, + 43, 44, 45, 46, 47, 41, 48, 40, + 49, 50, 51, 52, 36, 53, 54, 55, + 36, 36, 36, 36, 56, 36, 62, 61, + 61, 61, 61, 61, 61, 61, 63, 61, + 10, 64, 62, 61, 11, 65, 65, 3, + 6, 65, 65, 66, 65, 65, 65, 65, + 65, 67, 16, 17, 18, 19, 20, 21, + 22, 16, 23, 25, 25, 26, 27, 28, + 65, 29, 30, 31, 65, 65, 65, 65, + 33, 65, 11, 65, 65, 3, 6, 65, + 65, 66, 65, 65, 65, 65, 65, 65, 16, 17, 18, 19, 20, 21, 22, 16, - 23, 25, 25, 26, 27, 28, 63, 29, - 30, 31, 63, 11, 63, 63, 3, 6, - 63, 63, 64, 63, 63, 63, 63, 63, - 63, 16, 17, 18, 19, 20, 21, 22, - 16, 23, 25, 25, 26, 27, 28, 63, - 29, 30, 31, 63, 11, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 16, 17, 18, 19, 20, 63, - 63, 63, 63, 63, 63, 26, 27, 28, - 63, 29, 30, 31, 63, 11, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 17, 18, 19, 20, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 29, 30, 31, 63, 11, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 18, 19, - 20, 63, 11, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 19, 20, 63, 11, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 20, 63, 11, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 18, 19, 20, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 29, - 30, 31, 63, 11, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 18, 19, 20, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 30, 31, 63, 11, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 18, 19, 20, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 31, 63, 11, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 17, 18, 19, 20, - 63, 63, 63, 63, 63, 63, 26, 27, - 28, 63, 29, 30, 31, 63, 11, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 17, 18, 19, - 20, 63, 63, 63, 63, 63, 63, 63, - 27, 28, 63, 29, 30, 31, 63, 11, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 17, 18, - 19, 20, 63, 63, 63, 63, 63, 63, - 63, 63, 28, 63, 29, 30, 31, 63, - 11, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 16, 17, - 18, 19, 20, 63, 22, 16, 63, 63, - 63, 26, 27, 28, 63, 29, 30, 31, - 63, 11, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 16, - 17, 18, 19, 20, 63, 66, 16, 63, - 63, 63, 26, 27, 28, 63, 29, 30, - 31, 63, 11, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 16, 17, 18, 19, 20, 63, 63, 16, - 63, 63, 63, 26, 27, 28, 63, 29, - 30, 31, 63, 11, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 16, 17, 18, 19, 20, 21, 22, - 16, 63, 63, 63, 26, 27, 28, 63, - 29, 30, 31, 63, 11, 63, 63, 3, - 6, 63, 63, 64, 63, 63, 63, 63, - 63, 63, 16, 17, 18, 19, 20, 21, - 22, 16, 23, 63, 25, 26, 27, 28, - 63, 29, 30, 31, 63, 3, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 4, 67, 6, 67, 8, - 63, 63, 63, 8, 63, 63, 11, 63, - 63, 3, 6, 63, 63, 64, 63, 63, - 63, 63, 63, 63, 16, 17, 18, 19, - 20, 21, 22, 16, 23, 24, 25, 26, - 27, 28, 63, 29, 30, 31, 63, 11, - 63, 63, 3, 6, 63, 63, 64, 63, - 63, 63, 63, 63, 63, 16, 17, 18, + 23, 25, 25, 26, 27, 28, 65, 29, + 30, 31, 65, 65, 65, 65, 33, 65, + 11, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 16, 17, + 18, 19, 20, 65, 65, 65, 65, 65, + 65, 26, 27, 28, 65, 29, 30, 31, + 65, 65, 65, 65, 17, 65, 11, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 17, 18, 19, + 20, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 29, 30, 31, 65, 11, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 18, + 19, 20, 65, 11, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 19, 20, 65, 11, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 20, 65, 11, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 18, 19, 20, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 29, 30, 31, 65, 11, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 18, 19, 20, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 30, 31, 65, 11, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 18, 19, 20, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 31, 65, 11, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 17, 18, 19, + 20, 65, 65, 65, 65, 65, 65, 26, + 27, 28, 65, 29, 30, 31, 65, 65, + 65, 65, 17, 65, 11, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 17, 18, 19, 20, 65, + 65, 65, 65, 65, 65, 65, 27, 28, + 65, 29, 30, 31, 65, 65, 65, 65, + 17, 65, 11, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 17, 18, 19, 20, 65, 65, 65, + 65, 65, 65, 65, 65, 28, 65, 29, + 30, 31, 65, 65, 65, 65, 17, 65, + 11, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 16, 17, + 18, 19, 20, 65, 22, 16, 65, 65, + 65, 26, 27, 28, 65, 29, 30, 31, + 65, 65, 65, 65, 17, 65, 11, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 16, 17, 18, 19, + 20, 65, 68, 16, 65, 65, 65, 26, + 27, 28, 65, 29, 30, 31, 65, 65, + 65, 65, 17, 65, 11, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 16, 17, 18, 19, 20, 65, + 65, 16, 65, 65, 65, 26, 27, 28, + 65, 29, 30, 31, 65, 65, 65, 65, + 17, 65, 11, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 16, 17, 18, 19, 20, 21, 22, 16, + 65, 65, 65, 26, 27, 28, 65, 29, + 30, 31, 65, 65, 65, 65, 17, 65, + 11, 65, 65, 3, 6, 65, 65, 66, + 65, 65, 65, 65, 65, 65, 16, 17, + 18, 19, 20, 21, 22, 16, 23, 65, + 25, 26, 27, 28, 65, 29, 30, 31, + 65, 65, 65, 65, 33, 65, 3, 65, + 65, 65, 65, 65, 65, 11, 65, 65, + 65, 65, 65, 65, 4, 65, 65, 65, + 65, 65, 65, 65, 17, 18, 19, 20, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 29, 30, 31, 65, 3, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 4, 69, 6, 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, 69, 69, 69, 69, 69, 6, 69, + 8, 65, 65, 65, 8, 65, 65, 11, + 65, 65, 3, 6, 65, 65, 66, 65, + 65, 65, 65, 65, 65, 16, 17, 18, 19, 20, 21, 22, 16, 23, 24, 25, - 26, 27, 28, 63, 29, 30, 31, 63, - 69, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 69, 70, 68, 69, - 70, 68, 70, 68, 8, 67, 67, 67, - 8, 67, 0 + 26, 27, 28, 65, 29, 30, 31, 65, + 65, 65, 65, 33, 65, 11, 65, 65, + 3, 6, 65, 65, 66, 65, 65, 65, + 65, 65, 65, 16, 17, 18, 19, 20, + 21, 22, 16, 23, 24, 25, 26, 27, + 28, 65, 29, 30, 31, 65, 65, 65, + 65, 33, 65, 71, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 71, + 72, 70, 71, 72, 70, 72, 70, 8, + 69, 69, 69, 8, 69, 0 }; static const char _use_syllable_machine_trans_targs[] = { - 4, 8, 4, 31, 2, 4, 1, 5, - 6, 4, 28, 4, 49, 50, 51, 53, - 33, 34, 35, 36, 37, 44, 45, 47, - 52, 48, 41, 42, 43, 38, 39, 40, - 56, 4, 4, 4, 4, 7, 0, 27, - 11, 12, 13, 14, 15, 22, 23, 25, - 26, 19, 20, 21, 16, 17, 18, 10, - 4, 9, 24, 4, 29, 30, 4, 4, - 3, 32, 46, 4, 4, 54, 55 + 4, 8, 4, 32, 2, 4, 1, 5, + 6, 4, 29, 4, 51, 52, 53, 55, + 34, 35, 36, 37, 38, 45, 46, 48, + 54, 49, 42, 43, 44, 39, 40, 41, + 58, 50, 4, 4, 4, 4, 7, 0, + 28, 11, 12, 13, 14, 15, 22, 23, + 25, 26, 19, 20, 21, 16, 17, 18, + 27, 10, 4, 9, 24, 4, 30, 31, + 4, 4, 3, 33, 47, 4, 4, 56, + 57 }; static const char _use_syllable_machine_trans_actions[] = { @@ -264,11 +303,12 @@ static const char _use_syllable_machine_trans_actions[] = { 7, 8, 0, 9, 10, 10, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, - 0, 11, 12, 13, 14, 7, 0, 7, - 0, 0, 0, 0, 0, 0, 0, 0, - 7, 0, 0, 0, 0, 0, 0, 7, - 15, 0, 0, 16, 0, 0, 17, 18, - 0, 3, 0, 19, 20, 0, 0 + 0, 3, 11, 12, 13, 14, 7, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 7, 0, 0, 0, 0, 0, 0, + 0, 7, 15, 0, 0, 16, 0, 0, + 17, 18, 0, 3, 0, 19, 20, 0, + 0 }; static const char _use_syllable_machine_to_state_actions[] = { @@ -279,7 +319,7 @@ static const char _use_syllable_machine_to_state_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0 + 0, 0, 0 }; static const char _use_syllable_machine_from_state_actions[] = { @@ -290,18 +330,18 @@ static const char _use_syllable_machine_from_state_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0 + 0, 0, 0 }; static const short _use_syllable_machine_eof_trans[] = { - 1, 3, 3, 6, 0, 34, 36, 36, - 57, 57, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 60, 63, 60, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 68, 68, 64, 64, 69, 69, 69, - 68 + 1, 3, 3, 6, 0, 35, 37, 37, + 59, 59, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 59, 37, 62, 65, 62, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 70, 70, 66, 66, 71, + 71, 71, 70 }; static const int use_syllable_machine_start = 4; @@ -315,15 +355,14 @@ static const int use_syllable_machine_en_main = 4; -#line 141 "hb-ot-shape-complex-use-machine.rl" +#line 143 "hb-ot-shape-complex-use-machine.rl" #define found_syllable(syllable_type) \ HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \ - for (unsigned int i = last; i < p+1; i++) \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ + for (unsigned int i = ts; i < te; i++) \ info[i].syllable() = (syllable_serial << 4) | syllable_type; \ - last = p+1; \ syllable_serial++; \ if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ } HB_STMT_END @@ -331,11 +370,11 @@ 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, act; + unsigned int p, pe, eof, ts, te, act; int cs; hb_glyph_info_t *info = buffer->info; -#line 339 "hb-ot-shape-complex-use-machine.hh" +#line 378 "hb-ot-shape-complex-use-machine.hh" { cs = use_syllable_machine_start; ts = 0; @@ -343,16 +382,15 @@ find_syllables (hb_buffer_t *buffer) act = 0; } -#line 162 "hb-ot-shape-complex-use-machine.rl" +#line 163 "hb-ot-shape-complex-use-machine.rl" p = 0; pe = eof = buffer->len; - unsigned int last = 0; unsigned int syllable_serial = 1; -#line 356 "hb-ot-shape-complex-use-machine.hh" +#line 394 "hb-ot-shape-complex-use-machine.hh" { int _slen; int _trans; @@ -366,7 +404,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 370 "hb-ot-shape-complex-use-machine.hh" +#line 408 "hb-ot-shape-complex-use-machine.hh" } _keys = _use_syllable_machine_trans_keys + (cs<<1); @@ -389,59 +427,59 @@ _eof_trans: {te = p+1;} break; case 12: -#line 130 "hb-ot-shape-complex-use-machine.rl" +#line 132 "hb-ot-shape-complex-use-machine.rl" {te = p+1;{ found_syllable (independent_cluster); }} break; case 14: -#line 132 "hb-ot-shape-complex-use-machine.rl" +#line 134 "hb-ot-shape-complex-use-machine.rl" {te = p+1;{ found_syllable (standard_cluster); }} break; case 9: -#line 136 "hb-ot-shape-complex-use-machine.rl" +#line 138 "hb-ot-shape-complex-use-machine.rl" {te = p+1;{ found_syllable (broken_cluster); }} break; case 8: -#line 137 "hb-ot-shape-complex-use-machine.rl" +#line 139 "hb-ot-shape-complex-use-machine.rl" {te = p+1;{ found_syllable (non_cluster); }} break; case 11: -#line 130 "hb-ot-shape-complex-use-machine.rl" +#line 132 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (independent_cluster); }} break; case 15: -#line 131 "hb-ot-shape-complex-use-machine.rl" +#line 133 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (virama_terminated_cluster); }} break; case 13: -#line 132 "hb-ot-shape-complex-use-machine.rl" +#line 134 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (standard_cluster); }} break; case 17: -#line 133 "hb-ot-shape-complex-use-machine.rl" +#line 135 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (number_joiner_terminated_cluster); }} break; case 16: -#line 134 "hb-ot-shape-complex-use-machine.rl" +#line 136 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (numeral_cluster); }} break; case 20: -#line 135 "hb-ot-shape-complex-use-machine.rl" +#line 137 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (symbol_cluster); }} break; case 18: -#line 136 "hb-ot-shape-complex-use-machine.rl" +#line 138 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (broken_cluster); }} break; case 19: -#line 137 "hb-ot-shape-complex-use-machine.rl" +#line 139 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (non_cluster); }} break; case 1: -#line 132 "hb-ot-shape-complex-use-machine.rl" +#line 134 "hb-ot-shape-complex-use-machine.rl" {{p = ((te))-1;}{ found_syllable (standard_cluster); }} break; case 4: -#line 136 "hb-ot-shape-complex-use-machine.rl" +#line 138 "hb-ot-shape-complex-use-machine.rl" {{p = ((te))-1;}{ found_syllable (broken_cluster); }} break; case 2: @@ -459,16 +497,16 @@ _eof_trans: case 3: #line 1 "NONE" {te = p+1;} -#line 136 "hb-ot-shape-complex-use-machine.rl" +#line 138 "hb-ot-shape-complex-use-machine.rl" {act = 7;} break; case 10: #line 1 "NONE" {te = p+1;} -#line 137 "hb-ot-shape-complex-use-machine.rl" +#line 139 "hb-ot-shape-complex-use-machine.rl" {act = 8;} break; -#line 472 "hb-ot-shape-complex-use-machine.hh" +#line 510 "hb-ot-shape-complex-use-machine.hh" } _again: @@ -477,7 +515,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 481 "hb-ot-shape-complex-use-machine.hh" +#line 519 "hb-ot-shape-complex-use-machine.hh" } if ( ++p != pe ) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.rl b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.rl index a233b1200c1..7702cd94de9 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.rl +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.rl @@ -88,22 +88,19 @@ SMAbv = 41; # SYM_MOD_ABOVE SMBlw = 42; # SYM_MOD_BELOW CS = 43; # CONS_WITH_STACKER +HVM = 44; # HALANT_OR_VOWEL_MODIFIER + +h = H | HVM; # https://github.com/harfbuzz/harfbuzz/issues/1102 # 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*)*; +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?; dependent_vowels = VPre* VAbv* VBlw* VPst*; -vowel_modifiers = VMPre* VMAbv* VMBlw* VMPst*; +vowel_modifiers = HVM? VMPre* VMAbv* VMBlw* VMPst*; final_consonants = FAbv* FBlw* FPst* FM?; -virama_terminated_cluster = - (R|CS)? (B | GB) VS? - consonant_modifiers - ZWJ?.H.ZWJ? -; -standard_cluster = - (R|CS)? (B | GB) VS? +complex_syllable_tail = consonant_modifiers medial_consonants dependent_vowels @@ -111,13 +108,18 @@ standard_cluster = final_consonants ; +virama_terminated_cluster = + (R|CS)? (B | GB) VS? + consonant_modifiers + ZWJ?.h.ZWJ? +; +standard_cluster = + (R|CS)? (B | GB) VS? + complex_syllable_tail +; broken_cluster = R? - consonant_modifiers - medial_consonants - dependent_vowels - vowel_modifiers - final_consonants + complex_syllable_tail ; number_joiner_terminated_cluster = N VS? (HN N VS?)* HN; @@ -142,10 +144,9 @@ main := |* #define found_syllable(syllable_type) \ HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \ - for (unsigned int i = last; i < p+1; i++) \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ + for (unsigned int i = ts; i < te; i++) \ info[i].syllable() = (syllable_serial << 4) | syllable_type; \ - last = p+1; \ syllable_serial++; \ if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ } HB_STMT_END @@ -153,7 +154,7 @@ main := |* static void find_syllables (hb_buffer_t *buffer) { - unsigned int p, pe, eof, ts HB_UNUSED, te, act; + unsigned int p, pe, eof, ts, te, act; int cs; hb_glyph_info_t *info = buffer->info; %%{ @@ -164,7 +165,6 @@ find_syllables (hb_buffer_t *buffer) p = 0; pe = eof = buffer->len; - unsigned int last = 0; unsigned int syllable_serial = 1; %%{ write exec; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc index 4862b7fe943..e9c88aec4c4 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc @@ -24,6 +24,7 @@ #define GB USE_GB /* BASE_OTHER */ #define H USE_H /* HALANT */ #define HN USE_HN /* HALANT_NUM */ +#define HVM USE_HVM /* HALANT_OR_VOWEL_MODIFIER */ #define IND USE_IND /* BASE_IND */ #define N USE_N /* BASE_NUM */ #define O USE_O /* OTHER */ @@ -101,7 +102,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 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, + /* 09C0 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, O, O, VPst, VPst, 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, FM, O, @@ -134,7 +135,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 0B10 */ B, O, O, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0B20 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, /* 0B30 */ B, O, B, B, O, B, B, B, B, B, O, O, CMBlw, B, VPst, VAbv, - /* 0B40 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, O, O, VPre, VPre, H, O, O, + /* 0B40 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPst, O, O, VPst, VPst, H, O, O, /* 0B50 */ O, O, O, O, O, O, VAbv, VAbv, O, O, O, O, B, B, O, B, /* 0B60 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, /* 0B70 */ O, B, O, O, O, O, O, O, O, O, O, O, O, O, O, O, @@ -145,7 +146,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 0B90 */ B, O, B, B, B, B, O, O, O, B, B, O, B, O, B, B, /* 0BA0 */ O, O, O, B, B, O, O, O, B, B, B, O, O, O, B, B, /* 0BB0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, VPst, VPst, - /* 0BC0 */ VAbv, VPst, VPst, O, O, O, VPre, VPre, VPre, O, VPre, VPre, VPre, H, O, O, + /* 0BC0 */ VAbv, VPst, VPst, O, O, O, VPre, VPre, VPre, O, VPst, VPst, VPst, H, O, O, /* 0BD0 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, O, O, /* 0BE0 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B, /* 0BF0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, @@ -178,7 +179,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 0D10 */ B, O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0D20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0D30 */ B, B, B, B, B, B, B, B, B, B, B, VAbv, VAbv, B, VPst, VPst, - /* 0D40 */ VPst, VPst, VPst, VBlw, VBlw, O, VPre, VPre, VPre, O, VPre, VPre, VPre, H, R, O, + /* 0D40 */ VPst, VPst, VPst, VBlw, VBlw, O, VPre, VPre, VPre, O, VPst, VPst, VPst, H, R, O, /* 0D50 */ O, O, O, O, IND, IND, IND, VPst, O, O, O, O, O, O, O, B, /* 0D60 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, /* 0D70 */ O, O, O, O, O, O, O, O, O, O, IND, IND, IND, IND, IND, IND, @@ -190,11 +191,28 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 0DA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0DB0 */ B, B, O, B, B, B, B, B, B, B, B, B, O, B, O, O, /* 0DC0 */ B, B, B, B, B, B, B, O, O, O, H, O, O, O, O, VPst, - /* 0DD0 */ VPst, VPst, VAbv, VAbv, VBlw, O, VBlw, O, VPst, VPre, VPre, VPre, VPre, VPre, VPre, VPst, + /* 0DD0 */ VPst, VPst, VAbv, VAbv, VBlw, O, VBlw, O, VPst, VPre, VPst, VPre, VPst, VPst, VPst, VPst, /* 0DE0 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B, /* 0DF0 */ O, O, VPst, VPst, O, O, O, O, -#define use_offset_0x1000u 1360 +#define use_offset_0x0f18u 1360 + + + /* Tibetan */ + VBlw, VBlw, O, O, O, O, O, O, + /* 0F20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 0F30 */ B, B, B, B, O, FM, O, FM, O, CMAbv, O, O, O, O, VPst, VPre, + /* 0F40 */ B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, B, + /* 0F50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 0F60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, + /* 0F70 */ O, VBlw, VBlw, VAbv, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VMAbv, VMPst, + /* 0F80 */ VBlw, VAbv, VMAbv, VMAbv, VBlw, IND, VMAbv, VMAbv, B, B, B, B, B, SUB, SUB, SUB, + /* 0F90 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, SUB, SUB, SUB, SUB, SUB, SUB, SUB, + /* 0FA0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, + /* 0FB0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, O, O, + /* 0FC0 */ O, O, O, O, O, O, FM, O, + +#define use_offset_0x1000u 1536 /* Myanmar */ @@ -210,7 +228,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 1080 */ B, B, MBlw, VPst, VPre, VAbv, VAbv, VMPst, VMPst, VMPst, VMPst, VMPst, VMPst, VMBlw, B, VMPst, /* 1090 */ B, B, B, B, B, B, B, B, B, B, VMPst, VMPst, VPst, VAbv, O, O, -#define use_offset_0x1700u 1520 +#define use_offset_0x1700u 1696 /* Tagalog */ @@ -238,12 +256,12 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 1780 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1790 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 17A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 17B0 */ B, B, B, B, O, O, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VPre, VPre, - /* 17C0 */ VPre, VPre, VPre, VPre, VPre, VPre, VMAbv, VMPst, VPst, VMAbv, VMAbv, FM, FAbv, CMAbv, FM, FM, + /* 17B0 */ B, B, B, B, O, O, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VPst, VPst, + /* 17C0 */ VPst, VPre, VPre, VPre, VPst, VPst, VMAbv, VMPst, VPst, VMAbv, VMAbv, FM, FAbv, CMAbv, FM, FM, /* 17D0 */ FM, VAbv, H, FM, O, O, O, O, O, O, O, O, B, VAbv, O, O, /* 17E0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, -#define use_offset_0x1900u 1760 +#define use_offset_0x1900u 1936 /* Limbu */ @@ -287,7 +305,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 1A80 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* 1A90 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, -#define use_offset_0x1b00u 2176 +#define use_offset_0x1b00u 2352 /* Balinese */ @@ -296,7 +314,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 1B10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1B30 */ B, B, B, B, CMAbv, VPst, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VPre, - /* 1B40 */ VPre, VPre, VAbv, VAbv, H, B, B, B, B, B, B, B, O, O, O, O, + /* 1B40 */ VPst, VPst, VAbv, VAbv, H, B, B, B, B, B, B, B, O, O, O, O, /* 1B50 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* 1B60 */ O, O, O, O, O, O, O, O, O, O, O, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv, /* 1B70 */ SMAbv, SMAbv, SMAbv, SMAbv, O, O, O, O, O, O, O, O, O, O, O, O, @@ -319,11 +337,11 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 1C00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1C10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1C20 */ B, B, B, B, SUB, SUB, VPst, VPre, VPre, VPre, VPst, VPst, VBlw, FAbv, FAbv, FAbv, + /* 1C20 */ B, B, B, B, SUB, SUB, VPst, VPre, VPre, VPst, VPst, VPst, VBlw, FAbv, FAbv, FAbv, /* 1C30 */ FAbv, FAbv, FAbv, FAbv, VMPre, VMPre, FM, CMBlw, O, O, O, O, O, O, O, O, /* 1C40 */ B, B, B, B, B, B, B, B, B, B, O, O, O, B, B, B, -#define use_offset_0x1cd0u 2512 +#define use_offset_0x1cd0u 2688 /* Vedic Extensions */ @@ -332,20 +350,20 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 1CE0 */ VMAbv, VMPst, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, O, O, O, O, VMBlw, O, O, /* 1CF0 */ O, O, VMPst, VMPst, VMAbv, CS, CS, VMPst, VMAbv, VMAbv, O, O, O, O, O, O, -#define use_offset_0x1df8u 2560 +#define use_offset_0x1df8u 2736 /* Combining Diacritical Marks Supplement */ O, O, O, FM, O, O, O, O, -#define use_offset_0x2008u 2568 +#define use_offset_0x2008u 2744 /* General Punctuation */ O, O, O, O, ZWNJ, ZWJ, O, O, /* 2010 */ GB, GB, GB, GB, GB, O, O, O, -#define use_offset_0x2060u 2584 +#define use_offset_0x2060u 2760 /* 2060 */ WJ, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, @@ -354,20 +372,20 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 2070 */ O, O, O, O, FM, O, O, O, O, O, O, O, O, O, O, O, /* 2080 */ O, O, FM, FM, FM, O, O, O, -#define use_offset_0x20f0u 2624 +#define use_offset_0x20f0u 2800 /* Combining Diacritical Marks for Symbols */ /* 20F0 */ VMAbv, O, O, O, O, O, O, O, -#define use_offset_0x25c8u 2632 +#define use_offset_0x25c8u 2808 /* Geometric Shapes */ O, O, O, O, GB, O, O, O, -#define use_offset_0xa800u 2640 +#define use_offset_0xa800u 2816 /* Syloti Nagri */ @@ -454,7 +472,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* AAE0 */ B, B, B, B, B, B, B, B, B, B, B, VPre, VBlw, VAbv, VPre, VPst, /* AAF0 */ O, O, O, O, O, VMPst, H, O, -#define use_offset_0xabc0u 3400 +#define use_offset_0xabc0u 3576 /* Meetei Mayek */ @@ -464,14 +482,14 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* ABE0 */ B, B, B, VPst, VPst, VAbv, VPst, VPst, VBlw, VPst, VPst, O, VMPst, VBlw, O, O, /* ABF0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, -#define use_offset_0xfe00u 3464 +#define use_offset_0xfe00u 3640 /* Variation Selectors */ /* FE00 */ VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, -#define use_offset_0x10a00u 3480 +#define use_offset_0x10a00u 3656 /* Kharoshthi */ @@ -482,7 +500,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 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 3560 +#define use_offset_0x11000u 3736 /* Brahmi */ @@ -491,7 +509,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11010 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11020 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11030 */ B, B, B, B, B, B, B, B, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, - /* 11040 */ VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, H, O, O, O, O, O, O, O, O, O, + /* 11040 */ VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, HVM, O, O, O, O, O, O, O, O, O, /* 11050 */ O, O, N, N, N, N, N, N, N, N, N, N, N, N, N, N, /* 11060 */ N, N, N, N, N, N, B, B, B, B, B, B, B, B, B, B, /* 11070 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, HN, @@ -503,7 +521,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 3752 +#define use_offset_0x11100u 3928 /* Chakma */ @@ -511,7 +529,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11100 */ VMAbv, VMAbv, VMAbv, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11110 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11120 */ B, B, B, B, B, B, B, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VBlw, VAbv, VAbv, - /* 11130 */ VBlw, VAbv, VAbv, H, CMAbv, O, B, B, B, B, B, B, B, B, B, B, + /* 11130 */ VBlw, VAbv, VAbv, H, CMBlw, O, B, B, B, B, B, B, B, B, B, B, /* 11140 */ O, O, O, O, B, VPst, VPst, O, O, O, O, O, O, O, O, O, /* Mahajani */ @@ -541,7 +559,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 4072 +#define use_offset_0x11280u 4248 /* Multani */ @@ -564,12 +582,12 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 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, CMBlw, CMBlw, B, VPst, VPst, - /* 11340 */ VAbv, VPst, VPst, VPst, VPst, O, O, VPre, VPre, O, O, VPre, VPre, H, O, O, + /* 11340 */ VAbv, VPst, VPst, VPst, VPst, O, O, VPre, VPre, O, O, VPst, VPst, 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 4320 +#define use_offset_0x11400u 4496 /* Newa */ @@ -588,11 +606,11 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11480 */ O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11490 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 114A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 114B0 */ VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VPre, VAbv, VPre, VPre, VPst, VPre, VMAbv, + /* 114B0 */ VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VPre, VAbv, VPst, VPst, VPst, VPst, VMAbv, /* 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 4544 +#define use_offset_0x11580u 4720 /* Siddham */ @@ -600,7 +618,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11580 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11590 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 115A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, VPst, - /* 115B0 */ VPre, VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, VPre, VPre, VMAbv, VMAbv, VMPst, H, + /* 115B0 */ VPre, VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPst, VPst, VPst, VMAbv, VMAbv, VMPst, H, /* 115C0 */ CMBlw, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* 115D0 */ O, O, O, O, O, O, O, O, B, B, B, B, VBlw, VBlw, O, O, /* 115E0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, @@ -635,7 +653,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 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_0x11800u 4992 +#define use_offset_0x11800u 5168 /* Dogra */ @@ -645,7 +663,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 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 +#define use_offset_0x11a00u 5232 /* Zanabazar Square */ @@ -664,7 +682,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 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, B, O, O, -#define use_offset_0x11c00u 5216 +#define use_offset_0x11c00u 5392 /* Bhaiksuki */ @@ -685,7 +703,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 5400 +#define use_offset_0x11d00u 5576 /* Masaram Gondi */ @@ -705,7 +723,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 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 +#define use_offset_0x11ee0u 5752 /* Makasar */ @@ -713,7 +731,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 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% */ +}; /* Table items: 5776; occupancy: 74% */ USE_TABLE_ELEMENT_TYPE hb_use_get_category (hb_codepoint_t u) @@ -725,6 +743,7 @@ hb_use_get_category (hb_codepoint_t u) if (hb_in_range<hb_codepoint_t> (u, 0x00A0u, 0x00D7u)) return use_table[u - 0x00A0u + use_offset_0x00a0u]; if (hb_in_range<hb_codepoint_t> (u, 0x0348u, 0x034Fu)) return use_table[u - 0x0348u + use_offset_0x0348u]; if (hb_in_range<hb_codepoint_t> (u, 0x0900u, 0x0DF7u)) return use_table[u - 0x0900u + use_offset_0x0900u]; + if (hb_in_range<hb_codepoint_t> (u, 0x0F18u, 0x0FC7u)) return use_table[u - 0x0F18u + use_offset_0x0f18u]; break; case 0x1u: @@ -782,6 +801,7 @@ hb_use_get_category (hb_codepoint_t u) #undef GB #undef H #undef HN +#undef HVM #undef IND #undef N #undef O diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc index 676b15b6e9c..f9a580ca207 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc @@ -86,7 +86,14 @@ other_features[] = HB_TAG('h','a','l','n'), HB_TAG('p','r','e','s'), HB_TAG('p','s','t','s'), - /* Positioning features, though we don't care about the types. */ +}; +static const hb_tag_t +positioning_features[] = +{ + /* + * Positioning features. + * We don't care about the types. + */ HB_TAG('d','i','s','t'), HB_TAG('a','b','v','m'), HB_TAG('b','l','w','m'), @@ -122,33 +129,37 @@ collect_features_use (hb_ot_shape_planner_t *plan) map->add_gsub_pause (setup_syllables); /* "Default glyph pre-processing group" */ - map->add_global_bool_feature (HB_TAG('l','o','c','l')); - map->add_global_bool_feature (HB_TAG('c','c','m','p')); - map->add_global_bool_feature (HB_TAG('n','u','k','t')); - map->add_global_bool_feature (HB_TAG('a','k','h','n')); + map->enable_feature (HB_TAG('l','o','c','l')); + map->enable_feature (HB_TAG('c','c','m','p')); + map->enable_feature (HB_TAG('n','u','k','t')); + map->enable_feature (HB_TAG('a','k','h','n'), F_MANUAL_ZWJ); /* "Reordering group" */ map->add_gsub_pause (clear_substitution_flags); - map->add_feature (HB_TAG('r','p','h','f'), 1, F_MANUAL_ZWJ); + map->add_feature (HB_TAG('r','p','h','f'), F_MANUAL_ZWJ); map->add_gsub_pause (record_rphf); map->add_gsub_pause (clear_substitution_flags); - map->add_feature (HB_TAG('p','r','e','f'), 1, F_GLOBAL | F_MANUAL_ZWJ); + map->enable_feature (HB_TAG('p','r','e','f'), F_MANUAL_ZWJ); map->add_gsub_pause (record_pref); /* "Orthographic unit shaping group" */ for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++) - map->add_feature (basic_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ); + map->enable_feature (basic_features[i], F_MANUAL_ZWJ); map->add_gsub_pause (reorder); /* "Topographical features" */ for (unsigned int i = 0; i < ARRAY_LENGTH (arabic_features); i++) - map->add_feature (arabic_features[i], 1, F_NONE); + map->add_feature (arabic_features[i]); map->add_gsub_pause (nullptr); - /* "Standard typographic presentation" and "Positional feature application" */ + /* "Standard typographic presentation" */ for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++) - map->add_feature (other_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ); + map->enable_feature (other_features[i], F_MANUAL_ZWJ); + + /* "Positional feature application" */ + for (unsigned int i = 0; i < ARRAY_LENGTH (positioning_features); i++) + map->enable_feature (positioning_features[i]); } struct use_shape_plan_t @@ -586,7 +597,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_use = nullptr, /* decompose */ compose_use, setup_masks_use, - nullptr, /* disable_otl */ + HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY, false, /* fallback_position */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.hh index b8123e7914c..ab56e1b8f1d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.hh @@ -88,7 +88,10 @@ enum use_category_t { USE_VMPre = 23, /* VOWEL_MOD_PRE */ USE_SMAbv = 41, /* SYM_MOD_ABOVE */ USE_SMBlw = 42, /* SYM_MOD_BELOW */ - USE_CS = 43 /* CONS_WITH_STACKER */ + USE_CS = 43, /* CONS_WITH_STACKER */ + + /* https://github.com/harfbuzz/harfbuzz/issues/1102 */ + USE_HVM = 44, /* HALANT_OR_VOWEL_MODIFIER */ }; HB_INTERNAL USE_TABLE_ELEMENT_TYPE diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex.hh index a48a38a2015..2944d745c26 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex.hh @@ -29,11 +29,11 @@ #include "hb.hh" +#include "hb-ot-layout.hh" #include "hb-ot-shape.hh" #include "hb-ot-shape-normalize.hh" - /* buffer var allocations, used by complex shapers */ #define complex_var_u8_0() var2.u8[2] #define complex_var_u8_1() var2.u8[3] @@ -58,8 +58,8 @@ enum hb_ot_shape_zero_width_marks_type_t { HB_COMPLEX_SHAPER_IMPLEMENT (khmer) \ HB_COMPLEX_SHAPER_IMPLEMENT (myanmar) \ HB_COMPLEX_SHAPER_IMPLEMENT (myanmar_old) \ + HB_COMPLEX_SHAPER_IMPLEMENT (myanmar_zawgyi) \ HB_COMPLEX_SHAPER_IMPLEMENT (thai) \ - HB_COMPLEX_SHAPER_IMPLEMENT (tibetan) \ HB_COMPLEX_SHAPER_IMPLEMENT (use) \ /* ^--- Add new shapers here */ @@ -69,7 +69,7 @@ struct hb_ot_complex_shaper_t /* collect_features() * Called during shape_plan(). * Shapers should use plan->map to add their features and callbacks. - * May be nullptr. + * May be NULL. */ void (*collect_features) (hb_ot_shape_planner_t *plan); @@ -77,7 +77,7 @@ struct hb_ot_complex_shaper_t * Called during shape_plan(). * Shapers should use plan->map to override features and add callbacks after * common features are added. - * May be nullptr. + * May be NULL. */ void (*override_features) (hb_ot_shape_planner_t *plan); @@ -93,7 +93,7 @@ struct hb_ot_complex_shaper_t * Called when the shape_plan is being destroyed. * plan->data is passed here for destruction. * If nullptr is returned, means a plan failure. - * May be nullptr. + * May be NULL. */ void (*data_destroy) (void *data); @@ -101,7 +101,7 @@ struct hb_ot_complex_shaper_t /* preprocess_text() * Called during shape(). * Shapers can use to modify text before shaping starts. - * May be nullptr. + * May be NULL. */ void (*preprocess_text) (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, @@ -110,7 +110,7 @@ struct hb_ot_complex_shaper_t /* postprocess_glyphs() * Called during shape(). * Shapers can use to modify glyphs after shaping ends. - * May be nullptr. + * May be NULL. */ void (*postprocess_glyphs) (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, @@ -121,7 +121,7 @@ struct hb_ot_complex_shaper_t /* decompose() * Called during shape()'s normalization. - * May be nullptr. + * May be NULL. */ bool (*decompose) (const hb_ot_shape_normalize_context_t *c, hb_codepoint_t ab, @@ -130,7 +130,7 @@ struct hb_ot_complex_shaper_t /* compose() * Called during shape()'s normalization. - * May be nullptr. + * May be NULL. */ bool (*compose) (const hb_ot_shape_normalize_context_t *c, hb_codepoint_t a, @@ -141,24 +141,22 @@ struct hb_ot_complex_shaper_t * Called during shape(). * Shapers should use map to get feature masks and set on buffer. * Shapers may NOT modify characters. - * May be nullptr. + * May be NULL. */ void (*setup_masks) (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, hb_font_t *font); - /* disable_otl() - * Called during shape(). - * If set and returns true, GDEF/GSUB/GPOS of the font are ignored - * and fallback operations used. - * May be nullptr. + /* gpos_tag() + * If not HB_TAG_NONE, then must match found GPOS script tag for + * GPOS to be applied. Otherwise, fallback positioning will be used. */ - bool (*disable_otl) (const hb_ot_shape_plan_t *plan); + hb_tag_t gpos_tag; /* reorder_marks() * Called during shape(). * Shapers can use to modify ordering of combining marks. - * May be nullptr. + * May be NULL. */ void (*reorder_marks) (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, @@ -234,25 +232,12 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) return &_hb_ot_complex_shaper_hangul; - /* Unicode-2.0 additions */ - case HB_SCRIPT_TIBETAN: - - return &_hb_ot_complex_shaper_tibetan; - - /* Unicode-1.1 additions */ case HB_SCRIPT_HEBREW: return &_hb_ot_complex_shaper_hebrew; - /* ^--- Add new shapers here */ - -#if 0 - /* Unicode-4.1 additions */ - case HB_SCRIPT_NEW_TAI_LUE: -#endif - /* Unicode-1.1 additions */ case HB_SCRIPT_BENGALI: case HB_SCRIPT_DEVANAGARI: @@ -270,11 +255,13 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) /* 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. - * Note that for some simple scripts, there may not be *any* - * GSUB/GPOS needed, so there may be no scripts found! */ + * + * If it's indy3 tag, send to USE. */ if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T') || planner->map.chosen_script[0] == HB_TAG ('l','a','t','n')) return &_hb_ot_complex_shaper_default; + else if ((planner->map.chosen_script[0] & 0x000000FF) == '3') + return &_hb_ot_complex_shaper_use; else return &_hb_ot_complex_shaper_indic; @@ -291,7 +278,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) /* Unicode-2.0 additions */ - //case HB_SCRIPT_TIBETAN: + case HB_SCRIPT_TIBETAN: /* Unicode-3.0 additions */ //case HB_SCRIPT_MONGOLIAN: @@ -359,9 +346,9 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) /* Unicode-8.0 additions */ case HB_SCRIPT_AHOM: - //case HB_SCRIPT_MULTANI: /* Unicode-9.0 additions */ + //case HB_SCRIPT_ADLAM: case HB_SCRIPT_BHAIKSUKI: case HB_SCRIPT_MARCHEN: case HB_SCRIPT_NEWA: @@ -374,7 +361,9 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) /* Unicode-11.0 additions */ case HB_SCRIPT_DOGRA: case HB_SCRIPT_GUNJALA_GONDI: + //case HB_SCRIPT_HANIFI_ROHINGYA: case HB_SCRIPT_MAKASAR: + //case HB_SCRIPT_SOGDIAN: /* If the designer designed the font for the 'DFLT' script, * (or we ended up arbitrarily pick 'latn'), use the default shaper. @@ -386,6 +375,10 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) return &_hb_ot_complex_shaper_default; else return &_hb_ot_complex_shaper_use; + + /* https://github.com/harfbuzz/harfbuzz/issues/1162 */ + case HB_SCRIPT_MYANMAR_ZAWGYI: + return &_hb_ot_complex_shaper_myanmar_zawgyi; } } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc index 5f43023bec1..4c5ccc97425 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc @@ -25,7 +25,7 @@ */ #include "hb-ot-shape-fallback.hh" -#include "hb-ot-layout-gsubgpos.hh" +#include "hb-ot-kern-table.hh" static unsigned int recategorize_combining_class (hb_codepoint_t u, @@ -162,9 +162,9 @@ recategorize_combining_class (hb_codepoint_t u, } void -_hb_ot_shape_fallback_position_recategorize_marks (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_font_t *font HB_UNUSED, - hb_buffer_t *buffer) +_hb_ot_shape_fallback_mark_position_recategorize_marks (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_font_t *font HB_UNUSED, + hb_buffer_t *buffer) { unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; @@ -417,9 +417,9 @@ position_cluster (const hb_ot_shape_plan_t *plan, } void -_hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer) +_hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) { _hb_buffer_assert_gsubgpos_vars (buffer); @@ -435,60 +435,38 @@ _hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan, } -/* Performs old-style TrueType kerning. */ -void -_hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer) +struct hb_ot_shape_fallback_kern_driver_t { - if (!plan->has_kern) return; + hb_ot_shape_fallback_kern_driver_t (hb_font_t *font_, + hb_buffer_t *buffer) : + font (font_), direction (buffer->props.direction) {} - OT::hb_ot_apply_context_t c (1, font, buffer); - c.set_lookup_mask (plan->kern_mask); - c.set_lookup_props (OT::LookupFlag::IgnoreMarks); - OT::hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c.iter_input; - skippy_iter.init (&c); - - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - hb_glyph_position_t *pos = buffer->pos; - for (unsigned int idx = 0; idx < count;) + hb_position_t get_kerning (hb_codepoint_t first, hb_codepoint_t second) const { - skippy_iter.reset (idx, 1); - if (!skippy_iter.next ()) - { - idx++; - continue; - } - - hb_position_t x_kern, y_kern; - font->get_glyph_kerning_for_direction (info[idx].codepoint, - info[skippy_iter.idx].codepoint, - buffer->props.direction, - &x_kern, &y_kern); - - if (x_kern) - { - hb_position_t kern1 = x_kern >> 1; - hb_position_t kern2 = x_kern - kern1; - pos[idx].x_advance += kern1; - pos[skippy_iter.idx].x_advance += kern2; - pos[skippy_iter.idx].x_offset += kern2; - buffer->unsafe_to_break (idx, skippy_iter.idx + 1); - } + hb_position_t kern = 0; + font->get_glyph_kerning_for_direction (first, second, + direction, + &kern, &kern); + return kern; + } - if (y_kern) - { - hb_position_t kern1 = y_kern >> 1; - hb_position_t kern2 = y_kern - kern1; - pos[idx].y_advance += kern1; - pos[skippy_iter.idx].y_advance += kern2; - pos[skippy_iter.idx].y_offset += kern2; - buffer->unsafe_to_break (idx, skippy_iter.idx + 1); - } + hb_font_t *font; + hb_direction_t direction; +}; - idx = skippy_iter.idx; - } +/* Performs font-assisted kerning. */ +void +_hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) +{ + if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction) ? + !font->has_glyph_h_kerning_func () : + !font->has_glyph_v_kerning_func ()) + return; + hb_ot_shape_fallback_kern_driver_t driver (font, buffer); + hb_kern_machine_t<hb_ot_shape_fallback_kern_driver_t> machine (driver); + machine.kern (font, buffer, plan->kern_mask, false); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.hh index 730e7f28068..12f18ed12f2 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.hh @@ -32,13 +32,13 @@ #include "hb-ot-shape.hh" -HB_INTERNAL void _hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer); +HB_INTERNAL void _hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); -HB_INTERNAL void _hb_ot_shape_fallback_position_recategorize_marks (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer); +HB_INTERNAL void _hb_ot_shape_fallback_mark_position_recategorize_marks (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); HB_INTERNAL void _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan, diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc index fd0b63aecd3..a8229a98d94 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc @@ -264,15 +264,6 @@ decompose_multi_char_cluster (const hb_ot_shape_normalize_context_t *c, unsigned decompose_current_character (c, short_circuit); } -static inline void -decompose_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end, bool might_short_circuit, bool always_short_circuit) -{ - if (likely (c->buffer->idx + 1 == end)) - decompose_current_character (c, might_short_circuit); - else - decompose_multi_char_cluster (c, end, always_short_circuit); -} - static int compare_combining_class (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb) @@ -294,6 +285,16 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, _hb_buffer_assert_unicode_vars (buffer); hb_ot_shape_normalization_mode_t mode = plan->shaper->normalization_preference; + if (mode == HB_OT_SHAPE_NORMALIZATION_MODE_AUTO) + { + if (plan->has_gpos_mark) + // https://github.com/harfbuzz/harfbuzz/issues/653#issuecomment-423905920 + //mode = HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED; + mode = HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS; + else + mode = HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS; + } + const hb_ot_shape_normalize_context_t c = { plan, buffer, @@ -318,105 +319,81 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, /* First round, decompose */ - buffer->clear_output (); - count = buffer->len; - for (buffer->idx = 0; buffer->idx < count && buffer->successful;) + bool all_simple = true; { - unsigned int end; - for (end = buffer->idx + 1; end < count; end++) - if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[end])))) - break; + buffer->clear_output (); + count = buffer->len; + buffer->idx = 0; + do + { + unsigned int end; + for (end = buffer->idx + 1; end < count; end++) + if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[end])))) + break; - decompose_cluster (&c, end, might_short_circuit, always_short_circuit); - } - buffer->swap_buffers (); + if (end < count) + end--; /* Leave one base for the marks to cluster with. */ + /* From idx to end are simple clusters. */ + if (might_short_circuit) + { + unsigned int done = font->get_nominal_glyphs (end - buffer->idx, + &buffer->cur().codepoint, + sizeof (buffer->info[0]), + &buffer->cur().glyph_index(), + sizeof (buffer->info[0])); + buffer->next_glyphs (done); + } + while (buffer->idx < end && buffer->successful) + decompose_current_character (&c, might_short_circuit); - /* Second round, reorder (inplace) */ + if (buffer->idx == count || !buffer->successful) + break; - count = buffer->len; - for (unsigned int i = 0; i < count; i++) - { - if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i]) == 0) - continue; + all_simple = false; - unsigned int end; - for (end = i + 1; end < count; end++) - if (_hb_glyph_info_get_modified_combining_class (&buffer->info[end]) == 0) - break; + /* Find all the marks now. */ + for (end = buffer->idx + 1; end < count; end++) + if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[end]))) + break; - /* We are going to do a O(n^2). Only do this if the sequence is short. */ - if (end - i > HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS) { - i = end; - continue; + /* idx to end is one non-simple cluster. */ + decompose_multi_char_cluster (&c, end, always_short_circuit); } - - buffer->sort (i, end, compare_combining_class); - - if (plan->shaper->reorder_marks) - plan->shaper->reorder_marks (plan, buffer, i, end); - - i = end; + while (buffer->idx < count && buffer->successful); + buffer->swap_buffers (); } - if (mode == HB_OT_SHAPE_NORMALIZATION_MODE_NONE || - mode == HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED) - return; - - /* Third round, recompose */ - - /* As noted in the comment earlier, we don't try to combine - * ccc=0 chars with their previous Starter. */ + /* Second round, reorder (inplace) */ - buffer->clear_output (); - count = buffer->len; - unsigned int starter = 0; - buffer->next_glyph (); - while (buffer->idx < count && buffer->successful) + if (!all_simple) { - hb_codepoint_t composed, glyph; - if (/* We don't try to compose a non-mark character with it's preceding starter. - * This is both an optimization to avoid trying to compose every two neighboring - * glyphs in most scripts AND a desired feature for Hangul. Apparently Hangul - * fonts are not designed to mix-and-match pre-composed syllables and Jamo. */ - HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->cur()))) + count = buffer->len; + for (unsigned int i = 0; i < count; i++) { - if (/* If there's anything between the starter and this char, they should have CCC - * smaller than this character's. */ - (starter == buffer->out_len - 1 || - info_cc (buffer->prev()) < info_cc (buffer->cur())) && - /* And compose. */ - c.compose (&c, - buffer->out_info[starter].codepoint, - buffer->cur().codepoint, - &composed) && - /* And the font has glyph for the composite. */ - font->get_nominal_glyph (composed, &glyph)) - { - /* Composes. */ - buffer->next_glyph (); /* Copy to out-buffer. */ - if (unlikely (!buffer->successful)) - return; - buffer->merge_out_clusters (starter, buffer->out_len); - buffer->out_len--; /* Remove the second composable. */ - /* Modify starter and carry on. */ - buffer->out_info[starter].codepoint = composed; - buffer->out_info[starter].glyph_index() = glyph; - _hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer); + if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i]) == 0) + continue; + + unsigned int end; + for (end = i + 1; end < count; end++) + if (_hb_glyph_info_get_modified_combining_class (&buffer->info[end]) == 0) + break; + /* We are going to do a O(n^2). Only do this if the sequence is short. */ + if (end - i > HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS) { + i = end; continue; } - } - /* Blocked, or doesn't compose. */ - buffer->next_glyph (); + buffer->sort (i, end, compare_combining_class); - if (info_cc (buffer->prev()) == 0) - starter = buffer->out_len - 1; - } - buffer->swap_buffers (); + if (plan->shaper->reorder_marks) + plan->shaper->reorder_marks (plan, buffer, i, end); + i = end; + } + } if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_CGJ) { /* For all CGJ, check if it prevented any reordering at all. @@ -430,4 +407,63 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, _hb_glyph_info_unhide (&buffer->info[i]); } } + + + /* Third round, recompose */ + + if (!all_simple && + (mode == HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS || + mode == HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT)) + { + /* As noted in the comment earlier, we don't try to combine + * ccc=0 chars with their previous Starter. */ + + buffer->clear_output (); + count = buffer->len; + unsigned int starter = 0; + buffer->next_glyph (); + 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. + * This is both an optimization to avoid trying to compose every two neighboring + * glyphs in most scripts AND a desired feature for Hangul. Apparently Hangul + * fonts are not designed to mix-and-match pre-composed syllables and Jamo. */ + HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->cur()))) + { + if (/* If there's anything between the starter and this char, they should have CCC + * smaller than this character's. */ + (starter == buffer->out_len - 1 || + info_cc (buffer->prev()) < info_cc (buffer->cur())) && + /* And compose. */ + c.compose (&c, + buffer->out_info[starter].codepoint, + buffer->cur().codepoint, + &composed) && + /* And the font has glyph for the composite. */ + font->get_nominal_glyph (composed, &glyph)) + { + /* Composes. */ + buffer->next_glyph (); /* Copy to out-buffer. */ + if (unlikely (!buffer->successful)) + return; + buffer->merge_out_clusters (starter, buffer->out_len); + buffer->out_len--; /* Remove the second composable. */ + /* Modify starter and carry on. */ + buffer->out_info[starter].codepoint = composed; + buffer->out_info[starter].glyph_index() = glyph; + _hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer); + + continue; + } + } + + /* Blocked, or doesn't compose. */ + buffer->next_glyph (); + + if (info_cc (buffer->prev()) == 0) + starter = buffer->out_len - 1; + } + buffer->swap_buffers (); + } } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.hh index 4aea640b165..04f1a800912 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.hh @@ -38,10 +38,11 @@ struct hb_ot_shape_plan_t; enum hb_ot_shape_normalization_mode_t { HB_OT_SHAPE_NORMALIZATION_MODE_NONE, HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED, - HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS, /* never composes base-to-base */ - HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, /* always fully decomposes and then recompose back */ + HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS, /* Never composes base-to-base */ + HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, /* Always fully decomposes and then recompose back */ - HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT = HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS + HB_OT_SHAPE_NORMALIZATION_MODE_AUTO, /* See hb-ot-shape-normalize.cc for logic. */ + HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT = HB_OT_SHAPE_NORMALIZATION_MODE_AUTO }; HB_INTERNAL void _hb_ot_shape_normalize (const hb_ot_shape_plan_t *shaper, diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc index 63102f6b0cf..a5538871bb8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc @@ -36,32 +36,111 @@ #include "hb-ot-shape-normalize.hh" #include "hb-ot-face.hh" -#include "hb-ot-layout.hh" -#include "hb-unicode.hh" + #include "hb-set.hh" -#include "hb-ot-layout-gsubgpos.hh" #include "hb-aat-layout.hh" -static hb_tag_t common_features[] = { - HB_TAG('c','c','m','p'), - HB_TAG('l','o','c','l'), - HB_TAG('m','a','r','k'), - HB_TAG('m','k','m','k'), - HB_TAG('r','l','i','g'), -}; +static bool +_hb_apply_morx (hb_face_t *face) +{ + if (hb_options ().aat && + hb_aat_layout_has_substitution (face)) + return true; + + return !hb_ot_layout_has_substitution (face) && + hb_aat_layout_has_substitution (face); +} + +void +hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, + const int *coords, + unsigned int num_coords) +{ + plan.props = props; + plan.shaper = shaper; + map.compile (plan.map, coords, num_coords); + + plan.rtlm_mask = plan.map.get_1_mask (HB_TAG ('r','t','l','m')); + plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c')); + plan.numr_mask = plan.map.get_1_mask (HB_TAG ('n','u','m','r')); + plan.dnom_mask = plan.map.get_1_mask (HB_TAG ('d','n','o','m')); + plan.has_frac = plan.frac_mask || (plan.numr_mask && plan.dnom_mask); + hb_tag_t kern_tag = HB_DIRECTION_IS_HORIZONTAL (plan.props.direction) ? + HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n'); + plan.kern_mask = plan.map.get_mask (kern_tag); + + plan.requested_kerning = !!plan.kern_mask; + bool has_gpos_kern = plan.map.get_feature_index (1, kern_tag) != HB_OT_LAYOUT_NO_FEATURE_INDEX; + bool disable_gpos = plan.shaper->gpos_tag && + plan.shaper->gpos_tag != plan.map.chosen_script[1]; + + /* + * Decide who provides glyph classes. GDEF or Unicode. + */ + + if (!hb_ot_layout_has_glyph_classes (face)) + plan.fallback_glyph_classes = true; + + /* + * Decide who does substitutions. GSUB, morx, or fallback. + */ + + plan.apply_morx = _hb_apply_morx (face); + + /* + * Decide who does positioning. GPOS, kerx, kern, or fallback. + */ + + if (hb_options ().aat && hb_aat_layout_has_positioning (face)) + plan.apply_kerx = true; + else if (!disable_gpos && hb_ot_layout_has_positioning (face)) + plan.apply_gpos = true; + else if (hb_aat_layout_has_positioning (face)) + plan.apply_kerx = true; -static hb_tag_t horizontal_features[] = { - HB_TAG('c','a','l','t'), - HB_TAG('c','l','i','g'), - HB_TAG('c','u','r','s'), - HB_TAG('k','e','r','n'), - HB_TAG('l','i','g','a'), - HB_TAG('r','c','l','t'), + if (plan.requested_kerning && !plan.apply_kerx && !has_gpos_kern) + { + /* Apparently Apple applies kerx if GPOS kern was not applied. */ + if (hb_aat_layout_has_positioning (face)) + plan.apply_kerx = true; + if (hb_ot_layout_has_kerning (face)) + plan.apply_kern = true; + else + plan.fallback_kerning = true; + } + + plan.has_gpos_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k')); + if (!plan.apply_gpos && !plan.apply_kerx) + plan.fallback_mark_positioning = true; + + /* Currently we always apply trak. */ + plan.apply_trak = hb_aat_layout_has_tracking (face); +} + + +static const hb_ot_map_feature_t +common_features[] = +{ + {HB_TAG('c','c','m','p'), F_GLOBAL}, + {HB_TAG('l','o','c','l'), F_GLOBAL}, + {HB_TAG('m','a','r','k'), F_GLOBAL_MANUAL_JOINERS}, + {HB_TAG('m','k','m','k'), F_GLOBAL_MANUAL_JOINERS}, + {HB_TAG('r','l','i','g'), F_GLOBAL}, }; +static const hb_ot_map_feature_t +horizontal_features[] = +{ + {HB_TAG('c','a','l','t'), F_GLOBAL}, + {HB_TAG('c','l','i','g'), F_GLOBAL}, + {HB_TAG('c','u','r','s'), F_GLOBAL}, + {HB_TAG('k','e','r','n'), F_GLOBAL_HAS_FALLBACK}, + {HB_TAG('l','i','g','a'), F_GLOBAL}, + {HB_TAG('r','c','l','t'), F_GLOBAL}, +}; static void hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, @@ -71,17 +150,17 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, { hb_ot_map_builder_t *map = &planner->map; - map->add_global_bool_feature (HB_TAG('r','v','r','n')); + map->enable_feature (HB_TAG('r','v','r','n')); map->add_gsub_pause (nullptr); switch (props->direction) { case HB_DIRECTION_LTR: - map->add_global_bool_feature (HB_TAG ('l','t','r','a')); - map->add_global_bool_feature (HB_TAG ('l','t','r','m')); + map->enable_feature (HB_TAG ('l','t','r','a')); + map->enable_feature (HB_TAG ('l','t','r','m')); break; case HB_DIRECTION_RTL: - map->add_global_bool_feature (HB_TAG ('r','t','l','a')); - map->add_feature (HB_TAG ('r','t','l','m'), 1, F_NONE); + map->enable_feature (HB_TAG ('r','t','l','a')); + map->add_feature (HB_TAG ('r','t','l','m')); break; case HB_DIRECTION_TTB: case HB_DIRECTION_BTT: @@ -90,38 +169,46 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, break; } - map->add_feature (HB_TAG ('f','r','a','c'), 1, F_NONE); - map->add_feature (HB_TAG ('n','u','m','r'), 1, F_NONE); - map->add_feature (HB_TAG ('d','n','o','m'), 1, F_NONE); + /* Automatic fractions. */ + map->add_feature (HB_TAG ('f','r','a','c')); + map->add_feature (HB_TAG ('n','u','m','r')); + map->add_feature (HB_TAG ('d','n','o','m')); + + /* Random! */ + map->enable_feature (HB_TAG ('r','a','n','d'), F_RANDOM, HB_OT_MAP_MAX_VALUE); + + map->enable_feature (HB_TAG('H','A','R','F')); if (planner->shaper->collect_features) planner->shaper->collect_features (planner); + map->enable_feature (HB_TAG('B','U','Z','Z')); + for (unsigned int i = 0; i < ARRAY_LENGTH (common_features); i++) - map->add_global_bool_feature (common_features[i]); + map->add_feature (common_features[i]); if (HB_DIRECTION_IS_HORIZONTAL (props->direction)) for (unsigned int i = 0; i < ARRAY_LENGTH (horizontal_features); i++) - map->add_feature (horizontal_features[i], 1, F_GLOBAL | - (horizontal_features[i] == HB_TAG('k','e','r','n') ? - F_HAS_FALLBACK : F_NONE)); + map->add_feature (horizontal_features[i]); else { /* We really want to find a 'vert' feature if there's any in the font, no * matter which script/langsys it is listed (or not) under. * See various bugs referenced from: * https://github.com/harfbuzz/harfbuzz/issues/63 */ - map->add_feature (HB_TAG ('v','e','r','t'), 1, F_GLOBAL | F_GLOBAL_SEARCH); + map->enable_feature (HB_TAG ('v','e','r','t'), F_GLOBAL_SEARCH); } if (planner->shaper->override_features) planner->shaper->override_features (planner); - for (unsigned int i = 0; i < num_user_features; i++) { + for (unsigned int i = 0; i < num_user_features; i++) + { const hb_feature_t *feature = &user_features[i]; - map->add_feature (feature->tag, feature->value, - (feature->start == 0 && feature->end == (unsigned int) -1) ? - F_GLOBAL : F_NONE); + map->add_feature (feature->tag, + (feature->start == HB_FEATURE_GLOBAL_START && + feature->end == HB_FEATURE_GLOBAL_END) ? F_GLOBAL : F_NONE, + feature->value); } } @@ -184,7 +271,12 @@ _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan, hb_ot_shape_planner_t planner (shape_plan); - planner.shaper = hb_ot_shape_complex_categorize (&planner); + /* Ugly that we have to do this here... + * If we are going to apply morx, choose default shaper. */ + if (_hb_apply_morx (planner.face)) + planner.shaper = &_hb_ot_complex_shaper_default; + else + planner.shaper = hb_ot_shape_complex_categorize (&planner); hb_ot_shape_collect_features (&planner, &shape_plan->props, user_features, num_user_features); @@ -229,8 +321,6 @@ struct hb_ot_shape_context_t unsigned int num_user_features; /* Transient stuff */ - bool fallback_positioning; - bool fallback_glyph_classes; hb_direction_t target_direction; }; @@ -244,10 +334,39 @@ struct hb_ot_shape_context_t static void hb_set_unicode_props (hb_buffer_t *buffer) { + /* Implement enough of Unicode Graphemes here that shaping + * in reverse-direction wouldn't break graphemes. Namely, + * we mark all marks and ZWJ and ZWJ,Extended_Pictographic + * sequences as continuations. The foreach_grapheme() + * macro uses this bit. + * + * https://www.unicode.org/reports/tr29/#Regex_Definitions + */ unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; for (unsigned int i = 0; i < count; i++) + { _hb_glyph_info_set_unicode_props (&info[i], buffer); + + /* Marks are already set as continuation by the above line. + * Handle Emoji_Modifier and ZWJ-continuation. */ + if (unlikely (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL && + hb_in_range<hb_codepoint_t> (info[i].codepoint, 0x1F3FBu, 0x1F3FFu))) + { + _hb_glyph_info_set_continuation (&info[i]); + } + else if (unlikely (_hb_glyph_info_is_zwj (&info[i]))) + { + _hb_glyph_info_set_continuation (&info[i]); + if (i + 1 < count && + _hb_unicode_is_emoji_Extended_Pictographic (info[i + 1].codepoint)) + { + i++; + _hb_glyph_info_set_unicode_props (&info[i], buffer); + _hb_glyph_info_set_continuation (&info[i]); + } + } + } } static void @@ -255,8 +374,7 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) { if (!(buffer->flags & HB_BUFFER_FLAG_BOT) || buffer->context_len[0] || - _hb_glyph_info_get_general_category (&buffer->info[0]) != - HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) + !_hb_glyph_info_is_unicode_mark (&buffer->info[0])) return; if (!font->has_glyph (0x25CCu)) @@ -285,26 +403,12 @@ hb_form_clusters (hb_buffer_t *buffer) if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII)) return; - /* Loop duplicated in hb_ensure_native_direction(), and in _hb-coretext.cc */ - unsigned int base = 0; - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 1; i < count; i++) - { - if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])) && - !_hb_glyph_info_is_joiner (&info[i]))) - { - if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) - buffer->merge_clusters (base, i); - else - buffer->unsafe_to_break (base, i); - base = i; - } - } if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) - buffer->merge_clusters (base, count); + foreach_grapheme (buffer, start, end) + buffer->merge_clusters (start, end); else - buffer->unsafe_to_break (base, count); + foreach_grapheme (buffer, start, end) + buffer->unsafe_to_break (start, end); } static void @@ -322,25 +426,17 @@ hb_ensure_native_direction (hb_buffer_t *buffer) (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. */ - unsigned int base = 0; - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 1; i < count; i++) - { - if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])))) - { - if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS) - buffer->merge_clusters (base, i); - buffer->reverse_range (base, i); - base = i; - } - } if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS) - buffer->merge_clusters (base, count); - buffer->reverse_range (base, count); + foreach_grapheme (buffer, start, end) + { + buffer->merge_clusters (start, end); + buffer->reverse_range (start, end); + } + else + foreach_grapheme (buffer, start, end) + /* form_clusters() merged clusters already, we don't merge. */ + buffer->reverse_range (start, end); buffer->reverse (); @@ -352,7 +448,7 @@ hb_ensure_native_direction (hb_buffer_t *buffer) /* Substitute */ static inline void -hb_ot_mirror_chars (hb_ot_shape_context_t *c) +hb_ot_mirror_chars (const hb_ot_shape_context_t *c) { if (HB_DIRECTION_IS_FORWARD (c->target_direction)) return; @@ -373,7 +469,7 @@ hb_ot_mirror_chars (hb_ot_shape_context_t *c) } static inline void -hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c) +hb_ot_shape_setup_masks_fraction (const hb_ot_shape_context_t *c) { if (!(c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII) || !c->plan->has_frac) @@ -423,7 +519,7 @@ hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c) } static inline void -hb_ot_shape_initialize_masks (hb_ot_shape_context_t *c) +hb_ot_shape_initialize_masks (const hb_ot_shape_context_t *c) { hb_ot_map_t *map = &c->plan->map; hb_buffer_t *buffer = c->buffer; @@ -433,7 +529,7 @@ hb_ot_shape_initialize_masks (hb_ot_shape_context_t *c) } static inline void -hb_ot_shape_setup_masks (hb_ot_shape_context_t *c) +hb_ot_shape_setup_masks (const hb_ot_shape_context_t *c) { hb_ot_map_t *map = &c->plan->map; hb_buffer_t *buffer = c->buffer; @@ -455,7 +551,7 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c) } static void -hb_ot_zero_width_default_ignorables (hb_ot_shape_context_t *c) +hb_ot_zero_width_default_ignorables (const hb_ot_shape_context_t *c) { hb_buffer_t *buffer = c->buffer; @@ -474,7 +570,7 @@ hb_ot_zero_width_default_ignorables (hb_ot_shape_context_t *c) } static void -hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) +hb_ot_hide_default_ignorables (const hb_ot_shape_context_t *c) { hb_buffer_t *buffer = c->buffer; @@ -485,34 +581,24 @@ hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; hb_glyph_position_t *pos = buffer->pos; - unsigned int i = 0; - for (i = 0; i < count; i++) - { - if (unlikely (_hb_glyph_info_is_default_ignorable (&info[i]))) - break; - } - - /* No default-ignorables found; return. */ - if (i == count) - return; - hb_codepoint_t space; + hb_codepoint_t invisible = c->buffer->invisible; if (!(buffer->flags & HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES) && - c->font->get_nominal_glyph (' ', &space)) + (invisible || c->font->get_nominal_glyph (' ', &invisible))) { - /* Replace default-ignorables with a zero-advance space glyph. */ - for (/*continue*/; i < count; i++) + /* Replace default-ignorables with a zero-advance invisible glyph. */ + for (unsigned int i = 0; i < count; i++) { if (_hb_glyph_info_is_default_ignorable (&info[i])) - info[i].codepoint = space; + info[i].codepoint = invisible; } } else { /* Merge clusters and delete default-ignorables. * NOTE! We can't use out-buffer as we have positioning data. */ - unsigned int j = i; - for (; i < count; i++) + unsigned int j = 0; + for (unsigned int i = 0; i < count; i++) { if (_hb_glyph_info_is_default_ignorable (&info[i])) { @@ -567,7 +653,7 @@ hb_ot_map_glyphs_fast (hb_buffer_t *buffer) } static inline void -hb_synthesize_glyph_classes (hb_ot_shape_context_t *c) +hb_synthesize_glyph_classes (const hb_ot_shape_context_t *c) { unsigned int count = c->buffer->len; hb_glyph_info_t *info = c->buffer->info; @@ -593,7 +679,7 @@ hb_synthesize_glyph_classes (hb_ot_shape_context_t *c) } static inline void -hb_ot_substitute_default (hb_ot_shape_context_t *c) +hb_ot_substitute_default (const hb_ot_shape_context_t *c) { hb_buffer_t *buffer = c->buffer; @@ -606,8 +692,8 @@ hb_ot_substitute_default (hb_ot_shape_context_t *c) hb_ot_shape_setup_masks (c); /* This is unfortunate to go here, but necessary... */ - if (c->fallback_positioning) - _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, buffer); + if (c->plan->fallback_mark_positioning) + _hb_ot_shape_fallback_mark_position_recategorize_marks (c->plan, c->font, buffer); hb_ot_map_glyphs_fast (buffer); @@ -615,23 +701,23 @@ hb_ot_substitute_default (hb_ot_shape_context_t *c) } static inline void -hb_ot_substitute_complex (hb_ot_shape_context_t *c) +hb_ot_substitute_complex (const hb_ot_shape_context_t *c) { hb_buffer_t *buffer = c->buffer; hb_ot_layout_substitute_start (c->font, buffer); - if (!hb_ot_layout_has_glyph_classes (c->face)) + if (c->plan->fallback_glyph_classes) hb_synthesize_glyph_classes (c); - c->plan->substitute (c->font, buffer); - - if (0) /* XXX Call morx instead. */ - hb_aat_layout_substitute (c->font, c->buffer); + if (unlikely (c->plan->apply_morx)) + hb_aat_layout_substitute (c->plan, c->font, c->buffer); + else + c->plan->substitute (c->font, buffer); } static inline void -hb_ot_substitute (hb_ot_shape_context_t *c) +hb_ot_substitute (const hb_ot_shape_context_t *c) { hb_ot_substitute_default (c); @@ -671,7 +757,7 @@ zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets) } static inline void -hb_ot_position_default (hb_ot_shape_context_t *c) +hb_ot_position_default (const hb_ot_shape_context_t *c) { hb_direction_t direction = c->buffer->props.direction; unsigned int count = c->buffer->len; @@ -705,7 +791,7 @@ hb_ot_position_default (hb_ot_shape_context_t *c) } static inline void -hb_ot_position_complex (hb_ot_shape_context_t *c) +hb_ot_position_complex (const hb_ot_shape_context_t *c) { unsigned int count = c->buffer->len; hb_glyph_info_t *info = c->buffer->info; @@ -720,7 +806,7 @@ hb_ot_position_complex (hb_ot_shape_context_t *c) * If fallback positinoing happens or GPOS is present, we don't * care. */ - bool adjust_offsets_when_zeroing = c->fallback_positioning && + bool adjust_offsets_when_zeroing = c->plan->fallback_mark_positioning && !c->plan->shaper->fallback_position && HB_DIRECTION_IS_FORWARD (c->buffer->props.direction); @@ -735,32 +821,39 @@ hb_ot_position_complex (hb_ot_shape_context_t *c) hb_ot_layout_position_start (c->font, c->buffer); - switch (c->plan->shaper->zero_width_marks) - { - case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: - zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing); - break; - - default: - case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: - case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: - break; - } + if (!c->plan->apply_kerx) + switch (c->plan->shaper->zero_width_marks) + { + case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: + zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing); + break; + + default: + case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: + case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: + break; + } - if (likely (!c->fallback_positioning)) + if (c->plan->apply_gpos) c->plan->position (c->font, c->buffer); + else if (c->plan->apply_kerx) + hb_aat_layout_position (c->plan, c->font, c->buffer); - switch (c->plan->shaper->zero_width_marks) - { - case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: - zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing); - break; + if (c->plan->apply_trak) + hb_aat_layout_track (c->plan, c->font, c->buffer); - default: - case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: - case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: - break; - } + if (!c->plan->apply_kerx) + switch (c->plan->shaper->zero_width_marks) + { + case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: + zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing); + break; + + default: + case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: + case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: + break; + } /* Finishing off GPOS has to follow a certain order. */ hb_ot_layout_position_finish_advances (c->font, c->buffer); @@ -776,7 +869,7 @@ hb_ot_position_complex (hb_ot_shape_context_t *c) } static inline void -hb_ot_position (hb_ot_shape_context_t *c) +hb_ot_position (const hb_ot_shape_context_t *c) { c->buffer->clear_positions (); @@ -784,20 +877,20 @@ hb_ot_position (hb_ot_shape_context_t *c) hb_ot_position_complex (c); - if (c->fallback_positioning && c->plan->shaper->fallback_position) - _hb_ot_shape_fallback_position (c->plan, c->font, c->buffer); + if (c->plan->fallback_mark_positioning && c->plan->shaper->fallback_position) + _hb_ot_shape_fallback_mark_position (c->plan, c->font, c->buffer); if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction)) hb_buffer_reverse (c->buffer); /* Visual fallback goes here. */ - if (c->fallback_positioning) + if (c->plan->apply_kern) + hb_ot_layout_kern (c->font, c->buffer, c->plan->kern_mask); + else if (c->plan->fallback_kerning) _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer); _hb_buffer_deallocate_gsubgpos_vars (c->buffer); - - //hb_aat_layout_position (c->font, c->buffer); } static inline void @@ -844,11 +937,6 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c) (unsigned) HB_BUFFER_MAX_OPS_MIN); } - bool disable_otl = c->plan->shaper->disable_otl && c->plan->shaper->disable_otl (c->plan); - //c->fallback_substitute = disable_otl || !hb_ot_layout_has_substitution (c->face); - c->fallback_positioning = disable_otl || !hb_ot_layout_has_positioning (c->face); - c->fallback_glyph_classes = disable_otl || !hb_ot_layout_has_glyph_classes (c->face); - /* Save the original direction, we use it later. */ c->target_direction = c->buffer->props.direction; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh index b3a490a3723..c9c0d3e093d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh @@ -30,7 +30,7 @@ #include "hb.hh" #include "hb-ot-map.hh" -#include "hb-ot-layout.hh" +#include "hb-shape-plan.hh" @@ -42,9 +42,20 @@ struct hb_ot_shape_plan_t const void *data; hb_mask_t rtlm_mask, frac_mask, numr_mask, dnom_mask; hb_mask_t kern_mask; - unsigned int has_frac : 1; - unsigned int has_kern : 1; - unsigned int has_mark : 1; + + bool requested_kerning : 1; + bool has_frac : 1; + bool has_gpos_mark : 1; + bool fallback_glyph_classes : 1; + bool fallback_kerning : 1; + bool fallback_mark_positioning : 1; + + bool apply_gpos : 1; + bool apply_kerx : 1; + bool apply_kern : 1; + bool apply_morx : 1; + bool apply_trak : 1; + inline void collect_lookups (hb_tag_t table_tag, hb_set_t *lookups) const { @@ -83,26 +94,9 @@ struct hb_ot_shape_planner_t shaper (nullptr), map (face, &props) {} - inline void compile (hb_ot_shape_plan_t &plan, - const int *coords, - unsigned int num_coords) - { - plan.props = props; - plan.shaper = shaper; - map.compile (plan.map, coords, num_coords); - - plan.rtlm_mask = plan.map.get_1_mask (HB_TAG ('r','t','l','m')); - plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c')); - plan.numr_mask = plan.map.get_1_mask (HB_TAG ('n','u','m','r')); - plan.dnom_mask = plan.map.get_1_mask (HB_TAG ('d','n','o','m')); - - plan.kern_mask = plan.map.get_mask (HB_DIRECTION_IS_HORIZONTAL (plan.props.direction) ? - HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n')); - - plan.has_frac = plan.frac_mask || (plan.numr_mask && plan.dnom_mask); - plan.has_kern = !!plan.kern_mask; - plan.has_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k')); - } + HB_INTERNAL void compile (hb_ot_shape_plan_t &plan, + const int *coords, + unsigned int num_coords); private: HB_DISALLOW_COPY_AND_ASSIGN (hb_ot_shape_planner_t); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-table.hh new file mode 100644 index 00000000000..b7090a0a787 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-table.hh @@ -0,0 +1,2064 @@ +/* == Start of generated table == */ +/* + * The following table is generated by running: + * + * ./gen-tag-table.py languagetags language-subtag-registry + * + * on files with these headers: + * + * <meta name="updated_at" content="2018-09-07 07:45 PM" /> + * File-Date: 2018-08-08 + */ + +#ifndef HB_OT_TAG_TABLE_HH +#define HB_OT_TAG_TABLE_HH + +static const LangTag ot_languages[] = { + {"aa", {HB_TAG('A','F','R',' ')}}, /* Afar */ + {"aae", {HB_TAG('S','Q','I',' ')}}, /* Arbëreshë Albanian -> Albanian */ + {"aao", {HB_TAG('A','R','A',' ')}}, /* Algerian Saharan Arabic -> Arabic */ + {"aat", {HB_TAG('S','Q','I',' ')}}, /* Arvanitika Albanian -> Albanian */ + {"ab", {HB_TAG('A','B','K',' ')}}, /* Abkhazian */ + {"abh", {HB_TAG('A','R','A',' ')}}, /* Tajiki Arabic -> Arabic */ + {"abq", {HB_TAG('A','B','A',' ')}}, /* Abaza */ + {"abv", {HB_TAG('A','R','A',' ')}}, /* Baharna Arabic -> Arabic */ + {"acf", {HB_TAG('F','A','N',' ')}}, /* Saint Lucian Creole French -> French Antillean */ + {"ach", {HB_TAG('A','C','H',' ')}}, /* Acoli -> Acholi */ + {"acm", {HB_TAG('A','R','A',' ')}}, /* Mesopotamian Arabic -> Arabic */ + {"acq", {HB_TAG('A','R','A',' ')}}, /* Ta'izzi-Adeni Arabic -> Arabic */ + {"acr", {HB_TAG('A','C','R',' ')}}, /* Achi */ + {"acw", {HB_TAG('A','R','A',' ')}}, /* Hijazi Arabic -> Arabic */ + {"acx", {HB_TAG('A','R','A',' ')}}, /* Omani Arabic -> Arabic */ + {"acy", {HB_TAG('A','R','A',' ')}}, /* Cypriot Arabic -> Arabic */ + {"ada", {HB_TAG('D','N','G',' ')}}, /* Adangme -> Dangme */ + {"adf", {HB_TAG('A','R','A',' ')}}, /* Dhofari Arabic -> Arabic */ + {"adp", {HB_TAG('D','Z','N',' ')}}, /* Adap (retired code) -> Dzongkha */ + {"ady", {HB_TAG('A','D','Y',' ')}}, /* Adyghe */ + {"aeb", {HB_TAG('A','R','A',' ')}}, /* Tunisian Arabic -> Arabic */ + {"aec", {HB_TAG('A','R','A',' ')}}, /* Saidi Arabic -> Arabic */ + {"af", {HB_TAG('A','F','K',' ')}}, /* Afrikaans */ + {"afb", {HB_TAG('A','R','A',' ')}}, /* Gulf Arabic -> Arabic */ + {"ahg", {HB_TAG('A','G','W',' ')}}, /* Qimant -> Agaw */ + {"aht", {HB_TAG('A','T','H',' ')}}, /* Ahtena -> Athapaskan */ + {"aii", {HB_TAG('S','W','A',' '), /* Assyrian Neo-Aramaic -> Swadaya Aramaic */ + HB_TAG('S','Y','R',' ')}}, /* Assyrian Neo-Aramaic -> Syriac */ + {"aio", {HB_TAG('A','I','O',' ')}}, /* Aiton */ + {"aiw", {HB_TAG('A','R','I',' ')}}, /* Aari */ + {"ajp", {HB_TAG('A','R','A',' ')}}, /* South Levantine Arabic -> Arabic */ + {"ak", {HB_TAG('A','K','A',' '), /* Akan [macrolanguage] */ + HB_TAG('T','W','I',' ')}}, /* Akan [macrolanguage] -> Twi */ + {"aln", {HB_TAG('S','Q','I',' ')}}, /* Gheg Albanian -> Albanian */ + {"als", {HB_TAG('S','Q','I',' ')}}, /* Tosk Albanian -> Albanian */ + {"alt", {HB_TAG('A','L','T',' ')}}, /* Southern Altai -> Altai */ + {"am", {HB_TAG('A','M','H',' ')}}, /* Amharic */ + {"amf", {HB_TAG('H','B','N',' ')}}, /* Hamer-Banna -> Hammer-Banna */ + {"amw", {HB_TAG('S','Y','R',' ')}}, /* Western Neo-Aramaic -> Syriac */ + {"an", {HB_TAG('A','R','G',' ')}}, /* Aragonese */ + {"ang", {HB_TAG('A','N','G',' ')}}, /* Old English (ca. 450-1100) -> Anglo-Saxon */ + {"apc", {HB_TAG('A','R','A',' ')}}, /* North Levantine Arabic -> Arabic */ + {"apd", {HB_TAG('A','R','A',' ')}}, /* Sudanese Arabic -> Arabic */ + {"apj", {HB_TAG('A','T','H',' ')}}, /* Jicarilla Apache -> Athapaskan */ + {"apk", {HB_TAG('A','T','H',' ')}}, /* Kiowa Apache -> Athapaskan */ + {"apl", {HB_TAG('A','T','H',' ')}}, /* Lipan Apache -> Athapaskan */ + {"apm", {HB_TAG('A','T','H',' ')}}, /* Mescalero-Chiricahua Apache -> Athapaskan */ + {"apw", {HB_TAG('A','T','H',' ')}}, /* Western Apache -> Athapaskan */ + {"ar", {HB_TAG('A','R','A',' ')}}, /* Arabic [macrolanguage] */ + {"arb", {HB_TAG('A','R','A',' ')}}, /* Standard Arabic -> Arabic */ + {"arn", {HB_TAG('M','A','P',' ')}}, /* Mapudungun */ + {"arq", {HB_TAG('A','R','A',' ')}}, /* Algerian Arabic -> Arabic */ + {"ars", {HB_TAG('A','R','A',' ')}}, /* Najdi Arabic -> Arabic */ + {"ary", {HB_TAG('M','O','R',' ')}}, /* Moroccan Arabic -> Moroccan */ + {"arz", {HB_TAG('A','R','A',' ')}}, /* Egyptian Arabic -> Arabic */ + {"as", {HB_TAG('A','S','M',' ')}}, /* Assamese */ + {"ast", {HB_TAG('A','S','T',' ')}}, /* Asturian */ + {"ath", {HB_TAG('A','T','H',' ')}}, /* Athapascan [family] -> Athapaskan */ + {"atj", {HB_TAG('R','C','R',' ')}}, /* Atikamekw -> R-Cree */ + {"atv", {HB_TAG('A','L','T',' ')}}, /* Northern Altai -> Altai */ + {"auz", {HB_TAG('A','R','A',' ')}}, /* Uzbeki Arabic -> Arabic */ + {"av", {HB_TAG('A','V','R',' ')}}, /* Avaric -> Avar */ + {"avl", {HB_TAG('A','R','A',' ')}}, /* Eastern Egyptian Bedawi Arabic -> Arabic */ + {"awa", {HB_TAG('A','W','A',' ')}}, /* Awadhi */ + {"ay", {HB_TAG('A','Y','M',' ')}}, /* Aymara [macrolanguage] */ + {"ayc", {HB_TAG('A','Y','M',' ')}}, /* Southern Aymara -> Aymara */ + {"ayh", {HB_TAG('A','R','A',' ')}}, /* Hadrami Arabic -> Arabic */ + {"ayl", {HB_TAG('A','R','A',' ')}}, /* Libyan Arabic -> Arabic */ + {"ayn", {HB_TAG('A','R','A',' ')}}, /* Sanaani Arabic -> Arabic */ + {"ayp", {HB_TAG('A','R','A',' ')}}, /* North Mesopotamian Arabic -> Arabic */ + {"ayr", {HB_TAG('A','Y','M',' ')}}, /* Central Aymara -> Aymara */ + {"az", {HB_TAG('A','Z','E',' ')}}, /* Azerbaijani [macrolanguage] */ + {"azb", {HB_TAG('A','Z','B',' ')}}, /* South Azerbaijani -> Torki */ + {"azj", {HB_TAG('A','Z','E',' ')}}, /* North Azerbaijani -> Azerbaijani */ + {"ba", {HB_TAG('B','S','H',' ')}}, /* Bashkir */ + {"bad", {HB_TAG('B','A','D','0')}}, /* Banda [family] */ + {"bai", {HB_TAG('B','M','L',' ')}}, /* Bamileke [family] */ + {"bal", {HB_TAG('B','L','I',' ')}}, /* Baluchi [macrolanguage] */ + {"ban", {HB_TAG('B','A','N',' ')}}, /* Balinese */ + {"bar", {HB_TAG('B','A','R',' ')}}, /* Bavarian */ + {"bbc", {HB_TAG('B','B','C',' ')}}, /* Batak Toba */ + {"bbz", {HB_TAG('A','R','A',' ')}}, /* Babalia Creole Arabic -> Arabic */ + {"bcc", {HB_TAG('B','L','I',' ')}}, /* Southern Balochi -> Baluchi */ + {"bci", {HB_TAG('B','A','U',' ')}}, /* Baoulé -> Baulé */ + {"bcl", {HB_TAG('B','I','K',' ')}}, /* Central Bikol -> Bikol */ + {"bcq", {HB_TAG('B','C','H',' ')}}, /* Bench */ + {"bcr", {HB_TAG('A','T','H',' ')}}, /* Babine -> Athapaskan */ + {"bdy", {HB_TAG('B','D','Y',' ')}}, /* Bandjalang */ + {"be", {HB_TAG('B','E','L',' ')}}, /* Belarusian -> Belarussian */ + {"bea", {HB_TAG('A','T','H',' ')}}, /* Beaver -> Athapaskan */ + {"beb", {HB_TAG('B','T','I',' ')}}, /* Bebele -> Beti */ + {"bem", {HB_TAG('B','E','M',' ')}}, /* Bemba (Zambia) */ + {"ber", {HB_TAG('B','B','R',' ')}}, /* Berber [family] */ + {"bfq", {HB_TAG('B','A','D',' ')}}, /* Badaga */ + {"bft", {HB_TAG('B','L','T',' ')}}, /* Balti */ + {"bfu", {HB_TAG('L','A','H',' ')}}, /* Gahri -> Lahuli */ + {"bfy", {HB_TAG('B','A','G',' ')}}, /* Bagheli -> Baghelkhandi */ + {"bg", {HB_TAG('B','G','R',' ')}}, /* Bulgarian */ + {"bgc", {HB_TAG('B','G','C',' ')}}, /* Haryanvi */ + {"bgn", {HB_TAG('B','L','I',' ')}}, /* Western Balochi -> Baluchi */ + {"bgp", {HB_TAG('B','L','I',' ')}}, /* Eastern Balochi -> Baluchi */ + {"bgq", {HB_TAG('B','G','Q',' ')}}, /* Bagri */ + {"bgr", {HB_TAG('Q','I','N',' ')}}, /* Bawm Chin -> Chin */ + {"bhb", {HB_TAG('B','H','I',' ')}}, /* Bhili */ + {"bhi", {HB_TAG('B','H','I',' ')}}, /* Bhilali -> Bhili */ + {"bhk", {HB_TAG('B','I','K',' ')}}, /* Albay Bicolano (retired code) -> Bikol */ + {"bho", {HB_TAG('B','H','O',' ')}}, /* Bhojpuri */ + {"bhr", {HB_TAG('M','L','G',' ')}}, /* Bara Malagasy -> Malagasy */ + {"bi", {HB_TAG('B','I','S',' ')}}, /* Bislama */ + {"bik", {HB_TAG('B','I','K',' ')}}, /* Bikol [macrolanguage] */ + {"bin", {HB_TAG('E','D','O',' ')}}, /* Edo */ + {"bjj", {HB_TAG('B','J','J',' ')}}, /* Kanauji */ + {"bjn", {HB_TAG('M','L','Y',' ')}}, /* Banjar -> Malay */ + {"bjq", {HB_TAG('M','L','G',' ')}}, /* Southern Betsimisaraka Malagasy (retired code) -> Malagasy */ + {"bjt", {HB_TAG('B','L','N',' ')}}, /* Balanta-Ganja -> Balante */ + {"bla", {HB_TAG('B','K','F',' ')}}, /* Siksika -> Blackfoot */ + {"ble", {HB_TAG('B','L','N',' ')}}, /* Balanta-Kentohe -> Balante */ + {"blk", {HB_TAG('B','L','K',' ')}}, /* Pa'o Karen */ + {"bln", {HB_TAG('B','I','K',' ')}}, /* Southern Catanduanes Bikol -> Bikol */ + {"bm", {HB_TAG('B','M','B',' ')}}, /* Bambara (Bamanankan) */ + {"bmm", {HB_TAG('M','L','G',' ')}}, /* Northern Betsimisaraka Malagasy -> Malagasy */ + {"bn", {HB_TAG('B','E','N',' ')}}, /* Bengali */ + {"bo", {HB_TAG('T','I','B',' ')}}, /* Tibetan */ + {"bpy", {HB_TAG('B','P','Y',' ')}}, /* Bishnupriya -> Bishnupriya Manipuri */ + {"bqi", {HB_TAG('L','R','C',' ')}}, /* Bakhtiari -> Luri */ + {"br", {HB_TAG('B','R','E',' ')}}, /* Breton */ + {"bra", {HB_TAG('B','R','I',' ')}}, /* Braj -> Braj Bhasha */ + {"brh", {HB_TAG('B','R','H',' ')}}, /* Brahui */ + {"brx", {HB_TAG('B','R','X',' ')}}, /* Bodo (India) */ + {"bs", {HB_TAG('B','O','S',' ')}}, /* Bosnian */ + {"bsk", {HB_TAG('B','S','K',' ')}}, /* Burushaski */ + {"btb", {HB_TAG('B','T','I',' ')}}, /* Beti (Cameroon) (retired code) */ + {"btj", {HB_TAG('M','L','Y',' ')}}, /* Bacanese Malay -> Malay */ + {"bto", {HB_TAG('B','I','K',' ')}}, /* Rinconada Bikol -> Bikol */ + {"bts", {HB_TAG('B','T','S',' ')}}, /* Batak Simalungun */ + {"bug", {HB_TAG('B','U','G',' ')}}, /* Buginese -> Bugis */ + {"bum", {HB_TAG('B','T','I',' ')}}, /* Bulu (Cameroon) -> Beti */ + {"bve", {HB_TAG('M','L','Y',' ')}}, /* Berau Malay -> Malay */ + {"bvu", {HB_TAG('M','L','Y',' ')}}, /* Bukit Malay -> Malay */ + {"bxk", {HB_TAG('L','U','H',' ')}}, /* Bukusu -> Luyia */ + {"bxp", {HB_TAG('B','T','I',' ')}}, /* Bebil -> Beti */ + {"bxr", {HB_TAG('R','B','U',' ')}}, /* Russia Buriat -> Russian Buriat */ + {"byn", {HB_TAG('B','I','L',' ')}}, /* Bilin -> Bilen */ + {"byv", {HB_TAG('B','Y','V',' ')}}, /* Medumba */ + {"bzc", {HB_TAG('M','L','G',' ')}}, /* Southern Betsimisaraka Malagasy -> Malagasy */ + {"ca", {HB_TAG('C','A','T',' ')}}, /* Catalan */ + {"caf", {HB_TAG('C','R','R',' '), /* Southern Carrier -> Carrier */ + HB_TAG('A','T','H',' ')}}, /* Southern Carrier -> Athapaskan */ + {"cak", {HB_TAG('C','A','K',' ')}}, /* Kaqchikel */ + {"cbk", {HB_TAG('C','B','K',' ')}}, /* Chavacano -> Zamboanga Chavacano */ + {"cbl", {HB_TAG('Q','I','N',' ')}}, /* Bualkhaw Chin -> Chin */ + {"cco", {HB_TAG('C','C','H','N')}}, /* Comaltepec Chinantec -> Chinantec */ + {"ccq", {HB_TAG('A','R','K',' ')}}, /* Chaungtha (retired code) -> Rakhine */ + {"cdo", {HB_TAG('Z','H','S',' ')}}, /* Min Dong Chinese -> Chinese Simplified */ + {"ce", {HB_TAG('C','H','E',' ')}}, /* Chechen */ + {"ceb", {HB_TAG('C','E','B',' ')}}, /* Cebuano */ + {"cfm", {HB_TAG('H','A','L',' ')}}, /* Halam (Falam Chin) */ + {"cgg", {HB_TAG('C','G','G',' ')}}, /* Chiga */ + {"ch", {HB_TAG('C','H','A',' ')}}, /* Chamorro */ + {"chj", {HB_TAG('C','C','H','N')}}, /* Ojitlán Chinantec -> Chinantec */ + {"chk", {HB_TAG('C','H','K','0')}}, /* Chuukese */ + {"cho", {HB_TAG('C','H','O',' ')}}, /* Choctaw */ + {"chp", {HB_TAG('C','H','P',' '), /* Chipewyan */ + HB_TAG('S','A','Y',' '), /* Chipewyan -> Sayisi */ + HB_TAG('A','T','H',' ')}}, /* Chipewyan -> Athapaskan */ + {"chq", {HB_TAG('C','C','H','N')}}, /* Quiotepec Chinantec -> Chinantec */ + {"chr", {HB_TAG('C','H','R',' ')}}, /* Cherokee */ + {"chy", {HB_TAG('C','H','Y',' ')}}, /* Cheyenne */ + {"chz", {HB_TAG('C','C','H','N')}}, /* Ozumacín Chinantec -> Chinantec */ + {"ciw", {HB_TAG('O','J','B',' ')}}, /* Chippewa -> Ojibway */ + {"cja", {HB_TAG('C','J','A',' ')}}, /* Western Cham */ + {"cjm", {HB_TAG('C','J','M',' ')}}, /* Eastern Cham */ + {"cjy", {HB_TAG('Z','H','S',' ')}}, /* Jinyu Chinese -> Chinese Simplified */ + {"cka", {HB_TAG('Q','I','N',' ')}}, /* Khumi Awa Chin (retired code) -> Chin */ + {"ckb", {HB_TAG('K','U','R',' ')}}, /* Central Kurdish -> Kurdish */ + {"ckt", {HB_TAG('C','H','K',' ')}}, /* Chukot -> Chukchi */ + {"clc", {HB_TAG('A','T','H',' ')}}, /* Chilcotin -> Athapaskan */ + {"cld", {HB_TAG('S','Y','R',' ')}}, /* Chaldean Neo-Aramaic -> Syriac */ + {"cle", {HB_TAG('C','C','H','N')}}, /* Lealao Chinantec -> Chinantec */ + {"cmn", {HB_TAG('Z','H','S',' ')}}, /* Mandarin Chinese -> Chinese Simplified */ + {"cmr", {HB_TAG('Q','I','N',' ')}}, /* Mro-Khimi Chin -> Chin */ + {"cnb", {HB_TAG('Q','I','N',' ')}}, /* Chinbon Chin -> Chin */ + {"cnh", {HB_TAG('Q','I','N',' ')}}, /* Hakha Chin -> Chin */ + {"cnk", {HB_TAG('Q','I','N',' ')}}, /* Khumi Chin -> Chin */ + {"cnl", {HB_TAG('C','C','H','N')}}, /* Lalana Chinantec -> Chinantec */ + {"cnt", {HB_TAG('C','C','H','N')}}, /* Tepetotutla Chinantec -> Chinantec */ + {"cnw", {HB_TAG('Q','I','N',' ')}}, /* Ngawn Chin -> Chin */ + {"co", {HB_TAG('C','O','S',' ')}}, /* Corsican */ + {"coa", {HB_TAG('M','L','Y',' ')}}, /* Cocos Islands Malay -> Malay */ + {"cop", {HB_TAG('C','O','P',' ')}}, /* Coptic */ + {"coq", {HB_TAG('A','T','H',' ')}}, /* Coquille -> Athapaskan */ + {"cpa", {HB_TAG('C','C','H','N')}}, /* Palantla Chinantec -> Chinantec */ + {"cpe", {HB_TAG('C','P','P',' ')}}, /* English-based creoles and pidgins [family] -> Creoles */ + {"cpf", {HB_TAG('C','P','P',' ')}}, /* French-based creoles and pidgins [family] -> Creoles */ + {"cpp", {HB_TAG('C','P','P',' ')}}, /* Portuguese-based creoles and pidgins [family] -> Creoles */ + {"cpx", {HB_TAG('Z','H','S',' ')}}, /* Pu-Xian Chinese -> Chinese Simplified */ + {"cqd", {HB_TAG('H','M','N',' ')}}, /* Chuanqiandian Cluster Miao -> Hmong */ + {"cqu", {HB_TAG('Q','U','H',' ')}}, /* Chilean Quechua (retired code) -> Quechua (Bolivia) */ + {"cr", {HB_TAG('C','R','E',' '), /* Cree [macrolanguage] */ + HB_TAG('Y','C','R',' ')}}, /* Cree [macrolanguage] -> Y-Cree */ + {"crh", {HB_TAG('C','R','T',' ')}}, /* Crimean Tatar */ + {"crj", {HB_TAG('E','C','R',' ')}}, /* Southern East Cree -> Eastern Cree */ + {"crk", {HB_TAG('W','C','R',' ')}}, /* Plains Cree -> West-Cree */ + {"crl", {HB_TAG('E','C','R',' ')}}, /* Northern East Cree -> Eastern Cree */ + {"crm", {HB_TAG('M','C','R',' '), /* Moose Cree */ + HB_TAG('L','C','R',' ')}}, /* Moose Cree -> L-Cree */ + {"crp", {HB_TAG('C','P','P',' ')}}, /* Creoles and pidgins [family] -> Creoles */ + {"crx", {HB_TAG('C','R','R',' '), /* Carrier */ + HB_TAG('A','T','H',' ')}}, /* Carrier -> Athapaskan */ + {"cs", {HB_TAG('C','S','Y',' ')}}, /* Czech */ + {"csa", {HB_TAG('C','C','H','N')}}, /* Chiltepec Chinantec -> Chinantec */ + {"csb", {HB_TAG('C','S','B',' ')}}, /* Kashubian */ + {"csh", {HB_TAG('Q','I','N',' ')}}, /* Asho Chin -> Chin */ + {"cso", {HB_TAG('C','C','H','N')}}, /* Sochiapam Chinantec -> Chinantec */ + {"csw", {HB_TAG('N','C','R',' '), /* Swampy Cree -> N-Cree */ + HB_TAG('N','H','C',' ')}}, /* Swampy Cree -> Norway House Cree */ + {"csy", {HB_TAG('Q','I','N',' ')}}, /* Siyin Chin -> Chin */ + {"ctc", {HB_TAG('A','T','H',' ')}}, /* Chetco -> Athapaskan */ + {"ctd", {HB_TAG('Q','I','N',' ')}}, /* Tedim Chin -> Chin */ + {"cte", {HB_TAG('C','C','H','N')}}, /* Tepinapa Chinantec -> Chinantec */ + {"ctg", {HB_TAG('C','T','G',' ')}}, /* Chittagonian */ + {"ctl", {HB_TAG('C','C','H','N')}}, /* Tlacoatzintepec Chinantec -> Chinantec */ + {"cts", {HB_TAG('B','I','K',' ')}}, /* Northern Catanduanes Bikol -> Bikol */ + {"cu", {HB_TAG('C','S','L',' ')}}, /* Church Slavonic */ + {"cuc", {HB_TAG('C','C','H','N')}}, /* Usila Chinantec -> Chinantec */ + {"cuk", {HB_TAG('C','U','K',' ')}}, /* San Blas Kuna */ + {"cv", {HB_TAG('C','H','U',' ')}}, /* Chuvash */ + {"cvn", {HB_TAG('C','C','H','N')}}, /* Valle Nacional Chinantec -> Chinantec */ + {"cwd", {HB_TAG('D','C','R',' '), /* Woods Cree */ + HB_TAG('T','C','R',' ')}}, /* Woods Cree -> TH-Cree */ + {"cy", {HB_TAG('W','E','L',' ')}}, /* Welsh */ + {"czh", {HB_TAG('Z','H','S',' ')}}, /* Huizhou Chinese -> Chinese Simplified */ + {"czo", {HB_TAG('Z','H','S',' ')}}, /* Min Zhong Chinese -> Chinese Simplified */ + {"czt", {HB_TAG('Q','I','N',' ')}}, /* Zotung Chin -> Chin */ + {"da", {HB_TAG('D','A','N',' ')}}, /* Danish */ + {"dao", {HB_TAG('Q','I','N',' ')}}, /* Daai Chin -> Chin */ + {"dap", {HB_TAG('N','I','S',' ')}}, /* Nisi (India) (retired code) */ + {"dar", {HB_TAG('D','A','R',' ')}}, /* Dargwa */ + {"dax", {HB_TAG('D','A','X',' ')}}, /* Dayi */ + {"de", {HB_TAG('D','E','U',' ')}}, /* German */ + {"den", {HB_TAG('S','L','A',' '), /* Slave (Athapascan) [macrolanguage] -> Slavey */ + HB_TAG('A','T','H',' ')}}, /* Slave (Athapascan) [macrolanguage] -> Athapaskan */ + {"dgo", {HB_TAG('D','G','O',' ')}}, /* Dogri */ + {"dgr", {HB_TAG('A','T','H',' ')}}, /* Dogrib -> Athapaskan */ + {"dhd", {HB_TAG('M','A','W',' ')}}, /* Dhundari -> Marwari */ + {"dhg", {HB_TAG('D','H','G',' ')}}, /* Dhangu */ + {"dib", {HB_TAG('D','N','K',' ')}}, /* South Central Dinka -> Dinka */ + {"dik", {HB_TAG('D','N','K',' ')}}, /* Southwestern Dinka -> Dinka */ + {"din", {HB_TAG('D','N','K',' ')}}, /* Dinka [macrolanguage] */ + {"dip", {HB_TAG('D','N','K',' ')}}, /* Northeastern Dinka -> Dinka */ + {"diq", {HB_TAG('D','I','Q',' ')}}, /* Dimli */ + {"diw", {HB_TAG('D','N','K',' ')}}, /* Northwestern Dinka -> Dinka */ + {"dje", {HB_TAG('D','J','R',' ')}}, /* Zarma */ + {"djr", {HB_TAG('D','J','R','0')}}, /* Djambarrpuyngu */ + {"dks", {HB_TAG('D','N','K',' ')}}, /* Southeastern Dinka -> Dinka */ + {"dng", {HB_TAG('D','U','N',' ')}}, /* Dungan */ + {"dnj", {HB_TAG('D','N','J',' ')}}, /* Dan */ + {"doi", {HB_TAG('D','G','R',' ')}}, /* Dogri [macrolanguage] */ + {"drh", {HB_TAG('M','N','G',' ')}}, /* Darkhat (retired code) -> Mongolian */ + {"drw", {HB_TAG('D','R','I',' ')}}, /* Darwazi (retired code) -> Dari */ + {"dsb", {HB_TAG('L','S','B',' ')}}, /* Lower Sorbian */ + {"dty", {HB_TAG('N','E','P',' ')}}, /* Dotyali -> Nepali */ + {"duj", {HB_TAG('D','U','J',' ')}}, /* Dhuwal (retired code) */ + {"dup", {HB_TAG('M','L','Y',' ')}}, /* Duano -> Malay */ + {"dv", {HB_TAG('D','I','V',' '), /* Divehi (Dhivehi, Maldivian) */ + HB_TAG('D','H','V',' ')}}, /* Divehi (Dhivehi, Maldivian) (deprecated) */ + {"dwu", {HB_TAG('D','U','J',' ')}}, /* Dhuwal */ + {"dwy", {HB_TAG('D','U','J',' ')}}, /* Dhuwaya -> Dhuwal */ + {"dyu", {HB_TAG('J','U','L',' ')}}, /* Dyula -> Jula */ + {"dz", {HB_TAG('D','Z','N',' ')}}, /* Dzongkha */ + {"ee", {HB_TAG('E','W','E',' ')}}, /* Ewe */ + {"efi", {HB_TAG('E','F','I',' ')}}, /* Efik */ + {"ekk", {HB_TAG('E','T','I',' ')}}, /* Standard Estonian -> Estonian */ + {"el", {HB_TAG('E','L','L',' ')}}, /* Modern Greek (1453-) -> Greek */ + {"emk", {HB_TAG('E','M','K',' '), /* Eastern Maninkakan */ + HB_TAG('M','N','K',' ')}}, /* Eastern Maninkakan -> Maninka */ + {"en", {HB_TAG('E','N','G',' ')}}, /* English */ + {"enb", {HB_TAG('K','A','L',' ')}}, /* Markweeta -> Kalenjin */ + {"enf", {HB_TAG('F','N','E',' ')}}, /* Forest Enets -> Forest Nenets */ + {"enh", {HB_TAG('T','N','E',' ')}}, /* Tundra Enets -> Tundra Nenets */ + {"eo", {HB_TAG('N','T','O',' ')}}, /* Esperanto */ + {"es", {HB_TAG('E','S','P',' ')}}, /* Spanish */ + {"esg", {HB_TAG('G','O','N',' ')}}, /* Aheri Gondi -> Gondi */ + {"esi", {HB_TAG('I','P','K',' ')}}, /* North Alaskan Inupiatun -> Inupiat */ + {"esk", {HB_TAG('I','P','K',' ')}}, /* Northwest Alaska Inupiatun -> Inupiat */ + {"esu", {HB_TAG('E','S','U',' ')}}, /* Central Yupik */ + {"et", {HB_TAG('E','T','I',' ')}}, /* Estonian [macrolanguage] */ + {"eto", {HB_TAG('B','T','I',' ')}}, /* Eton (Cameroon) -> Beti */ + {"eu", {HB_TAG('E','U','Q',' ')}}, /* Basque */ + {"eve", {HB_TAG('E','V','N',' ')}}, /* Even */ + {"evn", {HB_TAG('E','V','K',' ')}}, /* Evenki */ + {"ewo", {HB_TAG('B','T','I',' ')}}, /* Ewondo -> Beti */ + {"eyo", {HB_TAG('K','A','L',' ')}}, /* Keiyo -> Kalenjin */ + {"fa", {HB_TAG('F','A','R',' ')}}, /* Persian [macrolanguage] */ + {"fan", {HB_TAG('F','A','N','0')}}, /* Fang (Equatorial Guinea) */ + {"fat", {HB_TAG('F','A','T',' ')}}, /* Fanti */ + {"fbl", {HB_TAG('B','I','K',' ')}}, /* West Albay Bikol -> Bikol */ + {"ff", {HB_TAG('F','U','L',' ')}}, /* Fulah [macrolanguage] */ + {"ffm", {HB_TAG('F','U','L',' ')}}, /* Maasina Fulfulde -> Fulah */ + {"fi", {HB_TAG('F','I','N',' ')}}, /* Finnish */ + {"fil", {HB_TAG('P','I','L',' ')}}, /* Filipino */ + {"fj", {HB_TAG('F','J','I',' ')}}, /* Fijian */ + {"flm", {HB_TAG('H','A','L',' '), /* Halam (Falam Chin) (retired code) */ + HB_TAG('Q','I','N',' ')}}, /* Falam Chin (retired code) -> Chin */ + {"fmp", {HB_TAG('F','M','P',' ')}}, /* Fe'fe' */ + {"fo", {HB_TAG('F','O','S',' ')}}, /* Faroese */ + {"fon", {HB_TAG('F','O','N',' ')}}, /* Fon */ + {"fr", {HB_TAG('F','R','A',' ')}}, /* French */ + {"frc", {HB_TAG('F','R','C',' ')}}, /* Cajun French */ + {"frp", {HB_TAG('F','R','P',' ')}}, /* Arpitan */ + {"fub", {HB_TAG('F','U','L',' ')}}, /* Adamawa Fulfulde -> Fulah */ + {"fuc", {HB_TAG('F','U','L',' ')}}, /* Pulaar -> Fulah */ + {"fue", {HB_TAG('F','U','L',' ')}}, /* Borgu Fulfulde -> Fulah */ + {"fuf", {HB_TAG('F','T','A',' ')}}, /* Pular -> Futa */ + {"fuh", {HB_TAG('F','U','L',' ')}}, /* Western Niger Fulfulde -> Fulah */ + {"fui", {HB_TAG('F','U','L',' ')}}, /* Bagirmi Fulfulde -> Fulah */ + {"fuq", {HB_TAG('F','U','L',' ')}}, /* Central-Eastern Niger Fulfulde -> Fulah */ + {"fur", {HB_TAG('F','R','L',' ')}}, /* Friulian */ + {"fuv", {HB_TAG('F','U','V',' ')}}, /* Nigerian Fulfulde */ + {"fy", {HB_TAG('F','R','I',' ')}}, /* Western Frisian -> Frisian */ + {"ga", {HB_TAG('I','R','I',' ')}}, /* Irish */ + {"gaa", {HB_TAG('G','A','D',' ')}}, /* Ga */ + {"gag", {HB_TAG('G','A','G',' ')}}, /* Gagauz */ + {"gan", {HB_TAG('Z','H','S',' ')}}, /* Gan Chinese -> Chinese Simplified */ + {"gax", {HB_TAG('O','R','O',' ')}}, /* Borana-Arsi-Guji Oromo -> Oromo */ + {"gaz", {HB_TAG('O','R','O',' ')}}, /* West Central Oromo -> Oromo */ + {"gbm", {HB_TAG('G','A','W',' ')}}, /* Garhwali */ + {"gce", {HB_TAG('A','T','H',' ')}}, /* Galice -> Athapaskan */ + {"gd", {HB_TAG('G','A','E',' ')}}, /* Scottish Gaelic (Gaelic) */ + {"gda", {HB_TAG('R','A','J',' ')}}, /* Gade Lohar -> Rajasthani */ + {"gez", {HB_TAG('G','E','Z',' ')}}, /* Geez */ + {"ggo", {HB_TAG('G','O','N',' ')}}, /* Southern Gondi (retired code) -> Gondi */ + {"gih", {HB_TAG('G','I','H',' ')}}, /* Githabul */ + {"gil", {HB_TAG('G','I','L','0')}}, /* Kiribati (Gilbertese) */ + {"gju", {HB_TAG('R','A','J',' ')}}, /* Gujari -> Rajasthani */ + {"gkp", {HB_TAG('G','K','P',' ')}}, /* Guinea Kpelle -> Kpelle (Guinea) */ + {"gl", {HB_TAG('G','A','L',' ')}}, /* Galician */ + {"gld", {HB_TAG('N','A','N',' ')}}, /* Nanai */ + {"glk", {HB_TAG('G','L','K',' ')}}, /* Gilaki */ + {"gn", {HB_TAG('G','U','A',' ')}}, /* Guarani [macrolanguage] */ + {"gnn", {HB_TAG('G','N','N',' ')}}, /* Gumatj */ + {"gno", {HB_TAG('G','O','N',' ')}}, /* Northern Gondi -> Gondi */ + {"gnw", {HB_TAG('G','U','A',' ')}}, /* Western Bolivian Guaraní -> Guarani */ + {"gog", {HB_TAG('G','O','G',' ')}}, /* Gogo */ + {"gom", {HB_TAG('K','O','K',' ')}}, /* Goan Konkani -> Konkani */ + {"gon", {HB_TAG('G','O','N',' ')}}, /* Gondi [macrolanguage] */ + {"grt", {HB_TAG('G','R','O',' ')}}, /* Garo */ + {"gru", {HB_TAG('S','O','G',' ')}}, /* Kistane -> Sodo Gurage */ + {"gsw", {HB_TAG('A','L','S',' ')}}, /* Alsatian */ + {"gu", {HB_TAG('G','U','J',' ')}}, /* Gujarati */ + {"guc", {HB_TAG('G','U','C',' ')}}, /* Wayuu */ + {"guf", {HB_TAG('G','U','F',' ')}}, /* Gupapuyngu */ + {"gug", {HB_TAG('G','U','A',' ')}}, /* Paraguayan Guaraní -> Guarani */ + {"gui", {HB_TAG('G','U','A',' ')}}, /* Eastern Bolivian Guaraní -> Guarani */ + {"guk", {HB_TAG('G','M','Z',' '), /* Gumuz */ + HB_TAG('G','U','K',' ')}}, /* Gumuz (SIL fonts) */ + {"gun", {HB_TAG('G','U','A',' ')}}, /* Mbyá Guaraní -> Guarani */ + {"guz", {HB_TAG('G','U','Z',' ')}}, /* Gusii */ + {"gv", {HB_TAG('M','N','X',' ')}}, /* Manx */ + {"gwi", {HB_TAG('A','T','H',' ')}}, /* Gwichʼin -> Athapaskan */ + {"ha", {HB_TAG('H','A','U',' ')}}, /* Hausa */ + {"haa", {HB_TAG('A','T','H',' ')}}, /* Han -> Athapaskan */ + {"hae", {HB_TAG('O','R','O',' ')}}, /* Eastern Oromo -> Oromo */ + {"hak", {HB_TAG('Z','H','S',' ')}}, /* Hakka Chinese -> Chinese Simplified */ + {"har", {HB_TAG('H','R','I',' ')}}, /* Harari */ + {"haw", {HB_TAG('H','A','W',' ')}}, /* Hawaiian */ + {"hay", {HB_TAG('H','A','Y',' ')}}, /* Haya */ + {"haz", {HB_TAG('H','A','Z',' ')}}, /* Hazaragi */ + {"he", {HB_TAG('I','W','R',' ')}}, /* Hebrew */ + {"hea", {HB_TAG('H','M','N',' ')}}, /* Northern Qiandong Miao -> Hmong */ + {"hi", {HB_TAG('H','I','N',' ')}}, /* Hindi */ + {"hil", {HB_TAG('H','I','L',' ')}}, /* Hiligaynon */ + {"hji", {HB_TAG('M','L','Y',' ')}}, /* Haji -> Malay */ + {"hlt", {HB_TAG('Q','I','N',' ')}}, /* Matu Chin -> Chin */ + {"hma", {HB_TAG('H','M','N',' ')}}, /* Southern Mashan Hmong -> Hmong */ + {"hmc", {HB_TAG('H','M','N',' ')}}, /* Central Huishui Hmong -> Hmong */ + {"hmd", {HB_TAG('H','M','N',' ')}}, /* Large Flowery Miao -> Hmong */ + {"hme", {HB_TAG('H','M','N',' ')}}, /* Eastern Huishui Hmong -> Hmong */ + {"hmg", {HB_TAG('H','M','N',' ')}}, /* Southwestern Guiyang Hmong -> Hmong */ + {"hmh", {HB_TAG('H','M','N',' ')}}, /* Southwestern Huishui Hmong -> Hmong */ + {"hmi", {HB_TAG('H','M','N',' ')}}, /* Northern Huishui Hmong -> Hmong */ + {"hmj", {HB_TAG('H','M','N',' ')}}, /* Ge -> Hmong */ + {"hml", {HB_TAG('H','M','N',' ')}}, /* Luopohe Hmong -> Hmong */ + {"hmm", {HB_TAG('H','M','N',' ')}}, /* Central Mashan Hmong -> Hmong */ + {"hmn", {HB_TAG('H','M','N',' ')}}, /* Hmong [macrolanguage] */ + {"hmp", {HB_TAG('H','M','N',' ')}}, /* Northern Mashan Hmong -> Hmong */ + {"hmq", {HB_TAG('H','M','N',' ')}}, /* Eastern Qiandong Miao -> Hmong */ + {"hms", {HB_TAG('H','M','N',' ')}}, /* Southern Qiandong Miao -> Hmong */ + {"hmw", {HB_TAG('H','M','N',' ')}}, /* Western Mashan Hmong -> Hmong */ + {"hmy", {HB_TAG('H','M','N',' ')}}, /* Southern Guiyang Hmong -> Hmong */ + {"hmz", {HB_TAG('H','M','N',' ')}}, /* Hmong Shua -> Hmong */ + {"hnd", {HB_TAG('H','N','D',' ')}}, /* Southern Hindko -> Hindko */ + {"hne", {HB_TAG('C','H','H',' ')}}, /* Chhattisgarhi -> Chattisgarhi */ + {"hnj", {HB_TAG('H','M','N',' ')}}, /* Hmong Njua -> Hmong */ + {"hno", {HB_TAG('H','N','D',' ')}}, /* Northern Hindko -> Hindko */ + {"ho", {HB_TAG('H','M','O',' ')}}, /* Hiri Motu */ + {"hoc", {HB_TAG('H','O',' ',' ')}}, /* Ho */ + {"hoi", {HB_TAG('A','T','H',' ')}}, /* Holikachuk -> Athapaskan */ + {"hoj", {HB_TAG('H','A','R',' ')}}, /* Hadothi -> Harauti */ + {"hr", {HB_TAG('H','R','V',' ')}}, /* Croatian */ + {"hrm", {HB_TAG('H','M','N',' ')}}, /* Horned Miao -> Hmong */ + {"hsb", {HB_TAG('U','S','B',' ')}}, /* Upper Sorbian */ + {"hsn", {HB_TAG('Z','H','S',' ')}}, /* Xiang Chinese -> Chinese Simplified */ + {"ht", {HB_TAG('H','A','I',' ')}}, /* Haitian (Haitian Creole) */ + {"hu", {HB_TAG('H','U','N',' ')}}, /* Hungarian */ + {"huj", {HB_TAG('H','M','N',' ')}}, /* Northern Guiyang Hmong -> Hmong */ + {"hup", {HB_TAG('A','T','H',' ')}}, /* Hupa -> Athapaskan */ + {"hy", {HB_TAG('H','Y','E','0'), /* Armenian -> Armenian East */ + HB_TAG('H','Y','E',' ')}}, /* Armenian */ + {"hyw", {HB_TAG('H','Y','E',' ')}}, /* Western Armenian -> Armenian */ + {"hz", {HB_TAG('H','E','R',' ')}}, /* Herero */ + {"ia", {HB_TAG('I','N','A',' ')}}, /* Interlingua (International Auxiliary Language Association) */ + {"iba", {HB_TAG('I','B','A',' ')}}, /* Iban */ + {"ibb", {HB_TAG('I','B','B',' ')}}, /* Ibibio */ + {"id", {HB_TAG('I','N','D',' ')}}, /* Indonesian */ + {"ida", {HB_TAG('L','U','H',' ')}}, /* Idakho-Isukha-Tiriki -> Luyia */ + {"ie", {HB_TAG('I','L','E',' ')}}, /* Interlingue */ + {"ig", {HB_TAG('I','B','O',' ')}}, /* Igbo */ + {"igb", {HB_TAG('E','B','I',' ')}}, /* Ebira */ + {"ii", {HB_TAG('Y','I','M',' ')}}, /* Sichuan Yi -> Yi Modern */ + {"ijc", {HB_TAG('I','J','O',' ')}}, /* Izon -> Ijo */ + {"ijo", {HB_TAG('I','J','O',' ')}}, /* Ijo [family] */ + {"ik", {HB_TAG('I','P','K',' ')}}, /* Inupiaq [macrolanguage] -> Inupiat */ + {"ike", {HB_TAG('I','N','U',' ')}}, /* Eastern Canadian Inuktitut -> Inuktitut */ + {"ikt", {HB_TAG('I','N','U',' ')}}, /* Inuinnaqtun -> Inuktitut */ + {"ilo", {HB_TAG('I','L','O',' ')}}, /* Iloko -> Ilokano */ + {"in", {HB_TAG('I','N','D',' ')}}, /* Indonesian (retired code) */ + {"ing", {HB_TAG('A','T','H',' ')}}, /* Degexit'an -> Athapaskan */ + {"inh", {HB_TAG('I','N','G',' ')}}, /* Ingush */ + {"io", {HB_TAG('I','D','O',' ')}}, /* Ido */ + {"is", {HB_TAG('I','S','L',' ')}}, /* Icelandic */ + {"it", {HB_TAG('I','T','A',' ')}}, /* Italian */ + {"iu", {HB_TAG('I','N','U',' ')}}, /* Inuktitut [macrolanguage] */ + {"iw", {HB_TAG('I','W','R',' ')}}, /* Hebrew (retired code) */ + {"ja", {HB_TAG('J','A','N',' ')}}, /* Japanese */ + {"jak", {HB_TAG('M','L','Y',' ')}}, /* Jakun -> Malay */ + {"jam", {HB_TAG('J','A','M',' ')}}, /* Jamaican Creole English -> Jamaican Creole */ + {"jax", {HB_TAG('M','L','Y',' ')}}, /* Jambi Malay -> Malay */ + {"jbo", {HB_TAG('J','B','O',' ')}}, /* Lojban */ + {"jct", {HB_TAG('J','C','T',' ')}}, /* Krymchak */ + {"ji", {HB_TAG('J','I','I',' ')}}, /* Yiddish (retired code) */ + {"jv", {HB_TAG('J','A','V',' ')}}, /* Javanese */ + {"jw", {HB_TAG('J','A','V',' ')}}, /* Javanese (retired code) */ + {"ka", {HB_TAG('K','A','T',' ')}}, /* Georgian */ + {"kaa", {HB_TAG('K','R','K',' ')}}, /* Kara-Kalpak -> Karakalpak */ + {"kab", {HB_TAG('K','A','B','0')}}, /* Kabyle */ + {"kam", {HB_TAG('K','M','B',' ')}}, /* Kamba (Kenya) */ + {"kar", {HB_TAG('K','R','N',' ')}}, /* Karen [family] */ + {"kbd", {HB_TAG('K','A','B',' ')}}, /* Kabardian */ + {"kby", {HB_TAG('K','N','R',' ')}}, /* Manga Kanuri -> Kanuri */ + {"kca", {HB_TAG('K','H','K',' '), /* Khanty -> Khanty-Kazim */ + HB_TAG('K','H','S',' '), /* Khanty -> Khanty-Shurishkar */ + HB_TAG('K','H','V',' ')}}, /* Khanty -> Khanty-Vakhi */ + {"kde", {HB_TAG('K','D','E',' ')}}, /* Makonde */ + {"kdr", {HB_TAG('K','R','M',' ')}}, /* Karaim */ + {"kdt", {HB_TAG('K','U','Y',' ')}}, /* Kuy */ + {"kea", {HB_TAG('K','E','A',' ')}}, /* Kabuverdianu (Crioulo) */ + {"kek", {HB_TAG('K','E','K',' ')}}, /* Kekchi */ + {"kex", {HB_TAG('K','K','N',' ')}}, /* Kukna -> Kokni */ + {"kfa", {HB_TAG('K','O','D',' ')}}, /* Kodava -> Kodagu */ + {"kfr", {HB_TAG('K','A','C',' ')}}, /* Kachhi -> Kachchi */ + {"kfx", {HB_TAG('K','U','L',' ')}}, /* Kullu Pahari -> Kulvi */ + {"kfy", {HB_TAG('K','M','N',' ')}}, /* Kumaoni */ + {"kg", {HB_TAG('K','O','N','0')}}, /* Kongo [macrolanguage] */ + {"kha", {HB_TAG('K','S','I',' ')}}, /* Khasi */ + {"khb", {HB_TAG('X','B','D',' ')}}, /* Lü */ + {"khk", {HB_TAG('M','N','G',' ')}}, /* Halh Mongolian -> Mongolian */ + {"kht", {HB_TAG('K','H','N',' '), /* Khamti -> Khamti Shan (Microsoft fonts) */ + HB_TAG('K','H','T',' ')}}, /* Khamti -> Khamti Shan (OpenType spec and SIL fonts) */ + {"khw", {HB_TAG('K','H','W',' ')}}, /* Khowar */ + {"ki", {HB_TAG('K','I','K',' ')}}, /* Kikuyu (Gikuyu) */ + {"kiu", {HB_TAG('K','I','U',' ')}}, /* Kirmanjki */ + {"kj", {HB_TAG('K','U','A',' ')}}, /* Kuanyama */ + {"kjd", {HB_TAG('K','J','D',' ')}}, /* Southern Kiwai */ + {"kjh", {HB_TAG('K','H','A',' ')}}, /* Khakas -> Khakass */ + {"kjp", {HB_TAG('K','J','P',' ')}}, /* Pwo Eastern Karen -> Eastern Pwo Karen */ + {"kjz", {HB_TAG('K','J','Z',' ')}}, /* Bumthangkha */ + {"kk", {HB_TAG('K','A','Z',' ')}}, /* Kazakh */ + {"kkz", {HB_TAG('A','T','H',' ')}}, /* Kaska -> Athapaskan */ + {"kl", {HB_TAG('G','R','N',' ')}}, /* Greenlandic */ + {"kln", {HB_TAG('K','A','L',' ')}}, /* Kalenjin [macrolanguage] */ + {"km", {HB_TAG('K','H','M',' ')}}, /* Khmer */ + {"kmb", {HB_TAG('M','B','N',' ')}}, /* Kimbundu -> Mbundu */ + {"kmr", {HB_TAG('K','U','R',' ')}}, /* Northern Kurdish -> Kurdish */ + {"kmw", {HB_TAG('K','M','O',' ')}}, /* Komo (Democratic Republic of Congo) */ + {"kmz", {HB_TAG('K','M','Z',' ')}}, /* Khorasani Turkish -> Khorasani Turkic */ + {"kn", {HB_TAG('K','A','N',' ')}}, /* Kannada */ + {"knc", {HB_TAG('K','N','R',' ')}}, /* Central Kanuri -> Kanuri */ + {"kng", {HB_TAG('K','O','N','0')}}, /* Koongo -> Kongo */ + {"knn", {HB_TAG('K','O','K',' ')}}, /* Konkani */ + {"ko", {HB_TAG('K','O','R',' ')}}, /* Korean */ + {"koi", {HB_TAG('K','O','P',' ')}}, /* Komi-Permyak */ + {"kok", {HB_TAG('K','O','K',' ')}}, /* Konkani [macrolanguage] */ + {"kos", {HB_TAG('K','O','S',' ')}}, /* Kosraean */ + {"koy", {HB_TAG('A','T','H',' ')}}, /* Koyukon -> Athapaskan */ + {"kpe", {HB_TAG('K','P','L',' ')}}, /* Kpelle [macrolanguage] */ + {"kpv", {HB_TAG('K','O','Z',' ')}}, /* Komi-Zyrian */ + {"kpy", {HB_TAG('K','Y','K',' ')}}, /* Koryak */ + {"kqs", {HB_TAG('K','I','S',' ')}}, /* Northern Kissi -> Kisii */ + {"kqy", {HB_TAG('K','R','T',' ')}}, /* Koorete */ + {"kr", {HB_TAG('K','N','R',' ')}}, /* Kanuri [macrolanguage] */ + {"krc", {HB_TAG('K','A','R',' '), /* Karachay-Balkar -> Karachay */ + HB_TAG('B','A','L',' ')}}, /* Karachay-Balkar -> Balkar */ + {"kri", {HB_TAG('K','R','I',' ')}}, /* Krio */ + {"krl", {HB_TAG('K','R','L',' ')}}, /* Karelian */ + {"krt", {HB_TAG('K','N','R',' ')}}, /* Tumari Kanuri -> Kanuri */ + {"kru", {HB_TAG('K','U','U',' ')}}, /* Kurukh */ + {"ks", {HB_TAG('K','S','H',' ')}}, /* Kashmiri */ + {"ksh", {HB_TAG('K','S','H','0')}}, /* Kölsch -> Ripuarian */ + {"kss", {HB_TAG('K','I','S',' ')}}, /* Southern Kisi -> Kisii */ + {"ksw", {HB_TAG('K','S','W',' ')}}, /* S’gaw Karen */ + {"ktb", {HB_TAG('K','E','B',' ')}}, /* Kambaata -> Kebena */ + {"ktu", {HB_TAG('K','O','N',' ')}}, /* Kituba (Democratic Republic of Congo) -> Kikongo */ + {"ktw", {HB_TAG('A','T','H',' ')}}, /* Kato -> Athapaskan */ + {"ku", {HB_TAG('K','U','R',' ')}}, /* Kurdish [macrolanguage] */ + {"kum", {HB_TAG('K','U','M',' ')}}, /* Kumyk */ + {"kuu", {HB_TAG('A','T','H',' ')}}, /* Upper Kuskokwim -> Athapaskan */ + {"kv", {HB_TAG('K','O','M',' ')}}, /* Komi [macrolanguage] */ + {"kvb", {HB_TAG('M','L','Y',' ')}}, /* Kubu -> Malay */ + {"kvr", {HB_TAG('M','L','Y',' ')}}, /* Kerinci -> Malay */ + {"kw", {HB_TAG('C','O','R',' ')}}, /* Cornish */ + {"kwy", {HB_TAG('K','O','N','0')}}, /* San Salvador Kongo -> Kongo */ + {"kxc", {HB_TAG('K','M','S',' ')}}, /* Konso -> Komso */ + {"kxd", {HB_TAG('M','L','Y',' ')}}, /* Brunei -> Malay */ + {"kxu", {HB_TAG('K','U','I',' ')}}, /* Kui (India) */ + {"ky", {HB_TAG('K','I','R',' ')}}, /* Kirghiz (Kyrgyz) */ + {"kyu", {HB_TAG('K','Y','U',' ')}}, /* Western Kayah */ + {"la", {HB_TAG('L','A','T',' ')}}, /* Latin */ + {"lad", {HB_TAG('J','U','D',' ')}}, /* Ladino */ + {"lb", {HB_TAG('L','T','Z',' ')}}, /* Luxembourgish */ + {"lbe", {HB_TAG('L','A','K',' ')}}, /* Lak */ + {"lbj", {HB_TAG('L','D','K',' ')}}, /* Ladakhi */ + {"lbl", {HB_TAG('B','I','K',' ')}}, /* Libon Bikol -> Bikol */ + {"lce", {HB_TAG('M','L','Y',' ')}}, /* Loncong -> Malay */ + {"lcf", {HB_TAG('M','L','Y',' ')}}, /* Lubu -> Malay */ + {"ldi", {HB_TAG('K','O','N','0')}}, /* Laari -> Kongo */ + {"lez", {HB_TAG('L','E','Z',' ')}}, /* Lezghian -> Lezgi */ + {"lg", {HB_TAG('L','U','G',' ')}}, /* Ganda */ + {"li", {HB_TAG('L','I','M',' ')}}, /* Limburgish */ + {"lif", {HB_TAG('L','M','B',' ')}}, /* Limbu */ + {"lij", {HB_TAG('L','I','J',' ')}}, /* Ligurian */ + {"lis", {HB_TAG('L','I','S',' ')}}, /* Lisu */ + {"liw", {HB_TAG('M','L','Y',' ')}}, /* Col -> Malay */ + {"ljp", {HB_TAG('L','J','P',' ')}}, /* Lampung Api -> Lampung */ + {"lkb", {HB_TAG('L','U','H',' ')}}, /* Kabras -> Luyia */ + {"lki", {HB_TAG('L','K','I',' ')}}, /* Laki */ + {"lko", {HB_TAG('L','U','H',' ')}}, /* Khayo -> Luyia */ + {"lks", {HB_TAG('L','U','H',' ')}}, /* Kisa -> Luyia */ + {"lld", {HB_TAG('L','A','D',' ')}}, /* Ladin */ + {"lmn", {HB_TAG('L','A','M',' ')}}, /* Lambadi -> Lambani */ + {"lmo", {HB_TAG('L','M','O',' ')}}, /* Lombard */ + {"ln", {HB_TAG('L','I','N',' ')}}, /* Lingala */ + {"lo", {HB_TAG('L','A','O',' ')}}, /* Lao */ + {"lom", {HB_TAG('L','O','M',' ')}}, /* Loma (Liberia) */ + {"lrc", {HB_TAG('L','R','C',' ')}}, /* Northern Luri -> Luri */ + {"lri", {HB_TAG('L','U','H',' ')}}, /* Marachi -> Luyia */ + {"lrm", {HB_TAG('L','U','H',' ')}}, /* Marama -> Luyia */ + {"lsm", {HB_TAG('L','U','H',' ')}}, /* Saamia -> Luyia */ + {"lt", {HB_TAG('L','T','H',' ')}}, /* Lithuanian */ + {"ltg", {HB_TAG('L','V','I',' ')}}, /* Latgalian -> Latvian */ + {"lto", {HB_TAG('L','U','H',' ')}}, /* Tsotso -> Luyia */ + {"lts", {HB_TAG('L','U','H',' ')}}, /* Tachoni -> Luyia */ + {"lu", {HB_TAG('L','U','B',' ')}}, /* Luba-Katanga */ + {"lua", {HB_TAG('L','U','A',' ')}}, /* Luba-Lulua */ + {"luo", {HB_TAG('L','U','O',' ')}}, /* Luo (Kenya and Tanzania) */ + {"lus", {HB_TAG('M','I','Z',' ')}}, /* Lushai -> Mizo */ + {"luy", {HB_TAG('L','U','H',' ')}}, /* Luyia [macrolanguage] */ + {"luz", {HB_TAG('L','R','C',' ')}}, /* Southern Luri -> Luri */ + {"lv", {HB_TAG('L','V','I',' ')}}, /* Latvian [macrolanguage] */ + {"lvs", {HB_TAG('L','V','I',' ')}}, /* Standard Latvian -> Latvian */ + {"lwg", {HB_TAG('L','U','H',' ')}}, /* Wanga -> Luyia */ + {"lzh", {HB_TAG('Z','H','T',' ')}}, /* Literary Chinese -> Chinese Traditional */ + {"lzz", {HB_TAG('L','A','Z',' ')}}, /* Laz */ + {"mad", {HB_TAG('M','A','D',' ')}}, /* Madurese -> Madura */ + {"mag", {HB_TAG('M','A','G',' ')}}, /* Magahi */ + {"mai", {HB_TAG('M','T','H',' ')}}, /* Maithili */ + {"mak", {HB_TAG('M','K','R',' ')}}, /* Makasar */ + {"mam", {HB_TAG('M','A','M',' ')}}, /* Mam */ + {"man", {HB_TAG('M','N','K',' ')}}, /* Mandingo [macrolanguage] -> Maninka */ + {"max", {HB_TAG('M','L','Y',' ')}}, /* North Moluccan Malay -> Malay */ + {"mbo", {HB_TAG('M','B','O',' ')}}, /* Mbo (Cameroon) */ + {"mct", {HB_TAG('B','T','I',' ')}}, /* Mengisa -> Beti */ + {"mdf", {HB_TAG('M','O','K',' ')}}, /* Moksha */ + {"mdr", {HB_TAG('M','D','R',' ')}}, /* Mandar */ + {"mdy", {HB_TAG('M','L','E',' ')}}, /* Male (Ethiopia) */ + {"men", {HB_TAG('M','D','E',' ')}}, /* Mende (Sierra Leone) */ + {"meo", {HB_TAG('M','L','Y',' ')}}, /* Kedah Malay -> Malay */ + {"mer", {HB_TAG('M','E','R',' ')}}, /* Meru */ + {"mfa", {HB_TAG('M','F','A',' ')}}, /* Pattani Malay */ + {"mfb", {HB_TAG('M','L','Y',' ')}}, /* Bangka -> Malay */ + {"mfe", {HB_TAG('M','F','E',' ')}}, /* Morisyen */ + {"mg", {HB_TAG('M','L','G',' ')}}, /* Malagasy [macrolanguage] */ + {"mh", {HB_TAG('M','A','H',' ')}}, /* Marshallese */ + {"mhr", {HB_TAG('L','M','A',' ')}}, /* Eastern Mari -> Low Mari */ + {"mhv", {HB_TAG('A','R','K',' ')}}, /* Arakanese (retired code) -> Rakhine */ + {"mi", {HB_TAG('M','R','I',' ')}}, /* Maori */ + {"min", {HB_TAG('M','I','N',' ')}}, /* Minangkabau */ + {"mk", {HB_TAG('M','K','D',' ')}}, /* Macedonian */ + {"mku", {HB_TAG('M','N','K',' ')}}, /* Konyanka Maninka -> Maninka */ + {"mkw", {HB_TAG('M','K','W',' ')}}, /* Kituba (Congo) */ + {"ml", {HB_TAG('M','A','L',' '), /* Malayalam -> Malayalam Traditional */ + HB_TAG('M','L','R',' ')}}, /* Malayalam -> Malayalam Reformed */ + {"mlq", {HB_TAG('M','L','N',' '), /* Western Maninkakan -> Malinke */ + HB_TAG('M','N','K',' ')}}, /* Western Maninkakan -> Maninka */ + {"mmr", {HB_TAG('H','M','N',' ')}}, /* Western Xiangxi Miao -> Hmong */ + {"mn", {HB_TAG('M','N','G',' ')}}, /* Mongolian [macrolanguage] */ + {"mnc", {HB_TAG('M','C','H',' ')}}, /* Manchu */ + {"mni", {HB_TAG('M','N','I',' ')}}, /* Manipuri */ + {"mnk", {HB_TAG('M','N','D',' '), /* Mandinka */ + HB_TAG('M','N','K',' ')}}, /* Mandinka -> Maninka */ + {"mnp", {HB_TAG('Z','H','S',' ')}}, /* Min Bei Chinese -> Chinese Simplified */ + {"mns", {HB_TAG('M','A','N',' ')}}, /* Mansi */ + {"mnw", {HB_TAG('M','O','N',' ')}}, /* Mon */ + {"mo", {HB_TAG('M','O','L',' ')}}, /* Moldavian (retired code) */ + {"moh", {HB_TAG('M','O','H',' ')}}, /* Mohawk */ + {"mos", {HB_TAG('M','O','S',' ')}}, /* Mossi */ + {"mpe", {HB_TAG('M','A','J',' ')}}, /* Majang */ + {"mqg", {HB_TAG('M','L','Y',' ')}}, /* Kota Bangun Kutai Malay -> Malay */ + {"mr", {HB_TAG('M','A','R',' ')}}, /* Marathi */ + {"mrh", {HB_TAG('Q','I','N',' ')}}, /* Mara Chin -> Chin */ + {"mrj", {HB_TAG('H','M','A',' ')}}, /* Western Mari -> High Mari */ + {"ms", {HB_TAG('M','L','Y',' ')}}, /* Malay [macrolanguage] */ + {"msc", {HB_TAG('M','N','K',' ')}}, /* Sankaran Maninka -> Maninka */ + {"msh", {HB_TAG('M','L','G',' ')}}, /* Masikoro Malagasy -> Malagasy */ + {"msi", {HB_TAG('M','L','Y',' ')}}, /* Sabah Malay -> Malay */ + {"mt", {HB_TAG('M','T','S',' ')}}, /* Maltese */ + {"mtr", {HB_TAG('M','A','W',' ')}}, /* Mewari -> Marwari */ + {"mui", {HB_TAG('M','L','Y',' ')}}, /* Musi -> Malay */ + {"mup", {HB_TAG('R','A','J',' ')}}, /* Malvi -> Rajasthani */ + {"muq", {HB_TAG('H','M','N',' ')}}, /* Eastern Xiangxi Miao -> Hmong */ + {"mus", {HB_TAG('M','U','S',' ')}}, /* Creek -> Muscogee */ + {"mvb", {HB_TAG('A','T','H',' ')}}, /* Mattole -> Athapaskan */ + {"mve", {HB_TAG('M','A','W',' ')}}, /* Marwari (Pakistan) */ + {"mvf", {HB_TAG('M','N','G',' ')}}, /* Peripheral Mongolian -> Mongolian */ + {"mwk", {HB_TAG('M','N','K',' ')}}, /* Kita Maninkakan -> Maninka */ + {"mwl", {HB_TAG('M','W','L',' ')}}, /* Mirandese */ + {"mwr", {HB_TAG('M','A','W',' ')}}, /* Marwari [macrolanguage] */ + {"mww", {HB_TAG('M','W','W',' ')}}, /* Hmong Daw */ + {"my", {HB_TAG('B','R','M',' ')}}, /* Burmese */ + {"mym", {HB_TAG('M','E','N',' ')}}, /* Me'en */ + {"myn", {HB_TAG('M','Y','N',' ')}}, /* Mayan [family] */ + {"myq", {HB_TAG('M','N','K',' ')}}, /* Forest Maninka (retired code) -> Maninka */ + {"myv", {HB_TAG('E','R','Z',' ')}}, /* Erzya */ + {"mzn", {HB_TAG('M','Z','N',' ')}}, /* Mazanderani */ + {"na", {HB_TAG('N','A','U',' ')}}, /* Nauru -> Nauruan */ + {"nag", {HB_TAG('N','A','G',' ')}}, /* Naga Pidgin -> Naga-Assamese */ + {"nah", {HB_TAG('N','A','H',' ')}}, /* Nahuatl [family] */ + {"nan", {HB_TAG('Z','H','S',' ')}}, /* Min Nan Chinese -> Chinese Simplified */ + {"nap", {HB_TAG('N','A','P',' ')}}, /* Neapolitan */ + {"nb", {HB_TAG('N','O','R',' ')}}, /* Norwegian Bokmål -> Norwegian */ + {"nd", {HB_TAG('N','D','B',' ')}}, /* North Ndebele -> Ndebele */ + {"ndc", {HB_TAG('N','D','C',' ')}}, /* Ndau */ + {"nds", {HB_TAG('N','D','S',' ')}}, /* Low Saxon */ + {"ne", {HB_TAG('N','E','P',' ')}}, /* Nepali [macrolanguage] */ + {"new", {HB_TAG('N','E','W',' ')}}, /* Newari */ + {"ng", {HB_TAG('N','D','G',' ')}}, /* Ndonga */ + {"nga", {HB_TAG('N','G','A',' ')}}, /* Ngbaka */ + {"ngl", {HB_TAG('L','M','W',' ')}}, /* Lomwe */ + {"ngo", {HB_TAG('S','X','T',' ')}}, /* Ngoni -> Sutu */ + {"nhd", {HB_TAG('G','U','A',' ')}}, /* Chiripá -> Guarani */ + {"niq", {HB_TAG('K','A','L',' ')}}, /* Nandi -> Kalenjin */ + {"niu", {HB_TAG('N','I','U',' ')}}, /* Niuean */ + {"niv", {HB_TAG('G','I','L',' ')}}, /* Gilyak */ + {"njz", {HB_TAG('N','I','S',' ')}}, /* Nyishi -> Nisi */ + {"nl", {HB_TAG('N','L','D',' ')}}, /* Dutch */ + {"nle", {HB_TAG('L','U','H',' ')}}, /* East Nyala -> Luyia */ + {"nn", {HB_TAG('N','Y','N',' ')}}, /* Norwegian Nynorsk (Nynorsk, Norwegian) */ + {"no", {HB_TAG('N','O','R',' ')}}, /* Norwegian [macrolanguage] */ + {"nod", {HB_TAG('N','T','A',' ')}}, /* Northern Thai -> Northern Tai */ + {"noe", {HB_TAG('N','O','E',' ')}}, /* Nimadi */ + {"nog", {HB_TAG('N','O','G',' ')}}, /* Nogai */ + {"nov", {HB_TAG('N','O','V',' ')}}, /* Novial */ + {"npi", {HB_TAG('N','E','P',' ')}}, /* Nepali */ + {"nqo", {HB_TAG('N','K','O',' ')}}, /* N'Ko */ + {"nr", {HB_TAG('N','D','B',' ')}}, /* South Ndebele -> Ndebele */ + {"nsk", {HB_TAG('N','A','S',' ')}}, /* Naskapi */ + {"nso", {HB_TAG('N','S','O',' ')}}, /* Pedi -> Sotho, Northern */ + {"nv", {HB_TAG('N','A','V',' '), /* Navajo */ + HB_TAG('A','T','H',' ')}}, /* Navajo -> Athapaskan */ + {"ny", {HB_TAG('C','H','I',' ')}}, /* Chichewa (Chewa, Nyanja) */ + {"nyd", {HB_TAG('L','U','H',' ')}}, /* Nyore -> Luyia */ + {"nym", {HB_TAG('N','Y','M',' ')}}, /* Nyamwezi */ + {"nyn", {HB_TAG('N','K','L',' ')}}, /* Nyankole */ + {"nza", {HB_TAG('N','Z','A',' ')}}, /* Tigon Mbembe -> Mbembe Tigon */ + {"oc", {HB_TAG('O','C','I',' ')}}, /* Occitan (post 1500) */ + {"oj", {HB_TAG('O','J','B',' ')}}, /* Ojibwa [macrolanguage] -> Ojibway */ + {"ojb", {HB_TAG('O','J','B',' ')}}, /* Northwestern Ojibwa -> Ojibway */ + {"ojc", {HB_TAG('O','J','B',' ')}}, /* Central Ojibwa -> Ojibway */ + {"ojg", {HB_TAG('O','J','B',' ')}}, /* Eastern Ojibwa -> Ojibway */ + {"ojs", {HB_TAG('O','C','R',' ')}}, /* Severn Ojibwa -> Oji-Cree */ + {"ojw", {HB_TAG('O','J','B',' ')}}, /* Western Ojibwa -> Ojibway */ + {"oki", {HB_TAG('K','A','L',' ')}}, /* Okiek -> Kalenjin */ + {"okm", {HB_TAG('K','O','H',' ')}}, /* Middle Korean (10th-16th cent.) -> Korean Old Hangul */ + {"om", {HB_TAG('O','R','O',' ')}}, /* Oromo [macrolanguage] */ + {"or", {HB_TAG('O','R','I',' ')}}, /* Odia (formerly Oriya) [macrolanguage] */ + {"orc", {HB_TAG('O','R','O',' ')}}, /* Orma -> Oromo */ + {"orn", {HB_TAG('M','L','Y',' ')}}, /* Orang Kanaq -> Malay */ + {"ors", {HB_TAG('M','L','Y',' ')}}, /* Orang Seletar -> Malay */ + {"ory", {HB_TAG('O','R','I',' ')}}, /* Odia (formerly Oriya) */ + {"os", {HB_TAG('O','S','S',' ')}}, /* Ossetian */ + {"otw", {HB_TAG('O','J','B',' ')}}, /* Ottawa -> Ojibway */ + {"pa", {HB_TAG('P','A','N',' ')}}, /* Punjabi */ + {"pag", {HB_TAG('P','A','G',' ')}}, /* Pangasinan */ + {"pam", {HB_TAG('P','A','M',' ')}}, /* Pampanga -> Pampangan */ + {"pap", {HB_TAG('P','A','P','0')}}, /* Papiamento -> Papiamentu */ + {"pau", {HB_TAG('P','A','U',' ')}}, /* Palauan */ + {"pbt", {HB_TAG('P','A','S',' ')}}, /* Southern Pashto -> Pashto */ + {"pbu", {HB_TAG('P','A','S',' ')}}, /* Northern Pashto -> Pashto */ + {"pcc", {HB_TAG('P','C','C',' ')}}, /* Bouyei */ + {"pcd", {HB_TAG('P','C','D',' ')}}, /* Picard */ + {"pce", {HB_TAG('P','L','G',' ')}}, /* Ruching Palaung -> Palaung */ + {"pck", {HB_TAG('Q','I','N',' ')}}, /* Paite Chin -> Chin */ + {"pdc", {HB_TAG('P','D','C',' ')}}, /* Pennsylvania German */ + {"pel", {HB_TAG('M','L','Y',' ')}}, /* Pekal -> Malay */ + {"pes", {HB_TAG('F','A','R',' ')}}, /* Iranian Persian -> Persian */ + {"pga", {HB_TAG('A','R','A',' ')}}, /* Sudanese Creole Arabic -> Arabic */ + {"phk", {HB_TAG('P','H','K',' ')}}, /* Phake */ + {"pi", {HB_TAG('P','A','L',' ')}}, /* Pali */ + {"pih", {HB_TAG('P','I','H',' ')}}, /* Pitcairn-Norfolk -> Norfolk */ + {"pko", {HB_TAG('K','A','L',' ')}}, /* Pökoot -> Kalenjin */ + {"pl", {HB_TAG('P','L','K',' ')}}, /* Polish */ + {"pll", {HB_TAG('P','L','G',' ')}}, /* Shwe Palaung -> Palaung */ + {"plp", {HB_TAG('P','A','P',' ')}}, /* Palpa */ + {"plt", {HB_TAG('M','L','G',' ')}}, /* Plateau Malagasy -> Malagasy */ + {"pms", {HB_TAG('P','M','S',' ')}}, /* Piemontese */ + {"pnb", {HB_TAG('P','N','B',' ')}}, /* Western Panjabi */ + {"poh", {HB_TAG('P','O','H',' ')}}, /* Poqomchi' -> Pocomchi */ + {"pon", {HB_TAG('P','O','N',' ')}}, /* Pohnpeian */ + {"ppa", {HB_TAG('B','A','G',' ')}}, /* Pao (retired code) -> Baghelkhandi */ + {"pro", {HB_TAG('P','R','O',' ')}}, /* Old Provençal (to 1500) -> Provençal / Old Provençal */ + {"prs", {HB_TAG('D','R','I',' ')}}, /* Dari */ + {"ps", {HB_TAG('P','A','S',' ')}}, /* Pashto [macrolanguage] */ + {"pse", {HB_TAG('M','L','Y',' ')}}, /* Central Malay -> Malay */ + {"pst", {HB_TAG('P','A','S',' ')}}, /* Central Pashto -> Pashto */ + {"pt", {HB_TAG('P','T','G',' ')}}, /* Portuguese */ + {"pwo", {HB_TAG('P','W','O',' ')}}, /* Pwo Western Karen -> Western Pwo Karen */ + {"qu", {HB_TAG('Q','U','Z',' ')}}, /* Quechua [macrolanguage] */ + {"qub", {HB_TAG('Q','W','H',' ')}}, /* Huallaga Huánuco Quechua -> Quechua (Peru) */ + {"quc", {HB_TAG('Q','U','C',' ')}}, /* K’iche’ */ + {"qud", {HB_TAG('Q','V','I',' ')}}, /* Calderón Highland Quichua -> Quechua (Ecuador) */ + {"quf", {HB_TAG('Q','U','Z',' ')}}, /* Lambayeque Quechua -> Quechua */ + {"qug", {HB_TAG('Q','V','I',' ')}}, /* Chimborazo Highland Quichua -> Quechua (Ecuador) */ + {"quh", {HB_TAG('Q','U','H',' ')}}, /* South Bolivian Quechua -> Quechua (Bolivia) */ + {"quk", {HB_TAG('Q','U','Z',' ')}}, /* Chachapoyas Quechua -> Quechua */ + {"qul", {HB_TAG('Q','U','Z',' ')}}, /* North Bolivian Quechua -> Quechua */ + {"qup", {HB_TAG('Q','V','I',' ')}}, /* Southern Pastaza Quechua -> Quechua (Ecuador) */ + {"qur", {HB_TAG('Q','W','H',' ')}}, /* Yanahuanca Pasco Quechua -> Quechua (Peru) */ + {"qus", {HB_TAG('Q','U','H',' ')}}, /* Santiago del Estero Quichua -> Quechua (Bolivia) */ + {"quw", {HB_TAG('Q','V','I',' ')}}, /* Tena Lowland Quichua -> Quechua (Ecuador) */ + {"qux", {HB_TAG('Q','W','H',' ')}}, /* Yauyos Quechua -> Quechua (Peru) */ + {"quy", {HB_TAG('Q','U','Z',' ')}}, /* Ayacucho Quechua -> Quechua */ + {"quz", {HB_TAG('Q','U','Z',' ')}}, /* Cusco Quechua -> Quechua */ + {"qva", {HB_TAG('Q','W','H',' ')}}, /* Ambo-Pasco Quechua -> Quechua (Peru) */ + {"qvc", {HB_TAG('Q','U','Z',' ')}}, /* Cajamarca Quechua -> Quechua */ + {"qve", {HB_TAG('Q','U','Z',' ')}}, /* Eastern Apurímac Quechua -> Quechua */ + {"qvh", {HB_TAG('Q','W','H',' ')}}, /* Huamalíes-Dos de Mayo Huánuco Quechua -> Quechua (Peru) */ + {"qvi", {HB_TAG('Q','V','I',' ')}}, /* Imbabura Highland Quichua -> Quechua (Ecuador) */ + {"qvj", {HB_TAG('Q','V','I',' ')}}, /* Loja Highland Quichua -> Quechua (Ecuador) */ + {"qvl", {HB_TAG('Q','W','H',' ')}}, /* Cajatambo North Lima Quechua -> Quechua (Peru) */ + {"qvm", {HB_TAG('Q','W','H',' ')}}, /* Margos-Yarowilca-Lauricocha Quechua -> Quechua (Peru) */ + {"qvn", {HB_TAG('Q','W','H',' ')}}, /* North Junín Quechua -> Quechua (Peru) */ + {"qvo", {HB_TAG('Q','V','I',' ')}}, /* Napo Lowland Quechua -> Quechua (Ecuador) */ + {"qvp", {HB_TAG('Q','W','H',' ')}}, /* Pacaraos Quechua -> Quechua (Peru) */ + {"qvs", {HB_TAG('Q','U','Z',' ')}}, /* San Martín Quechua -> Quechua */ + {"qvw", {HB_TAG('Q','W','H',' ')}}, /* Huaylla Wanca Quechua -> Quechua (Peru) */ + {"qvz", {HB_TAG('Q','V','I',' ')}}, /* Northern Pastaza Quichua -> Quechua (Ecuador) */ + {"qwa", {HB_TAG('Q','W','H',' ')}}, /* Corongo Ancash Quechua -> Quechua (Peru) */ + {"qwc", {HB_TAG('Q','U','Z',' ')}}, /* Classical Quechua -> Quechua */ + {"qwh", {HB_TAG('Q','W','H',' ')}}, /* Huaylas Ancash Quechua -> Quechua (Peru) */ + {"qws", {HB_TAG('Q','W','H',' ')}}, /* Sihuas Ancash Quechua -> Quechua (Peru) */ + {"qxa", {HB_TAG('Q','W','H',' ')}}, /* Chiquián Ancash Quechua -> Quechua (Peru) */ + {"qxc", {HB_TAG('Q','W','H',' ')}}, /* Chincha Quechua -> Quechua (Peru) */ + {"qxh", {HB_TAG('Q','W','H',' ')}}, /* Panao Huánuco Quechua -> Quechua (Peru) */ + {"qxl", {HB_TAG('Q','V','I',' ')}}, /* Salasaca Highland Quichua -> Quechua (Ecuador) */ + {"qxn", {HB_TAG('Q','W','H',' ')}}, /* Northern Conchucos Ancash Quechua -> Quechua (Peru) */ + {"qxo", {HB_TAG('Q','W','H',' ')}}, /* Southern Conchucos Ancash Quechua -> Quechua (Peru) */ + {"qxp", {HB_TAG('Q','U','Z',' ')}}, /* Puno Quechua -> Quechua */ + {"qxr", {HB_TAG('Q','V','I',' ')}}, /* Cañar Highland Quichua -> Quechua (Ecuador) */ + {"qxt", {HB_TAG('Q','W','H',' ')}}, /* Santa Ana de Tusi Pasco Quechua -> Quechua (Peru) */ + {"qxu", {HB_TAG('Q','U','Z',' ')}}, /* Arequipa-La Unión Quechua -> Quechua */ + {"qxw", {HB_TAG('Q','W','H',' ')}}, /* Jauja Wanca Quechua -> Quechua (Peru) */ + {"rag", {HB_TAG('L','U','H',' ')}}, /* Logooli -> Luyia */ + {"raj", {HB_TAG('R','A','J',' ')}}, /* Rajasthani [macrolanguage] */ + {"rar", {HB_TAG('R','A','R',' ')}}, /* Rarotongan */ + {"rbb", {HB_TAG('P','L','G',' ')}}, /* Rumai Palaung -> Palaung */ + {"rbl", {HB_TAG('B','I','K',' ')}}, /* Miraya Bikol -> Bikol */ + {"rej", {HB_TAG('R','E','J',' ')}}, /* Rejang */ + {"ria", {HB_TAG('R','I','A',' ')}}, /* Riang (India) */ + {"rif", {HB_TAG('R','I','F',' ')}}, /* Tarifit */ + {"rit", {HB_TAG('R','I','T',' ')}}, /* Ritarungo */ + {"rki", {HB_TAG('A','R','K',' ')}}, /* Rakhine */ + {"rkw", {HB_TAG('R','K','W',' ')}}, /* Arakwal */ + {"rm", {HB_TAG('R','M','S',' ')}}, /* Romansh */ + {"rmc", {HB_TAG('R','O','Y',' ')}}, /* Carpathian Romani -> Romany */ + {"rmf", {HB_TAG('R','O','Y',' ')}}, /* Kalo Finnish Romani -> Romany */ + {"rml", {HB_TAG('R','O','Y',' ')}}, /* Baltic Romani -> Romany */ + {"rmn", {HB_TAG('R','O','Y',' ')}}, /* Balkan Romani -> Romany */ + {"rmo", {HB_TAG('R','O','Y',' ')}}, /* Sinte Romani -> Romany */ + {"rmw", {HB_TAG('R','O','Y',' ')}}, /* Welsh Romani -> Romany */ + {"rmy", {HB_TAG('R','M','Y',' ')}}, /* Vlax Romani */ + {"rmz", {HB_TAG('A','R','K',' ')}}, /* Marma -> Rakhine */ + {"rn", {HB_TAG('R','U','N',' ')}}, /* Rundi */ + {"rnl", {HB_TAG('H','A','L',' ')}}, /* Ranglong -> Halam (Falam Chin) */ + {"ro", {HB_TAG('R','O','M',' ')}}, /* Romanian */ + {"rom", {HB_TAG('R','O','Y',' ')}}, /* Romany [macrolanguage] */ + {"rtm", {HB_TAG('R','T','M',' ')}}, /* Rotuman */ + {"ru", {HB_TAG('R','U','S',' ')}}, /* Russian */ + {"rue", {HB_TAG('R','S','Y',' ')}}, /* Rusyn */ + {"rup", {HB_TAG('R','U','P',' ')}}, /* Aromanian */ + {"rw", {HB_TAG('R','U','A',' ')}}, /* Kinyarwanda */ + {"rwr", {HB_TAG('M','A','W',' ')}}, /* Marwari (India) */ + {"sa", {HB_TAG('S','A','N',' ')}}, /* Sanskrit */ + {"sah", {HB_TAG('Y','A','K',' ')}}, /* Yakut -> Sakha */ + {"sam", {HB_TAG('P','A','A',' ')}}, /* Samaritan Aramaic -> Palestinian Aramaic */ + {"sas", {HB_TAG('S','A','S',' ')}}, /* Sasak */ + {"sat", {HB_TAG('S','A','T',' ')}}, /* Santali */ + {"sc", {HB_TAG('S','R','D',' ')}}, /* Sardinian [macrolanguage] */ + {"sck", {HB_TAG('S','A','D',' ')}}, /* Sadri */ + {"scn", {HB_TAG('S','C','N',' ')}}, /* Sicilian */ + {"sco", {HB_TAG('S','C','O',' ')}}, /* Scots */ + {"scs", {HB_TAG('S','C','S',' '), /* North Slavey */ + HB_TAG('S','L','A',' '), /* North Slavey -> Slavey */ + HB_TAG('A','T','H',' ')}}, /* North Slavey -> Athapaskan */ + {"sd", {HB_TAG('S','N','D',' ')}}, /* Sindhi */ + {"sdc", {HB_TAG('S','R','D',' ')}}, /* Sassarese Sardinian -> Sardinian */ + {"sdh", {HB_TAG('K','U','R',' ')}}, /* Southern Kurdish -> Kurdish */ + {"sdn", {HB_TAG('S','R','D',' ')}}, /* Gallurese Sardinian -> Sardinian */ + {"se", {HB_TAG('N','S','M',' ')}}, /* Northern Sami */ + {"seh", {HB_TAG('S','N','A',' ')}}, /* Sena */ + {"sek", {HB_TAG('A','T','H',' ')}}, /* Sekani -> Athapaskan */ + {"sel", {HB_TAG('S','E','L',' ')}}, /* Selkup */ + {"sez", {HB_TAG('Q','I','N',' ')}}, /* Senthang Chin -> Chin */ + {"sfm", {HB_TAG('H','M','N',' ')}}, /* Small Flowery Miao -> Hmong */ + {"sg", {HB_TAG('S','G','O',' ')}}, /* Sango */ + {"sga", {HB_TAG('S','G','A',' ')}}, /* Old Irish (to 900) */ + {"sgc", {HB_TAG('K','A','L',' ')}}, /* Kipsigis -> Kalenjin */ + {"sgs", {HB_TAG('S','G','S',' ')}}, /* Samogitian */ + {"sgw", {HB_TAG('C','H','G',' '), /* Sebat Bet Gurage -> Chaha Gurage */ + HB_TAG('S','G','W',' ')}}, /* Sebat Bet Gurage -> Chaha Gurage (SIL fonts) */ + {"shi", {HB_TAG('S','H','I',' ')}}, /* Tachelhit */ + {"shn", {HB_TAG('S','H','N',' ')}}, /* Shan */ + {"shu", {HB_TAG('A','R','A',' ')}}, /* Chadian Arabic -> Arabic */ + {"si", {HB_TAG('S','N','H',' ')}}, /* Sinhala (Sinhalese) */ + {"sid", {HB_TAG('S','I','D',' ')}}, /* Sidamo */ + {"sjd", {HB_TAG('K','S','M',' ')}}, /* Kildin Sami */ + {"sjo", {HB_TAG('S','I','B',' ')}}, /* Xibe -> Sibe */ + {"sk", {HB_TAG('S','K','Y',' ')}}, /* Slovak */ + {"skg", {HB_TAG('M','L','G',' ')}}, /* Sakalava Malagasy -> Malagasy */ + {"skr", {HB_TAG('S','R','K',' ')}}, /* Saraiki */ + {"sl", {HB_TAG('S','L','V',' ')}}, /* Slovenian */ + {"sm", {HB_TAG('S','M','O',' ')}}, /* Samoan */ + {"sma", {HB_TAG('S','S','M',' ')}}, /* Southern Sami */ + {"smj", {HB_TAG('L','S','M',' ')}}, /* Lule Sami */ + {"smn", {HB_TAG('I','S','M',' ')}}, /* Inari Sami */ + {"sms", {HB_TAG('S','K','S',' ')}}, /* Skolt Sami */ + {"sn", {HB_TAG('S','N','A','0')}}, /* Shona */ + {"snk", {HB_TAG('S','N','K',' ')}}, /* Soninke */ + {"so", {HB_TAG('S','M','L',' ')}}, /* Somali */ + {"sop", {HB_TAG('S','O','P',' ')}}, /* Songe */ + {"spv", {HB_TAG('O','R','I',' ')}}, /* Sambalpuri -> Odia (formerly Oriya) */ + {"spy", {HB_TAG('K','A','L',' ')}}, /* Sabaot -> Kalenjin */ + {"sq", {HB_TAG('S','Q','I',' ')}}, /* Albanian [macrolanguage] */ + {"sr", {HB_TAG('S','R','B',' ')}}, /* Serbian */ + {"src", {HB_TAG('S','R','D',' ')}}, /* Logudorese Sardinian -> Sardinian */ + {"sro", {HB_TAG('S','R','D',' ')}}, /* Campidanese Sardinian -> Sardinian */ + {"srr", {HB_TAG('S','R','R',' ')}}, /* Serer */ + {"srs", {HB_TAG('A','T','H',' ')}}, /* Sarsi -> Athapaskan */ + {"ss", {HB_TAG('S','W','Z',' ')}}, /* Swati */ + {"ssh", {HB_TAG('A','R','A',' ')}}, /* Shihhi Arabic -> Arabic */ + {"st", {HB_TAG('S','O','T',' ')}}, /* Southern Sotho -> Sotho, Southern */ + {"stq", {HB_TAG('S','T','Q',' ')}}, /* Saterfriesisch -> Saterland Frisian */ + {"stv", {HB_TAG('S','I','G',' ')}}, /* Silt'e -> Silte Gurage */ + {"su", {HB_TAG('S','U','N',' ')}}, /* Sundanese */ + {"suk", {HB_TAG('S','U','K',' ')}}, /* Sukuma */ + {"suq", {HB_TAG('S','U','R',' ')}}, /* Suri */ + {"sv", {HB_TAG('S','V','E',' ')}}, /* Swedish */ + {"sva", {HB_TAG('S','V','A',' ')}}, /* Svan */ + {"sw", {HB_TAG('S','W','K',' ')}}, /* Swahili [macrolanguage] */ + {"swb", {HB_TAG('C','M','R',' ')}}, /* Maore Comorian -> Comorian */ + {"swc", {HB_TAG('S','W','K',' ')}}, /* Congo Swahili -> Swahili */ + {"swh", {HB_TAG('S','W','K',' ')}}, /* Swahili */ + {"swv", {HB_TAG('M','A','W',' ')}}, /* Shekhawati -> Marwari */ + {"sxu", {HB_TAG('S','X','U',' ')}}, /* Upper Saxon */ + {"syc", {HB_TAG('S','Y','R',' ')}}, /* Classical Syriac -> Syriac */ + {"syl", {HB_TAG('S','Y','L',' ')}}, /* Sylheti */ + {"syr", {HB_TAG('S','Y','R',' ')}}, /* Syriac [macrolanguage] */ + {"szl", {HB_TAG('S','Z','L',' ')}}, /* Silesian */ + {"ta", {HB_TAG('T','A','M',' ')}}, /* Tamil */ + {"taa", {HB_TAG('A','T','H',' ')}}, /* Lower Tanana -> Athapaskan */ + {"tab", {HB_TAG('T','A','B',' ')}}, /* Tabassaran -> Tabasaran */ + {"taq", {HB_TAG('T','M','H',' ')}}, /* Tamasheq -> Tamashek */ + {"tau", {HB_TAG('A','T','H',' ')}}, /* Upper Tanana -> Athapaskan */ + {"tcb", {HB_TAG('A','T','H',' ')}}, /* Tanacross -> Athapaskan */ + {"tce", {HB_TAG('A','T','H',' ')}}, /* Southern Tutchone -> Athapaskan */ + {"tcp", {HB_TAG('Q','I','N',' ')}}, /* Tawr Chin -> Chin */ + {"tcy", {HB_TAG('T','U','L',' ')}}, /* Tulu -> Tumbuka */ + {"tcz", {HB_TAG('Q','I','N',' ')}}, /* Thado Chin -> Chin */ + {"tdd", {HB_TAG('T','D','D',' ')}}, /* Tai Nüa -> Dehong Dai */ + {"tdx", {HB_TAG('M','L','G',' ')}}, /* Tandroy-Mahafaly Malagasy -> Malagasy */ + {"te", {HB_TAG('T','E','L',' ')}}, /* Telugu */ + {"tec", {HB_TAG('K','A','L',' ')}}, /* Terik -> Kalenjin */ + {"tem", {HB_TAG('T','M','N',' ')}}, /* Timne -> Temne */ + {"tet", {HB_TAG('T','E','T',' ')}}, /* Tetum */ + {"tfn", {HB_TAG('A','T','H',' ')}}, /* Tanaina -> Athapaskan */ + {"tg", {HB_TAG('T','A','J',' ')}}, /* Tajik -> Tajiki */ + {"tgj", {HB_TAG('N','I','S',' ')}}, /* Tagin -> Nisi */ + {"tgx", {HB_TAG('A','T','H',' ')}}, /* Tagish -> Athapaskan */ + {"th", {HB_TAG('T','H','A',' ')}}, /* Thai */ + {"tht", {HB_TAG('A','T','H',' ')}}, /* Tahltan -> Athapaskan */ + {"thv", {HB_TAG('T','M','H',' ')}}, /* Tahaggart Tamahaq -> Tamashek */ + {"thz", {HB_TAG('T','M','H',' ')}}, /* Tayart Tamajeq -> Tamashek */ + {"ti", {HB_TAG('T','G','Y',' ')}}, /* Tigrinya */ + {"tig", {HB_TAG('T','G','R',' ')}}, /* Tigre */ + {"tiv", {HB_TAG('T','I','V',' ')}}, /* Tiv */ + {"tk", {HB_TAG('T','K','M',' ')}}, /* Turkmen */ + {"tkg", {HB_TAG('M','L','G',' ')}}, /* Tesaka Malagasy -> Malagasy */ + {"tl", {HB_TAG('T','G','L',' ')}}, /* Tagalog */ + {"tmh", {HB_TAG('T','M','H',' ')}}, /* Tamashek [macrolanguage] */ + {"tmw", {HB_TAG('M','L','Y',' ')}}, /* Temuan -> Malay */ + {"tn", {HB_TAG('T','N','A',' ')}}, /* Tswana */ + {"tnf", {HB_TAG('D','R','I',' ')}}, /* Tangshewi (retired code) -> Dari */ + {"to", {HB_TAG('T','G','N',' ')}}, /* Tonga (Tonga Islands) -> Tongan */ + {"tod", {HB_TAG('T','O','D','0')}}, /* Toma */ + {"toi", {HB_TAG('T','N','G',' ')}}, /* Tonga (Zambia) */ + {"tol", {HB_TAG('A','T','H',' ')}}, /* Tolowa -> Athapaskan */ + {"tpi", {HB_TAG('T','P','I',' ')}}, /* Tok Pisin */ + {"tr", {HB_TAG('T','R','K',' ')}}, /* Turkish */ + {"tru", {HB_TAG('T','U','A',' '), /* Turoyo -> Turoyo Aramaic */ + HB_TAG('S','Y','R',' ')}}, /* Turoyo -> Syriac */ + {"ts", {HB_TAG('T','S','G',' ')}}, /* Tsonga */ + {"tsj", {HB_TAG('T','S','J',' ')}}, /* Tshangla */ + {"tt", {HB_TAG('T','A','T',' ')}}, /* Tatar */ + {"ttm", {HB_TAG('A','T','H',' ')}}, /* Northern Tutchone -> Athapaskan */ + {"ttq", {HB_TAG('T','M','H',' ')}}, /* Tawallammat Tamajaq -> Tamashek */ + {"tum", {HB_TAG('T','U','M',' ')}}, /* Tumbuka -> Tulu */ + {"tuu", {HB_TAG('A','T','H',' ')}}, /* Tututni -> Athapaskan */ + {"tuy", {HB_TAG('K','A','L',' ')}}, /* Tugen -> Kalenjin */ + {"tvl", {HB_TAG('T','V','L',' ')}}, /* Tuvalu */ + {"tw", {HB_TAG('T','W','I',' '), /* Twi */ + HB_TAG('A','K','A',' ')}}, /* Twi -> Akan */ + {"txc", {HB_TAG('A','T','H',' ')}}, /* Tsetsaut -> Athapaskan */ + {"txy", {HB_TAG('M','L','G',' ')}}, /* Tanosy Malagasy -> Malagasy */ + {"ty", {HB_TAG('T','H','T',' ')}}, /* Tahitian */ + {"tyv", {HB_TAG('T','U','V',' ')}}, /* Tuvinian -> Tuvin */ + {"tyz", {HB_TAG('T','Y','Z',' ')}}, /* Tày */ + {"tzm", {HB_TAG('T','Z','M',' ')}}, /* Central Atlas Tamazight -> Tamazight */ + {"tzo", {HB_TAG('T','Z','O',' ')}}, /* Tzotzil */ + {"ubl", {HB_TAG('B','I','K',' ')}}, /* Buhi'non Bikol -> Bikol */ + {"udm", {HB_TAG('U','D','M',' ')}}, /* Udmurt */ + {"ug", {HB_TAG('U','Y','G',' ')}}, /* Uyghur */ + {"uk", {HB_TAG('U','K','R',' ')}}, /* Ukrainian */ + {"umb", {HB_TAG('U','M','B',' ')}}, /* Umbundu */ + {"unr", {HB_TAG('M','U','N',' ')}}, /* Mundari */ + {"ur", {HB_TAG('U','R','D',' ')}}, /* Urdu */ + {"urk", {HB_TAG('M','L','Y',' ')}}, /* Urak Lawoi' -> Malay */ + {"uz", {HB_TAG('U','Z','B',' ')}}, /* Uzbek [macrolanguage] */ + {"uzn", {HB_TAG('U','Z','B',' ')}}, /* Northern Uzbek -> Uzbek */ + {"uzs", {HB_TAG('U','Z','B',' ')}}, /* Southern Uzbek -> Uzbek */ + {"ve", {HB_TAG('V','E','N',' ')}}, /* Venda */ + {"vec", {HB_TAG('V','E','C',' ')}}, /* Venetian */ + {"vi", {HB_TAG('V','I','T',' ')}}, /* Vietnamese */ + {"vkk", {HB_TAG('M','L','Y',' ')}}, /* Kaur -> Malay */ + {"vkt", {HB_TAG('M','L','Y',' ')}}, /* Tenggarong Kutai Malay -> Malay */ + {"vls", {HB_TAG('F','L','E',' ')}}, /* Vlaams -> Dutch (Flemish) */ + {"vmw", {HB_TAG('M','A','K',' ')}}, /* Makhuwa */ + {"vo", {HB_TAG('V','O','L',' ')}}, /* Volapük */ + {"vro", {HB_TAG('V','R','O',' ')}}, /* Võro */ + {"wa", {HB_TAG('W','L','N',' ')}}, /* Walloon */ + {"war", {HB_TAG('W','A','R',' ')}}, /* Waray (Philippines) -> Waray-Waray */ + {"wbm", {HB_TAG('W','A',' ',' ')}}, /* Wa */ + {"wbr", {HB_TAG('W','A','G',' ')}}, /* Wagdi */ + {"wlc", {HB_TAG('C','M','R',' ')}}, /* Mwali Comorian -> Comorian */ + {"wle", {HB_TAG('S','I','G',' ')}}, /* Wolane -> Silte Gurage */ + {"wlk", {HB_TAG('A','T','H',' ')}}, /* Wailaki -> Athapaskan */ + {"wni", {HB_TAG('C','M','R',' ')}}, /* Ndzwani Comorian -> Comorian */ + {"wo", {HB_TAG('W','L','F',' ')}}, /* Wolof */ + {"wry", {HB_TAG('M','A','W',' ')}}, /* Merwari -> Marwari */ + {"wsg", {HB_TAG('G','O','N',' ')}}, /* Adilabad Gondi -> Gondi */ + {"wtm", {HB_TAG('W','T','M',' ')}}, /* Mewati */ + {"wuu", {HB_TAG('Z','H','S',' ')}}, /* Wu Chinese -> Chinese Simplified */ + {"xal", {HB_TAG('K','L','M',' '), /* Kalmyk */ + HB_TAG('T','O','D',' ')}}, /* Kalmyk -> Todo */ + {"xan", {HB_TAG('S','E','K',' ')}}, /* Xamtanga -> Sekota */ + {"xh", {HB_TAG('X','H','S',' ')}}, /* Xhosa */ + {"xjb", {HB_TAG('X','J','B',' ')}}, /* Minjungbal -> Minjangbal */ + {"xkf", {HB_TAG('X','K','F',' ')}}, /* Khengkha */ + {"xmm", {HB_TAG('M','L','Y',' ')}}, /* Manado Malay -> Malay */ + {"xmv", {HB_TAG('M','L','G',' ')}}, /* Antankarana Malagasy -> Malagasy */ + {"xmw", {HB_TAG('M','L','G',' ')}}, /* Tsimihety Malagasy -> Malagasy */ + {"xnr", {HB_TAG('D','G','R',' ')}}, /* Kangri -> Dogri */ + {"xog", {HB_TAG('X','O','G',' ')}}, /* Soga */ + {"xpe", {HB_TAG('X','P','E',' ')}}, /* Liberia Kpelle -> Kpelle (Liberia) */ + {"xsl", {HB_TAG('S','S','L',' '), /* South Slavey */ + HB_TAG('S','L','A',' '), /* South Slavey -> Slavey */ + HB_TAG('A','T','H',' ')}}, /* South Slavey -> Athapaskan */ + {"xst", {HB_TAG('S','I','G',' ')}}, /* Silt'e (retired code) -> Silte Gurage */ + {"xwo", {HB_TAG('T','O','D',' ')}}, /* Written Oirat -> Todo */ + {"yao", {HB_TAG('Y','A','O',' ')}}, /* Yao */ + {"yap", {HB_TAG('Y','A','P',' ')}}, /* Yapese */ + {"ybd", {HB_TAG('A','R','K',' ')}}, /* Yangbye (retired code) -> Rakhine */ + {"ydd", {HB_TAG('J','I','I',' ')}}, /* Eastern Yiddish -> Yiddish */ + {"yi", {HB_TAG('J','I','I',' ')}}, /* Yiddish [macrolanguage] */ + {"yih", {HB_TAG('J','I','I',' ')}}, /* Western Yiddish -> Yiddish */ + {"yo", {HB_TAG('Y','B','A',' ')}}, /* Yoruba */ + {"yos", {HB_TAG('Q','I','N',' ')}}, /* Yos (retired code) -> Chin */ + {"yrk", {HB_TAG('T','N','E',' '), /* Nenets -> Tundra Nenets */ + HB_TAG('F','N','E',' ')}}, /* Nenets -> Forest Nenets */ + {"yue", {HB_TAG('Z','H','H',' ')}}, /* Yue Chinese -> Chinese, Hong Kong SAR */ + {"za", {HB_TAG('Z','H','A',' ')}}, /* Zhuang [macrolanguage] */ + {"zch", {HB_TAG('Z','H','A',' ')}}, /* Central Hongshuihe Zhuang -> Zhuang */ + {"zdj", {HB_TAG('C','M','R',' ')}}, /* Ngazidja Comorian -> Comorian */ + {"zea", {HB_TAG('Z','E','A',' ')}}, /* Zeeuws -> Zealandic */ + {"zeh", {HB_TAG('Z','H','A',' ')}}, /* Eastern Hongshuihe Zhuang -> Zhuang */ + {"zgb", {HB_TAG('Z','H','A',' ')}}, /* Guibei Zhuang -> Zhuang */ + {"zgh", {HB_TAG('Z','G','H',' ')}}, /* Standard Moroccan Tamazight */ + {"zgm", {HB_TAG('Z','H','A',' ')}}, /* Minz Zhuang -> Zhuang */ + {"zgn", {HB_TAG('Z','H','A',' ')}}, /* Guibian Zhuang -> Zhuang */ + {"zh", {HB_TAG('Z','H','S',' ')}}, /* Chinese [macrolanguage] -> Chinese Simplified */ + {"zhd", {HB_TAG('Z','H','A',' ')}}, /* Dai Zhuang -> Zhuang */ + {"zhn", {HB_TAG('Z','H','A',' ')}}, /* Nong Zhuang -> Zhuang */ + {"zlj", {HB_TAG('Z','H','A',' ')}}, /* Liujiang Zhuang -> Zhuang */ + {"zlm", {HB_TAG('M','L','Y',' ')}}, /* Malay */ + {"zln", {HB_TAG('Z','H','A',' ')}}, /* Lianshan Zhuang -> Zhuang */ + {"zlq", {HB_TAG('Z','H','A',' ')}}, /* Liuqian Zhuang -> Zhuang */ + {"zmi", {HB_TAG('M','L','Y',' ')}}, /* Negeri Sembilan Malay -> Malay */ + {"zne", {HB_TAG('Z','N','D',' ')}}, /* Zande */ + {"zom", {HB_TAG('Q','I','N',' ')}}, /* Zou -> Chin */ + {"zqe", {HB_TAG('Z','H','A',' ')}}, /* Qiubei Zhuang -> Zhuang */ + {"zsm", {HB_TAG('M','L','Y',' ')}}, /* Standard Malay -> Malay */ + {"zu", {HB_TAG('Z','U','L',' ')}}, /* Zulu */ + {"zum", {HB_TAG('L','R','C',' ')}}, /* Kumzari -> Luri */ + {"zyb", {HB_TAG('Z','H','A',' ')}}, /* Yongbei Zhuang -> Zhuang */ + {"zyg", {HB_TAG('Z','H','A',' ')}}, /* Yang Zhuang -> Zhuang */ + {"zyj", {HB_TAG('Z','H','A',' ')}}, /* Youjiang Zhuang -> Zhuang */ + {"zyn", {HB_TAG('Z','H','A',' ')}}, /* Yongnan Zhuang -> Zhuang */ + {"zza", {HB_TAG('Z','Z','A',' ')}}, /* Zazaki [macrolanguage] */ + {"zzj", {HB_TAG('Z','H','A',' ')}}, /* Zuojiang Zhuang -> Zhuang */ +}; + +static_assert (HB_OT_MAX_TAGS_PER_LANGUAGE == 3u, ""); + +/** + * hb_ot_tags_from_complex_language: + * @lang_str: a BCP 47 language tag to convert. + * @limit: a pointer to the end of the substring of @lang_str to consider for + * conversion. + * @count: maximum number of language tags to retrieve (IN) and actual number of + * language tags retrieved (OUT). If no tags are retrieved, it is not modified. + * @tags: array of size at least @language_count to store the language tag + * results + * + * Converts a multi-subtag BCP 47 language tag to language tags. + * + * Return value: Whether any language systems were retrieved. + **/ +static bool +hb_ot_tags_from_complex_language (const char *lang_str, + const char *limit, + unsigned int *count /* IN/OUT */, + hb_tag_t *tags /* OUT */) +{ + if (subtag_matches (lang_str, limit, "-fonnapa")) + { + /* Undetermined; North American Phonetic Alphabet */ + tags[0] = HB_TAG('A','P','P','H'); /* Phonetic transcription—Americanist conventions */ + *count = 1; + return true; + } + if (subtag_matches (lang_str, limit, "-polyton")) + { + /* Modern Greek (1453-); Polytonic Greek */ + tags[0] = HB_TAG('P','G','R',' '); /* Polytonic Greek */ + *count = 1; + return true; + } + if (subtag_matches (lang_str, limit, "-provenc")) + { + /* Occitan (post 1500); Provençal */ + tags[0] = HB_TAG('P','R','O',' '); /* Provençal / Old Provençal */ + *count = 1; + return true; + } + if (subtag_matches (lang_str, limit, "-fonipa")) + { + /* Undetermined; International Phonetic Alphabet */ + tags[0] = HB_TAG('I','P','P','H'); /* Phonetic transcription—IPA conventions */ + *count = 1; + return true; + } + if (subtag_matches (lang_str, limit, "-geok")) + { + /* Undetermined; Khutsuri (Asomtavruli and Nuskhuri) */ + tags[0] = HB_TAG('K','G','E',' '); /* Khutsuri Georgian */ + *count = 1; + return true; + } + if (subtag_matches (lang_str, limit, "-syre")) + { + /* Undetermined; Syriac (Estrangelo variant) */ + tags[0] = HB_TAG('S','Y','R','E'); /* Syriac, Estrangela script-variant (equivalent to ISO 15924 'Syre') */ + *count = 1; + return true; + } + if (subtag_matches (lang_str, limit, "-syrj")) + { + /* Undetermined; Syriac (Western variant) */ + tags[0] = HB_TAG('S','Y','R','J'); /* Syriac, Western script-variant (equivalent to ISO 15924 'Syrj') */ + *count = 1; + return true; + } + if (subtag_matches (lang_str, limit, "-syrn")) + { + /* Undetermined; Syriac (Eastern variant) */ + tags[0] = HB_TAG('S','Y','R','N'); /* Syriac, Eastern script-variant (equivalent to ISO 15924 'Syrn') */ + *count = 1; + return true; + } + switch (lang_str[0]) + { + case 'a': + if (0 == strcmp (&lang_str[1], "rt-lojban")) + { + /* Lojban */ + tags[0] = HB_TAG('J','B','O',' '); /* Lojban */ + *count = 1; + return true; + } + break; + case 'c': + if (lang_matches (&lang_str[1], "do-hant-hk")) + { + /* Min Dong Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "do-hant-mo")) + { + /* Min Dong Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "jy-hant-hk")) + { + /* Jinyu Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "jy-hant-mo")) + { + /* Jinyu Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "mn-hant-hk")) + { + /* Mandarin Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "mn-hant-mo")) + { + /* Mandarin Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "px-hant-hk")) + { + /* Pu-Xian Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "px-hant-mo")) + { + /* Pu-Xian Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "zh-hant-hk")) + { + /* Huizhou Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "zh-hant-mo")) + { + /* Huizhou Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "zo-hant-hk")) + { + /* Min Zhong Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "zo-hant-mo")) + { + /* Min Zhong Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "do-hans")) + { + /* Min Dong Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "do-hant")) + { + /* Min Dong Chinese */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "jy-hans")) + { + /* Jinyu Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "jy-hant")) + { + /* Jinyu Chinese */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "mn-hans")) + { + /* Mandarin Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "mn-hant")) + { + /* Mandarin Chinese */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "px-hans")) + { + /* Pu-Xian Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "px-hant")) + { + /* Pu-Xian Chinese */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "zh-hans")) + { + /* Huizhou Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "zh-hant")) + { + /* Huizhou Chinese */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "zo-hans")) + { + /* Min Zhong Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "zo-hant")) + { + /* Min Zhong Chinese */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "do-", 3) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Min Dong Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "do-", 3) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Min Dong Chinese; Macao */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "do-", 3) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Min Dong Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "jy-", 3) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Jinyu Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "jy-", 3) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Jinyu Chinese; Macao */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "jy-", 3) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Jinyu Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "mn-", 3) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Mandarin Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "mn-", 3) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Mandarin Chinese; Macao */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "mn-", 3) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Mandarin Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "px-", 3) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Pu-Xian Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "px-", 3) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Pu-Xian Chinese; Macao */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "px-", 3) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Pu-Xian Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "zh-", 3) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Huizhou Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "zh-", 3) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Huizhou Chinese; Macao */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "zh-", 3) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Huizhou Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "zo-", 3) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Min Zhong Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "zo-", 3) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Min Zhong Chinese; Macao */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "zo-", 3) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Min Zhong Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + break; + case 'g': + if (lang_matches (&lang_str[1], "an-hant-hk")) + { + /* Gan Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "an-hant-mo")) + { + /* Gan Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "an-hans")) + { + /* Gan Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "an-hant")) + { + /* Gan Chinese */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "a-latg")) + { + /* Irish */ + tags[0] = HB_TAG('I','R','T',' '); /* Irish Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "an-", 3) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Gan Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "an-", 3) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Gan Chinese; Macao */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "an-", 3) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Gan Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + break; + case 'h': + if (lang_matches (&lang_str[1], "ak-hant-hk")) + { + /* Hakka Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "ak-hant-mo")) + { + /* Hakka Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "sn-hant-hk")) + { + /* Xiang Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "sn-hant-mo")) + { + /* Xiang Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "ak-hans")) + { + /* Hakka Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "ak-hant")) + { + /* Hakka Chinese */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "sn-hans")) + { + /* Xiang Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "sn-hant")) + { + /* Xiang Chinese */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "ak-", 3) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Hakka Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "ak-", 3) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Hakka Chinese; Macao */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "ak-", 3) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Hakka Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "sn-", 3) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Xiang Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "sn-", 3) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Xiang Chinese; Macao */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "sn-", 3) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Xiang Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + break; + case 'i': + if (0 == strcmp (&lang_str[1], "-navajo")) + { + /* Navajo */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('N','A','V',' '), /* Navajo */ + HB_TAG('A','T','H',' '), /* Athapaskan */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } + if (0 == strcmp (&lang_str[1], "-hak")) + { + /* Hakka */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (0 == strcmp (&lang_str[1], "-lux")) + { + /* Luxembourgish */ + tags[0] = HB_TAG('L','T','Z',' '); /* Luxembourgish */ + *count = 1; + return true; + } + break; + case 'l': + if (lang_matches (&lang_str[1], "zh-hans")) + { + /* Literary Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + break; + case 'm': + if (lang_matches (&lang_str[1], "np-hant-hk")) + { + /* Min Bei Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "np-hant-mo")) + { + /* Min Bei Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "np-hans")) + { + /* Min Bei Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "np-hant")) + { + /* Min Bei Chinese */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "np-", 3) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Min Bei Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "np-", 3) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Min Bei Chinese; Macao */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "np-", 3) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Min Bei Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + break; + case 'n': + if (lang_matches (&lang_str[1], "an-hant-hk")) + { + /* Min Nan Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "an-hant-mo")) + { + /* Min Nan Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "an-hans")) + { + /* Min Nan Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "an-hant")) + { + /* Min Nan Chinese */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "an-", 3) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Min Nan Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "an-", 3) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Min Nan Chinese; Macao */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "an-", 3) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Min Nan Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (0 == strcmp (&lang_str[1], "o-bok")) + { + /* Norwegian Bokmal */ + tags[0] = HB_TAG('N','O','R',' '); /* Norwegian */ + *count = 1; + return true; + } + if (0 == strcmp (&lang_str[1], "o-nyn")) + { + /* Norwegian Nynorsk */ + tags[0] = HB_TAG('N','Y','N',' '); /* Norwegian Nynorsk (Nynorsk, Norwegian) */ + *count = 1; + return true; + } + break; + case 'r': + if (0 == strncmp (&lang_str[1], "o-", 2) + && subtag_matches (lang_str, limit, "-md")) + { + /* Romanian; Moldova */ + tags[0] = HB_TAG('M','O','L',' '); /* Moldavian */ + *count = 1; + return true; + } + break; + case 'w': + if (lang_matches (&lang_str[1], "uu-hant-hk")) + { + /* Wu Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "uu-hant-mo")) + { + /* Wu Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "uu-hans")) + { + /* Wu Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "uu-hant")) + { + /* Wu Chinese */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "uu-", 3) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Wu Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "uu-", 3) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Wu Chinese; Macao */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "uu-", 3) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Wu Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + break; + case 'y': + if (lang_matches (&lang_str[1], "ue-hans")) + { + /* Yue Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + break; + case 'z': + if (lang_matches (&lang_str[1], "h-hant-hk")) + { + /* Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "h-hant-mo")) + { + /* Chinese */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strcmp (&lang_str[1], "h-min-nan")) + { + /* Minnan, Hokkien, Amoy, Taiwanese, Southern Min, Southern Fujian, Hoklo, Southern Fukien, Ho-lo */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "h-hans")) + { + /* Chinese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "h-hant")) + { + /* Chinese */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + if (0 == strcmp (&lang_str[1], "h-min")) + { + /* Min, Fuzhou, Hokkien, Amoy, or Taiwanese */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "h-", 2) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "h-", 2) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Chinese; Macao */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "h-", 2) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + *count = 1; + return true; + } + break; + } + return false; +} + +/** + * hb_ot_ambiguous_tag_to_language + * @tag: A language tag. + * + * Converts @tag to a BCP 47 language tag if it is ambiguous (it corresponds to + * many language tags) and the best tag is not the alphabetically first, or if + * the best tag consists of multiple subtags. + * + * Return value: The #hb_language_t corresponding to the BCP 47 language tag, + * or #HB_LANGUAGE_INVALID if @tag is not ambiguous. + **/ +static hb_language_t +hb_ot_ambiguous_tag_to_language (hb_tag_t tag) +{ + switch (tag) + { + case HB_TAG('A','P','P','H'): /* Phonetic transcription—Americanist conventions */ + return hb_language_from_string ("und-fonnapa", -1); /* Undetermined; North American Phonetic Alphabet */ + case HB_TAG('A','R','A',' '): /* Arabic */ + return hb_language_from_string ("ar", -1); /* Arabic */ + case HB_TAG('A','R','K',' '): /* Rakhine */ + return hb_language_from_string ("rki", -1); /* Rakhine */ + case HB_TAG('A','T','H',' '): /* Athapaskan */ + return hb_language_from_string ("ath", -1); /* Athapascan */ + case HB_TAG('B','I','K',' '): /* Bikol */ + return hb_language_from_string ("bik", -1); /* Bikol */ + case HB_TAG('C','P','P',' '): /* Creoles */ + return hb_language_from_string ("crp", -1); /* Creoles and pidgins */ + case HB_TAG('C','R','R',' '): /* Carrier */ + return hb_language_from_string ("crx", -1); /* Carrier */ + case HB_TAG('D','N','K',' '): /* Dinka */ + return hb_language_from_string ("din", -1); /* Dinka */ + case HB_TAG('D','R','I',' '): /* Dari */ + return hb_language_from_string ("prs", -1); /* Dari */ + case HB_TAG('D','U','J',' '): /* Dhuwal */ + return hb_language_from_string ("dwu", -1); /* Dhuwal */ + case HB_TAG('D','Z','N',' '): /* Dzongkha */ + return hb_language_from_string ("dz", -1); /* Dzongkha */ + case HB_TAG('E','T','I',' '): /* Estonian */ + return hb_language_from_string ("et", -1); /* Estonian */ + case HB_TAG('G','O','N',' '): /* Gondi */ + return hb_language_from_string ("gon", -1); /* Gondi */ + case HB_TAG('H','M','N',' '): /* Hmong */ + return hb_language_from_string ("hmn", -1); /* Hmong */ + case HB_TAG('I','J','O',' '): /* Ijo */ + return hb_language_from_string ("ijo", -1); /* Ijo */ + case HB_TAG('I','N','U',' '): /* Inuktitut */ + return hb_language_from_string ("iu", -1); /* Inuktitut */ + case HB_TAG('I','P','K',' '): /* Inupiat */ + return hb_language_from_string ("ik", -1); /* Inupiaq */ + case HB_TAG('I','P','P','H'): /* Phonetic transcription—IPA conventions */ + return hb_language_from_string ("und-fonipa", -1); /* Undetermined; International Phonetic Alphabet */ + case HB_TAG('I','R','T',' '): /* Irish Traditional */ + return hb_language_from_string ("ga-Latg", -1); /* Irish; Latin (Gaelic variant) */ + case HB_TAG('J','I','I',' '): /* Yiddish */ + return hb_language_from_string ("yi", -1); /* Yiddish */ + case HB_TAG('K','A','L',' '): /* Kalenjin */ + return hb_language_from_string ("kln", -1); /* Kalenjin */ + case HB_TAG('K','G','E',' '): /* Khutsuri Georgian */ + return hb_language_from_string ("und-Geok", -1); /* Undetermined; Khutsuri (Asomtavruli and Nuskhuri) */ + case HB_TAG('K','N','R',' '): /* Kanuri */ + return hb_language_from_string ("kr", -1); /* Kanuri */ + case HB_TAG('K','O','K',' '): /* Konkani */ + return hb_language_from_string ("kok", -1); /* Konkani */ + case HB_TAG('K','U','R',' '): /* Kurdish */ + return hb_language_from_string ("ku", -1); /* Kurdish */ + case HB_TAG('L','U','H',' '): /* Luyia */ + return hb_language_from_string ("luy", -1); /* Luyia */ + case HB_TAG('L','V','I',' '): /* Latvian */ + return hb_language_from_string ("lv", -1); /* Latvian */ + case HB_TAG('M','A','W',' '): /* Marwari */ + return hb_language_from_string ("mwr", -1); /* Marwari */ + case HB_TAG('M','L','G',' '): /* Malagasy */ + return hb_language_from_string ("mg", -1); /* Malagasy */ + case HB_TAG('M','L','Y',' '): /* Malay */ + return hb_language_from_string ("ms", -1); /* Malay */ + case HB_TAG('M','N','G',' '): /* Mongolian */ + return hb_language_from_string ("mn", -1); /* Mongolian */ + case HB_TAG('M','O','L',' '): /* Moldavian */ + return hb_language_from_string ("ro-MD", -1); /* Romanian; Moldova */ + case HB_TAG('N','E','P',' '): /* Nepali */ + return hb_language_from_string ("ne", -1); /* Nepali */ + case HB_TAG('N','I','S',' '): /* Nisi */ + return hb_language_from_string ("njz", -1); /* Nyishi */ + case HB_TAG('N','O','R',' '): /* Norwegian */ + return hb_language_from_string ("no", -1); /* Norwegian */ + case HB_TAG('O','J','B',' '): /* Ojibway */ + return hb_language_from_string ("oj", -1); /* Ojibwa */ + case HB_TAG('O','R','O',' '): /* Oromo */ + return hb_language_from_string ("om", -1); /* Oromo */ + case HB_TAG('P','A','S',' '): /* Pashto */ + return hb_language_from_string ("ps", -1); /* Pashto */ + case HB_TAG('P','G','R',' '): /* Polytonic Greek */ + return hb_language_from_string ("el-polyton", -1); /* Modern Greek (1453-); Polytonic Greek */ + case HB_TAG('P','R','O',' '): /* Provençal / Old Provençal */ + return hb_language_from_string ("pro", -1); /* Old Provençal (to 1500) */ + case HB_TAG('Q','U','H',' '): /* Quechua (Bolivia) */ + return hb_language_from_string ("quh", -1); /* South Bolivian Quechua */ + case HB_TAG('Q','V','I',' '): /* Quechua (Ecuador) */ + return hb_language_from_string ("qvi", -1); /* Imbabura Highland Quichua */ + case HB_TAG('Q','W','H',' '): /* Quechua (Peru) */ + return hb_language_from_string ("qwh", -1); /* Huaylas Ancash Quechua */ + case HB_TAG('R','A','J',' '): /* Rajasthani */ + return hb_language_from_string ("raj", -1); /* Rajasthani */ + case HB_TAG('R','O','Y',' '): /* Romany */ + return hb_language_from_string ("rom", -1); /* Romany */ + case HB_TAG('S','Q','I',' '): /* Albanian */ + return hb_language_from_string ("sq", -1); /* Albanian */ + case HB_TAG('S','Y','R',' '): /* Syriac */ + return hb_language_from_string ("syr", -1); /* Syriac */ + case HB_TAG('S','Y','R','E'): /* Syriac, Estrangela script-variant (equivalent to ISO 15924 'Syre') */ + return hb_language_from_string ("und-Syre", -1); /* Undetermined; Syriac (Estrangelo variant) */ + case HB_TAG('S','Y','R','J'): /* Syriac, Western script-variant (equivalent to ISO 15924 'Syrj') */ + return hb_language_from_string ("und-Syrj", -1); /* Undetermined; Syriac (Western variant) */ + case HB_TAG('S','Y','R','N'): /* Syriac, Eastern script-variant (equivalent to ISO 15924 'Syrn') */ + return hb_language_from_string ("und-Syrn", -1); /* Undetermined; Syriac (Eastern variant) */ + case HB_TAG('T','M','H',' '): /* Tamashek */ + return hb_language_from_string ("tmh", -1); /* Tamashek */ + case HB_TAG('T','N','E',' '): /* Tundra Nenets */ + return hb_language_from_string ("yrk", -1); /* Nenets */ + case HB_TAG('Z','H','H',' '): /* Chinese, Hong Kong SAR */ + return hb_language_from_string ("zh-HK", -1); /* Chinese; Hong Kong */ + case HB_TAG('Z','H','S',' '): /* Chinese Simplified */ + return hb_language_from_string ("zh-Hans", -1); /* Chinese; Han (Simplified variant) */ + case HB_TAG('Z','H','T',' '): /* Chinese Traditional */ + return hb_language_from_string ("zh-Hant", -1); /* Chinese; Han (Traditional variant) */ + default: + return HB_LANGUAGE_INVALID; + } +} + +#endif /* HB_OT_TAG_TABLE_HH */ + +/* == End of generated table == */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc index 283723e27d8..3d4e8b06612 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc @@ -36,7 +36,8 @@ hb_ot_old_tag_from_script (hb_script_t script) { /* This seems to be accurate as of end of 2012. */ - switch ((hb_tag_t) script) { + switch ((hb_tag_t) script) + { case HB_SCRIPT_INVALID: return HB_OT_TAG_DEFAULT_SCRIPT; /* KATAKANA and HIRAGANA both map to 'kana' */ @@ -49,8 +50,6 @@ hb_ot_old_tag_from_script (hb_script_t script) case HB_SCRIPT_NKO: return HB_TAG('n','k','o',' '); /* Unicode-5.1 additions */ case HB_SCRIPT_VAI: return HB_TAG('v','a','i',' '); - /* Unicode-5.2 additions */ - /* Unicode-6.0 additions */ } /* Else, just change first char to lowercase and return */ @@ -114,6 +113,18 @@ hb_ot_new_tag_to_script (hb_tag_t tag) return HB_SCRIPT_UNKNOWN; } +void +hb_ot_tags_from_script (hb_script_t script, + hb_tag_t *script_tag_1, + hb_tag_t *script_tag_2) +{ + unsigned int count = 2; + hb_tag_t tags[2]; + hb_ot_tags_from_script_and_language (script, HB_LANGUAGE_INVALID, &count, tags, nullptr, nullptr); + *script_tag_1 = count > 0 ? tags[0] : HB_OT_TAG_DEFAULT_SCRIPT; + *script_tag_2 = count > 1 ? tags[1] : HB_OT_TAG_DEFAULT_SCRIPT; +} + /* * Complete list at: * https://docs.microsoft.com/en-us/typography/opentype/spec/scripttags @@ -122,28 +133,37 @@ hb_ot_new_tag_to_script (hb_tag_t tag) * So we just do that, and handle the exceptional cases in a switch. */ -void -hb_ot_tags_from_script (hb_script_t script, - hb_tag_t *script_tag_1, - hb_tag_t *script_tag_2) +static void +hb_ot_all_tags_from_script (hb_script_t script, + unsigned int *count /* IN/OUT */, + hb_tag_t *tags /* OUT */) { - hb_tag_t new_tag; + unsigned int i = 0; - *script_tag_2 = HB_OT_TAG_DEFAULT_SCRIPT; - *script_tag_1 = hb_ot_old_tag_from_script (script); + hb_tag_t new_tag = hb_ot_new_tag_from_script (script); + if (unlikely (new_tag != HB_OT_TAG_DEFAULT_SCRIPT)) + { + tags[i++] = new_tag | '3'; + if (*count > i) + tags[i++] = new_tag; + } - new_tag = hb_ot_new_tag_from_script (script); - if (unlikely (new_tag != HB_OT_TAG_DEFAULT_SCRIPT)) { - *script_tag_2 = *script_tag_1; - *script_tag_1 = new_tag; + if (*count > i) + { + hb_tag_t old_tag = hb_ot_old_tag_from_script (script); + if (old_tag != HB_OT_TAG_DEFAULT_SCRIPT) + tags[i++] = old_tag; } + + *count = i; } hb_script_t hb_ot_tag_to_script (hb_tag_t tag) { - if (unlikely ((tag & 0x000000FFu) == '2')) - return hb_ot_new_tag_to_script (tag); + unsigned char digit = tag & 0x000000FFu; + if (unlikely (digit == '2' || digit == '3')) + return hb_ot_new_tag_to_script (tag & 0xFFFFFF32); return hb_ot_old_tag_to_script (tag); } @@ -151,732 +171,6 @@ hb_ot_tag_to_script (hb_tag_t tag) /* hb_language_t */ -typedef struct { - char language[4]; - hb_tag_t tag; -} LangTag; - -/* - * Complete list at: - * 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 - * 2008-08-04, matching on name, and finally adjusted manually. - * - * Updated on 2012-12-07 with more research into remaining codes. - * - * Updated on 2013-11-23 based on usage in SIL and Microsoft fonts, - * the new proposal from Microsoft, and latest ISO 639-3 names. - * - * Some items still missing. Those are commented out at the end. - * Keep sorted for bsearch. - * - * 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: - * https://docs.microsoft.com/en-us/typography/opentype/spec/languagetags - */ - -static const LangTag ot_languages[] = { - {"aa", HB_TAG('A','F','R',' ')}, /* Afar */ - {"ab", HB_TAG('A','B','K',' ')}, /* Abkhazian */ - {"abq", HB_TAG('A','B','A',' ')}, /* Abaza */ - {"acf", HB_TAG('F','A','N',' ')}, /* French Antillean */ - {"ach", HB_TAG('A','C','H',' ')}, /* Acoli */ - {"acr", HB_TAG('A','C','R',' ')}, /* Achi */ - {"ada", HB_TAG('D','N','G',' ')}, /* Dangme */ - {"ady", HB_TAG('A','D','Y',' ')}, /* Adyghe */ - {"af", HB_TAG('A','F','K',' ')}, /* Afrikaans */ - {"ahg", HB_TAG('A','G','W',' ')}, /* Agaw */ - {"aii", HB_TAG('S','W','A',' ')}, /* Swadaya Aramaic */ - {"aio", HB_TAG('A','I','O',' ')}, /* Aiton */ - {"aiw", HB_TAG('A','R','I',' ')}, /* Aari */ - {"ak", HB_TAG('T','W','I',' ')}, /* Akan [macrolanguage] */ - {"aka", HB_TAG('A','K','A',' ')}, /* Akan */ - {"alt", HB_TAG('A','L','T',' ')}, /* [Southern] Altai */ - {"am", HB_TAG('A','M','H',' ')}, /* Amharic */ - {"amf", HB_TAG('H','B','N',' ')}, /* Hammer-Banna */ - {"amw", HB_TAG('S','Y','R',' ')}, /* Western Neo-Aramaic */ - {"an", HB_TAG('A','R','G',' ')}, /* Aragonese */ - {"ang", HB_TAG('A','N','G',' ')}, /* Old English (ca. 450-1100) */ - {"ar", HB_TAG('A','R','A',' ')}, /* Arabic [macrolanguage] */ - {"arb", HB_TAG('A','R','A',' ')}, /* Standard Arabic */ - {"arn", HB_TAG('M','A','P',' ')}, /* Mapudungun */ - {"ary", HB_TAG('M','O','R',' ')}, /* Moroccan Arabic */ - {"as", HB_TAG('A','S','M',' ')}, /* Assamese */ - {"ast", HB_TAG('A','S','T',' ')}, /* Asturian/Asturleonese/Bable/Leonese */ - {"ath", HB_TAG('A','T','H',' ')}, /* Athapaskan [family] */ - {"atj", HB_TAG('R','C','R',' ')}, /* R-Cree */ - {"atv", HB_TAG('A','L','T',' ')}, /* [Northern] Altai */ - {"av", HB_TAG('A','V','R',' ')}, /* Avaric */ - {"awa", HB_TAG('A','W','A',' ')}, /* Awadhi */ - {"ay", HB_TAG('A','Y','M',' ')}, /* Aymara [macrolanguage] */ - {"az", HB_TAG('A','Z','E',' ')}, /* Azerbaijani [macrolanguage] */ - {"azb", HB_TAG('A','Z','B',' ')}, /* South Azerbaijani */ - {"azj", HB_TAG('A','Z','E',' ')}, /* North Azerbaijani */ - {"ba", HB_TAG('B','S','H',' ')}, /* Bashkir */ - {"bad", HB_TAG('B','A','D','0')}, /* Banda */ - {"bai", HB_TAG('B','M','L',' ')}, /* Bamileke [family] */ - {"bal", HB_TAG('B','L','I',' ')}, /* Baluchi [macrolangauge] */ - {"ban", HB_TAG('B','A','N',' ')}, /* Balinese */ - {"bar", HB_TAG('B','A','R',' ')}, /* Bavarian */ - {"bbc", HB_TAG('B','B','C',' ')}, /* Batak Toba */ - {"bci", HB_TAG('B','A','U',' ')}, /* Baoulé */ - {"bcl", HB_TAG('B','I','K',' ')}, /* Central Bikol */ - {"bcq", HB_TAG('B','C','H',' ')}, /* Bench */ - {"bdy", HB_TAG('B','D','Y',' ')}, /* Bandjalang */ - {"be", HB_TAG('B','E','L',' ')}, /* Belarusian */ - {"bem", HB_TAG('B','E','M',' ')}, /* Bemba (Zambia) */ - {"ber", HB_TAG('B','E','R',' ')}, /* Berber [family] */ - {"bfq", HB_TAG('B','A','D',' ')}, /* Badaga */ - {"bft", HB_TAG('B','L','T',' ')}, /* Balti */ - {"bfu", HB_TAG('L','A','H',' ')}, /* Lahuli */ - {"bfy", HB_TAG('B','A','G',' ')}, /* Baghelkhandi */ - {"bg", HB_TAG('B','G','R',' ')}, /* Bulgarian */ - {"bgc", HB_TAG('B','G','C',' ')}, /* Haryanvi */ - {"bgq", HB_TAG('B','G','Q',' ')}, /* Bagri */ - {"bgr", HB_TAG('Q','I','N',' ')}, /* Bawm Chin */ - {"bhb", HB_TAG('B','H','I',' ')}, /* Bhili */ - {"bhk", HB_TAG('B','I','K',' ')}, /* Albay Bicolano (retired code) */ - {"bho", HB_TAG('B','H','O',' ')}, /* Bhojpuri */ - {"bi", HB_TAG('B','I','S',' ')}, /* Bislama */ - {"bik", HB_TAG('B','I','K',' ')}, /* Bikol [macrolanguage] */ - {"bin", HB_TAG('E','D','O',' ')}, /* Bini */ - {"bjj", HB_TAG('B','J','J',' ')}, /* Kanauji */ - {"bjt", HB_TAG('B','L','N',' ')}, /* Balanta-Ganja */ - {"bla", HB_TAG('B','K','F',' ')}, /* Blackfoot */ - {"ble", HB_TAG('B','L','N',' ')}, /* Balanta-Kentohe */ - {"blk", HB_TAG('B','L','K',' ')}, /* Pa'O/Pa'o Karen */ - {"bln", HB_TAG('B','I','K',' ')}, /* Southern Catanduanes Bikol */ - {"bm", HB_TAG('B','M','B',' ')}, /* Bambara */ - {"bn", HB_TAG('B','E','N',' ')}, /* Bengali */ - {"bo", HB_TAG('T','I','B',' ')}, /* Tibetan */ - {"bpy", HB_TAG('B','P','Y',' ')}, /* Bishnupriya */ - {"bqi", HB_TAG('L','R','C',' ')}, /* Bakhtiari */ - {"br", HB_TAG('B','R','E',' ')}, /* Breton */ - {"bra", HB_TAG('B','R','I',' ')}, /* Braj Bhasha */ - {"brh", HB_TAG('B','R','H',' ')}, /* Brahui */ - {"brx", HB_TAG('B','R','X',' ')}, /* Bodo (India) */ - {"bs", HB_TAG('B','O','S',' ')}, /* Bosnian */ - {"btb", HB_TAG('B','T','I',' ')}, /* Beti (Cameroon) */ - {"bto", HB_TAG('B','I','K',' ')}, /* Rinconada Bikol */ - {"bts", HB_TAG('B','T','S',' ')}, /* Batak Simalungun */ - {"bug", HB_TAG('B','U','G',' ')}, /* Buginese */ - {"bxr", HB_TAG('R','B','U',' ')}, /* Russian Buriat */ - {"byn", HB_TAG('B','I','L',' ')}, /* Bilen */ - {"ca", HB_TAG('C','A','T',' ')}, /* Catalan */ - {"cak", HB_TAG('C','A','K',' ')}, /* Kaqchikel */ - {"cbk", HB_TAG('C','B','K',' ')}, /* Chavacano */ - {"cbl", HB_TAG('Q','I','N',' ')}, /* Bualkhaw Chin */ - {"cco", HB_TAG('C','C','H','N')}, /* Chinantec */ - {"ce", HB_TAG('C','H','E',' ')}, /* Chechen */ - {"ceb", HB_TAG('C','E','B',' ')}, /* Cebuano */ - {"cfm", HB_TAG('H','A','L',' ')}, /* Halam/Falam Chin */ - {"cgg", HB_TAG('C','G','G',' ')}, /* Chiga */ - {"ch", HB_TAG('C','H','A',' ')}, /* Chamorro */ - {"chj", HB_TAG('C','C','H','N')}, /* Chinantec */ - {"chk", HB_TAG('C','H','K','0')}, /* Chuukese */ - {"cho", HB_TAG('C','H','O',' ')}, /* Choctaw */ - {"chp", HB_TAG('C','H','P',' ')}, /* Chipewyan */ - {"chq", HB_TAG('C','C','H','N')}, /* Chinantec */ - {"chr", HB_TAG('C','H','R',' ')}, /* Cherokee */ - {"chy", HB_TAG('C','H','Y',' ')}, /* Cheyenne */ - {"chz", HB_TAG('C','C','H','N')}, /* Chinantec */ - {"cja", HB_TAG('C','J','A',' ')}, /* Western Cham */ - {"cjm", HB_TAG('C','J','M',' ')}, /* Eastern Cham */ - {"cka", HB_TAG('Q','I','N',' ')}, /* Khumi Awa Chin */ - {"ckb", HB_TAG('K','U','R',' ')}, /* Central Kurdish (Sorani) */ - {"ckt", HB_TAG('C','H','K',' ')}, /* Chukchi */ - {"cld", HB_TAG('S','Y','R',' ')}, /* Chaldean Neo-Aramaic */ - {"cle", HB_TAG('C','C','H','N')}, /* Chinantec */ - {"cmr", HB_TAG('Q','I','N',' ')}, /* Mro-Khimi Chin */ - {"cnb", HB_TAG('Q','I','N',' ')}, /* Chinbon Chin */ - {"cnh", HB_TAG('Q','I','N',' ')}, /* Hakha Chin */ - {"cnk", HB_TAG('Q','I','N',' ')}, /* Khumi Chin */ - {"cnl", HB_TAG('C','C','H','N')}, /* Chinantec */ - {"cnt", HB_TAG('C','C','H','N')}, /* Chinantec */ - {"cnw", HB_TAG('Q','I','N',' ')}, /* Ngawn Chin */ - {"cop", HB_TAG('C','O','P',' ')}, /* Coptic */ - {"cpa", HB_TAG('C','C','H','N')}, /* Chinantec */ - {"cpp", HB_TAG('C','P','P',' ')}, /* Creoles */ - {"cr", HB_TAG('C','R','E',' ')}, /* Cree */ - {"cre", HB_TAG('Y','C','R',' ')}, /* Y-Cree */ - {"crh", HB_TAG('C','R','T',' ')}, /* Crimean Tatar */ - {"crj", HB_TAG('E','C','R',' ')}, /* [Southern] East Cree */ - {"crk", HB_TAG('W','C','R',' ')}, /* West-Cree */ - {"crl", HB_TAG('E','C','R',' ')}, /* [Northern] East Cree */ - {"crm", HB_TAG('M','C','R',' ')}, /* Moose Cree */ - {"crx", HB_TAG('C','R','R',' ')}, /* Carrier */ - {"cs", HB_TAG('C','S','Y',' ')}, /* Czech */ - {"csa", HB_TAG('C','C','H','N')}, /* Chinantec */ - {"csb", HB_TAG('C','S','B',' ')}, /* Kashubian */ - {"csh", HB_TAG('Q','I','N',' ')}, /* Asho Chin */ - {"cso", HB_TAG('C','C','H','N')}, /* Chinantec */ - {"csy", HB_TAG('Q','I','N',' ')}, /* Siyin Chin */ - {"ctd", HB_TAG('Q','I','N',' ')}, /* Tedim Chin */ - {"cte", HB_TAG('C','C','H','N')}, /* Chinantec */ - {"ctg", HB_TAG('C','T','G',' ')}, /* Chittagonian */ - {"ctl", HB_TAG('C','C','H','N')}, /* Chinantec */ - {"cts", HB_TAG('B','I','K',' ')}, /* Northern Catanduanes Bikol */ - {"cu", HB_TAG('C','S','L',' ')}, /* Church Slavic */ - {"cuc", HB_TAG('C','C','H','N')}, /* Chinantec */ - {"cuk", HB_TAG('C','U','K',' ')}, /* San Blas Kuna */ - {"cv", HB_TAG('C','H','U',' ')}, /* Chuvash */ - {"cvn", HB_TAG('C','C','H','N')}, /* Chinantec */ - {"cwd", HB_TAG('D','C','R',' ')}, /* Woods Cree */ - {"cy", HB_TAG('W','E','L',' ')}, /* Welsh */ - {"czt", HB_TAG('Q','I','N',' ')}, /* Zotung Chin */ - {"da", HB_TAG('D','A','N',' ')}, /* Danish */ - {"dao", HB_TAG('Q','I','N',' ')}, /* Daai Chin */ - {"dap", HB_TAG('N','I','S',' ')}, /* Nisi (India) */ - {"dar", HB_TAG('D','A','R',' ')}, /* Dargwa */ - {"dax", HB_TAG('D','A','X',' ')}, /* Dayi */ - {"de", HB_TAG('D','E','U',' ')}, /* German */ - {"dgo", HB_TAG('D','G','O',' ')}, /* Dogri */ - {"dhd", HB_TAG('M','A','W',' ')}, /* Dhundari */ - {"dhg", HB_TAG('D','H','G',' ')}, /* Dhangu */ - {"din", HB_TAG('D','N','K',' ')}, /* Dinka [macrolanguage] */ - {"diq", HB_TAG('D','I','Q',' ')}, /* Dimli */ - {"dje", HB_TAG('D','J','R',' ')}, /* Zarma */ - {"djr", HB_TAG('D','J','R','0')}, /* Djambarrpuyngu */ - {"dng", HB_TAG('D','U','N',' ')}, /* Dungan */ - {"dnj", HB_TAG('D','N','J',' ')}, /* Dan */ - {"doi", HB_TAG('D','G','R',' ')}, /* Dogri [macrolanguage] */ - {"dsb", HB_TAG('L','S','B',' ')}, /* Lower Sorbian */ - {"duj", HB_TAG('D','U','J',' ')}, /* Dhuwal */ - {"dv", HB_TAG('D','I','V',' ')}, /* Dhivehi/Divehi/Maldivian */ - {"dyu", HB_TAG('J','U','L',' ')}, /* Jula */ - {"dz", HB_TAG('D','Z','N',' ')}, /* Dzongkha */ - {"ee", HB_TAG('E','W','E',' ')}, /* Ewe */ - {"efi", HB_TAG('E','F','I',' ')}, /* Efik */ - {"ekk", HB_TAG('E','T','I',' ')}, /* Standard Estonian */ - {"el", HB_TAG('E','L','L',' ')}, /* Modern Greek (1453-) */ - {"emk", HB_TAG('M','N','K',' ')}, /* Eastern Maninkakan */ - {"en", HB_TAG('E','N','G',' ')}, /* English */ - {"enf", HB_TAG('F','N','E',' ')}, /* Forest Nenets */ - {"enh", HB_TAG('T','N','E',' ')}, /* Tundra Nenets */ - {"eo", HB_TAG('N','T','O',' ')}, /* Esperanto */ - {"eot", HB_TAG('B','T','I',' ')}, /* Beti (Côte d'Ivoire) */ - {"es", HB_TAG('E','S','P',' ')}, /* Spanish */ - {"esu", HB_TAG('E','S','U',' ')}, /* Central Yupik */ - {"et", HB_TAG('E','T','I',' ')}, /* Estonian [macrolanguage] */ - {"eu", HB_TAG('E','U','Q',' ')}, /* Basque */ - {"eve", HB_TAG('E','V','N',' ')}, /* Even */ - {"evn", HB_TAG('E','V','K',' ')}, /* Evenki */ - {"fa", HB_TAG('F','A','R',' ')}, /* Persian [macrolanguage] */ - {"fan", HB_TAG('F','A','N','0')}, /* Fang */ - {"fat", HB_TAG('F','A','T',' ')}, /* Fanti */ - {"ff", HB_TAG('F','U','L',' ')}, /* Fulah [macrolanguage] */ - {"fi", HB_TAG('F','I','N',' ')}, /* Finnish */ - {"fil", HB_TAG('P','I','L',' ')}, /* Filipino */ - {"fj", HB_TAG('F','J','I',' ')}, /* Fijian */ - {"flm", HB_TAG('H','A','L',' ')}, /* Halam/Falam Chin [retired ISO639 code] */ - {"fo", HB_TAG('F','O','S',' ')}, /* Faroese */ - {"fon", HB_TAG('F','O','N',' ')}, /* Fon */ - {"fr", HB_TAG('F','R','A',' ')}, /* French */ - {"frc", HB_TAG('F','R','C',' ')}, /* Cajun French */ - {"frp", HB_TAG('F','R','P',' ')}, /* Arpitan/Francoprovençal */ - {"fuf", HB_TAG('F','T','A',' ')}, /* Futa */ - {"fur", HB_TAG('F','R','L',' ')}, /* Friulian */ - {"fuv", HB_TAG('F','U','V',' ')}, /* Nigerian Fulfulde */ - {"fy", HB_TAG('F','R','I',' ')}, /* Western Frisian */ - {"ga", HB_TAG('I','R','I',' ')}, /* Irish */ - {"gaa", HB_TAG('G','A','D',' ')}, /* Ga */ - {"gag", HB_TAG('G','A','G',' ')}, /* Gagauz */ - {"gbm", HB_TAG('G','A','W',' ')}, /* Garhwali */ - {"gd", HB_TAG('G','A','E',' ')}, /* Scottish Gaelic */ - {"gez", HB_TAG('G','E','Z',' ')}, /* Ge'ez */ - {"ggo", HB_TAG('G','O','N',' ')}, /* Southern Gondi */ - {"gih", HB_TAG('G','I','H',' ')}, /* Githabul */ - {"gil", HB_TAG('G','I','L','0')}, /* Kiribati (Gilbertese) */ - {"gkp", HB_TAG('G','K','P',' ')}, /* Kpelle (Guinea) */ - {"gl", HB_TAG('G','A','L',' ')}, /* Galician */ - {"gld", HB_TAG('N','A','N',' ')}, /* Nanai */ - {"glk", HB_TAG('G','L','K',' ')}, /* Gilaki */ - {"gn", HB_TAG('G','U','A',' ')}, /* Guarani [macrolanguage] */ - {"gnn", HB_TAG('G','N','N',' ')}, /* Gumatj */ - {"gno", HB_TAG('G','O','N',' ')}, /* Northern Gondi */ - {"gog", HB_TAG('G','O','G',' ')}, /* Gogo */ - {"gon", HB_TAG('G','O','N',' ')}, /* Gondi [macrolanguage] */ - {"grt", HB_TAG('G','R','O',' ')}, /* Garo */ - {"gru", HB_TAG('S','O','G',' ')}, /* Sodo Gurage */ - {"gsw", HB_TAG('A','L','S',' ')}, /* Alsatian */ - {"gu", HB_TAG('G','U','J',' ')}, /* Gujarati */ - {"guc", HB_TAG('G','U','C',' ')}, /* Wayuu */ - {"guf", HB_TAG('G','U','F',' ')}, /* Gupapuyngu */ - {"guk", HB_TAG('G','M','Z',' ')}, /* Gumuz */ -/*{"guk", HB_TAG('G','U','K',' ')},*/ /* Gumuz (in SIL fonts) */ - {"guz", HB_TAG('G','U','Z',' ')}, /* Ekegusii/Gusii */ - {"gv", HB_TAG('M','N','X',' ')}, /* Manx */ - {"ha", HB_TAG('H','A','U',' ')}, /* Hausa */ - {"har", HB_TAG('H','R','I',' ')}, /* Harari */ - {"haw", HB_TAG('H','A','W',' ')}, /* Hawaiian */ - {"hay", HB_TAG('H','A','Y',' ')}, /* Haya */ - {"haz", HB_TAG('H','A','Z',' ')}, /* Hazaragi */ - {"he", HB_TAG('I','W','R',' ')}, /* Hebrew */ - {"hi", HB_TAG('H','I','N',' ')}, /* Hindi */ - {"hil", HB_TAG('H','I','L',' ')}, /* Hiligaynon */ - {"hlt", HB_TAG('Q','I','N',' ')}, /* Matu Chin */ - {"hmn", HB_TAG('H','M','N',' ')}, /* Hmong */ - {"hnd", HB_TAG('H','N','D',' ')}, /* [Southern] Hindko */ - {"hne", HB_TAG('C','H','H',' ')}, /* Chattisgarhi */ - {"hno", HB_TAG('H','N','D',' ')}, /* [Northern] Hindko */ - {"ho", HB_TAG('H','M','O',' ')}, /* Hiri Motu */ - {"hoc", HB_TAG('H','O',' ',' ')}, /* Ho */ - {"hoj", HB_TAG('H','A','R',' ')}, /* Harauti */ - {"hr", HB_TAG('H','R','V',' ')}, /* Croatian */ - {"hsb", HB_TAG('U','S','B',' ')}, /* Upper Sorbian */ - {"ht", HB_TAG('H','A','I',' ')}, /* Haitian/Haitian Creole */ - {"hu", HB_TAG('H','U','N',' ')}, /* Hungarian */ - {"hy", HB_TAG('H','Y','E',' ')}, /* Armenian */ - {"hz", HB_TAG('H','E','R',' ')}, /* Herero */ - {"ia", HB_TAG('I','N','A',' ')}, /* Interlingua (International Auxiliary Language Association) */ - {"iba", HB_TAG('I','B','A',' ')}, /* Iban */ - {"ibb", HB_TAG('I','B','B',' ')}, /* Ibibio */ - {"id", HB_TAG('I','N','D',' ')}, /* Indonesian */ - {"ie", HB_TAG('I','L','E',' ')}, /* Interlingue/Occidental */ - {"ig", HB_TAG('I','B','O',' ')}, /* Igbo */ - {"igb", HB_TAG('E','B','I',' ')}, /* Ebira */ - {"ii", HB_TAG('Y','I','M',' ')}, /* Yi Modern */ - {"ijc", HB_TAG('I','J','O',' ')}, /* Izon */ - {"ijo", HB_TAG('I','J','O',' ')}, /* Ijo [family] */ - {"ik", HB_TAG('I','P','K',' ')}, /* Inupiaq [macrolanguage] */ - {"ilo", HB_TAG('I','L','O',' ')}, /* Ilokano */ - {"inh", HB_TAG('I','N','G',' ')}, /* Ingush */ - {"io", HB_TAG('I','D','O',' ')}, /* Ido */ - {"is", HB_TAG('I','S','L',' ')}, /* Icelandic */ - {"it", HB_TAG('I','T','A',' ')}, /* Italian */ - {"iu", HB_TAG('I','N','U',' ')}, /* Inuktitut [macrolanguage] */ - {"ja", HB_TAG('J','A','N',' ')}, /* Japanese */ - {"jam", HB_TAG('J','A','M',' ')}, /* Jamaican Creole English */ - {"jbo", HB_TAG('J','B','O',' ')}, /* Lojban */ - {"jv", HB_TAG('J','A','V',' ')}, /* Javanese */ - {"ka", HB_TAG('K','A','T',' ')}, /* Georgian */ - {"kaa", HB_TAG('K','R','K',' ')}, /* Karakalpak */ - {"kab", HB_TAG('K','A','B','0')}, /* Kabyle */ - {"kam", HB_TAG('K','M','B',' ')}, /* Kamba (Kenya) */ - {"kar", HB_TAG('K','R','N',' ')}, /* Karen [family] */ - {"kat", HB_TAG('K','G','E',' ')}, /* Khutsuri Georgian */ - {"kbd", HB_TAG('K','A','B',' ')}, /* Kabardian */ - {"kde", HB_TAG('K','D','E',' ')}, /* Makonde */ - {"kdr", HB_TAG('K','R','M',' ')}, /* Karaim */ - {"kdt", HB_TAG('K','U','Y',' ')}, /* Kuy */ - {"kea", HB_TAG('K','E','A',' ')}, /* Kabuverdianu (Crioulo) */ - {"kek", HB_TAG('K','E','K',' ')}, /* Kekchi */ - {"kex", HB_TAG('K','K','N',' ')}, /* Kokni */ - {"kfa", HB_TAG('K','O','D',' ')}, /* Kodagu */ - {"kfr", HB_TAG('K','A','C',' ')}, /* Kachchi */ - {"kfx", HB_TAG('K','U','L',' ')}, /* Kulvi */ - {"kfy", HB_TAG('K','M','N',' ')}, /* Kumaoni */ - {"kg", HB_TAG('K','O','N',' ')}, /* Kongo [macrolanguage] */ - {"kha", HB_TAG('K','S','I',' ')}, /* Khasi */ - {"khb", HB_TAG('X','B','D',' ')}, /* Lü */ - {"kht", HB_TAG('K','H','N',' ')}, /* Khamti (Microsoft fonts) */ -/*{"kht", HB_TAG('K','H','T',' ')},*/ /* Khamti (OpenType spec and SIL fonts) */ - {"khw", HB_TAG('K','H','W',' ')}, /* Khowar */ - {"ki", HB_TAG('K','I','K',' ')}, /* Gikuyu/Kikuyu */ - {"kiu", HB_TAG('K','I','U',' ')}, /* Kirmanjki */ - {"kj", HB_TAG('K','U','A',' ')}, /* Kuanyama/Kwanyama */ - {"kjd", HB_TAG('K','J','D',' ')}, /* Southern Kiwai */ - {"kjh", HB_TAG('K','H','A',' ')}, /* Khakass */ - {"kjp", HB_TAG('K','J','P',' ')}, /* Pwo Eastern Karen */ - {"kk", HB_TAG('K','A','Z',' ')}, /* Kazakh */ - {"kl", HB_TAG('G','R','N',' ')}, /* Kalaallisut */ - {"kln", HB_TAG('K','A','L',' ')}, /* Kalenjin */ - {"km", HB_TAG('K','H','M',' ')}, /* Central Khmer */ - {"kmb", HB_TAG('M','B','N',' ')}, /* Kimbundu */ - {"kmw", HB_TAG('K','M','O',' ')}, /* Komo (Democratic Republic of Congo) */ - {"kn", HB_TAG('K','A','N',' ')}, /* Kannada */ - {"knn", HB_TAG('K','O','K',' ')}, /* Konkani */ - {"ko", HB_TAG('K','O','R',' ')}, /* Korean */ - {"koi", HB_TAG('K','O','P',' ')}, /* Komi-Permyak */ - {"kok", HB_TAG('K','O','K',' ')}, /* Konkani [macrolanguage] */ - {"kon", HB_TAG('K','O','N','0')}, /* Kongo */ - {"kos", HB_TAG('K','O','S',' ')}, /* Kosraean */ - {"kpe", HB_TAG('K','P','L',' ')}, /* Kpelle [macrolanguage] */ - {"kpv", HB_TAG('K','O','Z',' ')}, /* Komi-Zyrian */ - {"kpy", HB_TAG('K','Y','K',' ')}, /* Koryak */ - {"kqy", HB_TAG('K','R','T',' ')}, /* Koorete */ - {"kr", HB_TAG('K','N','R',' ')}, /* Kanuri [macrolanguage] */ - {"kri", HB_TAG('K','R','I',' ')}, /* Krio */ - {"krl", HB_TAG('K','R','L',' ')}, /* Karelian */ - {"kru", HB_TAG('K','U','U',' ')}, /* Kurukh */ - {"ks", HB_TAG('K','S','H',' ')}, /* Kashmiri */ - {"ksh", HB_TAG('K','S','H','0')}, /* Ripuarian, Kölsch */ -/*{"ksw", HB_TAG('K','R','N',' ')},*/ /* S'gaw Karen (Microsoft fonts?) */ - {"ksw", HB_TAG('K','S','W',' ')}, /* S'gaw Karen (OpenType spec and SIL fonts) */ - {"ktb", HB_TAG('K','E','B',' ')}, /* Kebena */ - {"ktu", HB_TAG('K','O','N',' ')}, /* Kikongo */ - {"ku", HB_TAG('K','U','R',' ')}, /* Kurdish [macrolanguage] */ - {"kum", HB_TAG('K','U','M',' ')}, /* Kumyk */ - {"kv", HB_TAG('K','O','M',' ')}, /* Komi [macrolanguage] */ - {"kvd", HB_TAG('K','U','I',' ')}, /* Kui (Indonesia) */ - {"kw", HB_TAG('C','O','R',' ')}, /* Cornish */ - {"kxc", HB_TAG('K','M','S',' ')}, /* Komso */ - {"kxu", HB_TAG('K','U','I',' ')}, /* Kui (India) */ - {"ky", HB_TAG('K','I','R',' ')}, /* Kirghiz/Kyrgyz */ - {"kyu", HB_TAG('K','Y','U',' ')}, /* Western Kayah */ - {"la", HB_TAG('L','A','T',' ')}, /* Latin */ - {"lad", HB_TAG('J','U','D',' ')}, /* Ladino */ - {"lb", HB_TAG('L','T','Z',' ')}, /* Luxembourgish */ - {"lbe", HB_TAG('L','A','K',' ')}, /* Lak */ - {"lbj", HB_TAG('L','D','K',' ')}, /* Ladakhi */ - {"lez", HB_TAG('L','E','Z',' ')}, /* Lezgi */ - {"lg", HB_TAG('L','U','G',' ')}, /* Ganda */ - {"li", HB_TAG('L','I','M',' ')}, /* Limburgan/Limburger/Limburgish */ - {"lif", HB_TAG('L','M','B',' ')}, /* Limbu */ - {"lij", HB_TAG('L','I','J',' ')}, /* Ligurian */ - {"lis", HB_TAG('L','I','S',' ')}, /* Lisu */ - {"ljp", HB_TAG('L','J','P',' ')}, /* Lampung Api */ - {"lki", HB_TAG('L','K','I',' ')}, /* Laki */ - {"lld", HB_TAG('L','A','D',' ')}, /* Ladin */ - {"lmn", HB_TAG('L','A','M',' ')}, /* Lambani */ - {"lmo", HB_TAG('L','M','O',' ')}, /* Lombard */ - {"ln", HB_TAG('L','I','N',' ')}, /* Lingala */ - {"lo", HB_TAG('L','A','O',' ')}, /* Lao */ - {"lom", HB_TAG('L','O','M',' ')}, /* Loma */ - {"lrc", HB_TAG('L','R','C',' ')}, /* Northern Luri */ - {"lt", HB_TAG('L','T','H',' ')}, /* Lithuanian */ - {"lu", HB_TAG('L','U','B',' ')}, /* Luba-Katanga */ - {"lua", HB_TAG('L','U','B',' ')}, /* Luba-Kasai */ - {"luo", HB_TAG('L','U','O',' ')}, /* Luo (Kenya and Tanzania) */ - {"lus", HB_TAG('M','I','Z',' ')}, /* Mizo */ - {"luy", HB_TAG('L','U','H',' ')}, /* Luyia/Oluluyia [macrolanguage] */ - {"luz", HB_TAG('L','R','C',' ')}, /* Southern Luri */ - {"lv", HB_TAG('L','V','I',' ')}, /* Latvian */ - {"lzz", HB_TAG('L','A','Z',' ')}, /* Laz */ - {"mad", HB_TAG('M','A','D',' ')}, /* Madurese */ - {"mag", HB_TAG('M','A','G',' ')}, /* Magahi */ - {"mai", HB_TAG('M','T','H',' ')}, /* Maithili */ - {"mak", HB_TAG('M','K','R',' ')}, /* Makasar */ - {"mam", HB_TAG('M','A','M',' ')}, /* Mam */ - {"man", HB_TAG('M','N','K',' ')}, /* Manding/Mandingo [macrolanguage] */ - {"mdc", HB_TAG('M','L','E',' ')}, /* Male (Papua New Guinea) */ - {"mdf", HB_TAG('M','O','K',' ')}, /* Moksha */ - {"mdr", HB_TAG('M','D','R',' ')}, /* Mandar */ - {"mdy", HB_TAG('M','L','E',' ')}, /* Male (Ethiopia) */ - {"men", HB_TAG('M','D','E',' ')}, /* Mende (Sierra Leone) */ - {"mer", HB_TAG('M','E','R',' ')}, /* Meru */ - {"mfe", HB_TAG('M','F','E',' ')}, /* Morisyen */ - {"mg", HB_TAG('M','L','G',' ')}, /* Malagasy [macrolanguage] */ - {"mh", HB_TAG('M','A','H',' ')}, /* Marshallese */ - {"mhr", HB_TAG('L','M','A',' ')}, /* Low Mari */ - {"mi", HB_TAG('M','R','I',' ')}, /* Maori */ - {"min", HB_TAG('M','I','N',' ')}, /* Minangkabau */ - {"mk", HB_TAG('M','K','D',' ')}, /* Macedonian */ - {"mku", HB_TAG('M','N','K',' ')}, /* Konyanka Maninka */ - {"mkw", HB_TAG('M','K','W',' ')}, /* Kituba (Congo) */ - {"ml", HB_TAG('M','L','R',' ')}, /* Malayalam */ - {"mlq", HB_TAG('M','N','K',' ')}, /* Western Maninkakan */ - {"mn", HB_TAG('M','N','G',' ')}, /* Mongolian [macrolanguage] */ - {"mnc", HB_TAG('M','C','H',' ')}, /* Manchu */ - {"mni", HB_TAG('M','N','I',' ')}, /* Manipuri */ - {"mnk", HB_TAG('M','N','D',' ')}, /* Mandinka */ - {"mns", HB_TAG('M','A','N',' ')}, /* Mansi */ - {"mnw", HB_TAG('M','O','N',' ')}, /* Mon */ - {"mo", HB_TAG('M','O','L',' ')}, /* Moldavian */ - {"moh", HB_TAG('M','O','H',' ')}, /* Mohawk */ - {"mos", HB_TAG('M','O','S',' ')}, /* Mossi */ - {"mpe", HB_TAG('M','A','J',' ')}, /* Majang */ - {"mr", HB_TAG('M','A','R',' ')}, /* Marathi */ - {"mrh", HB_TAG('Q','I','N',' ')}, /* Mara Chin */ - {"mrj", HB_TAG('H','M','A',' ')}, /* High Mari */ - {"ms", HB_TAG('M','L','Y',' ')}, /* Malay [macrolanguage] */ - {"msc", HB_TAG('M','N','K',' ')}, /* Sankaran Maninka */ - {"mt", HB_TAG('M','T','S',' ')}, /* Maltese */ - {"mtr", HB_TAG('M','A','W',' ')}, /* Mewari */ - {"mus", HB_TAG('M','U','S',' ')}, /* Creek */ - {"mve", HB_TAG('M','A','W',' ')}, /* Marwari (Pakistan) */ - {"mwk", HB_TAG('M','N','K',' ')}, /* Kita Maninkakan */ - {"mwl", HB_TAG('M','W','L',' ')}, /* Mirandese */ - {"mwr", HB_TAG('M','A','W',' ')}, /* Marwari [macrolanguage] */ - {"mww", HB_TAG('M','W','W',' ')}, /* Hmong Daw */ - {"my", HB_TAG('B','R','M',' ')}, /* Burmese */ - {"mym", HB_TAG('M','E','N',' ')}, /* Me'en */ - {"myn", HB_TAG('M','Y','N',' ')}, /* Mayan */ - {"myq", HB_TAG('M','N','K',' ')}, /* Forest Maninka (retired code) */ - {"myv", HB_TAG('E','R','Z',' ')}, /* Erzya */ - {"mzn", HB_TAG('M','Z','N',' ')}, /* Mazanderani */ - {"na", HB_TAG('N','A','U',' ')}, /* Nauru */ - {"nag", HB_TAG('N','A','G',' ')}, /* Naga-Assamese */ - {"nah", HB_TAG('N','A','H',' ')}, /* Nahuatl [family] */ - {"nap", HB_TAG('N','A','P',' ')}, /* Neapolitan */ - {"nb", HB_TAG('N','O','R',' ')}, /* Norwegian Bokmål */ - {"nco", HB_TAG('S','I','B',' ')}, /* Sibe */ - {"nd", HB_TAG('N','D','B',' ')}, /* [North] Ndebele */ - {"ndc", HB_TAG('N','D','C',' ')}, /* Ndau */ - {"nds", HB_TAG('N','D','S',' ')}, /* Low German/Low Saxon */ - {"ne", HB_TAG('N','E','P',' ')}, /* Nepali */ - {"new", HB_TAG('N','E','W',' ')}, /* Newari */ - {"ng", HB_TAG('N','D','G',' ')}, /* Ndonga */ - {"nga", HB_TAG('N','G','A',' ')}, /* Ngabaka */ - {"ngl", HB_TAG('L','M','W',' ')}, /* Lomwe */ - {"ngo", HB_TAG('S','X','T',' ')}, /* Sutu */ - {"niu", HB_TAG('N','I','U',' ')}, /* Niuean */ - {"niv", HB_TAG('G','I','L',' ')}, /* Gilyak */ - {"nl", HB_TAG('N','L','D',' ')}, /* Dutch */ - {"nn", HB_TAG('N','Y','N',' ')}, /* Norwegian Nynorsk */ - {"no", HB_TAG('N','O','R',' ')}, /* Norwegian [macrolanguage] */ - {"nod", HB_TAG('N','T','A',' ')}, /* Northern Thai */ - {"noe", HB_TAG('N','O','E',' ')}, /* Nimadi */ - {"nog", HB_TAG('N','O','G',' ')}, /* Nogai */ - {"nov", HB_TAG('N','O','V',' ')}, /* Novial */ - {"nqo", HB_TAG('N','K','O',' ')}, /* N'Ko */ - {"nr", HB_TAG('N','D','B',' ')}, /* [South] Ndebele */ - {"nsk", HB_TAG('N','A','S',' ')}, /* Naskapi */ - {"nso", HB_TAG('S','O','T',' ')}, /* [Northern] Sotho */ - {"nv", HB_TAG('N','A','V',' ')}, /* Navajo */ - {"ny", HB_TAG('C','H','I',' ')}, /* Chewa/Chichwa/Nyanja */ - {"nym", HB_TAG('N','Y','M',' ')}, /* Nyamwezi */ - {"nyn", HB_TAG('N','K','L',' ')}, /* Nyankole */ - {"oc", HB_TAG('O','C','I',' ')}, /* Occitan (post 1500) */ - {"oj", HB_TAG('O','J','B',' ')}, /* Ojibwa [macrolanguage] */ - {"ojs", HB_TAG('O','C','R',' ')}, /* Oji-Cree */ - {"okm", HB_TAG('K','O','H',' ')}, /* Korean Old Hangul */ - {"om", HB_TAG('O','R','O',' ')}, /* Oromo [macrolanguage] */ - {"or", HB_TAG('O','R','I',' ')}, /* Oriya */ - {"os", HB_TAG('O','S','S',' ')}, /* Ossetian */ - {"pa", HB_TAG('P','A','N',' ')}, /* Panjabi */ - {"pag", HB_TAG('P','A','G',' ')}, /* Pangasinan */ - {"pam", HB_TAG('P','A','M',' ')}, /* Kapampangan/Pampanga */ - {"pap", HB_TAG('P','A','P','0')}, /* Papiamento */ - {"pau", HB_TAG('P','A','U',' ')}, /* Palauan */ - {"pcc", HB_TAG('P','C','C',' ')}, /* Bouyei */ - {"pcd", HB_TAG('P','C','D',' ')}, /* Picard */ - {"pce", HB_TAG('P','L','G',' ')}, /* [Ruching] Palaung */ - {"pck", HB_TAG('Q','I','N',' ')}, /* Paite Chin */ - {"pdc", HB_TAG('P','D','C',' ')}, /* Pennsylvania German */ - {"pes", HB_TAG('F','A','R',' ')}, /* Iranian Persian */ - {"phk", HB_TAG('P','H','K',' ')}, /* Phake */ - {"pi", HB_TAG('P','A','L',' ')}, /* Pali */ - {"pih", HB_TAG('P','I','H',' ')}, /* Pitcairn-Norfolk */ - {"pl", HB_TAG('P','L','K',' ')}, /* Polish */ - {"pll", HB_TAG('P','L','G',' ')}, /* [Shwe] Palaung */ - {"plp", HB_TAG('P','A','P',' ')}, /* Palpa */ - {"pms", HB_TAG('P','M','S',' ')}, /* Piemontese */ - {"pnb", HB_TAG('P','N','B',' ')}, /* Western Panjabi */ - {"poh", HB_TAG('P','O','H',' ')}, /* Pocomchi */ - {"pon", HB_TAG('P','O','N',' ')}, /* Pohnpeian */ - {"prs", HB_TAG('D','R','I',' ')}, /* Afghan Persian/Dari */ - {"ps", HB_TAG('P','A','S',' ')}, /* Pashto/Pushto [macrolanguage] */ - {"pt", HB_TAG('P','T','G',' ')}, /* Portuguese */ - {"pwo", HB_TAG('P','W','O',' ')}, /* Pwo Western Karen */ - {"qu", HB_TAG('Q','U','Z',' ')}, /* Quechua [macrolanguage] */ - {"quc", HB_TAG('Q','U','C',' ')}, /* K'iche'/Quiché */ - {"quh", HB_TAG('Q','U','H',' ')}, /* Quechua (Bolivia) */ - {"quz", HB_TAG('Q','U','Z',' ')}, /* Cusco Quechua */ - {"qvi", HB_TAG('Q','V','I',' ')}, /* Quechua (Ecuador) */ - {"qwh", HB_TAG('Q','W','H',' ')}, /* Quechua (Peru) */ - {"raj", HB_TAG('R','A','J',' ')}, /* Rajasthani [macrolanguage] */ - {"rar", HB_TAG('R','A','R',' ')}, /* Rarotongan */ - {"rbb", HB_TAG('P','L','G',' ')}, /* Rumai Palaung */ - {"rej", HB_TAG('R','E','J',' ')}, /* Rejang */ - {"ria", HB_TAG('R','I','A',' ')}, /* Riang (India) */ - {"rif", HB_TAG('R','I','F',' ')}, /* Tarifit */ - {"ril", HB_TAG('R','I','A',' ')}, /* Riang (Myanmar) */ - {"rit", HB_TAG('R','I','T',' ')}, /* Ritarungo */ - {"rki", HB_TAG('A','R','K',' ')}, /* Rakhine */ - {"rkw", HB_TAG('R','K','W',' ')}, /* Arakwal */ - {"rm", HB_TAG('R','M','S',' ')}, /* Romansh */ - {"rmy", HB_TAG('R','M','Y',' ')}, /* Vlax Romani */ - {"rn", HB_TAG('R','U','N',' ')}, /* Rundi */ - {"ro", HB_TAG('R','O','M',' ')}, /* Romanian */ - {"rom", HB_TAG('R','O','Y',' ')}, /* Romany [macrolanguage] */ - {"rtm", HB_TAG('R','T','M',' ')}, /* Rotuman */ - {"ru", HB_TAG('R','U','S',' ')}, /* Russian */ - {"rue", HB_TAG('R','S','Y',' ')}, /* Rusyn */ - {"rup", HB_TAG('R','U','P',' ')}, /* Aromanian/Arumanian/Macedo-Romanian */ - {"rw", HB_TAG('R','U','A',' ')}, /* Kinyarwanda */ - {"rwr", HB_TAG('M','A','W',' ')}, /* Marwari (India) */ - {"sa", HB_TAG('S','A','N',' ')}, /* Sanskrit */ - {"sah", HB_TAG('Y','A','K',' ')}, /* Yakut */ - {"sam", HB_TAG('P','A','A',' ')}, /* Palestinian Aramaic */ - {"sas", HB_TAG('S','A','S',' ')}, /* Sasak */ - {"sat", HB_TAG('S','A','T',' ')}, /* Santali */ - {"sc", HB_TAG('S','R','D',' ')}, /* Sardinian [macrolanguage] */ - {"sck", HB_TAG('S','A','D',' ')}, /* Sadri */ - {"scn", HB_TAG('S','C','N',' ')}, /* Sicilian */ - {"sco", HB_TAG('S','C','O',' ')}, /* Scots */ - {"scs", HB_TAG('S','L','A',' ')}, /* [North] Slavey */ - {"sd", HB_TAG('S','N','D',' ')}, /* Sindhi */ - {"se", HB_TAG('N','S','M',' ')}, /* Northern Sami */ - {"seh", HB_TAG('S','N','A',' ')}, /* Sena */ - {"sel", HB_TAG('S','E','L',' ')}, /* Selkup */ - {"sez", HB_TAG('Q','I','N',' ')}, /* Senthang Chin */ - {"sg", HB_TAG('S','G','O',' ')}, /* Sango */ - {"sga", HB_TAG('S','G','A',' ')}, /* Old Irish (to 900) */ - {"sgs", HB_TAG('S','G','S',' ')}, /* Samogitian */ - {"sgw", HB_TAG('C','H','G',' ')}, /* Sebat Bet Gurage */ -/*{"sgw", HB_TAG('S','G','W',' ')},*/ /* Sebat Bet Gurage (in SIL fonts) */ - {"shi", HB_TAG('S','H','I',' ')}, /* Tachelhit */ - {"shn", HB_TAG('S','H','N',' ')}, /* Shan */ - {"si", HB_TAG('S','N','H',' ')}, /* Sinhala */ - {"sid", HB_TAG('S','I','D',' ')}, /* Sidamo */ - {"sjd", HB_TAG('K','S','M',' ')}, /* Kildin Sami */ - {"sk", HB_TAG('S','K','Y',' ')}, /* Slovak */ - {"skr", HB_TAG('S','R','K',' ')}, /* Seraiki */ - {"sl", HB_TAG('S','L','V',' ')}, /* Slovenian */ - {"sm", HB_TAG('S','M','O',' ')}, /* Samoan */ - {"sma", HB_TAG('S','S','M',' ')}, /* Southern Sami */ - {"smj", HB_TAG('L','S','M',' ')}, /* Lule Sami */ - {"smn", HB_TAG('I','S','M',' ')}, /* Inari Sami */ - {"sms", HB_TAG('S','K','S',' ')}, /* Skolt Sami */ - {"sn", HB_TAG('S','N','A','0')}, /* Shona */ - {"snk", HB_TAG('S','N','K',' ')}, /* Soninke */ - {"so", HB_TAG('S','M','L',' ')}, /* Somali */ - {"sop", HB_TAG('S','O','P',' ')}, /* Songe */ - {"sq", HB_TAG('S','Q','I',' ')}, /* Albanian [macrolanguage] */ - {"sr", HB_TAG('S','R','B',' ')}, /* Serbian */ - {"srr", HB_TAG('S','R','R',' ')}, /* Serer */ - {"ss", HB_TAG('S','W','Z',' ')}, /* Swati */ - {"st", HB_TAG('S','O','T',' ')}, /* [Southern] Sotho */ - {"stq", HB_TAG('S','T','Q',' ')}, /* Saterfriesisch */ - {"stv", HB_TAG('S','I','G',' ')}, /* Silt'e */ - {"su", HB_TAG('S','U','N',' ')}, /* Sundanese */ - {"suk", HB_TAG('S','U','K',' ')}, /* Sukama */ - {"suq", HB_TAG('S','U','R',' ')}, /* Suri */ - {"sv", HB_TAG('S','V','E',' ')}, /* Swedish */ - {"sva", HB_TAG('S','V','A',' ')}, /* Svan */ - {"sw", HB_TAG('S','W','K',' ')}, /* Swahili [macrolanguage] */ - {"swb", HB_TAG('C','M','R',' ')}, /* Comorian */ - {"swh", HB_TAG('S','W','K',' ')}, /* Kiswahili/Swahili */ - {"swv", HB_TAG('M','A','W',' ')}, /* Shekhawati */ - {"sxu", HB_TAG('S','X','U',' ')}, /* Upper Saxon */ - {"syc", HB_TAG('S','Y','R',' ')}, /* Classical Syriac */ - {"syl", HB_TAG('S','Y','L',' ')}, /* Sylheti */ - {"syr", HB_TAG('S','Y','R',' ')}, /* Syriac [macrolanguage] */ - {"szl", HB_TAG('S','Z','L',' ')}, /* Silesian */ - {"ta", HB_TAG('T','A','M',' ')}, /* Tamil */ - {"tab", HB_TAG('T','A','B',' ')}, /* Tabasaran */ - {"tcp", HB_TAG('Q','I','N',' ')}, /* Tawr Chin */ - {"tcy", HB_TAG('T','U','L',' ')}, /* Tulu */ - {"tcz", HB_TAG('Q','I','N',' ')}, /* Thado Chin */ - {"tdd", HB_TAG('T','D','D',' ')}, /* Tai Nüa */ - {"te", HB_TAG('T','E','L',' ')}, /* Telugu */ - {"tem", HB_TAG('T','M','N',' ')}, /* Temne */ - {"tet", HB_TAG('T','E','T',' ')}, /* Tetum */ - {"tg", HB_TAG('T','A','J',' ')}, /* Tajik */ - {"th", HB_TAG('T','H','A',' ')}, /* Thai */ - {"ti", HB_TAG('T','G','Y',' ')}, /* Tigrinya */ - {"tig", HB_TAG('T','G','R',' ')}, /* Tigre */ - {"tiv", HB_TAG('T','I','V',' ')}, /* Tiv */ - {"tk", HB_TAG('T','K','M',' ')}, /* Turkmen */ - {"tl", HB_TAG('T','G','L',' ')}, /* Tagalog */ - {"tmh", HB_TAG('T','M','H',' ')}, /* Tamashek */ - {"tn", HB_TAG('T','N','A',' ')}, /* Tswana */ - {"to", HB_TAG('T','G','N',' ')}, /* Tonga (Tonga Islands) */ - {"tod", HB_TAG('T','O','D','0')}, /* Toma */ - {"toi", HB_TAG('T','N','G',' ')}, /* Tonga */ - {"tpi", HB_TAG('T','P','I',' ')}, /* Tok Pisin */ - {"tr", HB_TAG('T','R','K',' ')}, /* Turkish */ - {"tru", HB_TAG('T','U','A',' ')}, /* Turoyo Aramaic */ - {"ts", HB_TAG('T','S','G',' ')}, /* Tsonga */ - {"tt", HB_TAG('T','A','T',' ')}, /* Tatar */ - {"tum", HB_TAG('T','U','M',' ')}, /* Tumbuka */ - {"tvl", HB_TAG('T','V','L',' ')}, /* Tuvalu */ - {"tw", HB_TAG('T','W','I',' ')}, /* Twi */ - {"ty", HB_TAG('T','H','T',' ')}, /* Tahitian */ - {"tyv", HB_TAG('T','U','V',' ')}, /* Tuvin */ - {"tyz", HB_TAG('T','Y','Z',' ')}, /* Tày */ - {"tzm", HB_TAG('T','Z','M',' ')}, /* Central Atlas Tamazight */ - {"tzo", HB_TAG('T','Z','O',' ')}, /* Tzotzil */ - {"udm", HB_TAG('U','D','M',' ')}, /* Udmurt */ - {"ug", HB_TAG('U','Y','G',' ')}, /* Uighur */ - {"uk", HB_TAG('U','K','R',' ')}, /* Ukrainian */ - {"umb", HB_TAG('U','M','B',' ')}, /* Umbundu */ - {"unr", HB_TAG('M','U','N',' ')}, /* Mundari */ - {"ur", HB_TAG('U','R','D',' ')}, /* Urdu */ - {"uz", HB_TAG('U','Z','B',' ')}, /* Uzbek [macrolanguage] */ - {"uzn", HB_TAG('U','Z','B',' ')}, /* Northern Uzbek */ - {"uzs", HB_TAG('U','Z','B',' ')}, /* Southern Uzbek */ - {"ve", HB_TAG('V','E','N',' ')}, /* Venda */ - {"vec", HB_TAG('V','E','C',' ')}, /* Venetian */ - {"vi", HB_TAG('V','I','T',' ')}, /* Vietnamese */ - {"vls", HB_TAG('F','L','E',' ')}, /* Vlaams */ - {"vmw", HB_TAG('M','A','K',' ')}, /* Makhuwa */ - {"vo", HB_TAG('V','O','L',' ')}, /* Volapük */ - {"vro", HB_TAG('V','R','O',' ')}, /* Võro */ - {"wa", HB_TAG('W','L','N',' ')}, /* Walloon */ - {"war", HB_TAG('W','A','R',' ')}, /* Waray (Philippines) */ - {"wbm", HB_TAG('W','A',' ',' ')}, /* Wa */ - {"wbr", HB_TAG('W','A','G',' ')}, /* Wagdi */ - {"wle", HB_TAG('S','I','G',' ')}, /* Wolane */ - {"wo", HB_TAG('W','L','F',' ')}, /* Wolof */ - {"wry", HB_TAG('M','A','W',' ')}, /* Merwari */ - {"wtm", HB_TAG('W','T','M',' ')}, /* Mewati */ - {"xal", HB_TAG('K','L','M',' ')}, /* Kalmyk */ - {"xan", HB_TAG('S','E','K',' ')}, /* Sekota */ - {"xh", HB_TAG('X','H','S',' ')}, /* Xhosa */ - {"xjb", HB_TAG('X','J','B',' ')}, /* Minjangbal */ - {"xog", HB_TAG('X','O','G',' ')}, /* Soga */ - {"xom", HB_TAG('K','M','O',' ')}, /* Komo (Sudan) */ - {"xpe", HB_TAG('X','P','E',' ')}, /* Kpelle (Liberia) */ - {"xsl", HB_TAG('S','S','L',' ')}, /* South Slavey */ - {"xst", HB_TAG('S','I','G',' ')}, /* Silt'e (retired code) */ - {"xwo", HB_TAG('T','O','D',' ')}, /* Written Oirat (Todo) */ - {"yao", HB_TAG('Y','A','O',' ')}, /* Yao */ - {"yap", HB_TAG('Y','A','P',' ')}, /* Yapese */ - {"yi", HB_TAG('J','I','I',' ')}, /* Yiddish [macrolanguage] */ - {"yo", HB_TAG('Y','B','A',' ')}, /* Yoruba */ - {"yos", HB_TAG('Q','I','N',' ')}, /* Yos, deprecated by IANA in favor of Zou [zom] */ - {"yso", HB_TAG('N','I','S',' ')}, /* Nisi (China) */ - {"za", HB_TAG('Z','H','A',' ')}, /* Chuang/Zhuang [macrolanguage] */ - {"zea", HB_TAG('Z','E','A',' ')}, /* Zeeuws */ - {"zgh", HB_TAG('Z','G','H',' ')}, /* Standard Morrocan Tamazigh */ - {"zne", HB_TAG('Z','N','D',' ')}, /* Zande */ - {"zom", HB_TAG('Q','I','N',' ')}, /* Zou */ - {"zu", HB_TAG('Z','U','L',' ')}, /* Zulu */ - {"zum", HB_TAG('L','R','C',' ')}, /* Kumzari */ - {"zza", HB_TAG('Z','Z','A',' ')}, /* Zazaki */ - - /* The corresponding languages IDs for the following IDs are unclear, - * overlap, or are architecturally weird. Needs more research. */ - -/*{"chp", HB_TAG('S','A','Y',' ')},*/ /* Sayisi */ -/*{"cwd", HB_TAG('T','C','R',' ')},*/ /* TH-Cree */ -/*{"emk", HB_TAG('E','M','K',' ')},*/ /* Eastern Maninkakan */ -/*{"krc", HB_TAG('B','A','L',' ')},*/ /* Balkar */ -/*{"??", HB_TAG('B','C','R',' ')},*/ /* Bible Cree */ -/*{"zh?", HB_TAG('C','H','N',' ')},*/ /* Chinese (seen in Microsoft fonts) */ -/*{"ar-Syrc?", HB_TAG('G','A','R',' ')},*/ /* Garshuni */ -/*{"hy?", HB_TAG('H','Y','E','0')},*/ /* Armenian East (ISO 639-3 hye according to Microsoft, but that’s equivalent to ISO 639-1 hy) */ -/*{"ga-Latg?/" HB_TAG('I','R','T',' ')},*/ /* Irish Traditional */ -/*{"krc", HB_TAG('K','A','R',' ')},*/ /* Karachay */ -/*{"ka-Geok?", HB_TAG('K','G','E',' ')},*/ /* Khutsuri Georgian */ -/*{"kca", HB_TAG('K','H','K',' ')},*/ /* Khanty-Kazim */ -/*{"kca", HB_TAG('K','H','S',' ')},*/ /* Khanty-Shurishkar */ -/*{"kca", HB_TAG('K','H','V',' ')},*/ /* Khanty-Vakhi */ -/*{"kqs, kss", HB_TAG('K','I','S',' ')},*/ /* Kisii */ -/*{"lua", HB_TAG('L','U','A',' ')},*/ /* Luba-Lulua */ -/*{"mlq", HB_TAG('M','L','N',' ')},*/ /* Malinke */ -/*{"nso", HB_TAG('N','S','O',' ')},*/ /* Sotho, Northern */ -/*{"??", HB_TAG('M','A','L',' ')},*/ /* Malayalam Traditional */ -/*{"csw", HB_TAG('N','C','R',' ')},*/ /* N-Cree */ -/*{"csw", HB_TAG('N','H','C',' ')},*/ /* Norway House Cree */ -/*{"el-polyton", HB_TAG('P','G','R',' ')},*/ /* Polytonic Greek */ -/*{"bgr, cnh, cnw, czt, sez, tcp, csy, ctd, flm, pck, tcz, zom, cmr, dao, hlt, cka, cnk, mrh, mwg, cbl, cnb, csh", HB_TAG('Q','I','N',' ')},*/ /* Chin */ -/*{"??", HB_TAG('Y','I','C',' ')},*/ /* Yi Classic */ -/*{"zh-Latn-pinyin", HB_TAG('Z','H','P',' ')},*/ /* Chinese Phonetic */ -}; - -typedef struct { - char language[11]; - hb_tag_t tag; -} LangTagLong; -static const LangTagLong ot_languages_zh[] = { - /* Store longest-first, if one is a prefix of another. */ - {"zh-cn", HB_TAG('Z','H','S',' ')}, /* Chinese (China) */ - {"zh-hk", HB_TAG('Z','H','H',' ')}, /* Chinese (Hong Kong) */ - {"zh-mo", HB_TAG('Z','H','H',' ')}, /* Chinese (Macao) */ - {"zh-sg", HB_TAG('Z','H','S',' ')}, /* Chinese (Singapore) */ - {"zh-tw", HB_TAG('Z','H','T',' ')}, /* Chinese (Taiwan) */ - {"zh-hans", HB_TAG('Z','H','S',' ')}, /* Chinese (Simplified) */ - {"zh-hant-hk",HB_TAG('Z','H','H',' ')}, /* Chinese (Hong Kong) */ - {"zh-hant-mo",HB_TAG('Z','H','H',' ')}, /* Chinese (Macao) */ - {"zh-hant", HB_TAG('Z','H','T',' ')}, /* Chinese (Traditional) */ -}; - static int lang_compare_first_component (const void *pa, const void *pb) @@ -895,6 +189,21 @@ lang_compare_first_component (const void *pa, return strncmp (a, b, MAX (da, db)); } +static bool +subtag_matches (const char *lang_str, + const char *limit, + const char *subtag) +{ + do { + const char *s = strstr (lang_str, subtag); + if (!s || s >= limit) + return false; + if (!ISALNUM (s[strlen (subtag)])) + return true; + lang_str = s + strlen (subtag); + } while (1); +} + static hb_bool_t lang_matches (const char *lang_str, const char *spec) { @@ -904,106 +213,187 @@ lang_matches (const char *lang_str, const char *spec) (lang_str[len] == '\0' || lang_str[len] == '-'); } +typedef struct { + char language[4]; + hb_tag_t tags[HB_OT_MAX_TAGS_PER_LANGUAGE]; +} LangTag; + +#include "hb-ot-tag-table.hh" + +/* The corresponding languages IDs for the following IDs are unclear, + * overlap, or are architecturally weird. Needs more research. */ + +/*{"??", {HB_TAG('B','C','R',' ')}},*/ /* Bible Cree */ +/*{"zh?", {HB_TAG('C','H','N',' ')}},*/ /* Chinese (seen in Microsoft fonts) */ +/*{"ar-Syrc?", {HB_TAG('G','A','R',' ')}},*/ /* Garshuni */ +/*{"??", {HB_TAG('N','G','R',' ')}},*/ /* Nagari */ +/*{"??", {HB_TAG('Y','I','C',' ')}},*/ /* Yi Classic */ +/*{"zh?", {HB_TAG('Z','H','P',' ')}},*/ /* Chinese Phonetic */ + hb_tag_t hb_ot_tag_from_language (hb_language_t language) { - const char *lang_str, *s; + unsigned int count = 1; + hb_tag_t tags[1]; + hb_ot_tags_from_script_and_language (HB_SCRIPT_UNKNOWN, language, nullptr, nullptr, &count, tags); + return count > 0 ? tags[0] : HB_OT_TAG_DEFAULT_LANGUAGE; +} - if (language == HB_LANGUAGE_INVALID) - return HB_OT_TAG_DEFAULT_LANGUAGE; +static void +hb_ot_tags_from_language (const char *lang_str, + const char *limit, + const char *private_use_subtag, + unsigned int *count, + hb_tag_t *tags) +{ + const char *s; - lang_str = hb_language_to_string (language); + /* Check for matches of multiple subtags. */ + if (hb_ot_tags_from_complex_language (lang_str, limit, count, tags)) + return; - s = strstr (lang_str, "x-hbot"); - if (s) { - char tag[4]; - int i; - s += 6; - for (i = 0; i < 4 && ISALNUM (s[i]); i++) - tag[i] = TOUPPER (s[i]); - if (i) { - for (; i < 4; i++) - tag[i] = ' '; - return HB_TAG (tag[0], tag[1], tag[2], tag[3]); + /* Find a language matching in the first component. */ + s = strchr (lang_str, '-'); + { + const LangTag *lang_tag; + if (s && limit - lang_str >= 6) + { + const char *extlang_end = strchr (s + 1, '-'); + /* If there is an extended language tag, use it. */ + if (3 == (extlang_end ? extlang_end - s - 1 : strlen (s + 1)) && + ISALPHA (s[1])) + lang_str = s + 1; + } + lang_tag = (LangTag *) bsearch (lang_str, ot_languages, + ARRAY_LENGTH (ot_languages), sizeof (LangTag), + lang_compare_first_component); + if (lang_tag) + { + unsigned int i; + for (i = 0; i < *count && lang_tag->tags[i] != HB_TAG_NONE; i++) + tags[i] = lang_tag->tags[i]; + *count = i; + return; } } - /* - * "fonipa" is a variant tag in BCP-47, meaning the International Phonetic Alphabet. - * It can be applied to any language. - */ - if (strstr (lang_str, "-fonipa")) { - return HB_TAG('I','P','P','H'); /* Phonetic transcription—IPA conventions */ - } - - /* - * "fonnapa" is a variant tag in BCP-47, meaning the North American Phonetic Alphabet - * also known as Americanist Phonetic Notation. It can be applied to any language. - */ - if (strstr (lang_str, "-fonnapa")) { - return HB_TAG('A','P','P','H'); /* Phonetic transcription—Americanist conventions */ + if (!s) + s = lang_str + strlen (lang_str); + if (s - lang_str == 3) { + /* Assume it's ISO-639-3 and upper-case and use it. */ + tags[0] = hb_tag_from_string (lang_str, s - lang_str) & ~0x20202000u; + *count = 1; + return; } - /* - * "Syre" is a BCP-47 script tag, meaning the Estrangela variant of the Syriac script. - * It can be applied to any language. - */ - if (strstr (lang_str, "-syre")) { - return HB_TAG('S','Y','R','E'); /* Estrangela Syriac */ - } + *count = 0; +} - /* - * "Syrj" is a BCP-47 script tag, meaning the Western variant of the Syriac script. - * It can be applied to any language. - */ - if (strstr (lang_str, "-syrj")) { - return HB_TAG('S','Y','R','J'); /* Western Syriac */ +static bool +parse_private_use_subtag (const char *private_use_subtag, + unsigned int *count, + hb_tag_t *tags, + const char *prefix, + unsigned char (*normalize) (unsigned char)) +{ + if (private_use_subtag && count && tags && *count) + { + const char *s = strstr (private_use_subtag, prefix); + if (s) + { + char tag[4]; + int i; + s += strlen (prefix); + for (i = 0; i < 4 && ISALNUM (s[i]); i++) + tag[i] = normalize (s[i]); + if (i) + { + for (; i < 4; i++) + tag[i] = ' '; + tags[0] = HB_TAG (tag[0], tag[1], tag[2], tag[3]); + if ((tags[0] & 0xDFDFDFDF) == HB_OT_TAG_DEFAULT_SCRIPT) + tags[0] ^= ~0xDFDFDFDF; + *count = 1; + return false; + } + } } + return true; +} - /* - * "Syrn" is a BCP-47 script tag, meaning the Eastern variant of the Syriac script. - * It can be applied to any language. - */ - if (strstr (lang_str, "-syrn")) { - return HB_TAG('S','Y','R','N'); /* Eastern Syriac */ - } +/** + * hb_ot_tags_from_script_and_language: + * @script: an #hb_script_t to convert. + * @language: an #hb_language_t to convert. + * @script_count: (allow-none): maximum number of script tags to retrieve (IN) + * and actual number of script tags retrieved (OUT) + * @script_tags: (out) (allow-none): array of size at least @script_count to store the + * script tag results + * @language_count: (allow-none): maximum number of language tags to retrieve + * (IN) and actual number of language tags retrieved (OUT) + * @language_tags: (out) (allow-none): array of size at least @language_count to store + * the language tag results + * + * Converts an #hb_script_t and an #hb_language_t to script and language tags. + * + * Since: 2.0.0 + **/ +void +hb_ot_tags_from_script_and_language (hb_script_t script, + hb_language_t language, + unsigned int *script_count /* IN/OUT */, + hb_tag_t *script_tags /* OUT */, + unsigned int *language_count /* IN/OUT */, + hb_tag_t *language_tags /* OUT */) +{ + bool needs_script = true; - /* Find a language matching in the first component */ + if (language == HB_LANGUAGE_INVALID) { - const LangTag *lang_tag; - lang_tag = (LangTag *) bsearch (lang_str, ot_languages, - ARRAY_LENGTH (ot_languages), sizeof (LangTag), - lang_compare_first_component); - if (lang_tag) - return lang_tag->tag; + if (language_count && language_tags && *language_count) + *language_count = 0; } - - /* Otherwise, check the Chinese ones */ - if (0 == lang_compare_first_component (lang_str, "zh")) + else { - unsigned int i; + const char *lang_str, *s, *limit, *private_use_subtag; + bool needs_language; - for (i = 0; i < ARRAY_LENGTH (ot_languages_zh); i++) + lang_str = hb_language_to_string (language); + limit = nullptr; + private_use_subtag = nullptr; + if (lang_str[0] == 'x' && lang_str[1] == '-') { - const LangTagLong *lang_tag; - lang_tag = &ot_languages_zh[i]; - if (lang_matches (lang_str, lang_tag->language)) - return lang_tag->tag; + private_use_subtag = lang_str; + } else { + for (s = lang_str + 1; *s; s++) + { + if (s[-1] == '-' && s[1] == '-') + { + if (s[0] == 'x') + { + private_use_subtag = s; + if (!limit) + limit = s - 1; + break; + } else if (!limit) + { + limit = s - 1; + } + } + } + if (!limit) + limit = s; } - /* Otherwise just return 'ZHS ' */ - return HB_TAG('Z','H','S',' '); - } + needs_script = parse_private_use_subtag (private_use_subtag, script_count, script_tags, "-hbsc", TOLOWER); + needs_language = parse_private_use_subtag (private_use_subtag, language_count, language_tags, "-hbot", TOUPPER); - s = strchr (lang_str, '-'); - if (!s) - s = lang_str + strlen (lang_str); - if (s - lang_str == 3) { - /* Assume it's ISO-639-3 and upper-case and use it. */ - return hb_tag_from_string (lang_str, s - lang_str) & ~0x20202000u; + if (needs_language && language_count && language_tags && *language_count) + hb_ot_tags_from_language (lang_str, limit, private_use_subtag, language_count, language_tags); } - return HB_OT_TAG_DEFAULT_LANGUAGE; + if (needs_script && script_count && script_tags && *script_count) + hb_ot_all_tags_from_script (script, script_count, script_tags); } /** @@ -1023,36 +413,16 @@ hb_ot_tag_to_language (hb_tag_t tag) if (tag == HB_OT_TAG_DEFAULT_LANGUAGE) return nullptr; - /* struct LangTag has only room for 3-letter language tags. */ - switch (tag) { - case HB_TAG('A','P','P','H'): /* Phonetic transcription—Americanist conventions */ - return hb_language_from_string ("und-fonnapa", -1); - case HB_TAG('I','P','P','H'): /* Phonetic transcription—IPA conventions */ - return hb_language_from_string ("und-fonipa", -1); - case HB_TAG('S','Y','R',' '): /* Syriac [macrolanguage] */ - return hb_language_from_string ("syr", -1); - case HB_TAG('S','Y','R','E'): /* Estrangela Syriac */ - return hb_language_from_string ("und-Syre", -1); - case HB_TAG('S','Y','R','J'): /* Western Syriac */ - return hb_language_from_string ("und-Syrj", -1); - case HB_TAG('S','Y','R','N'): /* Eastern Syriac */ - return hb_language_from_string ("und-Syrn", -1); + { + hb_language_t disambiguated_tag = hb_ot_ambiguous_tag_to_language (tag); + if (disambiguated_tag != HB_LANGUAGE_INVALID) + return disambiguated_tag; } for (i = 0; i < ARRAY_LENGTH (ot_languages); i++) - if (ot_languages[i].tag == tag) + if (ot_languages[i].tags[0] == tag) return hb_language_from_string (ot_languages[i].language, -1); - /* If tag starts with ZH, it's Chinese */ - if ((tag & 0xFFFF0000u) == 0x5A480000u) { - switch (tag) { - case HB_TAG('Z','H','H',' '): return hb_language_from_string ("zh-hk", -1); /* Hong Kong */ - case HB_TAG('Z','H','S',' '): return hb_language_from_string ("zh-Hans", -1); /* Simplified */ - case HB_TAG('Z','H','T',' '): return hb_language_from_string ("zh-Hant", -1); /* Traditional */ - default: break; /* Fall through */ - } - } - /* Else return a custom language in the form of "x-hbotABCD" */ { unsigned char buf[11] = "x-hbot"; @@ -1067,6 +437,71 @@ hb_ot_tag_to_language (hb_tag_t tag) } } +/** + * hb_ot_tags_to_script_and_language: + * @script_tag: a script tag + * @language_tag: a language tag + * @script: (allow-none): the #hb_script_t corresponding to @script_tag (OUT). + * @language: (allow-none): the #hb_language_t corresponding to @script_tag and + * @language_tag (OUT). + * + * Converts a script tag and a language tag to an #hb_script_t and an + * #hb_language_t. + * + * Since: 2.0.0 + **/ +void +hb_ot_tags_to_script_and_language (hb_tag_t script_tag, + hb_tag_t language_tag, + hb_script_t *script /* OUT */, + hb_language_t *language /* OUT */) +{ + hb_script_t script_out = hb_ot_tag_to_script (script_tag); + if (script) + *script = script_out; + if (language) + { + unsigned int script_count = 1; + hb_tag_t primary_script_tag[1]; + hb_ot_tags_from_script_and_language (script_out, + HB_LANGUAGE_INVALID, + &script_count, + primary_script_tag, + nullptr, nullptr); + *language = hb_ot_tag_to_language (language_tag); + if (script_count == 0 || primary_script_tag[0] != script_tag) + { + unsigned char *buf; + const char *lang_str = hb_language_to_string (*language); + size_t len = strlen (lang_str); + buf = (unsigned char *) malloc (len + 11); + if (unlikely (!buf)) + { + *language = nullptr; + } + else + { + memcpy (buf, lang_str, len); + if (lang_str[0] != 'x' || lang_str[1] != '-') { + buf[len++] = '-'; + buf[len++] = 'x'; + } + buf[len++] = '-'; + buf[len++] = 'h'; + buf[len++] = 'b'; + buf[len++] = 's'; + buf[len++] = 'c'; + buf[len++] = script_tag >> 24; + buf[len++] = (script_tag >> 16) & 0xFF; + buf[len++] = (script_tag >> 8) & 0xFF; + buf[len++] = script_tag & 0xFF; + *language = hb_language_from_string ((char *) buf, len); + free (buf); + } + } + } +} + #ifdef MAIN static inline void test_langs_sorted (void) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.h index 54fb747f582..33a4dbdbc0d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.h @@ -39,20 +39,39 @@ HB_BEGIN_DECLS #define HB_OT_TAG_DEFAULT_SCRIPT HB_TAG ('D', 'F', 'L', 'T') #define HB_OT_TAG_DEFAULT_LANGUAGE HB_TAG ('d', 'f', 'l', 't') +/** + * HB_OT_MAX_TAGS_PER_SCRIPT: + * + * Since: 2.0.0 + **/ +#define HB_OT_MAX_TAGS_PER_SCRIPT 3u +/** + * HB_OT_MAX_TAGS_PER_LANGUAGE: + * + * Since: 2.0.0 + **/ +#define HB_OT_MAX_TAGS_PER_LANGUAGE 3u + HB_EXTERN void -hb_ot_tags_from_script (hb_script_t script, - hb_tag_t *script_tag_1, - hb_tag_t *script_tag_2); +hb_ot_tags_from_script_and_language (hb_script_t script, + hb_language_t language, + unsigned int *script_count /* IN/OUT */, + hb_tag_t *script_tags /* OUT */, + unsigned int *language_count /* IN/OUT */, + hb_tag_t *language_tags /* OUT */); HB_EXTERN hb_script_t hb_ot_tag_to_script (hb_tag_t tag); -HB_EXTERN hb_tag_t -hb_ot_tag_from_language (hb_language_t language); - HB_EXTERN hb_language_t hb_ot_tag_to_language (hb_tag_t tag); +HB_EXTERN void +hb_ot_tags_to_script_and_language (hb_tag_t script_tag, + hb_tag_t language_tag, + hb_script_t *script /* OUT */, + hb_language_t *language /* OUT */); + HB_END_DECLS diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh index 8343018b32f..d100ca21ef8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh @@ -93,6 +93,7 @@ struct SegmentMaps : ArrayOf<AxisValueMap> (value - arrayZ[i-1].fromCoord) + denom/2) / denom; } + public: DEFINE_SIZE_ARRAY (2, arrayZ); }; @@ -108,7 +109,7 @@ struct avar c->check_struct (this)))) return_trace (false); - const SegmentMaps *map = axisSegmentMapsZ; + const SegmentMaps *map = axisSegmentMapsZ.arrayZ; unsigned int count = axisCount; for (unsigned int i = 0; i < count; i++) { @@ -124,7 +125,7 @@ struct avar { unsigned int count = MIN<unsigned int> (coords_length, axisCount); - const SegmentMaps *map = axisSegmentMapsZ; + const SegmentMaps *map = axisSegmentMapsZ.arrayZ; for (unsigned int i = 0; i < count; i++) { coords[i] = map->map (coords[i]); @@ -139,7 +140,8 @@ 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[VAR]; + UnsizedArrayOf<SegmentMaps> + axisSegmentMapsZ; public: DEFINE_SIZE_MIN (8); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh index afd29046e15..96c39c10954 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh @@ -46,20 +46,21 @@ struct InstanceRecord { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && - c->check_array (coordinates, coordinates[0].static_size, axis_count)); + c->check_array (coordinatesZ.arrayZ, axis_count)); } protected: 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. */ + UnsizedArrayOf<Fixed> + coordinatesZ; /* The coordinates array for this instance. */ //NameID postScriptNameIDX;/*Optional. The name ID for entries in the 'name' // * table that provide PostScript names for this // * instance. */ public: - DEFINE_SIZE_ARRAY (4, coordinates); + DEFINE_SIZE_ARRAY (4, coordinatesZ); }; struct AxisRecord @@ -176,7 +177,7 @@ struct fvar v = (v - axis.default_value) / (axis.default_value - axis.min_value); else v = (v - axis.default_value) / (axis.max_value - axis.default_value); - return (int) (v * 16384. + (v >= 0. ? .5 : -.5)); + return (int) (v * 16384.f + (v >= 0.f ? .5f : -.5f)); } protected: diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh index 086e922fdc8..d87285b7f5d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh @@ -39,7 +39,7 @@ struct DeltaSetIndexMap { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && - c->check_array (mapData, get_width (), mapCount)); + c->check_array (mapDataZ.arrayZ, mapCount, get_width ())); } unsigned int map (unsigned int v) const /* Returns 16.16 outer.inner. */ @@ -55,7 +55,7 @@ struct DeltaSetIndexMap unsigned int u = 0; { /* Fetch it. */ unsigned int w = get_width (); - const HBUINT8 *p = mapData + w * v; + const HBUINT8 *p = mapDataZ.arrayZ + w * v; for (; w; w--) u = (u << 8) + *p++; } @@ -81,10 +81,11 @@ struct DeltaSetIndexMap HBUINT16 format; /* A packed field that describes the compressed * representation of delta-set indices. */ HBUINT16 mapCount; /* The number of mapping entries. */ - HBUINT8 mapData[VAR]; /* The delta-set index mapping data. */ + UnsizedArrayOf<HBUINT8> + mapDataZ; /* The delta-set index mapping data. */ public: - DEFINE_SIZE_ARRAY (4, mapData); + DEFINE_SIZE_ARRAY (4, mapDataZ); }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-mvar-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-mvar-table.hh index 20dd2200c50..d60c6b910e9 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-mvar-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-mvar-table.hh @@ -68,14 +68,14 @@ struct MVAR c->check_struct (this) && valueRecordSize >= VariationValueRecord::static_size && varStore.sanitize (c, this) && - c->check_array (values, valueRecordSize, valueRecordCount)); + c->check_array (valuesZ.arrayZ, valueRecordCount, valueRecordSize)); } inline float get_var (hb_tag_t tag, int *coords, unsigned int coord_count) const { const VariationValueRecord *record; - record = (VariationValueRecord *) bsearch (&tag, values, + record = (VariationValueRecord *) bsearch (&tag, valuesZ.arrayZ, valueRecordCount, valueRecordSize, tag_compare); if (!record) @@ -101,11 +101,12 @@ protected: HBUINT16 valueRecordCount;/* The number of value records — may be zero. */ OffsetTo<VariationStore> varStore; /* Offset to item variation store table. */ - HBUINT8 values[VAR]; /* Array of value records. The records must be + UnsizedArrayOf<HBUINT8> + valuesZ; /* Array of value records. The records must be * in binary order of their valueTag field. */ public: - DEFINE_SIZE_ARRAY (12, values); + DEFINE_SIZE_ARRAY (12, valuesZ); }; } /* namespace OT */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot.h index 2120a3efa34..4b6e3cf74bb 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot.h @@ -33,6 +33,7 @@ #include "hb-ot-font.h" #include "hb-ot-layout.h" #include "hb-ot-math.h" +#include "hb-ot-name.h" #include "hb-ot-tag.h" #include "hb-ot-shape.h" #include "hb-ot-var.h" diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh index 353403e9297..7ca32976116 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh @@ -368,8 +368,8 @@ struct hb_set_t if (!resize (count)) return; population = other->population; - memcpy (pages.arrayZ, other->pages.arrayZ, count * sizeof (pages.arrayZ[0])); - memcpy (page_map.arrayZ, other->page_map.arrayZ, count * sizeof (page_map.arrayZ[0])); + memcpy (pages.arrayZ(), other->pages.arrayZ(), count * sizeof (pages.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 diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper-list.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper-list.hh index b0835d31ab1..1fdb64810b3 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper-list.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper-list.hh @@ -39,9 +39,7 @@ HB_SHAPER_IMPLEMENT (graphite2) HB_SHAPER_IMPLEMENT (coretext_aat) #endif -#ifdef HAVE_OT HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */ -#endif #ifdef HAVE_UNISCRIBE HB_SHAPER_IMPLEMENT (uniscribe) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc index 5112d77be0a..e5507960d2a 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc @@ -28,6 +28,8 @@ #include "hb-open-type.hh" #include "hb-ot-layout-common.hh" +#include "hb-aat-layout-ankr-table.hh" /* I don't even want to know why... */ +#include "hb-aat-layout-common.hh" #include "hb-face.hh" #include "hb-ot-head-table.hh" @@ -41,6 +43,8 @@ hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_ DEFINE_NULL_NAMESPACE_BYTES (OT, Index) = {0xFF,0xFF}; DEFINE_NULL_NAMESPACE_BYTES (OT, LangSys) = {0x00,0x00, 0xFF,0xFF, 0x00,0x00}; DEFINE_NULL_NAMESPACE_BYTES (OT, RangeRecord) = {0x00,0x01, 0x00,0x00, 0x00, 0x00}; +/* Hand-coded because Lookup is a template. Sad. */ +const unsigned char _hb_Null_AAT_Lookup[2] = {0xFF, 0xFF}; void diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc index b714f291a88..9f14b89ba59 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc @@ -77,7 +77,7 @@ _subset2 (hb_subset_plan_t *plan) return false; } retry: - hb_serialize_context_t serializer (buf.arrayZ, buf_size); + hb_serialize_context_t serializer (buf.arrayZ(), buf_size); hb_subset_context_t c (plan, &serializer); result = table->subset (&c); if (serializer.ran_out_of_room) @@ -179,10 +179,10 @@ _subset_table (hb_subset_plan_t *plan, break; case HB_OT_TAG_GSUB: - //result = _subset2<const OT::GSUB> (plan); + result = _subset2<const OT::GSUB> (plan); break; case HB_OT_TAG_GPOS: - //result = _subset2<const OT::GPOS> (plan); + result = _subset2<const OT::GPOS> (plan); break; default: diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucdn.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucdn.cc index 624c1eb4163..3179683c261 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucdn.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucdn.cc @@ -16,7 +16,6 @@ #include "hb.hh" -#include "hb-unicode.hh" #include "hb-machinery.hh" #include "ucdn.h" @@ -182,15 +181,6 @@ hb_ucdn_combining_class(hb_unicode_funcs_t *ufuncs HB_UNUSED, return (hb_unicode_combining_class_t) ucdn_get_combining_class(unicode); } -static unsigned int -hb_ucdn_eastasian_width(hb_unicode_funcs_t *ufuncs HB_UNUSED, - hb_codepoint_t unicode, - void *user_data HB_UNUSED) -{ - int w = ucdn_get_east_asian_width(unicode); - return (w == UCDN_EAST_ASIAN_F || w == UCDN_EAST_ASIAN_W) ? 2 : 1; -} - static hb_unicode_general_category_t hb_ucdn_general_category(hb_unicode_funcs_t *ufuncs HB_UNUSED, hb_codepoint_t unicode, @@ -231,16 +221,10 @@ hb_ucdn_decompose(hb_unicode_funcs_t *ufuncs HB_UNUSED, return ucdn_decompose(ab, a, b); } -static unsigned int -hb_ucdn_decompose_compatibility(hb_unicode_funcs_t *ufuncs HB_UNUSED, - hb_codepoint_t u, hb_codepoint_t *decomposed, - void *user_data HB_UNUSED) -{ - return ucdn_compat_decompose(u, decomposed); -} - +#ifdef HB_USE_ATEXIT static void free_static_ucdn_funcs (void); +#endif static struct hb_ucdn_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader_t<hb_ucdn_unicode_funcs_lazy_loader_t> { @@ -248,10 +232,12 @@ static struct hb_ucdn_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader { hb_unicode_funcs_t *funcs = hb_unicode_funcs_create (nullptr); -#define HB_UNICODE_FUNC_IMPLEMENT(name) \ - hb_unicode_funcs_set_##name##_func (funcs, hb_ucdn_##name, nullptr, nullptr); - HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS -#undef HB_UNICODE_FUNC_IMPLEMENT + hb_unicode_funcs_set_combining_class_func (funcs, hb_ucdn_combining_class, nullptr, nullptr); + hb_unicode_funcs_set_general_category_func (funcs, hb_ucdn_general_category, nullptr, nullptr); + hb_unicode_funcs_set_mirroring_func (funcs, hb_ucdn_mirroring, nullptr, nullptr); + hb_unicode_funcs_set_script_func (funcs, hb_ucdn_script, nullptr, nullptr); + hb_unicode_funcs_set_compose_func (funcs, hb_ucdn_compose, nullptr, nullptr); + hb_unicode_funcs_set_decompose_func (funcs, hb_ucdn_decompose, nullptr, nullptr); hb_unicode_funcs_make_immutable (funcs); @@ -273,6 +259,9 @@ void free_static_ucdn_funcs (void) extern "C" HB_INTERNAL hb_unicode_funcs_t * +hb_ucdn_get_unicode_funcs (void); + +hb_unicode_funcs_t * hb_ucdn_get_unicode_funcs (void) { return static_ucdn_funcs.get_unconst (); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode-emoji-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode-emoji-table.hh new file mode 100644 index 00000000000..41199de53c8 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode-emoji-table.hh @@ -0,0 +1,269 @@ +/* == Start of generated table == */ +/* + * The following tables are generated by running: + * + * ./gen-emoji-table.py emoji-data.txt + * + * on file with this header: + * + * # emoji-data.txt + * # Date: 2018-02-07, 07:55:18 GMT + * # © 2018 Unicode®, Inc. + * # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. + * # For terms of use, see http://www.unicode.org/terms_of_use.html + * # + * # Emoji Data for UTS #51 + * # Version: 11.0 + * # + * # For documentation and usage, see http://www.unicode.org/reports/tr51 + */ + +#ifndef HB_UNICODE_EMOJI_TABLE_HH +#define HB_UNICODE_EMOJI_TABLE_HH + +#include "hb-unicode.hh" + + +static const struct hb_unicode_range_t _hb_unicode_emoji_Extended_Pictographic_table[] = +{ + {0x00A9, 0x00A9}, + {0x00AE, 0x00AE}, + {0x203C, 0x203C}, + {0x2049, 0x2049}, + {0x2122, 0x2122}, + {0x2139, 0x2139}, + {0x2194, 0x2199}, + {0x21A9, 0x21AA}, + {0x231A, 0x231B}, + {0x2328, 0x2328}, + {0x2388, 0x2388}, + {0x23CF, 0x23CF}, + {0x23E9, 0x23F3}, + {0x23F8, 0x23FA}, + {0x24C2, 0x24C2}, + {0x25AA, 0x25AB}, + {0x25B6, 0x25B6}, + {0x25C0, 0x25C0}, + {0x25FB, 0x25FE}, + {0x2600, 0x2605}, + {0x2607, 0x2612}, + {0x2614, 0x2615}, + {0x2616, 0x2617}, + {0x2618, 0x2618}, + {0x2619, 0x2619}, + {0x261A, 0x266F}, + {0x2670, 0x2671}, + {0x2672, 0x267D}, + {0x267E, 0x267F}, + {0x2680, 0x2685}, + {0x2690, 0x2691}, + {0x2692, 0x269C}, + {0x269D, 0x269D}, + {0x269E, 0x269F}, + {0x26A0, 0x26A1}, + {0x26A2, 0x26B1}, + {0x26B2, 0x26B2}, + {0x26B3, 0x26BC}, + {0x26BD, 0x26BF}, + {0x26C0, 0x26C3}, + {0x26C4, 0x26CD}, + {0x26CE, 0x26CE}, + {0x26CF, 0x26E1}, + {0x26E2, 0x26E2}, + {0x26E3, 0x26E3}, + {0x26E4, 0x26E7}, + {0x26E8, 0x26FF}, + {0x2700, 0x2700}, + {0x2701, 0x2704}, + {0x2705, 0x2705}, + {0x2708, 0x2709}, + {0x270A, 0x270B}, + {0x270C, 0x2712}, + {0x2714, 0x2714}, + {0x2716, 0x2716}, + {0x271D, 0x271D}, + {0x2721, 0x2721}, + {0x2728, 0x2728}, + {0x2733, 0x2734}, + {0x2744, 0x2744}, + {0x2747, 0x2747}, + {0x274C, 0x274C}, + {0x274E, 0x274E}, + {0x2753, 0x2755}, + {0x2757, 0x2757}, + {0x2763, 0x2767}, + {0x2795, 0x2797}, + {0x27A1, 0x27A1}, + {0x27B0, 0x27B0}, + {0x27BF, 0x27BF}, + {0x2934, 0x2935}, + {0x2B05, 0x2B07}, + {0x2B1B, 0x2B1C}, + {0x2B50, 0x2B50}, + {0x2B55, 0x2B55}, + {0x3030, 0x3030}, + {0x303D, 0x303D}, + {0x3297, 0x3297}, + {0x3299, 0x3299}, + {0x1F000, 0x1F02B}, + {0x1F02C, 0x1F02F}, + {0x1F030, 0x1F093}, + {0x1F094, 0x1F09F}, + {0x1F0A0, 0x1F0AE}, + {0x1F0AF, 0x1F0B0}, + {0x1F0B1, 0x1F0BE}, + {0x1F0BF, 0x1F0BF}, + {0x1F0C0, 0x1F0C0}, + {0x1F0C1, 0x1F0CF}, + {0x1F0D0, 0x1F0D0}, + {0x1F0D1, 0x1F0DF}, + {0x1F0E0, 0x1F0F5}, + {0x1F0F6, 0x1F0FF}, + {0x1F10D, 0x1F10F}, + {0x1F12F, 0x1F12F}, + {0x1F16C, 0x1F16F}, + {0x1F170, 0x1F171}, + {0x1F17E, 0x1F17E}, + {0x1F17F, 0x1F17F}, + {0x1F18E, 0x1F18E}, + {0x1F191, 0x1F19A}, + {0x1F1AD, 0x1F1E5}, + {0x1F201, 0x1F202}, + {0x1F203, 0x1F20F}, + {0x1F21A, 0x1F21A}, + {0x1F22F, 0x1F22F}, + {0x1F232, 0x1F23A}, + {0x1F23C, 0x1F23F}, + {0x1F249, 0x1F24F}, + {0x1F250, 0x1F251}, + {0x1F252, 0x1F25F}, + {0x1F260, 0x1F265}, + {0x1F266, 0x1F2FF}, + {0x1F300, 0x1F320}, + {0x1F321, 0x1F32C}, + {0x1F32D, 0x1F32F}, + {0x1F330, 0x1F335}, + {0x1F336, 0x1F336}, + {0x1F337, 0x1F37C}, + {0x1F37D, 0x1F37D}, + {0x1F37E, 0x1F37F}, + {0x1F380, 0x1F393}, + {0x1F394, 0x1F39F}, + {0x1F3A0, 0x1F3C4}, + {0x1F3C5, 0x1F3C5}, + {0x1F3C6, 0x1F3CA}, + {0x1F3CB, 0x1F3CE}, + {0x1F3CF, 0x1F3D3}, + {0x1F3D4, 0x1F3DF}, + {0x1F3E0, 0x1F3F0}, + {0x1F3F1, 0x1F3F7}, + {0x1F3F8, 0x1F3FA}, + {0x1F400, 0x1F43E}, + {0x1F43F, 0x1F43F}, + {0x1F440, 0x1F440}, + {0x1F441, 0x1F441}, + {0x1F442, 0x1F4F7}, + {0x1F4F8, 0x1F4F8}, + {0x1F4F9, 0x1F4FC}, + {0x1F4FD, 0x1F4FE}, + {0x1F4FF, 0x1F4FF}, + {0x1F500, 0x1F53D}, + {0x1F546, 0x1F54A}, + {0x1F54B, 0x1F54F}, + {0x1F550, 0x1F567}, + {0x1F568, 0x1F579}, + {0x1F57A, 0x1F57A}, + {0x1F57B, 0x1F5A3}, + {0x1F5A4, 0x1F5A4}, + {0x1F5A5, 0x1F5FA}, + {0x1F5FB, 0x1F5FF}, + {0x1F600, 0x1F600}, + {0x1F601, 0x1F610}, + {0x1F611, 0x1F611}, + {0x1F612, 0x1F614}, + {0x1F615, 0x1F615}, + {0x1F616, 0x1F616}, + {0x1F617, 0x1F617}, + {0x1F618, 0x1F618}, + {0x1F619, 0x1F619}, + {0x1F61A, 0x1F61A}, + {0x1F61B, 0x1F61B}, + {0x1F61C, 0x1F61E}, + {0x1F61F, 0x1F61F}, + {0x1F620, 0x1F625}, + {0x1F626, 0x1F627}, + {0x1F628, 0x1F62B}, + {0x1F62C, 0x1F62C}, + {0x1F62D, 0x1F62D}, + {0x1F62E, 0x1F62F}, + {0x1F630, 0x1F633}, + {0x1F634, 0x1F634}, + {0x1F635, 0x1F640}, + {0x1F641, 0x1F642}, + {0x1F643, 0x1F644}, + {0x1F645, 0x1F64F}, + {0x1F680, 0x1F6C5}, + {0x1F6C6, 0x1F6CF}, + {0x1F6D0, 0x1F6D0}, + {0x1F6D1, 0x1F6D2}, + {0x1F6D3, 0x1F6D4}, + {0x1F6D5, 0x1F6DF}, + {0x1F6E0, 0x1F6EC}, + {0x1F6ED, 0x1F6EF}, + {0x1F6F0, 0x1F6F3}, + {0x1F6F4, 0x1F6F6}, + {0x1F6F7, 0x1F6F8}, + {0x1F6F9, 0x1F6F9}, + {0x1F6FA, 0x1F6FF}, + {0x1F774, 0x1F77F}, + {0x1F7D5, 0x1F7D8}, + {0x1F7D9, 0x1F7FF}, + {0x1F80C, 0x1F80F}, + {0x1F848, 0x1F84F}, + {0x1F85A, 0x1F85F}, + {0x1F888, 0x1F88F}, + {0x1F8AE, 0x1F8FF}, + {0x1F90C, 0x1F90F}, + {0x1F910, 0x1F918}, + {0x1F919, 0x1F91E}, + {0x1F91F, 0x1F91F}, + {0x1F920, 0x1F927}, + {0x1F928, 0x1F92F}, + {0x1F930, 0x1F930}, + {0x1F931, 0x1F932}, + {0x1F933, 0x1F93A}, + {0x1F93C, 0x1F93E}, + {0x1F93F, 0x1F93F}, + {0x1F940, 0x1F945}, + {0x1F947, 0x1F94B}, + {0x1F94C, 0x1F94C}, + {0x1F94D, 0x1F94F}, + {0x1F950, 0x1F95E}, + {0x1F95F, 0x1F96B}, + {0x1F96C, 0x1F970}, + {0x1F971, 0x1F972}, + {0x1F973, 0x1F976}, + {0x1F977, 0x1F979}, + {0x1F97A, 0x1F97A}, + {0x1F97B, 0x1F97B}, + {0x1F97C, 0x1F97F}, + {0x1F980, 0x1F984}, + {0x1F985, 0x1F991}, + {0x1F992, 0x1F997}, + {0x1F998, 0x1F9A2}, + {0x1F9A3, 0x1F9AF}, + {0x1F9B0, 0x1F9B9}, + {0x1F9BA, 0x1F9BF}, + {0x1F9C0, 0x1F9C0}, + {0x1F9C1, 0x1F9C2}, + {0x1F9C3, 0x1F9CF}, + {0x1F9D0, 0x1F9E6}, + {0x1F9E7, 0x1F9FF}, + {0x1FA00, 0x1FA5F}, + {0x1FA60, 0x1FA6D}, + {0x1FA6E, 0x1FFFD}, +}; + +#endif /* HB_UNICODE_EMOJI_TABLE_HH */ + +/* == End of generated table == */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc index bb1cd6821ee..7b821b46d5e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc @@ -308,6 +308,8 @@ hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs) { if (unlikely (hb_object_is_inert (ufuncs))) return; + if (ufuncs->immutable) + return; ufuncs->immutable = true; } @@ -562,3 +564,19 @@ _hb_modified_combining_class[256] = 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, /* HB_UNICODE_COMBINING_CLASS_INVALID */ }; + + +/* + * Emoji + */ + +#include "hb-unicode-emoji-table.hh" + +bool +_hb_unicode_is_emoji_Extended_Pictographic (hb_codepoint_t cp) +{ + return hb_bsearch_r (&cp, _hb_unicode_emoji_Extended_Pictographic_table, + ARRAY_LENGTH (_hb_unicode_emoji_Extended_Pictographic_table), + sizeof (hb_unicode_range_t), + hb_unicode_range_t::cmp, nullptr); +} diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.h index c8d87e4d1d2..df0b91f0190 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.h @@ -44,7 +44,7 @@ HB_BEGIN_DECLS * HB_UNICODE_MAX * * Since: 1.9.0 - */ + **/ #define HB_UNICODE_MAX 0x10FFFFu @@ -230,9 +230,6 @@ hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs); typedef hb_unicode_combining_class_t (*hb_unicode_combining_class_func_t) (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode, void *user_data); -typedef unsigned int (*hb_unicode_eastasian_width_func_t) (hb_unicode_funcs_t *ufuncs, - hb_codepoint_t unicode, - void *user_data); typedef hb_unicode_general_category_t (*hb_unicode_general_category_func_t) (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode, void *user_data); @@ -254,32 +251,6 @@ typedef hb_bool_t (*hb_unicode_decompose_func_t) (hb_unicode_funcs_t *ufuncs, hb_codepoint_t *b, void *user_data); -/** - * hb_unicode_decompose_compatibility_func_t: - * @ufuncs: a Unicode function structure - * @u: codepoint to decompose - * @decomposed: address of codepoint array (of length %HB_UNICODE_MAX_DECOMPOSITION_LEN) to write decomposition into - * @user_data: user data pointer as passed to hb_unicode_funcs_set_decompose_compatibility_func() - * - * Fully decompose @u to its Unicode compatibility decomposition. The codepoints of the decomposition will be written to @decomposed. - * The complete length of the decomposition will be returned. - * - * If @u has no compatibility decomposition, zero should be returned. - * - * The Unicode standard guarantees that a buffer of length %HB_UNICODE_MAX_DECOMPOSITION_LEN codepoints will always be sufficient for any - * compatibility decomposition plus an terminating value of 0. Consequently, @decompose must be allocated by the caller to be at least this length. Implementations - * of this function type must ensure that they do not write past the provided array. - * - * Return value: number of codepoints in the full compatibility decomposition of @u, or 0 if no decomposition available. - */ -typedef unsigned int (*hb_unicode_decompose_compatibility_func_t) (hb_unicode_funcs_t *ufuncs, - hb_codepoint_t u, - hb_codepoint_t *decomposed, - void *user_data); - -/* See Unicode 6.1 for details on the maximum decomposition length. */ -#define HB_UNICODE_MAX_DECOMPOSITION_LEN (18+1) /* codepoints */ - /* setters */ /** @@ -299,22 +270,6 @@ hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs, void *user_data, hb_destroy_func_t destroy); /** - * hb_unicode_funcs_set_eastasian_width_func: - * @ufuncs: a Unicode function structure - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * - * - * - * Since: 0.9.2 - **/ -HB_EXTERN void -hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs, - hb_unicode_eastasian_width_func_t func, - void *user_data, hb_destroy_func_t destroy); - -/** * hb_unicode_funcs_set_general_category_func: * @ufuncs: a Unicode function structure * @func: (closure user_data) (destroy destroy) (scope notified): @@ -394,22 +349,6 @@ hb_unicode_funcs_set_decompose_func (hb_unicode_funcs_t *ufuncs, hb_unicode_decompose_func_t func, void *user_data, hb_destroy_func_t destroy); -/** - * hb_unicode_funcs_set_decompose_compatibility_func: - * @ufuncs: a Unicode function structure - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * - * - * - * Since: 0.9.2 - **/ -HB_EXTERN void -hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs, - hb_unicode_decompose_compatibility_func_t func, - void *user_data, hb_destroy_func_t destroy); - /* accessors */ /** @@ -422,15 +361,6 @@ hb_unicode_combining_class (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode); /** - * hb_unicode_eastasian_width: - * - * Since: 0.9.2 - **/ -HB_EXTERN unsigned int -hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs, - hb_codepoint_t unicode); - -/** * hb_unicode_general_category: * * Since: 0.9.2 @@ -469,11 +399,6 @@ hb_unicode_decompose (hb_unicode_funcs_t *ufuncs, hb_codepoint_t *a, hb_codepoint_t *b); -HB_EXTERN unsigned int -hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs, - hb_codepoint_t u, - hb_codepoint_t *decomposed); - HB_END_DECLS #endif /* HB_UNICODE_H */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.hh index e6bca5f08c8..6d6a4fa0ca1 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.hh @@ -101,24 +101,23 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE return ret; } - inline unsigned int - modified_combining_class (hb_codepoint_t unicode) + modified_combining_class (hb_codepoint_t u) { /* XXX This hack belongs to the Myanmar shaper. */ - if (unlikely (unicode == 0x1037u)) unicode = 0x103Au; + if (unlikely (u == 0x1037u)) u = 0x103Au; /* XXX This hack belongs to the USE shaper (for Tai Tham): * Reorder SAKOT to ensure it comes after any tone marks. */ - if (unlikely (unicode == 0x1A60u)) return 254; + if (unlikely (u == 0x1A60u)) return 254; /* XXX This hack belongs to the Tibetan shaper: * Reorder PADMA to ensure it comes after any vowel marks. */ - if (unlikely (unicode == 0x0FC6u)) return 254; + if (unlikely (u == 0x0FC6u)) return 254; /* Reorder TSA -PHRU to reorder before U+0F74 */ - if (unlikely (unicode == 0x0F39u)) return 127; + if (unlikely (u == 0x0F39u)) return 127; - return _hb_modified_combining_class[combining_class (unicode)]; + return _hb_modified_combining_class[combining_class (u)]; } static inline hb_bool_t @@ -267,7 +266,9 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE DECLARE_NULL_INSTANCE (hb_unicode_funcs_t); -/* Modified combining marks */ +/* + * Modified combining marks + */ /* Hebrew * @@ -360,10 +361,37 @@ DECLARE_NULL_INSTANCE (hb_unicode_funcs_t); FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | \ FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK))) -#define HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK_OR_MODIFIER_SYMBOL(gen_cat) \ - (FLAG_UNSAFE (gen_cat) & \ - (FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK) | \ - FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) | \ - FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL))) + +/* + * Ranges, used for bsearch tables. + */ + +struct hb_unicode_range_t +{ + static int + cmp (const void *_key, const void *_item, void *_arg) + { + hb_codepoint_t cp = *((hb_codepoint_t *) _key); + const hb_unicode_range_t *range = (hb_unicode_range_t *) _item; + + if (cp < range->start) + return -1; + else if (cp <= range->end) + return 0; + else + return +1; + } + + hb_codepoint_t start; + hb_codepoint_t end; +}; + +/* + * Emoji. + */ + +HB_INTERNAL bool +_hb_unicode_is_emoji_Extended_Pictographic (hb_codepoint_t cp); + #endif /* HB_UNICODE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc index 4a77c8c1f41..44a67ae4c63 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc @@ -392,7 +392,7 @@ _hb_rename_font (hb_blob_t *blob, wchar_t *new_name) name.stringOffset.set (name.get_size ()); for (unsigned int i = 0; i < ARRAY_LENGTH (name_IDs); i++) { - OT::NameRecord &record = name.nameRecord[i]; + OT::NameRecord &record = name.nameRecordZ[i]; record.platformID.set (3); record.encodingID.set (1); record.languageID.set (0x0409u); /* English */ @@ -717,7 +717,7 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan, { active_feature_t *feature = active_features.find (&event->feature); if (feature) - active_features.remove (feature - active_features.arrayZ); + active_features.remove (feature - active_features.arrayZ()); } } @@ -728,7 +728,7 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan, for (unsigned int i = 0; i < range_records.len; i++) { range_record_t *range = &range_records[i]; - range->props.potfRecords = feature_records.arrayZ + reinterpret_cast<uintptr_t> (range->props.potfRecords); + range->props.potfRecords = feature_records.arrayZ() + reinterpret_cast<uintptr_t> (range->props.potfRecords); } } @@ -902,8 +902,8 @@ retry: &items[i].a, script_tags[i], language_tag, - range_char_counts.arrayZ, - range_properties.arrayZ, + range_char_counts.arrayZ(), + range_properties.arrayZ(), range_properties.len, pchars + chars_offset, item_chars_len, @@ -943,8 +943,8 @@ retry: &items[i].a, script_tags[i], language_tag, - range_char_counts.arrayZ, - range_properties.arrayZ, + range_char_counts.arrayZ(), + range_properties.arrayZ(), range_properties.len, pchars + chars_offset, log_clusters + chars_offset, diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh index da548cbb12f..766e5fb8e61 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh @@ -35,35 +35,42 @@ template <typename Type, unsigned int StaticSize=8> struct hb_vector_t { unsigned int len; + private: unsigned int allocated; /* == 0 means allocation failed. */ - Type *arrayZ; + Type *arrayZ_; Type static_array[StaticSize]; + public: void init (void) { len = 0; allocated = ARRAY_LENGTH (static_array); - arrayZ = static_array; + arrayZ_ = nullptr; } + inline Type * arrayZ (void) + { return arrayZ_ ? arrayZ_ : static_array; } + inline const Type * arrayZ (void) const + { return arrayZ_ ? arrayZ_ : static_array; } + inline Type& operator [] (unsigned int i) { if (unlikely (i >= len)) return Crap (Type); - return arrayZ[i]; + return arrayZ()[i]; } inline const Type& operator [] (unsigned int i) const { if (unlikely (i >= len)) return Null(Type); - return arrayZ[i]; + return arrayZ()[i]; } inline Type *push (void) { if (unlikely (!resize (len + 1))) return &Crap(Type); - return &arrayZ[len - 1]; + return &arrayZ()[len - 1]; } inline Type *push (const Type& v) { @@ -91,17 +98,17 @@ struct hb_vector_t Type *new_array = nullptr; - if (arrayZ == static_array) + if (!arrayZ_) { new_array = (Type *) calloc (new_allocated, sizeof (Type)); if (new_array) - memcpy (new_array, arrayZ, len * sizeof (Type)); + memcpy (new_array, static_array, len * sizeof (Type)); } else { bool overflows = (new_allocated < allocated) || hb_unsigned_mul_overflows (new_allocated, sizeof (Type)); if (likely (!overflows)) - new_array = (Type *) realloc (arrayZ, new_allocated * sizeof (Type)); + new_array = (Type *) realloc (arrayZ_, new_allocated * sizeof (Type)); } if (unlikely (!new_array)) @@ -110,7 +117,7 @@ struct hb_vector_t return false; } - arrayZ = new_array; + arrayZ_ = new_array; allocated = new_allocated; return true; @@ -123,7 +130,7 @@ struct hb_vector_t return false; if (size > len) - memset (arrayZ + len, 0, (size - len) * sizeof (*arrayZ)); + memset (arrayZ() + len, 0, (size - len) * sizeof (*arrayZ())); len = size; return true; @@ -137,12 +144,13 @@ struct hb_vector_t inline void remove (unsigned int i) { - if (unlikely (i >= len)) - return; - memmove (static_cast<void *> (&arrayZ[i]), - static_cast<void *> (&arrayZ[i + 1]), - (len - i - 1) * sizeof (Type)); - len--; + if (unlikely (i >= len)) + return; + Type *array = arrayZ(); + memmove (static_cast<void *> (&array[i]), + static_cast<void *> (&array[i + 1]), + (len - i - 1) * sizeof (Type)); + len--; } inline void shrink (int size_) @@ -153,41 +161,55 @@ struct hb_vector_t } template <typename T> - inline Type *find (T v) { + inline Type *find (T v) + { + Type *array = arrayZ(); for (unsigned int i = 0; i < len; i++) - if (arrayZ[i] == v) - return &arrayZ[i]; + if (array[i] == v) + return &array[i]; return nullptr; } template <typename T> - inline const Type *find (T v) const { + inline const Type *find (T v) const + { + const Type *array = arrayZ(); for (unsigned int i = 0; i < len; i++) - if (arrayZ[i] == v) - return &arrayZ[i]; + if (array[i] == v) + return &array[i]; return nullptr; } inline void qsort (int (*cmp)(const void*, const void*)) { - ::qsort (arrayZ, len, sizeof (Type), cmp); + ::qsort (arrayZ(), len, sizeof (Type), cmp); } inline void qsort (void) { - ::qsort (arrayZ, len, sizeof (Type), Type::cmp); + ::qsort (arrayZ(), len, sizeof (Type), Type::cmp); } inline void qsort (unsigned int start, unsigned int end) { - ::qsort (arrayZ + 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) { + Type *array = arrayZ(); for (unsigned int i = 0; i < len; i++) - if (0 == this->arrayZ[i].cmp (&x)) - return &arrayZ[i]; + if (0 == array[i].cmp (&x)) + return &array[i]; + return nullptr; + } + template <typename T> + inline const Type *lsearch (const T &x) const + { + const Type *array = arrayZ(); + for (unsigned int i = 0; i < len; i++) + if (0 == array[i].cmp (&x)) + return &array[i]; return nullptr; } @@ -195,22 +217,23 @@ struct hb_vector_t inline Type *bsearch (const T &x) { unsigned int i; - return bfind (x, &i) ? &arrayZ[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) ? &arrayZ[i] : nullptr; + return bfind (x, &i) ? &arrayZ()[i] : nullptr; } template <typename T> inline bool bfind (const T &x, unsigned int *i) const { int min = 0, max = (int) this->len - 1; + const Type *array = this->arrayZ(); while (min <= max) { int mid = (min + max) / 2; - int c = this->arrayZ[mid].cmp (&x); + int c = array[mid].cmp (&x); if (c < 0) max = mid - 1; else if (c > 0) @@ -221,17 +244,26 @@ struct hb_vector_t return true; } } - if (max < 0 || (max < (int) this->len && this->arrayZ[max].cmp (&x) > 0)) + if (max < 0 || (max < (int) this->len && array[max].cmp (&x) > 0)) max++; *i = max; return false; } + inline void fini_deep (void) + { + Type *array = arrayZ(); + unsigned int count = len; + for (unsigned int i = 0; i < count; i++) + array[i].fini (); + fini (); + } + inline void fini (void) { - if (arrayZ != static_array) - free (arrayZ); - arrayZ = nullptr; + if (arrayZ_) + free (arrayZ_); + arrayZ_ = nullptr; allocated = len = 0; } }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh index 557ae6b35d9..098b5660401 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh @@ -35,12 +35,18 @@ #include "config.h" #endif +#ifndef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200809L +#endif + +#if defined (_MSC_VER) && defined (HB_DLL_EXPORT) +#define HB_EXTERN __declspec (dllexport) extern +#endif + #include "hb.h" #define HB_H_IN -#ifdef HAVE_OT #include "hb-ot.h" #define HB_OT_H_IN -#endif #include <math.h> #include <stdlib.h> @@ -174,8 +180,10 @@ struct _hb_alignof # if !defined(HB_NO_VISIBILITY) && !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(_MSC_VER) && !defined(__SUNPRO_CC) # define HB_INTERNAL __attribute__((__visibility__("hidden"))) # elif defined(__MINGW32__) - /* We use -export-symbols on mingw32, since it does not support visibility - * attribute. */ + /* We use -export-symbols on mingw32, since it does not support visibility attributes. */ +# define HB_INTERNAL +# elif defined (_MSC_VER) && defined (HB_DLL_EXPORT) + /* We do not try to export internal symbols on Visual Studio */ # define HB_INTERNAL #else # define HB_INTERNAL @@ -229,6 +237,15 @@ struct _hb_alignof # define HB_FALLTHROUGH /* FALLTHROUGH */ #endif +#if defined(__clang__) +/* Disable certain sanitizer errors. */ +/* https://github.com/harfbuzz/harfbuzz/issues/1247 */ +#define HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW __attribute__((no_sanitize("signed-integer-overflow"))) +#else +#define HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW +#endif + + #if defined(_WIN32) || defined(__CYGWIN__) /* We need Windows Vista for both Uniscribe backend and for * MemoryBarrier. We don't support compiling on Windows XP, @@ -237,7 +254,9 @@ struct _hb_alignof # undef _WIN32_WINNT # endif # ifndef _WIN32_WINNT -# define _WIN32_WINNT 0x0600 +# if !defined(WINAPI_FAMILY) || !(WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) +# define _WIN32_WINNT 0x0600 +# endif # endif # ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN 1 @@ -468,6 +487,14 @@ _hb_memalign(void **memptr, size_t alignment, size_t size) #endif +/* + * For lack of a better place, put Zawgyi script hack here. + * https://github.com/harfbuzz/harfbuzz/issues/1162 + */ + +#define HB_SCRIPT_MYANMAR_ZAWGYI ((hb_script_t) HB_TAG ('Q','a','a','g')) + + /* Headers we include for everyone. Keep sorted. They express dependency amongst * themselves, but no other file should include them.*/ #include "hb-atomic.hh" diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/test-unicode-ranges.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/test-unicode-ranges.cc index 1334ea030f9..d9342d7bb28 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/test-unicode-ranges.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/test-unicode-ranges.cc @@ -28,20 +28,20 @@ #include "hb-ot-os2-unicode-ranges.hh" -void +static void test (hb_codepoint_t cp, unsigned int bit) { - if (OT::hb_get_unicode_range_bit (cp) != bit) + if (OT::_hb_ot_os2_get_unicode_range_bit (cp) != bit) { fprintf (stderr, "got incorrect bit (%d) for cp 0x%X. Should have been %d.", - OT::hb_get_unicode_range_bit (cp), + OT::_hb_ot_os2_get_unicode_range_bit (cp), cp, bit); abort(); } } -void +static void test_get_unicode_range_bit (void) { test (0x0000, 0); diff --git a/Build/source/libs/harfbuzz/include/Makefile.am b/Build/source/libs/harfbuzz/include/Makefile.am index 1521db6a78d..7f74f205863 100644 --- a/Build/source/libs/harfbuzz/include/Makefile.am +++ b/Build/source/libs/harfbuzz/include/Makefile.am @@ -33,6 +33,7 @@ hdr_links += \ $(HARFBUZZ_SRC)/hb-ot-font.h \ $(HARFBUZZ_SRC)/hb-ot-layout.h \ $(HARFBUZZ_SRC)/hb-ot-math.h \ + $(HARFBUZZ_SRC)/hb-ot-name.h \ $(HARFBUZZ_SRC)/hb-ot-shape.h \ $(HARFBUZZ_SRC)/hb-ot-tag.h \ $(HARFBUZZ_SRC)/hb-ot-var.h diff --git a/Build/source/libs/harfbuzz/include/Makefile.in b/Build/source/libs/harfbuzz/include/Makefile.in index a06a4bed549..e0b84bb963a 100644 --- a/Build/source/libs/harfbuzz/include/Makefile.in +++ b/Build/source/libs/harfbuzz/include/Makefile.in @@ -258,9 +258,10 @@ hdr_links = $(HARFBUZZ_SRC)/hb.h $(HARFBUZZ_SRC)/hb-blob.h \ $(HARFBUZZ_SRC)/hb-shape-plan.h $(HARFBUZZ_SRC)/hb-unicode.h \ $(HARFBUZZ_BLD)/hb-version.h $(HARFBUZZ_SRC)/hb-ot.h \ $(HARFBUZZ_SRC)/hb-ot-font.h $(HARFBUZZ_SRC)/hb-ot-layout.h \ - $(HARFBUZZ_SRC)/hb-ot-math.h $(HARFBUZZ_SRC)/hb-ot-shape.h \ - $(HARFBUZZ_SRC)/hb-ot-tag.h $(HARFBUZZ_SRC)/hb-ot-var.h \ - $(HARFBUZZ_SRC)/hb-icu.h $(HARFBUZZ_SRC)/hb-graphite2.h + $(HARFBUZZ_SRC)/hb-ot-math.h $(HARFBUZZ_SRC)/hb-ot-name.h \ + $(HARFBUZZ_SRC)/hb-ot-shape.h $(HARFBUZZ_SRC)/hb-ot-tag.h \ + $(HARFBUZZ_SRC)/hb-ot-var.h $(HARFBUZZ_SRC)/hb-icu.h \ + $(HARFBUZZ_SRC)/hb-graphite2.h all: all-am .SUFFIXES: diff --git a/Build/source/libs/harfbuzz/version.ac b/Build/source/libs/harfbuzz/version.ac index 8740f5b5802..367d0aaa2c3 100644 --- a/Build/source/libs/harfbuzz/version.ac +++ b/Build/source/libs/harfbuzz/version.ac @@ -8,4 +8,4 @@ dnl dnl -------------------------------------------------------- dnl dnl m4-include this file to define the current harfbuzz version -m4_define([harfbuzz_version], [1.9.0]) +m4_define([harfbuzz_version], [2.0.0]) |