diff options
author | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2024-03-17 21:41:08 +0000 |
---|---|---|
committer | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2024-03-17 21:41:08 +0000 |
commit | 634e0f5dd8edba941dbfa19f2483fde313b4a641 (patch) | |
tree | 2e8bb7cc3e51d8af61ceb2a9c21cab4b547e486d /Build/source/libs/harfbuzz/harfbuzz-src | |
parent | c5d580adbdf22a09c4e387cd72e21236f41e3767 (diff) |
harfbuzz 8.3.1
git-svn-id: svn://tug.org/texlive/trunk@70680 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/harfbuzz/harfbuzz-src')
83 files changed, 4552 insertions, 698 deletions
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt b/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt index e22f2cfdd57..57ccf27679d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt +++ b/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt @@ -33,6 +33,7 @@ endif () ## HarfBuzz build configurations +option(HB_HAVE_CAIRO "Enable cairo interop helpers" OFF) option(HB_HAVE_FREETYPE "Enable freetype interop helpers" OFF) option(HB_HAVE_GRAPHITE2 "Enable Graphite2 complementary shaper" OFF) option(HB_HAVE_GLIB "Enable glib unicode functions" OFF) @@ -74,8 +75,8 @@ include_directories(AFTER ${PROJECT_BINARY_DIR}/src ) -# We need PYTHON_EXECUTABLE to be set for running the tests... -include (FindPythonInterp) +# We need Python3_EXECUTABLE to be set for running the tests... +find_package(Python3 COMPONENTS Interpreter) ## Functions and headers include (CheckFunctionExists) @@ -177,6 +178,8 @@ extract_make_variable(HB_SUBSET_CLI_sources ${UTILSOURCES}) add_prefix_to_list(HB_SUBSET_CLI_sources "${PROJECT_SOURCE_DIR}/util/") extract_make_variable(HB_OT_SHAPE_CLOSURE_sources ${UTILSOURCES}) add_prefix_to_list(HB_OT_SHAPE_CLOSURE_sources "${PROJECT_SOURCE_DIR}/util/") +extract_make_variable(HB_INFO_sources ${UTILSOURCES}) +add_prefix_to_list(HB_INFO_sources "${PROJECT_SOURCE_DIR}/util/") file(READ configure.ac CONFIGUREAC) @@ -340,6 +343,23 @@ if (WIN32 AND HB_HAVE_DIRECTWRITE) list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-directwrite.h) endif () +if (HB_HAVE_CAIRO) + # https://github.com/WebKit/webkit/blob/master/Source/cmake/FindCairo.cmake + find_package(PkgConfig) + pkg_check_modules(PC_CAIRO QUIET cairo) + + find_path(CAIRO_INCLUDE_DIRS NAMES cairo.h HINTS ${PC_CAIRO_INCLUDEDIR} ${PC_CAIRO_INCLUDE_DIRS} PATH_SUFFIXES cairo) + find_library(CAIRO_LIBRARIESNAMES cairo HINTS ${PC_CAIRO_LIBDIR} ${PC_CAIRO_LIBRARY_DIRS}) + if (NOT CAIRO_LIBRARIESNAMES) + message(FATAL_ERROR "HB_HAVE_CAIRO is ON but Cairo libraries are not found") + endif() + include_directories(${CAIRO_INCLUDE_DIRS}) + mark_as_advanced(CAIRO_INCLUDE_DIRS CAIRO_LIBRARIESNAMES) + add_definitions(-DHAVE_CAIRO=1) + list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-cairo.h) + list(APPEND THIRD_PARTY_LIBS ${CAIRO_LIBRARIESNAMES}) +endif() + if (HB_HAVE_GOBJECT) add_definitions(-DHAVE_GOBJECT) include (FindPerl) @@ -357,13 +377,13 @@ if (HB_HAVE_GOBJECT) # in the standard cmd.exe shell that we use, so we need to # first determine whether glib-mkenums is a Python or PERL # script - execute_process(COMMAND "${PYTHON_EXECUTABLE}" "${GLIB_MKENUMS}" --version + execute_process(COMMAND "${Python3_EXECUTABLE}" "${GLIB_MKENUMS}" --version RESULT_VARIABLE GLIB_MKENUMS_PYTHON OUTPUT_QUIET ERROR_QUIET ) if (GLIB_MKENUMS_PYTHON EQUAL 0) message("${GLIB_MKENUMS} is a Python script.") - set (GLIB_MKENUMS_CMD "${PYTHON_EXECUTABLE}" "${GLIB_MKENUMS}") + set (GLIB_MKENUMS_CMD "${Python3_EXECUTABLE}" "${GLIB_MKENUMS}") else () execute_process(COMMAND "${PERL_EXECUTABLE}" "${GLIB_MKENUMS}" --version RESULT_VARIABLE GLIB_MKENUMS_PERL @@ -472,7 +492,7 @@ endif () ## Define harfbuzz-subset library if (HB_BUILD_SUBSET) add_library(harfbuzz-subset ${subset_project_sources} ${subset_project_headers}) - list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-subset.h) + list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-subset.h ${PROJECT_SOURCE_DIR}/src/hb-subset-repacker.h) add_dependencies(harfbuzz-subset harfbuzz) target_link_libraries(harfbuzz-subset harfbuzz ${THIRD_PARTY_LIBS}) @@ -481,7 +501,7 @@ if (HB_BUILD_SUBSET) endif () endif () -if (UNIX OR MINGW) +if (UNIX OR MINGW OR VITA) # Make symbols link locally include (CheckCXXCompilerFlag) CHECK_CXX_COMPILER_FLAG(-Bsymbolic-functions CXX_SUPPORTS_FLAG_BSYMB_FUNCS) @@ -531,6 +551,18 @@ if (HB_HAVE_GOBJECT) endif () endif () +## Define harfbuzz-cairo library +if (HB_HAVE_CAIRO) + include_directories(${CAIRO_INCLUDE_DIRS}) + add_library(harfbuzz-cairo ${PROJECT_SOURCE_DIR}/src/hb-cairo.cc ${PROJECT_SOURCE_DIR}/src/hb-static.cc ${PROJECT_SOURCE_DIR}/src/hb-cairo.h) + add_dependencies(harfbuzz-cairo harfbuzz) + target_link_libraries(harfbuzz-cairo harfbuzz ${THIRD_PARTY_LIBS}) + + if (BUILD_SHARED_LIBS) + set_target_properties(harfbuzz-cairo PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE) + endif () +endif() + if (BUILD_SHARED_LIBS AND WIN32 AND NOT MINGW) add_definitions("-DHB_DLL_EXPORT") endif () @@ -557,8 +589,8 @@ if (HB_HAVE_INTROSPECTION) if (WIN32 AND NOT MINGW) # Note that since we already enable HB_HAVE_GOBJECT - # we would already have PYTHON_EXECUTABLE handy - set (G_IR_SCANNER_CMD "${PYTHON_EXECUTABLE}" "${G_IR_SCANNER}") + # we would already have Python3_EXECUTABLE handy + set (G_IR_SCANNER_CMD "${Python3_EXECUTABLE}" "${G_IR_SCANNER}") else () set (G_IR_SCANNER_CMD "${G_IR_SCANNER}") endif () @@ -635,14 +667,8 @@ if (HB_HAVE_INTROSPECTION) -I${PROJECT_BINARY_DIR}/src ${hb_includedir_cflags} ${hb_defines_cflags} - -DHB_H - -DHB_H_IN - -DHB_OT_H - -DHB_OT_H_IN - -DHB_AAT_H - -DHB_AAT_H_IN - -DHB_GOBJECT_H - -DHB_GOBJECT_H_IN + -DHB_NO_SINGLE_HEADER_ERROR + -DHB_HAVE_GOBJECT -DHB_EXTERN= --cflags-end --library=harfbuzz-gobject @@ -683,19 +709,13 @@ endif () ## Additional harfbuzz build artifacts if (HB_BUILD_UTILS) - # https://github.com/WebKit/webkit/blob/master/Source/cmake/FindCairo.cmake - find_package(PkgConfig) - pkg_check_modules(PC_CAIRO QUIET cairo) - - find_path(CAIRO_INCLUDE_DIRS NAMES cairo.h HINTS ${PC_CAIRO_INCLUDEDIR} ${PC_CAIRO_INCLUDE_DIRS} PATH_SUFFIXES cairo) - find_library(CAIRO_LIBRARIESNAMES cairo HINTS ${PC_CAIRO_LIBDIR} ${PC_CAIRO_LIBRARY_DIRS}) - add_definitions("-DPACKAGE_NAME=\"HarfBuzz\"") add_definitions("-DPACKAGE_VERSION=\"${HB_VERSION}\"") - include_directories(${CAIRO_INCLUDE_DIRS}) - add_executable(hb-view ${HB_VIEW_sources}) - target_link_libraries(hb-view harfbuzz ${CAIRO_LIBRARIESNAMES}) + if (HB_HAVE_CAIRO) + add_executable(hb-view ${HB_VIEW_sources}) + target_link_libraries(hb-view harfbuzz-cairo harfbuzz ${CAIRO_LIBRARIESNAMES}) + endif() add_executable(hb-shape ${HB_SHAPE_sources}) target_link_libraries(hb-shape harfbuzz) @@ -706,7 +726,10 @@ if (HB_BUILD_UTILS) add_executable(hb-ot-shape-closure ${HB_OT_SHAPE_CLOSURE_sources}) target_link_libraries(hb-ot-shape-closure harfbuzz) - mark_as_advanced(CAIRO_INCLUDE_DIRS CAIRO_LIBRARIESNAMES) + if (HB_HAVE_GOBJECT) + add_executable(hb-info ${HB_INFO_sources}) + target_link_libraries(hb-info harfbuzz-gobject harfbuzz) + endif() endif () @@ -743,7 +766,7 @@ macro ( make_pkgconfig_pc_file name ) string(REPLACE "%libdir%" "${CMAKE_INSTALL_LIBDIR}" FSTR ${FSTR}) else () string(REPLACE "%libdir%" "\${prefix}/${CMAKE_INSTALL_LIBDIR}" FSTR ${FSTR}) - endif () + endif () string(REPLACE "%VERSION%" "${HB_VERSION}" FSTR ${FSTR}) string(REPLACE "%requires_private%" "${PC_REQUIRES_PRIV}" FSTR ${FSTR}) @@ -758,6 +781,28 @@ macro ( make_pkgconfig_pc_file name ) ) endmacro ( make_pkgconfig_pc_file ) +# Generate hb-features.h with the features we enabled +macro (make_hb_features_h) + file(READ "${PROJECT_SOURCE_DIR}/src/hb-features.h.in" feature_h_in) + foreach(arg cairo coretext directwrite freetype gdi glib gobject graphite icu uniscribe wasm) + string(TOUPPER ${arg} feature_caps) + set(feature_instring "#mesondefine HB_HAS_${feature_caps}") + if (HB_HAVE_${feature_caps}) + set(feature_outstring "#define HB_HAS_${feature_caps} 1") + else () + set(feature_outstring "/* #undef HB_HAS_${feature_caps} */") + endif() + string(REPLACE ${feature_instring} ${feature_outstring} feature_h_in ${feature_h_in}) + endforeach() + file(WRITE "${PROJECT_BINARY_DIR}/src/hb-features.h" ${feature_h_in}) + if (NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL) + install( + FILES "${PROJECT_BINARY_DIR}/src/hb-features.h" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/harfbuzz" + ) + endif() +endmacro (make_hb_features_h) + if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL) install(TARGETS harfbuzz EXPORT harfbuzzConfig @@ -780,6 +825,15 @@ if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL) ) make_pkgconfig_pc_file("harfbuzz-icu") endif () + if (HB_HAVE_CAIRO) + install(TARGETS harfbuzz-cairo + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + FRAMEWORK DESTINATION Library/Frameworks + ) + make_pkgconfig_pc_file("harfbuzz-cairo") + endif () if (HB_BUILD_SUBSET) install(TARGETS harfbuzz-subset ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} @@ -792,9 +846,11 @@ if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL) RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) endif () - install(TARGETS hb-view - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - ) + if (HB_HAVE_CAIRO) + install(TARGETS hb-view + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ) + endif() install(TARGETS hb-subset RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) @@ -803,6 +859,12 @@ if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL) RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) + if (HB_HAVE_GOBJECT) + install(TARGETS hb-info + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ) + endif() + install(TARGETS hb-ot-shape-closure RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) @@ -830,4 +892,5 @@ if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL) ) endif () endif () + make_hb_features_h() endif () diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog b/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog index ed4e3cb9c37..6f0cfdb3d93 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog +++ b/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog @@ -1,3 +1,2105 @@ +commit 2b3631a866b3077d9d675caa4ec9010b342b5a7c +Author: Khaled Hosny <khaled@aliftype.com> +Date: Sun Mar 17 07:44:19 2024 +0200 + + 8.3.1 + + NEWS | 28 +++++++++++++++++++++++++--- + configure.ac | 2 +- + docs/harfbuzz-docs.xml | 1 + + meson.build | 2 +- + src/hb-subset-input.cc | 2 +- + src/hb-version.h | 4 ++-- + 6 files changed, 31 insertions(+), 8 deletions(-) + +commit c2f8f35a6cfce43b88552b3eb5c05062ac7007b2 +Author: Ozkan Sezer <sezeroz@gmail.com> +Date: Fri Mar 15 18:45:24 2024 +0300 + + Use inttypes.h PRI?32 macros in format strings for [u]int32_t args. + + This is a modified and cleaned-up version of PR #4619 by @jpcomito: + hb-common.h now expects 'inttypes.h' presence with MSVC exceptions, + defines __STDC_FORMAT_MACROS in there (if not already defined) and + undoes c930ae2 (PR #1974) and 902ab86. + + Co-authored-by: jcomito <jcomito@google.com> + + src/OT/glyf/glyf-helpers.hh | 2 +- + src/hb-common.cc | 2 +- + src/hb-common.h | 14 ++++---------- + src/hb-font.hh | 2 +- + src/hb-ot-shaper-arabic.cc | 8 ++++---- + src/hb-ot-tag.cc | 2 +- + src/hb.hh | 11 +++++++++++ + 7 files changed, 23 insertions(+), 18 deletions(-) + +commit cfbb6a68722361dc7a1a5ea016921930552bbec7 +Author: Qunxin Liu <48925186+qxliu76@users.noreply.github.com> +Date: Thu Mar 14 17:33:34 2024 -0700 + + [subset] support BASE table subsetting (#4618) + + * [subset] support BASE table + + * [subset] add tests for BASE table subsetting + + src/hb-open-type.hh | 7 + + src/hb-ot-layout-base-table.hh | 272 +++++++++++++++++++++ + src/hb-subset-input.cc | 1 - + src/hb-subset-plan-member-list.hh | 6 + + src/hb-subset-plan.cc | 54 ++++ + src/hb-subset.cc | 3 + + test/subset/data/Makefile.am | 1 + + test/subset/data/Makefile.sources | 1 + + ...r.retain-base-table-filter-scripts.61,62,63.otf | Bin 0 -> 2188 bytes + ...eSansPro-Regular.retain-base-table.61,62,63.otf | Bin 0 -> 2268 bytes + .../profiles/retain-base-table-filter-scripts.txt | 2 + + test/subset/data/profiles/retain-base-table.txt | 1 + + test/subset/data/tests/subset_base.tests | 10 + + test/subset/meson.build | 1 + + test/subset/run-tests.py | 2 +- + 15 files changed, 359 insertions(+), 2 deletions(-) + +commit e18565875a17c493e3c98f09f8c2d5c4c9436224 +Merge: 595def8fb 79eaa217a +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Mar 14 15:40:18 2024 -0600 + + Merge pull request #4616 from googlefonts/repacker + + [repacker] Rework how ClassDef sizes are estimated during splitting. + +commit 79eaa217ac65d7564e1fadd871de95c5206896ac +Author: Garret Rieger <grieger@google.com> +Date: Thu Mar 14 21:22:22 2024 +0000 + + [repacker] remove unused include. + + src/graph/classdef-graph.hh | 1 - + 1 file changed, 1 deletion(-) + +commit 595def8fb8e545af64b4ebe00ee84089500266f8 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Mar 14 12:34:39 2024 -0600 + + Revert "Fixing compiler warnings" + + This reverts commit 61a1ba2ff0fc1b1ed9db0b7c1dd0f59a4312e6e6. + + src/OT/glyf/glyf-helpers.hh | 3 +-- + src/hb-common.cc | 3 +-- + src/hb-font.hh | 3 +-- + src/hb-ot-shaper-arabic.cc | 10 +++++----- + src/hb-ot-tag.cc | 3 +-- + 5 files changed, 9 insertions(+), 13 deletions(-) + +commit 61a1ba2ff0fc1b1ed9db0b7c1dd0f59a4312e6e6 +Author: jcomito <jcomito@google.com> +Date: Tue Mar 12 21:34:14 2024 +0000 + + Fixing compiler warnings + + All warning are for format specifiers (-WFormat) in sprintf(). + + src/OT/glyf/glyf-helpers.hh | 3 ++- + src/hb-common.cc | 3 ++- + src/hb-font.hh | 3 ++- + src/hb-ot-shaper-arabic.cc | 10 +++++----- + src/hb-ot-tag.cc | 3 ++- + 5 files changed, 13 insertions(+), 9 deletions(-) + +commit 2da79f70a1d562d883bdde5b74f6603374fb7023 +Author: Lie Yan <robyn.lie.yan@outlook.com> +Date: Sat Mar 9 22:45:37 2024 +0800 + + fix(test-ot-math.c): remove redundant lines + + test/api/test-ot-math.c | 3 --- + 1 file changed, 3 deletions(-) + +commit 025f52769f637b23fa14f3229a4be86451570f52 +Author: Garret Rieger <grieger@google.com> +Date: Sat Mar 9 00:32:36 2024 +0000 + + [repacker] fix mem leak in test-classdef-graph test. + + src/graph/test-classdef-graph.cc | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +commit 01fc4a162fd98600334e1fec1437155cb506e1e1 +Author: Garret Rieger <grieger@google.com> +Date: Sat Mar 9 00:06:37 2024 +0000 + + [repacker] Fix repacker test. + + With class def size estimation changes this test is now able to pack closer to the limit. + + src/test-repacker.cc | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 8e1beefe0563589285921845bd1f89721f72cb86 +Author: Garret Rieger <grieger@google.com> +Date: Fri Mar 8 22:05:20 2024 +0000 + + [repacker] small fixes. + + src/graph/classdef-graph.hh | 4 ++-- + src/graph/pairpos-graph.hh | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +commit 17b37f10d5a5339f85f965fca900c08762e480fd +Author: Garret Rieger <grieger@google.com> +Date: Fri Mar 8 22:01:05 2024 +0000 + + [repacker] add classdef size est. test that you can add the same class multiple times. + + src/graph/test-classdef-graph.cc | 1 + + 1 file changed, 1 insertion(+) + +commit 0ac9e7da3989a7fcc5c5a2bf2befeb0d81bf0328 +Author: Garret Rieger <grieger@google.com> +Date: Fri Mar 8 21:53:10 2024 +0000 + + [repacker] in classdef estimator tests compare results to actual class def serialization. + + Fix the estimator to actually match real serialization sizes. + + src/graph/classdef-graph.hh | 48 +++++------ + src/graph/test-classdef-graph.cc | 167 ++++++++++++++++++++++++++++----------- + 2 files changed, 142 insertions(+), 73 deletions(-) + +commit 0692d23ccc4f253b5e69591433a3c3990687b4a9 +Author: David Corbett <corbett.dav@northeastern.edu> +Date: Thu Mar 7 17:30:56 2024 -0500 + + Update IANA Language Subtag Registry to 2024-03-07 + + src/gen-tag-table.py | 2 +- + src/hb-ot-tag-table.hh | 28 ++++++++++++++++------------ + 2 files changed, 17 insertions(+), 13 deletions(-) + +commit 8129b21dea061e4b335e32fe278ab6a1efdeebca +Author: Garret Rieger <grieger@google.com> +Date: Fri Mar 8 20:15:43 2024 +0000 + + Update classdef size estimator to pick the min coverage format. + + Previously this just assumed a worst case format 1. + + src/graph/classdef-graph.hh | 26 ++++++++++---- + src/graph/pairpos-graph.hh | 8 ++--- + src/graph/test-classdef-graph.cc | 74 +++++++++++++++++++++++----------------- + 3 files changed, 66 insertions(+), 42 deletions(-) + +commit 252a926fbfc1167c81b9a82bdb3caf2f0d90f8c8 +Author: Garret Rieger <grieger@google.com> +Date: Fri Mar 8 19:46:48 2024 +0000 + + [repacker] Rework how ClassDef sizes are estimated during splitting. + + The old approach considered only one class at a time, which in some cases can generate the wrong answer. This change updates the estimation to consider how all classes in the current split would end up encoded in a single ClassDef table. Additionally compute whether glyphs are consecutive only for the current split (instead of the fully mapping). + + src/graph/classdef-graph.hh | 63 +++++++++++++++------ + src/graph/pairpos-graph.hh | 8 ++- + src/graph/test-classdef-graph.cc | 115 +++++++++++++++++++++++++++++++++------ + 3 files changed, 149 insertions(+), 37 deletions(-) + +commit d6431dc7e6fba6ca96472e672e9f274192121bed +Author: Qunxin Liu <qxliu@google.com> +Date: Wed Mar 6 15:20:10 2024 -0800 + + [instancer] support *=drop, which would pin all axis to default location + + docs/harfbuzz-sections.txt | 1 + + src/hb-subset-input.cc | 40 ++++++++++++++++++++++++++++++++++++++++ + src/hb-subset.h | 4 ++++ + util/helper-subset.hh | 20 ++++++++++++++++++++ + util/test-hb-subset-parsing.c | 11 +++++++++++ + 5 files changed, 76 insertions(+) + +commit 06749fa481c02ced563ea20685ac7697ea933dfe +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Mar 4 11:25:44 2024 -0700 + + [icu] Use uscript_getCode() + + src/hb-icu.cc | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +commit f1464efb7804cf3b784851a35b777b65c4ca6753 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Mar 4 10:51:59 2024 +0000 + + Bump codecov/codecov-action from 4.0.1 to 4.1.0 + + Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4.0.1 to 4.1.0. + - [Release notes](https://github.com/codecov/codecov-action/releases) + - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) + - [Commits](https://github.com/codecov/codecov-action/compare/e0b68c6749509c5f83f984dd99a76a1c1a231044...54bcd8715eee62d40e33596ef5e8f0f48dbbccab) + + --- + updated-dependencies: + - dependency-name: codecov/codecov-action + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/linux-ci.yml | 2 +- + .github/workflows/macos-ci.yml | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit cbc3c539cc442035dc0542c19e5472ed9e4864eb +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Mar 4 10:52:05 2024 +0000 + + Bump github/codeql-action from 3.24.5 to 3.24.6 + + Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.24.5 to 3.24.6. + - [Release notes](https://github.com/github/codeql-action/releases) + - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) + - [Commits](https://github.com/github/codeql-action/compare/47b3d888fe66b639e431abf22ebca059152f1eea...8a470fddafa5cbb6266ee11b37ef4d8aae19c571) + + --- + updated-dependencies: + - dependency-name: github/codeql-action + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/scorecard.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 6864769c4dc2933ec25048cb8c1e9f240c94f345 +Author: L. E. Segovia <amy@amyspark.me> +Date: Sun Feb 25 13:46:05 2024 -0300 + + [meson] Block uses of hb-static throughout Microsoft compilers + + PE-COFF cannot export extern, non-dllexport symbols. + + src/meson.build | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +commit 61d57be1762c320aa814dc177a90a9c0a4b3cc07 +Author: خالد حسني (Khaled Hosny) <khaled@aliftype.com> +Date: Mon Feb 26 16:08:45 2024 +0200 + + Revert "Bump gcovr from 5.0 to 7.2 in /.ci" + + This reverts commit 58c6dba9cd523668d80d417131786e660f0418ef. + + .ci/requirements.in | 2 +- + .ci/requirements.txt | 14 +++----------- + 2 files changed, 4 insertions(+), 12 deletions(-) + +commit 05d43963faa417e46a1ba9ce2cce5c5a1f01f424 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Feb 26 11:00:58 2024 +0000 + + Revert "Bump codecov/codecov-action from 4.0.1 to 4.0.2" + + This reverts commit 52ecdd269c1e4ede571b8126e19c75b8f9265efb. + + .github/workflows/linux-ci.yml | 2 +- + .github/workflows/macos-ci.yml | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit 52ecdd269c1e4ede571b8126e19c75b8f9265efb +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Feb 26 10:20:12 2024 +0000 + + Bump codecov/codecov-action from 4.0.1 to 4.0.2 + + Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4.0.1 to 4.0.2. + - [Release notes](https://github.com/codecov/codecov-action/releases) + - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) + - [Commits](https://github.com/codecov/codecov-action/compare/e0b68c6749509c5f83f984dd99a76a1c1a231044...0cfda1dd0a4ad9efc75517f399d859cd1ea4ced1) + + --- + updated-dependencies: + - dependency-name: codecov/codecov-action + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/linux-ci.yml | 2 +- + .github/workflows/macos-ci.yml | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit 49dbf4eaf98de0d65dec7b3f489326e5ca0f1173 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Feb 26 10:20:20 2024 +0000 + + Bump github/codeql-action from 3.24.3 to 3.24.5 + + Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.24.3 to 3.24.5. + - [Release notes](https://github.com/github/codeql-action/releases) + - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) + - [Commits](https://github.com/github/codeql-action/compare/379614612a29c9e28f31f39a59013eb8012a51f0...47b3d888fe66b639e431abf22ebca059152f1eea) + + --- + updated-dependencies: + - dependency-name: github/codeql-action + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/scorecard.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 58c6dba9cd523668d80d417131786e660f0418ef +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Feb 26 10:37:56 2024 +0000 + + Bump gcovr from 5.0 to 7.2 in /.ci + + Bumps [gcovr](https://github.com/gcovr/gcovr) from 5.0 to 7.2. + - [Release notes](https://github.com/gcovr/gcovr/releases) + - [Changelog](https://github.com/gcovr/gcovr/blob/main/CHANGELOG.rst) + - [Commits](https://github.com/gcovr/gcovr/compare/5.0...7.2) + + --- + updated-dependencies: + - dependency-name: gcovr + dependency-type: direct:production + update-type: version-update:semver-major + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .ci/requirements.in | 2 +- + .ci/requirements.txt | 14 +++++++++++--- + 2 files changed, 12 insertions(+), 4 deletions(-) + +commit 4d8773bd818a5e35d8f5c38e30b2997e8e160fb1 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Feb 26 10:37:38 2024 +0000 + + Bump setuptools from 69.1.0 to 69.1.1 in /.ci + + Bumps [setuptools](https://github.com/pypa/setuptools) from 69.1.0 to 69.1.1. + - [Release notes](https://github.com/pypa/setuptools/releases) + - [Changelog](https://github.com/pypa/setuptools/blob/main/NEWS.rst) + - [Commits](https://github.com/pypa/setuptools/compare/v69.1.0...v69.1.1) + + --- + updated-dependencies: + - dependency-name: setuptools + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .ci/requirements.txt | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 225a7a8a5eb6192218ab223426e64eb263bced4a +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sat Feb 24 15:12:42 2024 +0100 + + [aat] Mark DELETED_GLYPH as IGNORABLE + + Fixes https://github.com/harfbuzz/harfbuzz/issues/4598 + + src/hb-aat-layout-morx-table.hh | 1 + + 1 file changed, 1 insertion(+) + +commit 5d1ff191c08780cee792de008f8092d0ec69fee1 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Feb 16 22:07:36 2024 +0100 + + Fix return type + + https://github.com/harfbuzz/harfbuzz/commit/1bddeb974ff0c08332c8225f6f5b5bd45bcddfdc#r138731107 + + src/hb-ot-stat-table.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 582a5b3a924044402b90883601a40d1a13767ae6 +Author: Bruce Mitchener <bruce.mitchener@gmail.com> +Date: Fri Feb 16 23:28:53 2024 +0700 + + cmake: Switch to `find_package(Python3)`. + + The existing way of working used in this file was deprecated in + cmake 3.12 and a new way supplied. + + See https://cmake.org/cmake/help/latest/policy/CMP0148.html + + CMakeLists.txt | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +commit 20ddabc78bd59e9553f1f86c26a90fcd75f89897 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Feb 19 10:55:23 2024 +0000 + + Bump fonttools from 4.48.1 to 4.49.0 in /.ci + + Bumps [fonttools](https://github.com/fonttools/fonttools) from 4.48.1 to 4.49.0. + - [Release notes](https://github.com/fonttools/fonttools/releases) + - [Changelog](https://github.com/fonttools/fonttools/blob/main/NEWS.rst) + - [Commits](https://github.com/fonttools/fonttools/compare/4.48.1...4.49.0) + + --- + updated-dependencies: + - dependency-name: fonttools + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .ci/requirements-fonttools.txt | 86 +++++++++++++++++++++--------------------- + .ci/requirements.txt | 86 +++++++++++++++++++++--------------------- + 2 files changed, 86 insertions(+), 86 deletions(-) + +commit 2b986af839825c0bcad2988b3a289e22ca9bc2cd +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Feb 19 10:55:08 2024 +0000 + + Bump meson from 1.3.1 to 1.3.2 in /.ci + + Bumps [meson](https://github.com/mesonbuild/meson) from 1.3.1 to 1.3.2. + - [Release notes](https://github.com/mesonbuild/meson/releases) + - [Commits](https://github.com/mesonbuild/meson/compare/1.3.1...1.3.2) + + --- + updated-dependencies: + - dependency-name: meson + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .ci/requirements.in | 2 +- + .ci/requirements.txt | 6 +++--- + 2 files changed, 4 insertions(+), 4 deletions(-) + +commit 58a9b3633384699d35b49c594db15aa653754f59 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Feb 19 10:24:14 2024 +0000 + + Bump github/codeql-action from 3.24.0 to 3.24.3 + + Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.24.0 to 3.24.3. + - [Release notes](https://github.com/github/codeql-action/releases) + - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) + - [Commits](https://github.com/github/codeql-action/compare/e8893c57a1f3a2b659b6b55564fdfdbbd2982911...379614612a29c9e28f31f39a59013eb8012a51f0) + + --- + updated-dependencies: + - dependency-name: github/codeql-action + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/scorecard.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit fb6d4d27d67e32084a50e3d8ad8b3743861ff24b +Author: Bruce Mitchener <bruce.mitchener@gmail.com> +Date: Sat Feb 17 15:23:29 2024 +0700 + + Remove unnecessary std::move(). + + This fixes a warning from clang-tidy: + + warning: std::move of the variable 'mapping' of the trivially-copyable + type 'AxisValueMap' has no effect [performance-move-const-arg] + + src/hb-ot-var-avar-table.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 3cfdbd671746180b87404c7a9935e62bdc8ebf48 +Author: Bruce Mitchener <bruce.mitchener@gmail.com> +Date: Fri Feb 16 23:41:55 2024 +0700 + + Use `noexcept` on swap, move constructors, etc. + + src/hb-algs.hh | 2 +- + src/hb-bit-set-invertible.hh | 6 +++--- + src/hb-bit-set.hh | 6 +++--- + src/hb-cplusplus.hh | 16 ++++++++-------- + src/hb-map.hh | 8 ++++---- + src/hb-ot-var-common.hh | 6 +++--- + src/hb-priority-queue.hh | 2 +- + src/hb-serialize.hh | 2 +- + src/hb-set.hh | 8 ++++---- + src/hb-vector.hh | 6 +++--- + 10 files changed, 31 insertions(+), 31 deletions(-) + +commit 1bddeb974ff0c08332c8225f6f5b5bd45bcddfdc +Author: Bruce Mitchener <bruce.mitchener@gmail.com> +Date: Fri Feb 16 23:20:54 2024 +0700 + + Use literal bools when possible rather than ints. + + src/hb-buffer-verify.cc | 4 ++-- + src/hb-ot-cmap-table.hh | 2 +- + src/hb-ot-stat-table.hh | 2 +- + 3 files changed, 4 insertions(+), 4 deletions(-) + +commit 8974fe484bb224b6b20137c797f954632abf6ed5 +Author: Garret Rieger <grieger@google.com> +Date: Wed Feb 14 21:09:21 2024 +0000 + + [subset] Add a partial instancing + IUP case to the subset benchmarks. + + perf/benchmark-subset.cc | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +commit b8178f25548c81e9b608e29c233c01839945aaa3 +Author: Magnus Larsen <i.am.larsenml@gmail.com> +Date: Mon Feb 12 21:48:28 2024 -0800 + + Disable Wcast-function-type on clang-cl, too + + src/hb-directwrite.cc | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit c926eb956c77fcb6fd8c9b4659f1787f8c62efcd +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Feb 12 10:45:51 2024 +0000 + + Bump actions/upload-artifact from 4.3.0 to 4.3.1 + + Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.0 to 4.3.1. + - [Release notes](https://github.com/actions/upload-artifact/releases) + - [Commits](https://github.com/actions/upload-artifact/compare/26f96dfa697d77e81fd5907df203aa23a56210a8...5d5d22a31266ced268874388b861e4b58bb5c2f3) + + --- + updated-dependencies: + - dependency-name: actions/upload-artifact + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/cifuzz.yml | 2 +- + .github/workflows/msys2-ci.yml | 2 +- + .github/workflows/scorecard.yml | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +commit 6d7da03d9559d952c0f51d154a26c23f4c347818 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Feb 12 10:57:20 2024 +0000 + + Bump setuptools from 69.0.3 to 69.1.0 in /.ci + + Bumps [setuptools](https://github.com/pypa/setuptools) from 69.0.3 to 69.1.0. + - [Release notes](https://github.com/pypa/setuptools/releases) + - [Changelog](https://github.com/pypa/setuptools/blob/main/NEWS.rst) + - [Commits](https://github.com/pypa/setuptools/compare/v69.0.3...v69.1.0) + + --- + updated-dependencies: + - dependency-name: setuptools + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .ci/requirements.txt | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit e79028c20f957821ecf6c3f0688625a66d07fed5 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Feb 12 10:57:35 2024 +0000 + + Bump fonttools from 4.47.2 to 4.48.1 in /.ci + + Bumps [fonttools](https://github.com/fonttools/fonttools) from 4.47.2 to 4.48.1. + - [Release notes](https://github.com/fonttools/fonttools/releases) + - [Changelog](https://github.com/fonttools/fonttools/blob/main/NEWS.rst) + - [Commits](https://github.com/fonttools/fonttools/compare/4.47.2...4.48.1) + + --- + updated-dependencies: + - dependency-name: fonttools + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .ci/requirements-fonttools.txt | 86 +++++++++++++++++++++--------------------- + .ci/requirements.txt | 86 +++++++++++++++++++++--------------------- + 2 files changed, 86 insertions(+), 86 deletions(-) + +commit 1ab8822b4108aeb30ee409cde863bb1eb8ef0921 +Author: Christer Sandberg <christer.sandberg@svt.se> +Date: Fri Feb 9 17:24:49 2024 +0100 + + Fixed some errors in STAT table implementation + + src/hb-ot-stat-table.hh | 4 ++-- + test/api/fonts/NotoSans-Bold.ttf | Bin 0 -> 582604 bytes + test/api/test-style.c | 18 ++++++++++++++++++ + 3 files changed, 20 insertions(+), 2 deletions(-) + +commit 031fdb1c8b81e0fc5911545550869cc97f1f2c6c +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Feb 6 14:51:41 2024 -0700 + + Rename VarStoreInstancer to ItemVarStoreInstancer + + src/OT/Color/COLR/COLR.hh | 94 +++++++++++++++++++++++------------------------ + src/hb-ot-var-common.hh | 4 +- + src/hb-subset-plan.hh | 2 +- + 3 files changed, 50 insertions(+), 50 deletions(-) + +commit 1cb47eff8f0ae8677015912214f7b9430e5f6507 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Feb 6 14:49:31 2024 -0700 + + Rename VariationStore to ItemVariationStore + + src/OT/Color/COLR/COLR.hh | 2 +- + src/OT/Layout/GDEF/GDEF.hh | 18 +++++++++--------- + src/OT/Layout/GPOS/ValueFormat.hh | 2 +- + src/hb-cff2-interp-cs.hh | 2 +- + src/hb-ot-cff2-table.hh | 14 +++++++------- + src/hb-ot-font.cc | 16 ++++++++-------- + src/hb-ot-hmtx-table.hh | 2 +- + src/hb-ot-layout-base-table.hh | 12 ++++++------ + src/hb-ot-layout-common.hh | 32 ++++++++++++++++---------------- + src/hb-ot-layout-gsubgpos.hh | 6 +++--- + src/hb-ot-var-avar-table.hh | 4 ++-- + src/hb-ot-var-common.hh | 8 ++++---- + src/hb-ot-var-hvar-table.hh | 10 +++++----- + src/hb-ot-var-mvar-table.hh | 6 +++--- + src/hb-subset-cff2.cc | 12 ++++++------ + src/test-item-varstore.cc | 2 +- + 16 files changed, 74 insertions(+), 74 deletions(-) + +commit 4c77bd921c897d977104ec9acb89bcc10251d02f +Author: Lőrinczy, Zsigmond <lzsiga@freemail.c3.hu> +Date: Tue Feb 6 17:51:49 2024 +0100 + + Update hb-serialize.hh (#4576) + + * Update hb-serialize.hh + + This version does compile with g++ 4.8.3 which is the newest available version on Aix5.3 + + * Update hb-serialize.hh + + Back to the original version, just without `this->` + + src/hb-serialize.hh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit c546aa6c5ae78605fd048fd628bd1f25b2e3e50f +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Feb 5 10:49:57 2024 +0000 + + Bump github/codeql-action from 3.23.2 to 3.24.0 + + Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.23.2 to 3.24.0. + - [Release notes](https://github.com/github/codeql-action/releases) + - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) + - [Commits](https://github.com/github/codeql-action/compare/b7bf0a3ed3ecfa44160715d7c442788f65f0f923...e8893c57a1f3a2b659b6b55564fdfdbbd2982911) + + --- + updated-dependencies: + - dependency-name: github/codeql-action + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/scorecard.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 672fcd968fa0d4bd10d3520108d7911c5954e492 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Feb 5 10:50:01 2024 +0000 + + Bump codecov/codecov-action from 3.1.5 to 4.0.1 + + Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3.1.5 to 4.0.1. + - [Release notes](https://github.com/codecov/codecov-action/releases) + - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) + - [Commits](https://github.com/codecov/codecov-action/compare/4fe8c5f003fae66aa5ebb77cfd3e7bfbbda0b6b0...e0b68c6749509c5f83f984dd99a76a1c1a231044) + + --- + updated-dependencies: + - dependency-name: codecov/codecov-action + dependency-type: direct:production + update-type: version-update:semver-major + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/linux-ci.yml | 2 +- + .github/workflows/macos-ci.yml | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit 8da99b83e636711fb4d1287a1cd8bba4d1c3b6a1 +Author: Khaled Hosny <khaled@aliftype.com> +Date: Sat Feb 3 14:20:41 2024 +0200 + + [docs] Order hb-ot-color functions is more organized way + + docs/harfbuzz-sections.txt | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +commit a9b8891799fcb2d2c135a3de35e89828df3f6b9a +Merge: bebdb3347 97309483e +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Feb 2 18:24:24 2024 -0700 + + Merge pull request #4563 from googlefonts/instancer_iup_delta_opt + + [Instancer] add code for iup delta optimization + +commit 97309483eae24037de9d3d9fce0051848afadaee +Author: Qunxin Liu <qxliu@google.com> +Date: Fri Feb 2 16:59:19 2024 -0800 + + [instancer] rename HB_SUBSET_FLAGS_IUP_DELTA_OPT to HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS + + src/hb-ot-var-gvar-table.hh | 2 +- + src/hb-subset-plan.cc | 2 +- + src/hb-subset.h | 4 ++-- + util/hb-subset.cc | 2 +- + 4 files changed, 5 insertions(+), 5 deletions(-) + +commit 2dabbdfc66175bbd7e097a3b63e0bc8beaacb2cd +Author: Qunxin Liu <qxliu@google.com> +Date: Fri Feb 2 13:39:04 2024 -0800 + + [instancer] fix help message for --optimize + + util/hb-subset.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit f072de9359da08c136a7b1131fc12bbe17a7d441 +Author: Qunxin Liu <qxliu@google.com> +Date: Tue Jan 30 10:31:14 2024 -0800 + + [instancer] move iup code to a seprate file + + src/Makefile.am | 4 +- + src/Makefile.sources | 2 + + src/harfbuzz-subset.cc | 1 + + src/hb-ot-var-common.hh | 526 ++-------------------------------------- + src/hb-subset-instancer-iup.cc | 532 +++++++++++++++++++++++++++++++++++++++++ + src/hb-subset-instancer-iup.hh | 37 +++ + src/meson.build | 6 +- + 7 files changed, 592 insertions(+), 516 deletions(-) + +commit bebdb3347c2d004edfeb2a284bffbb1df8c4874e +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jan 29 10:38:03 2024 +0000 + + Bump codecov/codecov-action from 3.1.4 to 3.1.5 + + Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3.1.4 to 3.1.5. + - [Release notes](https://github.com/codecov/codecov-action/releases) + - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) + - [Commits](https://github.com/codecov/codecov-action/compare/eaaf4bedf32dbdc6b720b63067d99c4d77d6047d...4fe8c5f003fae66aa5ebb77cfd3e7bfbbda0b6b0) + + --- + updated-dependencies: + - dependency-name: codecov/codecov-action + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/linux-ci.yml | 2 +- + .github/workflows/macos-ci.yml | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit 74228888fe7fe88ef86031771f8ab2f9d5ca844b +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jan 29 10:38:08 2024 +0000 + + Bump github/codeql-action from 3.23.1 to 3.23.2 + + Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.23.1 to 3.23.2. + - [Release notes](https://github.com/github/codeql-action/releases) + - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) + - [Commits](https://github.com/github/codeql-action/compare/0b21cf2492b6b02c465a3e5d7c473717ad7721ba...b7bf0a3ed3ecfa44160715d7c442788f65f0f923) + + --- + updated-dependencies: + - dependency-name: github/codeql-action + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/scorecard.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 0ba922041317ce1e315d8d91a968f50b901a91ac +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jan 29 10:38:10 2024 +0000 + + Bump actions/upload-artifact from 4.2.0 to 4.3.0 + + Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.2.0 to 4.3.0. + - [Release notes](https://github.com/actions/upload-artifact/releases) + - [Commits](https://github.com/actions/upload-artifact/compare/694cdabd8bdb0f10b2cea11669e1bf5453eed0a6...26f96dfa697d77e81fd5907df203aa23a56210a8) + + --- + updated-dependencies: + - dependency-name: actions/upload-artifact + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/cifuzz.yml | 2 +- + .github/workflows/msys2-ci.yml | 2 +- + .github/workflows/scorecard.yml | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +commit 98e290c0c867666fb075748844a3e849caece651 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jan 29 10:38:14 2024 +0000 + + Bump hendrikmuhs/ccache-action from 1.2.11 to 1.2.12 + + Bumps [hendrikmuhs/ccache-action](https://github.com/hendrikmuhs/ccache-action) from 1.2.11 to 1.2.12. + - [Release notes](https://github.com/hendrikmuhs/ccache-action/releases) + - [Commits](https://github.com/hendrikmuhs/ccache-action/compare/2a51777f6f64b7b7bea213601acba8f5f4fdbe03...faf867a11c028c0b483fb2ae72b6fc8f7d842714) + + --- + updated-dependencies: + - dependency-name: hendrikmuhs/ccache-action + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/linux-ci.yml | 2 +- + .github/workflows/macos-ci.yml | 2 +- + .github/workflows/msvc-ci.yml | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +commit 846d5204c07b006adcca2ca0937e5d6935d66334 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sat Jan 27 16:34:29 2024 -0800 + + [ft] Remove unnecessary cast + + src/hb-ft.cc | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +commit 9182315bbaac2b4eef6f707e4dab78ffb05aa713 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sat Jan 27 16:33:46 2024 -0800 + + [hb.hh] Add error -Wcast-function-type-strict + + src/hb.hh | 1 + + 1 file changed, 1 insertion(+) + +commit 97c85ab2d0f92fafb13ce20c134d25254cb65974 +Author: Qunxin Liu <qxliu@google.com> +Date: Fri Jan 26 16:36:56 2024 -0800 + + [instancer] iup delta optimize: fix is_composite_glyph value in gvar + + src/hb-ot-var-gvar-table.hh | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +commit 4d5fb233e3fb45bb6ebdaab15029f571db4f6ccb +Author: Qunxin Liu <qxliu@google.com> +Date: Fri Jan 26 16:00:58 2024 -0800 + + fix build + + src/hb-ot-var-common.hh | 10 +++++----- + src/hb-subset-plan.cc | 2 ++ + 2 files changed, 7 insertions(+), 5 deletions(-) + +commit 84771374e81b61a8e19e224fb95cbe852a5edba5 +Author: Qunxin Liu <qxliu@google.com> +Date: Fri Jan 26 15:45:32 2024 -0800 + + [instancer] add tests for iup delta optimization + + ...all-codepoint.wght=200-300,opsz=14.iup_optimize.ttf | Bin 0 -> 9984 bytes + ...odepoint.wght=400,wdth=100,opsz=14.iup_optimize.ttf | Bin 0 -> 6292 bytes + ...lt.retain-all-codepoint.wdth=112.5.iup_optimize.ttf | Bin 0 -> 2668 bytes + ...fault.retain-all-codepoint.wdth=75.iup_optimize.ttf | Bin 0 -> 3296 bytes + ...tures.retain-all-codepoint.wdth=75.iup_optimize.ttf | Bin 0 -> 4500 bytes + ...ault.retain-all-codepoint.wght=300.iup_optimize.ttf | Bin 0 -> 3276 bytes + ...epoint.wght=200-300-500,wdth=80-90.iup_optimize.ttf | Bin 0 -> 8684 bytes + ...all-codepoint.wght=300-600,wdth=85.iup_optimize.ttf | Bin 0 -> 7592 bytes + ...epoint.wght=200-300-500,wdth=80-90.iup_optimize.ttf | Bin 0 -> 7516 bytes + ...all-codepoint.wght=300-600,wdth=85.iup_optimize.ttf | Bin 0 -> 6928 bytes + ...wght=200-600,wdth=80-90,CTGR=20-60.iup_optimize.ttf | Bin 0 -> 4164 bytes + ....retain-all-codepoint.wght=300-600.iup_optimize.ttf | Bin 0 -> 6732 bytes + ....retain-all-codepoint.wght=500-800.iup_optimize.ttf | Bin 0 -> 7248 bytes + ...D=25,YEXT=520,wght=100-400,slnt=18.iup_optimize.ttf | Bin 0 -> 2184 bytes + ....retain-all-codepoint.wght=300-600.iup_optimize.ttf | Bin 0 -> 303960 bytes + ....retain-all-codepoint.wght=500-800.iup_optimize.ttf | Bin 0 -> 249808 bytes + ...ault.retain-all-codepoint.wght=400.iup_optimize.ttf | Bin 0 -> 1848 bytes + ...ints.retain-all-codepoint.wght=400.iup_optimize.ttf | Bin 0 -> 1824 bytes + test/subset/data/tests/empty_region_vardata.tests | 3 +++ + .../feature_variation_instance_collect_lookups.tests | 4 ++++ + .../tests/feature_variations_partial_instance.tests | 4 ++++ + test/subset/data/tests/gdef_partial_instance.tests | 4 ++++ + test/subset/data/tests/glyf_partial_instancing.tests | 4 ++++ + test/subset/data/tests/mvar_partial_instance.tests | 4 ++++ + test/subset/data/tests/sync_vmetrics.tests | 4 ++++ + test/subset/data/tests/update_def_wght.tests | 4 ++++ + .../data/tests/value_format_partial_instance.tests | 4 ++++ + test/subset/generate-expected-outputs.py | 15 +++++++++------ + test/subset/run-tests.py | 2 ++ + test/subset/subset_test_suite.py | 15 ++++++++++++--- + 30 files changed, 58 insertions(+), 9 deletions(-) + +commit 0cbc812340787bcd25ce5272dc4307559c070e58 +Author: Qunxin Liu <qxliu@google.com> +Date: Fri Jan 26 11:26:10 2024 -0800 + + [instancer] add iup_optimize() call into instantiation + + src/hb-ot-var-common.hh | 31 ++++++++++++++++++++++++++----- + src/hb-ot-var-gvar-table.hh | 6 +++++- + 2 files changed, 31 insertions(+), 6 deletions(-) + +commit aed309d1ec7fd47092154d8879f0975592443922 +Author: Patrick Griffis <pgriffis@igalia.com> +Date: Fri Jan 26 13:11:26 2024 -0600 + + [autotools] Installing missing hb-features.h header + + This is already installed by CMake and Meson. + + src/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 52c3cda31bf868b4430658fa15255635e41bd4ef +Author: Qunxin Liu <qxliu@google.com> +Date: Fri Jan 26 10:55:57 2024 -0800 + + [instancer] add composite_new_gids set in subset plan + + This is only used by iup delta optimization where we need to know + whether glyph is composite or not + + src/OT/glyf/CompositeGlyph.hh | 3 ++- + src/OT/glyf/Glyph.hh | 3 +++ + src/hb-subset-plan-member-list.hh | 3 +++ + src/hb-subset-plan.cc | 11 ++++++++--- + 4 files changed, 16 insertions(+), 4 deletions(-) + +commit a3e3473cc8591ace765623f91f2fd0770ee6ce62 +Author: Qunxin Liu <qxliu@google.com> +Date: Fri Jan 26 10:34:58 2024 -0800 + + [instancer] when iup delta opt is enabled, add default deltas to coords + + src/hb-ot-var-common.hh | 32 +++++++++++++++++++++++++------- + src/hb-subset-plan.hh | 23 +++++++++++++++++++++++ + 2 files changed, 48 insertions(+), 7 deletions(-) + +commit f1cdcc70c1a7cda9a8f0ebeba6f7131641fd642c +Author: Qunxin Liu <qxliu@google.com> +Date: Fri Jan 26 10:12:38 2024 -0800 + + [instancer] add iup delta optimization functions tuple_delta_t + + ported from fonttools + + src/hb-ot-var-common.hh | 609 +++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 597 insertions(+), 12 deletions(-) + +commit 8ad540bb84f0f67f8a0405a70fdded13ee49d0ad +Author: Qunxin Liu <qxliu@google.com> +Date: Fri Jan 26 09:58:48 2024 -0800 + + [instancer] move compile_point_set to be a member of tuple_delta_t + + Also change hb_bytes_t to vector for memory safety + + src/hb-ot-var-common.hh | 260 +++++++++++++++++++++++++----------------------- + 1 file changed, 135 insertions(+), 125 deletions(-) + +commit c7a6030b31cb395ebab41dd47b2a2125e3578641 +Author: Qunxin Liu <qxliu@google.com> +Date: Fri Jan 26 09:27:27 2024 -0800 + + [instancer] add a flag HB_SUBSET_FLAGS_IUP_DELTA_OPT + + src/hb-subset.h | 3 +++ + util/hb-subset.cc | 1 + + 2 files changed, 4 insertions(+) + +commit 93a148cde60f9f9f79e283be83001747e3f5dfef +Author: Elliot <35050275+apache-hb@users.noreply.github.com> +Date: Thu Jan 25 09:18:01 2024 -0500 + + fix warning when compiling with clang-cl + + meson.build | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +commit 4a18c502e22c27548db93862d5fb6442a3809995 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Jan 23 05:12:43 2024 -0800 + + [cmake] Treat VITA like gcc + + https://github.com/vitasdk/packages/issues/300 + + CMakeLists.txt | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 4b716b101ee9567f9505cf8fe0039b70c5e1a7fe +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jan 22 10:47:03 2024 +0000 + + Bump github/codeql-action from 3.23.0 to 3.23.1 + + Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.23.0 to 3.23.1. + - [Release notes](https://github.com/github/codeql-action/releases) + - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) + - [Commits](https://github.com/github/codeql-action/compare/e5f05b81d5b6ff8cfa111c80c22c5fd02a384118...0b21cf2492b6b02c465a3e5d7c473717ad7721ba) + + --- + updated-dependencies: + - dependency-name: github/codeql-action + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/scorecard.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit e67a94017ef63811e08998861016738ad93bb7d5 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jan 22 10:46:57 2024 +0000 + + Bump actions/upload-artifact from 4.1.0 to 4.2.0 + + Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.1.0 to 4.2.0. + - [Release notes](https://github.com/actions/upload-artifact/releases) + - [Commits](https://github.com/actions/upload-artifact/compare/1eb3cb2b3e0f29609092a73eb033bb759a334595...694cdabd8bdb0f10b2cea11669e1bf5453eed0a6) + + --- + updated-dependencies: + - dependency-name: actions/upload-artifact + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/cifuzz.yml | 2 +- + .github/workflows/msys2-ci.yml | 2 +- + .github/workflows/scorecard.yml | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +commit 62e1de7f16b250efba6902fda0803b0958e7add3 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jan 15 10:29:03 2024 +0000 + + Bump actions/upload-artifact from 4.0.0 to 4.1.0 + + Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.0.0 to 4.1.0. + - [Release notes](https://github.com/actions/upload-artifact/releases) + - [Commits](https://github.com/actions/upload-artifact/compare/c7d193f32edcb7bfad88892161225aeda64e9392...1eb3cb2b3e0f29609092a73eb033bb759a334595) + + --- + updated-dependencies: + - dependency-name: actions/upload-artifact + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/cifuzz.yml | 2 +- + .github/workflows/msys2-ci.yml | 2 +- + .github/workflows/scorecard.yml | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +commit d53c97e6af2fc1e45d9742629e17882856ee459c +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jan 15 10:29:08 2024 +0000 + + Bump github/codeql-action from 3.22.12 to 3.23.0 + + Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.22.12 to 3.23.0. + - [Release notes](https://github.com/github/codeql-action/releases) + - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) + - [Commits](https://github.com/github/codeql-action/compare/012739e5082ff0c22ca6d6ab32e07c36df03c4a4...e5f05b81d5b6ff8cfa111c80c22c5fd02a384118) + + --- + updated-dependencies: + - dependency-name: github/codeql-action + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/scorecard.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 9c143d5258beb1d5002f26ef93b037d99e126138 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jan 15 11:02:40 2024 +0000 + + Bump fonttools from 4.47.0 to 4.47.2 in /.ci + + Bumps [fonttools](https://github.com/fonttools/fonttools) from 4.47.0 to 4.47.2. + - [Release notes](https://github.com/fonttools/fonttools/releases) + - [Changelog](https://github.com/fonttools/fonttools/blob/main/NEWS.rst) + - [Commits](https://github.com/fonttools/fonttools/compare/4.47.0...4.47.2) + + --- + updated-dependencies: + - dependency-name: fonttools + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .ci/requirements-fonttools.txt | 86 +++++++++++++++++++++--------------------- + .ci/requirements.txt | 86 +++++++++++++++++++++--------------------- + 2 files changed, 86 insertions(+), 86 deletions(-) + +commit 032c931e1c0cfb20f18e5acb8ba005775242bd92 +Author: Sergei Trofimovich <slyich@gmail.com> +Date: Sat Jan 13 15:57:03 2024 +0000 + + use `calloc(nmemb, size)`, not `calloc(size, nmemb)` + + This minor mismatch is detected by new `-Wcalloc-transposed-args` + `gcc-14` warning as: + + In file included from ../src/hb-subset-plan.cc:38: + ../src/hb-ot-cff1-table.hh: In member function 'bool OT::cff1::accelerator_t::get_glyph_from_name(const char*, int, hb_codepoint_t*) const': + ../src/hb-ot-cff1-table.hh:1419:60: warning: 'void* calloc(size_t, size_t)' sizes specified with 'sizeof' in the earlier argument and not in the later argument [-Wcalloc-transposed-args] + 1419 | names = (hb_sorted_vector_t<gname_t> *) hb_calloc (sizeof (hb_sorted_vector_t<gname_t>), 1); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + src/hb-object.hh | 2 +- + src/hb-ot-cff1-table.hh | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit 11f8914adddc2cac3b07edfdb3b3f372eef76426 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Thu Jan 11 21:03:01 2024 +0000 + + Bump jinja2 from 3.1.2 to 3.1.3 in /.ci + + Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.2 to 3.1.3. + - [Release notes](https://github.com/pallets/jinja/releases) + - [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst) + - [Commits](https://github.com/pallets/jinja/compare/3.1.2...3.1.3) + + --- + updated-dependencies: + - dependency-name: jinja2 + dependency-type: indirect + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .ci/requirements.txt | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit ef1f5c4e0c011fc6f71b02d47b579a3154ca70ec +Author: Garret Rieger <grieger@google.com> +Date: Mon Jan 8 22:17:55 2024 +0000 + + [subset] Re-use common Coverage subsetting function in PairPosFormat2. + + Was using an identical but less efficient version. Fixes fuzzer test case: https://oss-fuzz.com/testcase-detail/6151390002806784 + + src/OT/Layout/GPOS/PairPosFormat2.hh | 13 ++----------- + ...-testcase-minimized-hb-subset-fuzzer-6151390002806784 | Bin 0 -> 2534 bytes + 2 files changed, 2 insertions(+), 11 deletions(-) + +commit e0e2b29ea89cc40b27d45a77806d35a239eaae55 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Jan 8 12:30:23 2024 -0700 + + [cmap] Implement MacRoman encoding + + For other Mac encodings just map the ASCII range. + + Fixes https://github.com/harfbuzz/harfbuzz/issues/4540 + + src/hb-algs.hh | 12 +++++++ + src/hb-ot-cmap-table.hh | 87 ++++++++++++++++++++++++++++++++++++++++++++++--- + 2 files changed, 94 insertions(+), 5 deletions(-) + +commit ef289a9e20d80ca96402c93c865af05d282ff362 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Jan 8 09:11:01 2024 -0700 + + [COLR] Reduce COLRv1 max edge count + + 64k sounds excessive. + + Fixes https://oss-fuzz.com/testcase-detail/5383336738291712 + + src/hb-limits.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 155015f4bec434ecc2f94621665844218f05ce51 +Author: Lie Yan <robyn.lie.yan@outlook.com> +Date: Mon Jan 8 21:44:27 2024 +0800 + + refactor(math-kern): call hb_bsearch_impl instead of raw binary search + + src/hb-ot-math-table.hh | 25 ++++++++++--------------- + 1 file changed, 10 insertions(+), 15 deletions(-) + +commit b42b1124563351b723f1d7c9ca448481ad3ca054 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jan 8 10:18:28 2024 +0000 + + Bump hendrikmuhs/ccache-action from 1.2.10 to 1.2.11 + + Bumps [hendrikmuhs/ccache-action](https://github.com/hendrikmuhs/ccache-action) from 1.2.10 to 1.2.11. + - [Release notes](https://github.com/hendrikmuhs/ccache-action/releases) + - [Commits](https://github.com/hendrikmuhs/ccache-action/compare/6d1841ec156c39a52b1b23a810da917ab98da1f4...2a51777f6f64b7b7bea213601acba8f5f4fdbe03) + + --- + updated-dependencies: + - dependency-name: hendrikmuhs/ccache-action + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/linux-ci.yml | 2 +- + .github/workflows/macos-ci.yml | 2 +- + .github/workflows/msvc-ci.yml | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +commit 2f41d54b8505abe016bc7d72eea8a789c1f35cdb +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Jan 7 13:43:50 2024 -0700 + + Fix old-compiler warning + + src/hb-ot-layout.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 1cc7ddb3c4ac5da1b8335f0a593281364f2a875a +Author: Ozkan Sezer <sezeroz@gmail.com> +Date: Sun Jan 7 18:55:40 2024 +0300 + + hb-subset-plan.cc: Fix -Wparentheses warning. + + In file included from hb-subset-plan.hh:30:0, + from hb-subset-plan.cc:27: + hb-subset-plan.cc: In function 'void _update_instance_metrics_map_from_cff2(hb_subset_plan_t*)': + hb-subset-plan.cc:998:81: warning: suggest parentheses around assignment used as truth value [-Wparentheses] + if (unlikely (!plan->check_success (font = _get_hb_font_with_variations (plan)))) + ^ + hb.hh:263:25: note: in definition of macro 'unlikely' + #define unlikely(expr) (expr) + ^ + + Fixes: https://github.com/harfbuzz/harfbuzz/issues/4545 + + src/hb-subset-plan.cc | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit c17d67467f86fa491835cc50b9f454d825648407 +Author: Lie Yan <robyn.lie.yan@outlook.com> +Date: Sun Jan 7 22:10:10 2024 +0800 + + [ot-math] Fix a bug in MathKern::get_value() + + Fixes https://github.com/harfbuzz/harfbuzz/issues/4542 + + src/hb-ot-math-table.hh | 14 ++++++-------- + test/api/test-ot-math.c | 8 ++++---- + 2 files changed, 10 insertions(+), 12 deletions(-) + +commit 5852d328a4b3c0064feb58d465f58c247ae1ad90 +Author: Khaled Hosny <khaled@aliftype.com> +Date: Sat Jan 6 16:46:55 2024 +0200 + + [circleci] Run pip inside a virtual environment + + Looks like newer versions of python disable pip for system-managed + installations. This should unbreak alpine job and prevent other jobs + from potentially breaking in the future. + + .circleci/config.yml | 70 +++++++++++++++++++++++++++++++++------------------- + 1 file changed, 44 insertions(+), 26 deletions(-) + +commit e9d727173cfef073ab126f2185039ebae9db3892 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Jan 4 09:36:14 2024 -0700 + + [cmap] Remove more unused code + + src/hb-ot-cmap-table.hh | 10 ---------- + 1 file changed, 10 deletions(-) + +commit f8d924e5b8a3c2a4d655266b40e48bc5225768f0 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Thu Jan 4 09:35:15 2024 -0700 + + [cmap] Remove unused code + + src/hb-ot-cmap-table.hh | 12 ------------ + 1 file changed, 12 deletions(-) + +commit 81c2212117b1035e3583b45c950799cb83865218 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Jan 1 13:52:33 2024 -0500 + + [test-instancer-solver] Fix on msys32 hopefully + + src/test-subset-instancer-solver.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit ba7dae79ee22c6427d56d1f93380ec59b9873156 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jan 1 10:47:52 2024 +0000 + + Bump ilammy/msvc-dev-cmd from 1.12.1 to 1.13.0 + + Bumps [ilammy/msvc-dev-cmd](https://github.com/ilammy/msvc-dev-cmd) from 1.12.1 to 1.13.0. + - [Release notes](https://github.com/ilammy/msvc-dev-cmd/releases) + - [Commits](https://github.com/ilammy/msvc-dev-cmd/compare/cec98b9d092141f74527d0afa6feb2af698cfe89...0b201ec74fa43914dc39ae48a89fd1d8cb592756) + + --- + updated-dependencies: + - dependency-name: ilammy/msvc-dev-cmd + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/msvc-ci.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 62fd46a84ec6a808f7e2c2c86c62e8f54574efbf +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jan 1 10:15:03 2024 +0000 + + Bump meson from 1.3.0 to 1.3.1 in /.ci + + Bumps [meson](https://github.com/mesonbuild/meson) from 1.3.0 to 1.3.1. + - [Release notes](https://github.com/mesonbuild/meson/releases) + - [Commits](https://github.com/mesonbuild/meson/compare/1.3.0...1.3.1) + + --- + updated-dependencies: + - dependency-name: meson + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .ci/requirements.in | 2 +- + .ci/requirements.txt | 6 +++--- + 2 files changed, 4 insertions(+), 4 deletions(-) + +commit 01702d305786f5d26c101f1fca85363761364243 +Author: Khaled Hosny <khaled@aliftype.com> +Date: Mon Jan 1 13:58:51 2024 +0200 + + Update Codacy Badge [ci skip] + + README.md | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit d455066ad24ff39e74b7a7cb8001ea8bd20caacc +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Dec 25 10:34:23 2023 +0000 + + Bump fonttools from 4.46.0 to 4.47.0 in /.ci + + Bumps [fonttools](https://github.com/fonttools/fonttools) from 4.46.0 to 4.47.0. + - [Release notes](https://github.com/fonttools/fonttools/releases) + - [Changelog](https://github.com/fonttools/fonttools/blob/main/NEWS.rst) + - [Commits](https://github.com/fonttools/fonttools/compare/4.46.0...4.47.0) + + --- + updated-dependencies: + - dependency-name: fonttools + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .ci/requirements-fonttools.txt | 86 +++++++++++++++++++++--------------------- + .ci/requirements.txt | 86 +++++++++++++++++++++--------------------- + 2 files changed, 86 insertions(+), 86 deletions(-) + +commit 74bb1be6e91665fa97c8a531b182325e3c93b0e0 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Dec 25 10:34:08 2023 +0000 + + Bump setuptools from 69.0.2 to 69.0.3 in /.ci + + Bumps [setuptools](https://github.com/pypa/setuptools) from 69.0.2 to 69.0.3. + - [Release notes](https://github.com/pypa/setuptools/releases) + - [Changelog](https://github.com/pypa/setuptools/blob/main/NEWS.rst) + - [Commits](https://github.com/pypa/setuptools/compare/v69.0.2...v69.0.3) + + --- + updated-dependencies: + - dependency-name: setuptools + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .ci/requirements.txt | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit d8a528743757715dec56ee3b91bfc7996774cc65 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Dec 25 10:18:45 2023 +0000 + + Bump github/codeql-action from 3.22.11 to 3.22.12 + + Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.22.11 to 3.22.12. + - [Release notes](https://github.com/github/codeql-action/releases) + - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) + - [Commits](https://github.com/github/codeql-action/compare/b374143c1149a9115d881581d29b8390bbcbb59c...012739e5082ff0c22ca6d6ab32e07c36df03c4a4) + + --- + updated-dependencies: + - dependency-name: github/codeql-action + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/scorecard.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit bb5c7ccb14572ea07e833c1d8dd5e8945238013f +Author: Garret Rieger <grieger@google.com> +Date: Tue Dec 19 20:55:46 2023 +0000 + + Also enforce IFTB requirements during instantiation of gvar. + + src/hb-ot-var-gvar-table.hh | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +commit f3efa6f6e54740214739ba8b00e777111e781882 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Dec 18 10:25:38 2023 +0000 + + Bump github/codeql-action from 2.22.9 to 3.22.11 + + Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.22.9 to 3.22.11. + - [Release notes](https://github.com/github/codeql-action/releases) + - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) + - [Commits](https://github.com/github/codeql-action/compare/c0d1daa7f7e14667747d73a7dbbe8c074bc8bfe2...b374143c1149a9115d881581d29b8390bbcbb59c) + + --- + updated-dependencies: + - dependency-name: github/codeql-action + dependency-type: direct:production + update-type: version-update:semver-major + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/scorecard.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit c853fc28faa2399481412082933694e01d6f92e9 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Dec 18 10:25:46 2023 +0000 + + Bump actions/upload-artifact from 3.1.3 to 4.0.0 + + Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3.1.3 to 4.0.0. + - [Release notes](https://github.com/actions/upload-artifact/releases) + - [Commits](https://github.com/actions/upload-artifact/compare/a8a3f3ad30e3422c9c7b888a15615d19a852ae32...c7d193f32edcb7bfad88892161225aeda64e9392) + + --- + updated-dependencies: + - dependency-name: actions/upload-artifact + dependency-type: direct:production + update-type: version-update:semver-major + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/cifuzz.yml | 2 +- + .github/workflows/msys2-ci.yml | 2 +- + .github/workflows/scorecard.yml | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +commit d80e0974d2e0f8136b6a28ec1b87651e4a179ce8 +Author: Garret Rieger <grieger@google.com> +Date: Fri Dec 15 22:49:46 2023 +0000 + + [repacker] Increase repacker max rounds to 32. + + Found an example font that needs the higher limit. + + src/hb-repacker.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 081cbfd906ff78c940fd629e2515707b1d6b0534 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Fri Dec 15 10:10:18 2023 -0700 + + Fix warnings + + util/test-hb-subset-parsing.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +commit 5b325c0ae9cdd7ca03c002d7cae92a6d17f5111b +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Dec 13 15:27:47 2023 -0700 + + [cff] Fix late sanitize + + Last summer I changed sanitizer->check_struct() to only check + the trailing point of the struct on 64bit machines. This works + mostly because offsets are always positive. + + Not anymore. Recently we introduced negative offsets in CFF, + and this was causing sanitize() for such structs pass while + the struct's leading edge was out of range. + + Fix that. + + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=64859 + + src/hb-ot-cff-common.hh | 16 +++++++++++--- + src/hb-ot-cff1-table.hh | 59 ++++++++++++++++--------------------------------- + src/hb-ot-cff2-table.hh | 31 +++++++++----------------- + 3 files changed, 43 insertions(+), 63 deletions(-) + +commit 74e897117196629f2f736b8053386cbf2e454e11 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Dec 11 10:42:37 2023 +0000 + + Bump github/codeql-action from 2.22.8 to 2.22.9 + + Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.22.8 to 2.22.9. + - [Release notes](https://github.com/github/codeql-action/releases) + - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) + - [Commits](https://github.com/github/codeql-action/compare/407ffafae6a767df3e0230c3df91b6443ae8df75...c0d1daa7f7e14667747d73a7dbbe8c074bc8bfe2) + + --- + updated-dependencies: + - dependency-name: github/codeql-action + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/scorecard.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 2e43c38f6ad09c4ae8701dd5495db9209cf94778 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Dec 11 10:42:31 2023 +0000 + + Bump actions/setup-python from 4.7.1 to 5.0.0 + + Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4.7.1 to 5.0.0. + - [Release notes](https://github.com/actions/setup-python/releases) + - [Commits](https://github.com/actions/setup-python/compare/65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236...0a5c61591373683505ea898e09a3ea4f39ef2b9c) + + --- + updated-dependencies: + - dependency-name: actions/setup-python + dependency-type: direct:production + update-type: version-update:semver-major + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/msvc-ci.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit df735213a8be1b74d08ee4a788a311420ab07666 +Author: Qunxin Liu <48925186+qxliu76@users.noreply.github.com> +Date: Wed Dec 6 09:50:29 2023 -0800 + + [instancer-solver] port solver fix (#4519) + + * [instancer-solver] port solver fix + + from https://github.com/fonttools/fonttools/pull/3374 + + src/hb-subset-instancer-solver.cc | 5 ++++- + src/test-subset-instancer-solver.cc | 18 ++++++++++++------ + ....abc.default.retain-all-codepoint.wght=500-800.ttf | Bin 7288 -> 7296 bytes + 3 files changed, 16 insertions(+), 7 deletions(-) + +commit bf84135edda601fdead430b231a9ce50d38837d2 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Dec 5 11:58:21 2023 -0500 + + [cff] Support negative offsets + + Fixes https://github.com/harfbuzz/harfbuzz/issues/4508 + + src/hb-cff-interp-dict-common.hh | 8 ++++---- + src/hb-ot-cff-common.hh | 7 ++++--- + src/hb-ot-cff1-table.hh | 30 +++++++++++++++--------------- + src/hb-ot-cff2-table.hh | 16 ++++++++-------- + 4 files changed, 31 insertions(+), 30 deletions(-) + +commit 7160c5b9e5d932d376bfe8dc29c11a4fd970a893 +Author: Garret Rieger <grieger@google.com> +Date: Tue Dec 5 20:58:00 2023 +0000 + + [repacker] add tests for multi-duplication. + + Further improve the resolution attempt by pre-emptively raising priority of a duplicated shared node. + + src/graph/graph.hh | 11 ++++++++++- + src/hb-repacker.hh | 19 ++++++++++++++++++- + src/test-repacker.cc | 41 +++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 69 insertions(+), 2 deletions(-) + +commit 6f64fa75e3741b040e3d00c4434b00be0dd6a3dd +Author: Garret Rieger <grieger@google.com> +Date: Tue Dec 5 19:45:16 2023 +0000 + + [repacker] improve resolution of overflows to shared nodes. + + Prior to this change overflows to shared nodes were handled by duplicating the link from only a single parent on each iteration. However, I've encountered fonts where there is a large number of parents sharing a single child. Using the prior strategy requires large number of overflow resolution iterations to resolve overflows. This changes shared overflow resolution to duplicate the shared child and re-assign multiple overflowing parents in a single iteration. This reduces total packing size in these cases and allows resolution to complete in far fewer iterations. + + src/graph/graph.hh | 87 +++++++++++++++++++++++++++++++++++++++++++++++++----- + src/hb-repacker.hh | 33 ++++++++++++++++++++- + 2 files changed, 112 insertions(+), 8 deletions(-) + +commit 13519b8999995d31a85b740f7ab27fc59b3e9839 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Dec 5 11:45:06 2023 -0500 + + [editorconfig] Make nvim happy + + .editorconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 0d9f497974b3551a178032add065d3cde907141b +Author: utelle <ulrich.telle@gmx.de> +Date: Mon Dec 4 21:25:02 2023 +0100 + + Adjust function hb_blob_create_from_file_or_fail + + On Windows the filename will be interpreted as UTF-8. + If the filename is NOT valid UTF-8, it will be interpreted according to the system codepage. + + src/hb-blob.cc | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +commit ce0a46f24ce8b83bd1fb96d548fbeb66cca8c32a +Merge: 7dbc84220 773a0c709 +Author: خالد حسني (Khaled Hosny) <khaled@aliftype.com> +Date: Mon Dec 4 18:48:58 2023 +0000 + + Merge pull request #4512 from pseiderer/ps-devel-fix-meson-has-function-detection-001 + + [meson] has_function detection needs suitable includes + +commit 7dbc84220afef4aa455b44a55a8ebed544722aef +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Dec 4 10:31:20 2023 +0000 + + Bump fonttools from 4.45.1 to 4.46.0 in /.ci + + Bumps [fonttools](https://github.com/fonttools/fonttools) from 4.45.1 to 4.46.0. + - [Release notes](https://github.com/fonttools/fonttools/releases) + - [Changelog](https://github.com/fonttools/fonttools/blob/main/NEWS.rst) + - [Commits](https://github.com/fonttools/fonttools/compare/4.45.1...4.46.0) + + --- + updated-dependencies: + - dependency-name: fonttools + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .ci/requirements-fonttools.txt | 86 +++++++++++++++++++++--------------------- + .ci/requirements.txt | 86 +++++++++++++++++++++--------------------- + 2 files changed, 86 insertions(+), 86 deletions(-) + +commit 773a0c70933eb895d6d732237116f957ffe8cee1 +Author: Peter Seiderer <ps.report@gmx.net> +Date: Mon Dec 4 10:32:48 2023 +0100 + + [meson] has_function detection needs suitable includes + + - fix meson has_function() detection, needs suitable include to avoid + false positive (see [1] for details) + + [1] https://github.com/mesonbuild/meson/issues/7652 + + Closes #4266 + + Signed-off-by: Peter Seiderer <ps.report@gmx.net> + + meson.build | 23 ++++++++++++----------- + 1 file changed, 12 insertions(+), 11 deletions(-) + +commit 85c9eac2a59b02aac6221689e3503c737b6dd001 +Merge: d7c4fdfaa 5e9710ffc +Author: خالد حسني (Khaled Hosny) <khaled@aliftype.com> +Date: Sat Dec 2 07:30:14 2023 +0000 + + Merge pull request #4507 from fanc999-1/cmake-improvements + + Improve CMake builds + +commit 5e9710ffc0c6bd1975107c498ea81662cc2f7fb4 +Author: Chun-wei Fan <fanchunwei@src.gnome.org> +Date: Thu Nov 30 17:42:46 2023 +0800 + + CMake: Update introspection cflags + + Make the flags between --cflags-[begin|end] correspond to the ones used in the + Meson builds better. + + CMakeLists.txt | 10 ++-------- + 1 file changed, 2 insertions(+), 8 deletions(-) + +commit ea526c3dcbf66955aba701d2e34bd2ec5782402e +Author: Chun-wei Fan <fanchunwei@src.gnome.org> +Date: Thu Nov 30 17:35:04 2023 +0800 + + CMake: Generate and install hb-features.h + + By the features that are enabled for the build. The header is installed unless + one chooses not to install it + + CMakeLists.txt | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +commit 86fd6b10c48a1b635067ee0cc35e253bda0bcf0f +Author: Chun-wei Fan <fanchunwei@src.gnome.org> +Date: Thu Nov 30 16:39:10 2023 +0800 + + CMake: Build the hb-info utility program + + ...if GObject support is enabled. + + CMakeLists.txt | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +commit d112ed40fcd0eb75ae68f05a0775e6426ebf4104 +Author: Chun-wei Fan <fanchunwei@src.gnome.org> +Date: Thu Nov 30 16:14:19 2023 +0800 + + CMake: Install hb-subset-repacker.h + + It ought to be installed. + + CMakeLists.txt | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 1d86b844df9408efdf198c1bf230c717f07f195e +Author: Chun-wei Fan <fanchunwei@src.gnome.org> +Date: Thu Nov 30 16:05:51 2023 +0800 + + CMake: Build libharfbuzz-cairo and fix hb-view build + + There is now a separate library that we build if Cairo support is enabled, + which will also be used to build hb-view, so we: + + * Add support in the CMake build files to build libharfbuzz-cairo, if enabled + via HB_HAVE_CAIRO. Move the Cairo detection bits around as a result. + * Generate pkg-config file for libharfbuzz-cairo, and add 'cairo' to + Requires.private. + * Fix building hb-view, which will now depend on libharfbuzz-cairo, so Cairo + support must be explicitly enabled. + * Stop depending automatically on Cairo if HB_BUILD_UTILS is enabled unless + Cairo support is enabled as a result. + + CMakeLists.txt | 63 ++++++++++++++++++++++++++++++++++++------------ + src/harfbuzz-cairo.pc.in | 1 + + 2 files changed, 49 insertions(+), 15 deletions(-) + +commit d7c4fdfaa2ed5e44dc5c01cd30c0ddc19ff78fdf +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Nov 27 10:18:20 2023 +0000 + + Bump setuptools from 68.2.2 to 69.0.2 in /.ci + + Bumps [setuptools](https://github.com/pypa/setuptools) from 68.2.2 to 69.0.2. + - [Release notes](https://github.com/pypa/setuptools/releases) + - [Changelog](https://github.com/pypa/setuptools/blob/main/NEWS.rst) + - [Commits](https://github.com/pypa/setuptools/compare/v68.2.2...v69.0.2) + + --- + updated-dependencies: + - dependency-name: setuptools + dependency-type: direct:production + update-type: version-update:semver-major + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .ci/requirements.txt | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 8e1fd02fdb70b05141909c4ff6cc8455c197747c +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Nov 27 10:18:06 2023 +0000 + + Bump fonttools from 4.44.3 to 4.45.1 in /.ci + + Bumps [fonttools](https://github.com/fonttools/fonttools) from 4.44.3 to 4.45.1. + - [Release notes](https://github.com/fonttools/fonttools/releases) + - [Changelog](https://github.com/fonttools/fonttools/blob/main/NEWS.rst) + - [Commits](https://github.com/fonttools/fonttools/compare/4.44.3...4.45.1) + + --- + updated-dependencies: + - dependency-name: fonttools + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .ci/requirements-fonttools.txt | 86 +++++++++++++++++++++--------------------- + .ci/requirements.txt | 86 +++++++++++++++++++++--------------------- + 2 files changed, 86 insertions(+), 86 deletions(-) + +commit d970b8a32702ea6da3d126bf92754057d192c92f +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Nov 27 10:10:23 2023 +0000 + + Bump github/codeql-action from 2.22.7 to 2.22.8 + + Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.22.7 to 2.22.8. + - [Release notes](https://github.com/github/codeql-action/releases) + - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) + - [Commits](https://github.com/github/codeql-action/compare/66b90a5db151a8042fa97405c6cf843bbe433f7b...407ffafae6a767df3e0230c3df91b6443ae8df75) + + --- + updated-dependencies: + - dependency-name: github/codeql-action + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/scorecard.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 258f2a27829a9abc36369f89b3cf432b4086a10b +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Nov 20 10:24:19 2023 +0000 + + Bump meson from 1.2.3 to 1.3.0 in /.ci + + Bumps [meson](https://github.com/mesonbuild/meson) from 1.2.3 to 1.3.0. + - [Release notes](https://github.com/mesonbuild/meson/releases) + - [Commits](https://github.com/mesonbuild/meson/compare/1.2.3...1.3.0) + + --- + updated-dependencies: + - dependency-name: meson + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .ci/requirements.in | 2 +- + .ci/requirements.txt | 6 +++--- + 2 files changed, 4 insertions(+), 4 deletions(-) + +commit bec9fa702dfeaac9469208f70fa3bfd3ffd32f68 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Nov 20 10:24:36 2023 +0000 + + Bump fonttools from 4.44.0 to 4.44.3 in /.ci + + Bumps [fonttools](https://github.com/fonttools/fonttools) from 4.44.0 to 4.44.3. + - [Release notes](https://github.com/fonttools/fonttools/releases) + - [Changelog](https://github.com/fonttools/fonttools/blob/main/NEWS.rst) + - [Commits](https://github.com/fonttools/fonttools/compare/4.44.0...4.44.3) + + --- + updated-dependencies: + - dependency-name: fonttools + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .ci/requirements-fonttools.txt | 86 +++++++++++++++++++++--------------------- + .ci/requirements.txt | 86 +++++++++++++++++++++--------------------- + 2 files changed, 86 insertions(+), 86 deletions(-) + +commit 16dc7338416be7e88bcb67147852ff405bf634f7 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Nov 20 10:51:58 2023 +0000 + + Bump github/codeql-action from 2.22.5 to 2.22.7 + + Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.22.5 to 2.22.7. + - [Release notes](https://github.com/github/codeql-action/releases) + - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) + - [Commits](https://github.com/github/codeql-action/compare/74483a38d39275f33fcff5f35b679b5ca4a26a99...66b90a5db151a8042fa97405c6cf843bbe433f7b) + + --- + updated-dependencies: + - dependency-name: github/codeql-action + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/scorecard.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit df635ab78ae1d397396e3a0fe688b8a4674b2e8a +Merge: f1ac36ba7 66a404cad +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Nov 15 14:55:11 2023 -0700 + + Merge pull request #4473 from googlefonts/help + + [instancer] add the option to leave blanks in the min:def:max syntax. + +commit 66a404cad4c5bf4a39241fe6ceb702aa9fddc56c +Author: Garret Rieger <grieger@google.com> +Date: Wed Nov 15 21:41:30 2023 +0000 + + [subset] Fix hb_subset_input_get_axis_range documentation. + + src/hb-subset-input.cc | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +commit ffa643c5aabe36c3fbf922852258dd45a01010e4 +Author: Garret Rieger <grieger@google.com> +Date: Wed Nov 15 21:36:02 2023 +0000 + + [subset] Add helper-subset.hh to Makefile sources. + + util/Makefile.sources | 1 + + util/helper-subset.hh | 1 + + 2 files changed, 2 insertions(+) + +commit 0dd7a47621bf41c6762c80d143c15cdc4a751608 +Author: Garret Rieger <grieger@google.com> +Date: Wed Nov 15 21:23:06 2023 +0000 + + Add hb_subset_input_get_axis_range to docs. + + docs/harfbuzz-sections.txt | 1 + + 1 file changed, 1 insertion(+) + +commit 15a3889ee1c588804de1bbd12fbffd41448200a4 +Author: Garret Rieger <grieger@google.com> +Date: Wed Nov 15 21:13:59 2023 +0000 + + Add hb_subset_input_get_axis_range to experimental symbols list. + + src/gen-def.py | 1 + + 1 file changed, 1 insertion(+) + +commit f1ac36ba7f0950c67c3f362a8fca75013bce541a +Author: Qunxin Liu <qxliu@google.com> +Date: Wed Nov 15 11:38:41 2023 -0800 + + [instancer] update hhea vertical metrics with OS/2 ones + + src/hb-ot-hmtx-table.hh | 23 +++++++++++++++++++++ + ...point.SPED=25,YEXT=520,wght=100-400,slnt=18.ttf | Bin 0 -> 2184 bytes + test/subset/data/fonts/playwrite_mm.subset.ttf | Bin 0 -> 6260 bytes + test/subset/data/tests/sync_vmetrics.tests | 11 ++++++++++ + test/subset/meson.build | 3 ++- + 5 files changed, 36 insertions(+), 1 deletion(-) + +commit d30c1dacf5bfc9f48cc4181e208a5c0d509d5c2d +Author: Garret Rieger <grieger@google.com> +Date: Wed Nov 15 20:16:07 2023 +0000 + + Add test suite for instancing option parsing. + + src/hb-subset-input.cc | 32 +++++++ + src/hb-subset.h | 7 ++ + util/hb-subset.cc | 159 +-------------------------------- + util/helper-subset.hh | 202 ++++++++++++++++++++++++++++++++++++++++++ + util/meson.build | 16 ++++ + util/test-hb-subset-parsing.c | 98 ++++++++++++++++++++ + 6 files changed, 357 insertions(+), 157 deletions(-) + +commit 43236ce34530b0a661382187b6fcf520a13d4add +Author: Garret Rieger <grieger@google.com> +Date: Wed Nov 1 22:34:39 2023 +0000 + + [instancer] add the option to leave blanks in the min:def:max syntax. + + When parsing axis positions in the --variations flag recognize empty values as meaning the existing value for that part. For example: + + :300:500 + + Specifies min = existing, def = 300, max = 500. + + See: https://github.com/fonttools/fonttools/issues/3322 + + src/hb-subset-input.cc | 30 ++++---- + src/hb-subset.h | 2 +- + util/hb-subset.cc | 198 +++++++++++++++++++++++++++++++------------------ + 3 files changed, 141 insertions(+), 89 deletions(-) + +commit 6a3ca373735f88d7f6140b8a4288e5c136cc4def +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Nov 13 16:36:32 2023 -0700 + + [map] Optimize storage + + Such that population isn't a bitfield as we access it often. + + src/hb-map.hh | 15 ++++++--------- + 1 file changed, 6 insertions(+), 9 deletions(-) + commit 894a1f72ee93a1fd8dc1d9218cb3fd8f048be29a Author: Khaled Hosny <khaled@aliftype.com> Date: Sat Nov 11 15:57:54 2023 +0200 @@ -58453,9 +60555,7 @@ Date: Thu Aug 12 11:11:51 2021 -0700 ..._anchors_1.notdef-outline-retain-gids.41,42,43.otf | Bin 1996 -> 0 bytes ...ple_anchors_1.notdef-outline-retain-gids.41,43.otf | Bin 2000 -> 0 bytes ..._multiple_anchors_1.notdef-outline.41,42,43,44.otf | Bin 1492 -> 0 bytes - ..._multiple_anchors_1.notdef-outline.41,42,43,45.otf | Bin 1488 -> 0 bytes ...os4_multiple_anchors_1.notdef-outline.41,42,43.otf | Bin 1284 -> 0 bytes - ...os4_multiple_anchors_1.notdef-outline.41,43,45.otf | Bin 1488 -> 0 bytes .../gpos4_multiple_anchors_1.notdef-outline.41,43.otf | Bin 1280 -> 0 bytes ...os5_font1.layout-test-retain-gids.41,42,43,44.otf} | Bin 2224 -> 2360 bytes ...os5_font1.layout-test-retain-gids.41,42,43,45.otf} | Bin 2220 -> 2356 bytes @@ -58468,7 +60568,7 @@ Date: Thu Aug 12 11:11:51 2021 -0700 ...otf => gpos5_font1.layout-test-retain-gids.42.otf} | Bin ....layout-test-retain-gids.retain-all-codepoint.otf} | Bin 3860 -> 4064 bytes ...44.otf => gpos5_font1.layout-test.41,42,43,44.otf} | Bin 1508 -> 1644 bytes - .../gpos5_font1.layout-test.41,42,43,45.otf | Bin 0 -> 1624 bytes + .../gpos5_font1.layout-test.41,42,43,45.otf} | Bin 1488 -> 1624 bytes .../layout.gpos5/gpos5_font1.layout-test.41,42,43.otf | Bin 0 -> 1408 bytes ...42,44.otf => gpos5_font1.layout-test.41,42,44.otf} | Bin 1420 -> 1552 bytes .../layout.gpos5/gpos5_font1.layout-test.41,42,45.otf | Bin 0 -> 1524 bytes @@ -58501,7 +60601,7 @@ Date: Thu Aug 12 11:11:51 2021 -0700 ...ne.41,42.otf => gpos6_font1.layout-test.41,42.otf} | Bin ...otf => gpos6_font1.layout-test.41,43,44,45,46.otf} | Bin 1808 -> 1940 bytes .../gpos6_font1.layout-test.41,43,44.otf} | Bin 1492 -> 1580 bytes - .../layout.gpos6/gpos6_font1.layout-test.41,43,45.otf | Bin 0 -> 1568 bytes + .../gpos6_font1.layout-test.41,43,45.otf} | Bin 1488 -> 1568 bytes .../layout.gpos6/gpos6_font1.layout-test.41,43.otf | Bin 0 -> 1348 bytes ...-outline.41.otf => gpos6_font1.layout-test.41.otf} | Bin ... gpos6_font1.layout-test.retain-all-codepoint.otf} | Bin 3820 -> 3972 bytes @@ -58516,28 +60616,23 @@ Date: Thu Aug 12 11:11:51 2021 -0700 ...ubrules_f1.layout-test-retain-gids.30,31,32,33.otf | Bin 0 -> 2400 bytes ..._subrules_f1.layout-test-retain-gids.41,42,43.otf} | Bin ...1.layout-test-retain-gids.retain-all-codepoint.otf | Bin 0 -> 4012 bytes - ...1_multiple_subrules_f1.layout-test.30,31,32,33.otf | Bin 0 -> 1928 bytes + ..._multiple_subrules_f1.layout-test.30,31,32,33.otf} | Bin 1820 -> 1928 bytes ...ng1_multiple_subrules_f1.layout-test.41,42,43.otf} | Bin ...e_subrules_f1.layout-test.retain-all-codepoint.otf | Bin 0 -> 4012 bytes ...ules_f1.notdef-outline-retain-gids.30,31,32,33.otf | Bin 2292 -> 0 bytes - ...ultiple_subrules_f1.notdef-outline.30,31,32,33.otf | Bin 1820 -> 0 bytes ...ubrules_f1.layout-test-retain-gids.30,31,32,33.otf | Bin 0 -> 2420 bytes ..._subrules_f1.layout-test-retain-gids.41,42,43.otf} | Bin ...1.layout-test-retain-gids.retain-all-codepoint.otf | Bin 0 -> 4044 bytes ...2_multiple_subrules_f1.layout-test.30,31,32,33.otf | Bin 0 -> 1948 bytes ...ng2_multiple_subrules_f1.layout-test.41,42,43.otf} | Bin ...e_subrules_f1.layout-test.retain-all-codepoint.otf | Bin 0 -> 4044 bytes - ...ules_f1.notdef-outline-retain-gids.30,31,32,33.otf | Bin 2292 -> 0 bytes - ...ultiple_subrules_f1.notdef-outline.30,31,32,33.otf | Bin 1820 -> 0 bytes - ..._simple_f1.layout-test-retain-gids.30,31,32,33.otf | Bin 0 -> 2392 bytes + ...simple_f1.layout-test-retain-gids.30,31,32,33.otf} | Bin 2292 -> 2392 bytes ...g3_simple_f1.layout-test-retain-gids.41,42,43.otf} | Bin ...1.layout-test-retain-gids.retain-all-codepoint.otf | Bin 0 -> 3980 bytes - ...os_chaining3_simple_f1.layout-test.30,31,32,33.otf | Bin 0 -> 1920 bytes + ...s_chaining3_simple_f1.layout-test.30,31,32,33.otf} | Bin 1820 -> 1920 bytes ...gpos_chaining3_simple_f1.layout-test.41,42,43.otf} | Bin ...ng3_simple_f1.layout-test.retain-all-codepoint.otf | Bin 0 -> 3980 bytes - ...mple_f1.notdef-outline-retain-gids.30,31,32,33.otf | Bin 2268 -> 0 bytes ...otdef-outline-retain-gids.retain-all-codepoint.otf | Bin 3856 -> 0 bytes - ...chaining3_simple_f1.notdef-outline.30,31,32,33.otf | Bin 1796 -> 0 bytes ..._simple_f1.notdef-outline.retain-all-codepoint.otf | Bin 3856 -> 0 bytes .../gpos9_font2.layout-test-retain-gids.41,42.otf | Bin 0 -> 1960 bytes ...otf => gpos9_font2.layout-test-retain-gids.41.otf} | Bin 1852 -> 1920 bytes @@ -58547,17 +60642,15 @@ Date: Thu Aug 12 11:11:51 2021 -0700 ...-outline.42.otf => gpos9_font2.layout-test.42.otf} | Bin 1008 -> 1076 bytes .../gpos9_font2.notdef-outline-retain-gids.41,42.otf | Bin 1868 -> 0 bytes .../layout.gpos9/gpos9_font2.notdef-outline.41,42.otf | Bin 1160 -> 0 bytes - .../gsub_alternate_substitution.default.53A9.otf | Bin 3884 -> 0 bytes .../gsub_alternate_substitution.default.53F1.otf | Bin 2440 -> 0 bytes ...ubstitution.layout-test-retain-gids.53A9,53F1.otf} | Bin 4440 -> 5076 bytes - ...nate_substitution.layout-test-retain-gids.53A9.otf | Bin 0 -> 4656 bytes + ...ate_substitution.layout-test-retain-gids.53A9.otf} | Bin 4036 -> 4656 bytes ...nate_substitution.layout-test-retain-gids.53F1.otf | Bin 0 -> 2996 bytes ....layout-test-retain-gids.retain-all-codepoint.otf} | Bin 6076 -> 6764 bytes ..._alternate_substitution.layout-test.53A9,53F1.otf} | Bin 4316 -> 4952 bytes - .../gsub_alternate_substitution.layout-test.53A9.otf | Bin 0 -> 4504 bytes + ... gsub_alternate_substitution.layout-test.53A9.otf} | Bin 3884 -> 4504 bytes .../gsub_alternate_substitution.layout-test.53F1.otf | Bin 0 -> 2804 bytes ...substitution.layout-test.retain-all-codepoint.otf} | Bin 5984 -> 6672 bytes - .../gsub_alternate_substitution.retain-gids.53A9.otf | Bin 4036 -> 0 bytes .../gsub_alternate_substitution.retain-gids.53F1.otf | Bin 2632 -> 0 bytes ...e_subrules_f2.layout-test-retain-gids.41,42,43.otf | Bin 0 -> 2236 bytes ...iple_subrules_f2.layout-test-retain-gids.41,42.otf | Bin 0 -> 2208 bytes @@ -58618,10 +60711,10 @@ Date: Thu Aug 12 11:11:51 2021 -0700 ...otdef-outline-retain-gids.retain-all-codepoint.otf | Bin 3892 -> 0 bytes ...ultiple_subrules_f1.notdef-outline.30,31,32,33.otf | Bin 1832 -> 0 bytes ...ubrules_f1.notdef-outline.retain-all-codepoint.otf | Bin 3892 -> 0 bytes - ..._simple_f2.layout-test-retain-gids.30,31,32,33.otf | Bin 0 -> 2360 bytes + ...simple_f2.layout-test-retain-gids.30,31,32,33.otf} | Bin 2268 -> 2360 bytes ...g3_simple_f2.layout-test-retain-gids.41,42,43.otf} | Bin ....layout-test-retain-gids.retain-all-codepoint.otf} | Bin 3812 -> 3952 bytes - ...ub_chaining3_simple_f2.layout-test.30,31,32,33.otf | Bin 0 -> 1888 bytes + ...b_chaining3_simple_f2.layout-test.30,31,32,33.otf} | Bin 1796 -> 1888 bytes ...gsub_chaining3_simple_f2.layout-test.41,42,43.otf} | Bin ...g3_simple_f2.layout-test.retain-all-codepoint.otf} | Bin 3812 -> 3952 bytes ...mple_f2.notdef-outline-retain-gids.30,31,32,33.otf | Bin 2280 -> 0 bytes @@ -58668,7 +60761,7 @@ Date: Thu Aug 12 11:11:51 2021 -0700 test/subset/data/tests/layout.gsub5.tests | 4 ++-- test/subset/data/tests/layout.gsub6.tests | 4 ++-- test/subset/data/tests/layout.gsub8.tests | 4 ++-- - 340 files changed, 33 insertions(+), 28 deletions(-) + 331 files changed, 33 insertions(+), 28 deletions(-) commit 7620da0f2b2ec83db401f598c1e1ab22c0cfa91d Merge: c0f3af91b ccc2a1921 @@ -62853,7 +64946,7 @@ Date: Wed Aug 4 11:38:38 2021 -0700 .../Roboto-Regular.keep-gdef-gpos.41,42,43.ttf | Bin 2568 -> 2532 bytes ...os1_2_font.notdef-outline-retain-gids.41,43.otf | Bin 0 -> 1980 bytes ...s1_2_font.notdef-outline-retain-gids.41,46.otf} | Bin 2188 -> 2140 bytes - ...gpos1_2_font.notdef-outline-retain-gids.41.otf} | Bin 1888 -> 1856 bytes + ...gpos1_2_font.notdef-outline-retain-gids.41.otf} | Bin 1892 -> 1856 bytes ...s1_2_font.notdef-outline-retain-gids.42,44.otf} | Bin 2012 -> 1964 bytes ...s1_2_font.notdef-outline-retain-gids.43,46.otf} | Bin 2052 -> 2004 bytes ...f-outline-retain-gids.retain-all-codepoint.otf} | Bin 3816 -> 3780 bytes @@ -62872,7 +64965,7 @@ Date: Wed Aug 4 11:38:38 2021 -0700 ...f => gpos2_1_font7.notdef-outline.21,23,25.otf} | Bin 1372 -> 1312 bytes ....otf => gpos2_1_font7.notdef-outline.21,23.otf} | Bin 1252 -> 1204 bytes ....otf => gpos2_1_font7.notdef-outline.2E,23.otf} | Bin 1524 -> 1476 bytes - .../gpos2_1_font7.notdef-outline.41,42,43.otf} | Bin 1296 -> 1264 bytes + ...f => gpos2_1_font7.notdef-outline.41,42,43.otf} | Bin 1300 -> 1264 bytes ..._font7.notdef-outline.retain-all-codepoint.otf} | Bin 3816 -> 3780 bytes ..._font5.notdef-outline-retain-gids.21,23,25.otf} | Bin 1716 -> 1656 bytes ...2_2_font5.notdef-outline-retain-gids.21,23.otf} | Bin 1580 -> 1532 bytes @@ -62892,7 +64985,7 @@ Date: Wed Aug 4 11:38:38 2021 -0700 ...29.otf => gpos3_font3.notdef-outline.28,29.otf} | Bin 1260 -> 1224 bytes ...2B.otf => gpos3_font3.notdef-outline.28,2B.otf} | Bin 1392 -> 1344 bytes ...2B.otf => gpos3_font3.notdef-outline.29,2B.otf} | Bin 1304 -> 1256 bytes - .../gpos3_font3.notdef-outline.41,42,43.otf} | Bin 1300 -> 1260 bytes + .../gpos3_font3.notdef-outline.41,42,43.otf | Bin 0 -> 1260 bytes ..._font3.notdef-outline.retain-all-codepoint.otf} | Bin 3848 -> 3812 bytes .../gpos4_multiple_anchors_1.default.41,42,43.otf | Bin 1320 -> 0 bytes .../gpos4_multiple_anchors_1.default.41.otf | Bin 1208 -> 0 bytes @@ -62904,15 +64997,15 @@ Date: Wed Aug 4 11:38:38 2021 -0700 ...hors_1.notdef-outline-retain-gids.41,43,44.otf} | Bin 2240 -> 2216 bytes ...hors_1.notdef-outline-retain-gids.41,43,45.otf} | Bin 2260 -> 2224 bytes ..._anchors_1.notdef-outline-retain-gids.41,43.otf | Bin 0 -> 2000 bytes - ...le_anchors_1.notdef-outline-retain-gids.41.otf} | Bin 1892 -> 1876 bytes + ...le_anchors_1.notdef-outline-retain-gids.41.otf} | Bin 1888 -> 1876 bytes ...f-outline-retain-gids.retain-all-codepoint.otf} | Bin 3880 -> 3844 bytes ...tiple_anchors_1.notdef-outline.41,42,43,44.otf} | Bin 1504 -> 1492 bytes ...tiple_anchors_1.notdef-outline.41,42,43,45.otf} | Bin 1512 -> 1488 bytes - ..._multiple_anchors_1.notdef-outline.41,42,43.otf | Bin 0 -> 1284 bytes + ...multiple_anchors_1.notdef-outline.41,42,43.otf} | Bin 1296 -> 1284 bytes ...s4_multiple_anchors_1.notdef-outline.41,42.otf} | Bin 1196 -> 1184 bytes ...le_anchors_1.notdef-outline.41,43,44,45,46.otf} | Bin 1856 -> 1832 bytes ...multiple_anchors_1.notdef-outline.41,43,44.otf} | Bin 1516 -> 1492 bytes - ...multiple_anchors_1.notdef-outline.41,43,45.otf} | Bin 1524 -> 1488 bytes + ...multiple_anchors_1.notdef-outline.41,43,45.otf} | Bin 1548 -> 1488 bytes ...s4_multiple_anchors_1.notdef-outline.41,43.otf} | Bin 1328 -> 1280 bytes ...gpos4_multiple_anchors_1.notdef-outline.41.otf} | Bin 1188 -> 1172 bytes ...hors_1.notdef-outline.retain-all-codepoint.otf} | Bin 3880 -> 3844 bytes @@ -62957,7 +65050,7 @@ Date: Wed Aug 4 11:38:38 2021 -0700 .../gpos6_font1.notdef-outline.41,42.otf} | Bin 1220 -> 1160 bytes .../gpos6_font1.notdef-outline.41,43,44,45,46.otf} | Bin 1880 -> 1808 bytes .../gpos6_font1.notdef-outline.41,43,44.otf} | Bin 1540 -> 1468 bytes - .../gpos6_font1.notdef-outline.41,43,45.otf} | Bin 1548 -> 1464 bytes + ...otf => gpos6_font1.notdef-outline.41,43,45.otf} | Bin 1524 -> 1464 bytes .../gpos6_font1.notdef-outline.41,43.otf} | Bin 1328 -> 1256 bytes .../gpos6_font1.notdef-outline.41.otf} | Bin 1208 -> 1148 bytes ..._font1.notdef-outline.retain-all-codepoint.otf} | Bin 3856 -> 3820 bytes diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/NEWS b/Build/source/libs/harfbuzz/harfbuzz-src/NEWS index 386a1067367..2d6a4a7d6bf 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/NEWS +++ b/Build/source/libs/harfbuzz/harfbuzz-src/NEWS @@ -1,3 +1,25 @@ +Overview of changes leading to 8.3.1 +Saturday, March 16, 2024 +==================================== +- hb_blob_create_from_file_or_fail() on Windows will now try to interpret the + file name as UTF-8 first, and as system code page if it is not valid UTF-8. +- Fix hb_style_get_value() in fonts with “STAT” table. +- Properly handle negative offsets in CFF table. +- Update IANA Language Subtag Registry to 2024-03-07. +- Subsetter now supports subsetting “BASE” table. +- Subsetter will update “hhea” font metrics in sync with “OS/2” ones. +- “--variations” option of “hb-subset” now supports leaving out values that + should be unchanged, e.g. “wght=:500:” will change the default and keep max + and min unchanged. It also supports “*=drop” to to pin all axes to default + location. +- Fix hb_ot_math_get_glyph_kerning() to match updated “MATH” table spec. +- Support legacy MacRoman encoding in “cmap” table. +- Various build fixes. +- Various subsetting and instancing fixes. + +- New API: +hb_subset_input_pin_all_axes_to_default() + Overview of changes leading to 8.3.0 Saturday, November 11, 2023 ==================================== @@ -191,7 +213,7 @@ Saturday, February 11, 2023 ==================================== - New hb-paint API that is designed mainly to paint “COLRv1” glyphs, but can be also used as a unified API to paint any of the glyph representations - supported by HarfBuzz (B/W outlines, color layers, or color bitmaps). + supported by HarfBuzz (B/W outlines, color layers, or color bitmaps). (Behdad Esfahbod, Matthias Clasen) - New hb-cairo API for integrating with cairo graphics library. This is provided as a separate harfbuzz-cairo library. (Behdad Esfahbod, Matthias Clasen) @@ -202,7 +224,7 @@ Saturday, February 11, 2023 https://github.com/harfbuzz/boring-expansion-spec/blob/main/glyf1-cubicOutlines.md for spec. (Behdad Esfahbod) - Various subsetter improvements. (Garret Rieger, Qunxin Liu, Behdad Esfahbod) -- Various documentation improvements. +- Various documentation improvements. (Behdad Esfahbod, Matthias Clasen, Khaled Hosny) - Significantly reduced memory use during shaping. (Behdad Esfahbod) - Greatly reduced memory use during subsetting “CFF” table. (Behdad Esfahbod) @@ -946,7 +968,7 @@ Tuesday, March 16, 2021 Previously these were shaped using the generalized Arabic shaper. (David Corbett) - Fix regression in shaping of U+0B55 ORIYA SIGN OVERLINE. (David Corbett) - Update language tags. (David Corbett) -- Variations: reduce error: do not round each interpolated delta. (Just van Rossum) +- Variations: reduce error: do not round each interpolated delta. (Just van Rossum) - Documentation improvements. (Khaled Hosny, Nathan Willis) - Subsetter improvements: subsets most, if not all, lookup types now. (Garret Rieger, Qunxin Liu) - Fuzzer-found fixes and other improvements when memory failures happen. (Behdad) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/README b/Build/source/libs/harfbuzz/harfbuzz-src/README index 33165091a8b..d11c489f100 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/README +++ b/Build/source/libs/harfbuzz/harfbuzz-src/README @@ -2,7 +2,7 @@ [![CircleCI Build Status](https://circleci.com/gh/harfbuzz/harfbuzz/tree/main.svg?style=svg)](https://circleci.com/gh/harfbuzz/harfbuzz/tree/main) [![OSS-Fuzz Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/harfbuzz.svg)](https://oss-fuzz-build-logs.storage.googleapis.com/index.html) [![Coverity Scan Build Status](https://scan.coverity.com/projects/15166/badge.svg)](https://scan.coverity.com/projects/harfbuzz) -[![Codacy Badge](https://app.codacy.com/project/badge/Grade/89c872f5ce1c42af802602bfcd15d90a)](https://www.codacy.com/gh/harfbuzz/harfbuzz/dashboard?utm_source=github.com&utm_medium=referral&utm_content=harfbuzz/harfbuzz&utm_campaign=Badge_Grade) +[![Codacy Badge](https://app.codacy.com/project/badge/Grade/89c872f5ce1c42af802602bfcd15d90a)](https://app.codacy.com/gh/harfbuzz/harfbuzz/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) [![Codecov Code Coverage](https://codecov.io/gh/harfbuzz/harfbuzz/branch/main/graph/badge.svg)](https://codecov.io/gh/harfbuzz/harfbuzz) [![Packaging status](https://repology.org/badge/tiny-repos/harfbuzz.svg)](https://repology.org/project/harfbuzz/versions) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/harfbuzz/harfbuzz/badge)](https://securityscorecards.dev/viewer/?uri=github.com/harfbuzz/harfbuzz) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/README.md b/Build/source/libs/harfbuzz/harfbuzz-src/README.md index 33165091a8b..d11c489f100 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/README.md +++ b/Build/source/libs/harfbuzz/harfbuzz-src/README.md @@ -2,7 +2,7 @@ [![CircleCI Build Status](https://circleci.com/gh/harfbuzz/harfbuzz/tree/main.svg?style=svg)](https://circleci.com/gh/harfbuzz/harfbuzz/tree/main) [![OSS-Fuzz Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/harfbuzz.svg)](https://oss-fuzz-build-logs.storage.googleapis.com/index.html) [![Coverity Scan Build Status](https://scan.coverity.com/projects/15166/badge.svg)](https://scan.coverity.com/projects/harfbuzz) -[![Codacy Badge](https://app.codacy.com/project/badge/Grade/89c872f5ce1c42af802602bfcd15d90a)](https://www.codacy.com/gh/harfbuzz/harfbuzz/dashboard?utm_source=github.com&utm_medium=referral&utm_content=harfbuzz/harfbuzz&utm_campaign=Badge_Grade) +[![Codacy Badge](https://app.codacy.com/project/badge/Grade/89c872f5ce1c42af802602bfcd15d90a)](https://app.codacy.com/gh/harfbuzz/harfbuzz/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) [![Codecov Code Coverage](https://codecov.io/gh/harfbuzz/harfbuzz/branch/main/graph/badge.svg)](https://codecov.io/gh/harfbuzz/harfbuzz) [![Packaging status](https://repology.org/badge/tiny-repos/harfbuzz.svg)](https://repology.org/project/harfbuzz/versions) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/harfbuzz/harfbuzz/badge)](https://securityscorecards.dev/viewer/?uri=github.com/harfbuzz/harfbuzz) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac b/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac index 0d5b3d96751..d7ac9333e26 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], - [8.3.0], + [8.3.1], [https://github.com/harfbuzz/harfbuzz/issues/new], [harfbuzz], [http://harfbuzz.org/]) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/meson.build b/Build/source/libs/harfbuzz/harfbuzz-src/meson.build index e8723b931ae..a5af3b8bdc9 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/meson.build +++ b/Build/source/libs/harfbuzz/harfbuzz-src/meson.build @@ -1,6 +1,6 @@ project('harfbuzz', 'c', 'cpp', meson_version: '>= 0.55.0', - version: '8.3.0', + version: '8.3.1', default_options: [ 'cpp_eh=none', # Just to support msvc, we are passing -fno-exceptions also anyway # 'cpp_rtti=false', # Do NOT enable, wraps inherit it and ICU needs RTTI @@ -22,9 +22,16 @@ pkgmod = import('pkgconfig') cpp = meson.get_compiler('cpp') null_dep = dependency('', required: false) -# Enforce C++14 requirement for MSVC STL -if ['clang', 'clang-cl'].contains(cpp.get_id()) and cpp.get_define('_MSC_FULL_VER') != '' - add_project_arguments('-std=c++14', language: 'cpp') +# Only perform these checks if cpp_std is c++11 as setting -std directly +# produces a warning from meson. +if get_option('cpp_std') == 'c++11' + # Enforce C++14 requirement for MSVC STL + if cpp.get_id() == 'clang' and cpp.get_define('_MSC_FULL_VER') != '' + add_project_arguments('-std=c++14', language: 'cpp') + elif cpp.get_id() == 'clang-cl' + # Clang-cl produces a warning when using -std=c++14, but not when using /std:c++14 + add_project_arguments('/std:c++14', language : 'cpp') + endif endif if cpp.get_argument_syntax() == 'msvc' @@ -72,15 +79,15 @@ check_headers = [ ] check_funcs = [ - ['atexit'], - ['mprotect'], - ['sysconf'], - ['getpagesize'], - ['mmap'], - ['isatty'], - ['uselocale'], - ['newlocale'], - ['sincosf'], + ['atexit', {'prefix': '#include <stdlib.h>'}], + ['mprotect', {'prefix': '#include <sys/mman.h>'}], + ['sysconf', {'prefix': '#include <unistd.h>'}], + ['getpagesize', {'prefix': '#include <unistd.h>'}], + ['mmap', {'prefix': '#include <sys/mman.h>'}], + ['isatty', {'prefix': '#include <unistd.h>'}], + ['uselocale', {'prefix': '#include <locale.h>'}], + ['newlocale', {'prefix': '#include <locale.h>'}], + ['sincosf', {'prefix': '#define _GNU_SOURCE\n#include <math.h>'}], ] m_dep = cpp.find_library('m', required: false) @@ -356,11 +363,12 @@ foreach check : check_funcs opts = check.get(1, {}) link_withs = opts.get('link_with', []) check_deps = opts.get('deps', []) + check_prefix = opts.get('prefix', '') extra_deps = [] found = true # First try without linking - found = cpp.has_function(name, dependencies: check_deps) + found = cpp.has_function(name, prefix: check_prefix, dependencies: check_deps) if not found and link_withs.length() > 0 found = true @@ -375,7 +383,7 @@ foreach check : check_funcs endforeach if found - found = cpp.has_function(name, dependencies: check_deps + extra_deps) + found = cpp.has_function(name, prefix: check_prefix, dependencies: check_deps + extra_deps) endif endif diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am index ff6a6d6f370..0f708a446f8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am @@ -174,7 +174,7 @@ libharfbuzz_la_CPPFLAGS = $(HBCFLAGS) $(CODE_COVERAGE_CFLAGS) libharfbuzz_la_LDFLAGS = $(base_link_flags) $(export_symbols) $(CODE_COVERAGE_LDFLAGS) libharfbuzz_la_LIBADD = $(HBLIBS) EXTRA_libharfbuzz_la_DEPENDENCIES = $(harfbuzz_def_dependency) -pkginclude_HEADERS = $(HBHEADERS) +pkginclude_HEADERS = $(HBHEADERS) hb-features.h nodist_pkginclude_HEADERS = pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = harfbuzz.pc @@ -533,11 +533,11 @@ test_instancer_solver_SOURCES = test-subset-instancer-solver.cc hb-subset-instan test_instancer_solver_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS) test_instancer_solver_LDADD = $(COMPILED_TESTS_LDADD) -test_tuple_varstore_SOURCES = test-tuple-varstore.cc hb-subset-instancer-solver.cc hb-static.cc +test_tuple_varstore_SOURCES = test-tuple-varstore.cc hb-subset-instancer-solver.cc hb-subset-instancer-iup.cc hb-static.cc test_tuple_varstore_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS) test_tuple_varstore_LDADD = $(COMPILED_TESTS_LDADD) -test_item_varstore_SOURCES = test-item-varstore.cc hb-subset-instancer-solver.cc hb-static.cc +test_item_varstore_SOURCES = test-item-varstore.cc hb-subset-instancer-solver.cc hb-subset-instancer-iup.cc hb-static.cc test_item_varstore_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS) test_item_varstore_LDADD = $(COMPILED_TESTS_LDADD) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources index fbbff5325e2..33b5ef8083f 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources @@ -368,6 +368,8 @@ HB_SUBSET_sources = \ hb-subset-cff2.cc \ hb-subset-input.cc \ hb-subset-input.hh \ + hb-subset-instancer-iup.hh \ + hb-subset-instancer-iup.cc \ hb-subset-instancer-solver.hh \ hb-subset-instancer-solver.cc \ hb-subset-accelerator.hh \ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh index b632a1d9eba..623775a771d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh @@ -68,7 +68,7 @@ public: hb_font_t *font; unsigned int palette_index; hb_color_t foreground; - VarStoreInstancer &instancer; + ItemVarStoreInstancer &instancer; hb_map_t current_glyphs; hb_map_t current_layers; int depth_left = HB_MAX_NESTING_LEVEL; @@ -80,7 +80,7 @@ public: hb_font_t *font_, unsigned int palette_, hb_color_t foreground_, - VarStoreInstancer &instancer_) : + ItemVarStoreInstancer &instancer_) : base (base_), funcs (funcs_), data (data_), @@ -245,7 +245,7 @@ struct Variable { value.closurev1 (c); } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); if (!value.subset (c, instancer, varIdxBase)) return_trace (false); @@ -270,7 +270,7 @@ struct Variable void get_color_stop (hb_paint_context_t *c, hb_color_stop_t *stop, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { value.get_color_stop (c, stop, varIdxBase, instancer); } @@ -305,7 +305,7 @@ struct NoVariable { value.closurev1 (c); } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); return_trace (value.subset (c, instancer, varIdxBase)); @@ -325,7 +325,7 @@ struct NoVariable void get_color_stop (hb_paint_context_t *c, hb_color_stop_t *stop, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { value.get_color_stop (c, stop, VarIdx::NO_VARIATION, instancer); } @@ -348,7 +348,7 @@ struct ColorStop { c->add_palette_index (paletteIndex); } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -374,7 +374,7 @@ struct ColorStop void get_color_stop (hb_paint_context_t *c, hb_color_stop_t *out, uint32_t varIdx, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { out->offset = stopOffset.to_float(instancer (varIdx, 0)); out->color = c->get_color (paletteIndex, @@ -410,7 +410,7 @@ struct ColorLine } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (this); @@ -439,7 +439,7 @@ struct ColorLine unsigned int start, unsigned int *count, hb_color_stop_t *color_stops, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { unsigned int len = stops.len; @@ -543,7 +543,7 @@ struct Affine2x3 } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -588,7 +588,7 @@ struct PaintColrLayers void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer HB_UNUSED) const + const ItemVarStoreInstancer &instancer HB_UNUSED) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); @@ -620,7 +620,7 @@ struct PaintSolid { c->add_palette_index (paletteIndex); } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -669,7 +669,7 @@ struct PaintLinearGradient { (this+colorLine).closurev1 (c); } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -736,7 +736,7 @@ struct PaintRadialGradient { (this+colorLine).closurev1 (c); } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -803,7 +803,7 @@ struct PaintSweepGradient { (this+colorLine).closurev1 (c); } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -863,7 +863,7 @@ struct PaintGlyph void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); @@ -906,7 +906,7 @@ struct PaintColrGlyph void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer HB_UNUSED) const + const ItemVarStoreInstancer &instancer HB_UNUSED) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); @@ -936,7 +936,7 @@ struct PaintTransform HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); @@ -975,7 +975,7 @@ struct PaintTranslate HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1024,7 +1024,7 @@ struct PaintScale HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1073,7 +1073,7 @@ struct PaintScaleAroundCenter HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1132,7 +1132,7 @@ struct PaintScaleUniform HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1176,7 +1176,7 @@ struct PaintScaleUniformAroundCenter HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1232,7 +1232,7 @@ struct PaintRotate HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1276,7 +1276,7 @@ struct PaintRotateAroundCenter HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1332,7 +1332,7 @@ struct PaintSkew HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1381,7 +1381,7 @@ struct PaintSkewAroundCenter HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1440,7 +1440,7 @@ struct PaintComposite void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); @@ -1491,7 +1491,7 @@ struct ClipBoxFormat1 return_trace (c->check_struct (this)); } - void get_clip_box (ClipBoxData &clip_box, const VarStoreInstancer &instancer HB_UNUSED) const + void get_clip_box (ClipBoxData &clip_box, const ItemVarStoreInstancer &instancer HB_UNUSED) const { clip_box.xMin = xMin; clip_box.yMin = yMin; @@ -1500,7 +1500,7 @@ struct ClipBoxFormat1 } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1533,7 +1533,7 @@ struct ClipBoxFormat1 struct ClipBoxFormat2 : Variable<ClipBoxFormat1> { - void get_clip_box (ClipBoxData &clip_box, const VarStoreInstancer &instancer) const + void get_clip_box (ClipBoxData &clip_box, const ItemVarStoreInstancer &instancer) const { value.get_clip_box(clip_box, instancer); if (instancer) @@ -1549,7 +1549,7 @@ struct ClipBoxFormat2 : Variable<ClipBoxFormat1> struct ClipBox { bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); switch (u.format) { @@ -1572,7 +1572,7 @@ struct ClipBox } bool get_extents (hb_glyph_extents_t *extents, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { ClipBoxData clip_box; switch (u.format) { @@ -1608,7 +1608,7 @@ struct ClipRecord bool subset (hb_subset_context_t *c, const void *base, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (*this); @@ -1625,7 +1625,7 @@ struct ClipRecord bool get_extents (hb_glyph_extents_t *extents, const void *base, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { return (base+clipBox).get_extents (extents, instancer); } @@ -1642,7 +1642,7 @@ DECLARE_NULL_NAMESPACE_BYTES (OT, ClipRecord); struct ClipList { unsigned serialize_clip_records (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, const hb_set_t& gids, const hb_map_t& gid_offset_map) const { @@ -1695,7 +1695,7 @@ struct ClipList } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (*this); @@ -1735,7 +1735,7 @@ struct ClipList bool get_extents (hb_codepoint_t gid, hb_glyph_extents_t *extents, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { auto *rec = clips.as_array ().bsearch (gid); if (rec) @@ -1855,7 +1855,7 @@ struct BaseGlyphPaintRecord bool serialize (hb_serialize_context_t *s, const hb_map_t* glyph_map, const void* src_base, hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SERIALIZE (this); auto *out = s->embed (this); @@ -1884,7 +1884,7 @@ struct BaseGlyphPaintRecord struct BaseGlyphList : SortedArray32Of<BaseGlyphPaintRecord> { bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (this); @@ -1916,7 +1916,7 @@ struct LayerList : Array32OfOffset32To<Paint> { return this+(*this)[i]; } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (this); @@ -2206,7 +2206,7 @@ struct COLR auto snap = c->serializer->snapshot (); if (!c->serializer->allocate_size<void> (5 * HBUINT32::static_size)) return_trace (false); - VarStoreInstancer instancer (varStore ? &(this+varStore) : nullptr, + ItemVarStoreInstancer instancer (varStore ? &(this+varStore) : nullptr, varIdxMap ? &(this+varIdxMap) : nullptr, c->plan->normalized_coords.as_array ()); @@ -2250,7 +2250,7 @@ struct COLR if (version != 1) return false; - VarStoreInstancer instancer (&(this+varStore), + ItemVarStoreInstancer instancer (&(this+varStore), &(this+varIdxMap), hb_array (font->coords, font->num_coords)); @@ -2301,7 +2301,7 @@ struct COLR bool get_clip (hb_codepoint_t glyph, hb_glyph_extents_t *extents, - const VarStoreInstancer instancer) const + const ItemVarStoreInstancer instancer) const { return (this+clipList).get_extents (glyph, extents, @@ -2312,7 +2312,7 @@ struct COLR bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, unsigned int palette_index, hb_color_t foreground, bool clip = true) const { - VarStoreInstancer instancer (&(this+varStore), + ItemVarStoreInstancer instancer (&(this+varStore), &(this+varIdxMap), hb_array (font->coords, font->num_coords)); hb_paint_context_t c (this, funcs, data, font, palette_index, foreground, instancer); @@ -2327,7 +2327,7 @@ struct COLR { // COLRv1 glyph - VarStoreInstancer instancer (&(this+varStore), + ItemVarStoreInstancer instancer (&(this+varStore), &(this+varIdxMap), hb_array (font->coords, font->num_coords)); @@ -2413,7 +2413,7 @@ struct COLR Offset32To<LayerList> layerList; Offset32To<ClipList> clipList; // Offset to ClipList table (may be NULL) Offset32To<DeltaSetIndexMap> varIdxMap; // Offset to DeltaSetIndexMap table (may be NULL) - Offset32To<VariationStore> varStore; + Offset32To<ItemVariationStore> varStore; public: DEFINE_SIZE_MIN (14); }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GDEF/GDEF.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GDEF/GDEF.hh index 14a9b5e5cd8..475e6d74d1e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GDEF/GDEF.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GDEF/GDEF.hh @@ -189,7 +189,7 @@ struct CaretValueFormat3 friend struct CaretValue; hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, - const VariationStore &var_store) const + const ItemVariationStore &var_store) const { return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_x (coordinate) + (this+deviceTable).get_x_delta (font, var_store) : @@ -251,7 +251,7 @@ struct CaretValue hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id, - const VariationStore &var_store) const + const ItemVariationStore &var_store) const { switch (u.format) { case 1: return u.format1.get_caret_value (font, direction); @@ -316,7 +316,7 @@ struct LigGlyph unsigned get_lig_carets (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id, - const VariationStore &var_store, + const ItemVariationStore &var_store, unsigned start_offset, unsigned *caret_count /* IN/OUT */, hb_position_t *caret_array /* OUT */) const @@ -372,7 +372,7 @@ struct LigCaretList unsigned int get_lig_carets (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id, - const VariationStore &var_store, + const ItemVariationStore &var_store, unsigned int start_offset, unsigned int *caret_count /* IN/OUT */, hb_position_t *caret_array /* OUT */) const @@ -609,7 +609,7 @@ struct GDEFVersion1_2 * definitions--from beginning of GDEF * header (may be NULL). Introduced * in version 0x00010002. */ - Offset32To<VariationStore> + Offset32To<ItemVariationStore> varStore; /* Offset to the table of Item Variation * Store--from beginning of GDEF * header (may be NULL). Introduced @@ -884,14 +884,14 @@ struct GDEF default: return false; } } - const VariationStore &get_var_store () const + const ItemVariationStore &get_var_store () const { switch (u.version.major) { - case 1: return u.version.to_int () >= 0x00010003u ? this+u.version1.varStore : Null(VariationStore); + case 1: return u.version.to_int () >= 0x00010003u ? this+u.version1.varStore : Null(ItemVariationStore); #ifndef HB_NO_BEYOND_64K case 2: return this+u.version2.varStore; #endif - default: return Null(VariationStore); + default: return Null(ItemVariationStore); } } @@ -1011,7 +1011,7 @@ struct GDEF hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map /* OUT */) const { if (!has_var_store ()) return; - const VariationStore &var_store = get_var_store (); + const ItemVariationStore &var_store = get_var_store (); float *store_cache = var_store.create_cache (); unsigned new_major = 0, new_minor = 0; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat2.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat2.hh index dd02da887d4..9c805b39a18 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat2.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat2.hh @@ -324,17 +324,8 @@ struct PairPosFormat2_4 : ValueBase } } - const hb_set_t &glyphset = *c->plan->glyphset_gsub (); - const hb_map_t &glyph_map = *c->plan->glyph_map; - - auto it = - + hb_iter (this+coverage) - | hb_filter (glyphset) - | hb_map_retains_sorting (glyph_map) - ; - - out->coverage.serialize_serialize (c->serializer, it); - return_trace (out->class1Count && out->class2Count && bool (it)); + bool ret = out->coverage.serialize_subset(c, coverage, this); + return_trace (out->class1Count && out->class2Count && ret); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/ValueFormat.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/ValueFormat.hh index 17f57db1f5f..9442cc1cc53 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/ValueFormat.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/ValueFormat.hh @@ -116,7 +116,7 @@ struct ValueFormat : HBUINT16 if (!use_x_device && !use_y_device) return ret; - const VariationStore &store = c->var_store; + const ItemVariationStore &store = c->var_store; auto *cache = c->var_store_cache; /* pixel -> fractional pixel */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/CompositeGlyph.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/CompositeGlyph.hh index 60858a5a581..5c0ecd5133d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/CompositeGlyph.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/CompositeGlyph.hh @@ -240,7 +240,8 @@ struct CompositeGlyphRecord } if (is_anchored ()) tx = ty = 0; - trans.init ((float) tx, (float) ty); + /* set is_end_point flag to true, used by IUP delta optimization */ + trans.init ((float) tx, (float) ty, true); { const F2DOT14 *points = (const F2DOT14 *) p; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh index 5ea611948f8..69a0b625c73 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh @@ -103,6 +103,9 @@ struct Glyph } } + bool is_composite () const + { return type == COMPOSITE; } + bool get_all_points_without_var (const hb_face_t *face, contour_point_vector_t &points /* OUT */) const { diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf-helpers.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf-helpers.hh index d0a5a132f05..f157bf00200 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf-helpers.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf-helpers.hh @@ -38,7 +38,7 @@ _write_loca (IteratorIn&& it, unsigned padded_size = *it++; offset += padded_size; - DEBUG_MSG (SUBSET, nullptr, "loca entry gid %u offset %u padded-size %u", gid, offset, padded_size); + DEBUG_MSG (SUBSET, nullptr, "loca entry gid %" PRIu32 " offset %u padded-size %u", gid, offset, padded_size); value = offset >> right_shift; *dest++ = value; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-def.py b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-def.py index c34976a0677..f199d7f3144 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-def.py +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-def.py @@ -23,6 +23,7 @@ if '--experimental-api' not in sys.argv: hb_subset_repack_or_fail hb_subset_input_override_name_table hb_subset_input_set_axis_range +hb_subset_input_get_axis_range """.splitlines () symbols = [x for x in symbols if x not in experimental_symbols] symbols = "\n".join (symbols) 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 index 7e15c08c56c..86913c3efab 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-tag-table.py +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-tag-table.py @@ -584,7 +584,7 @@ class BCP47Parser (object): self.grandfathered.add (subtag.lower ()) elif line.startswith ('Description: '): description = line.split (' ', 1)[1].replace (' (individual language)', '') - description = re.sub (' (\(family\)|\((individual |macro)language\)|languages)$', '', + description = re.sub (r' (\(family\)|\((individual |macro)language\)|languages)$', '', description) if subtag in self.names: self.names[subtag] += '\n' + description diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/classdef-graph.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/classdef-graph.hh index 9cf845a82d2..da6378820bb 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/classdef-graph.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/classdef-graph.hh @@ -134,20 +134,23 @@ struct ClassDef : public OT::ClassDef struct class_def_size_estimator_t { + // TODO(garretrieger): update to support beyond64k coverage/classdef tables. + constexpr static unsigned class_def_format1_base_size = 6; + constexpr static unsigned class_def_format2_base_size = 4; + constexpr static unsigned coverage_base_size = 4; + constexpr static unsigned bytes_per_range = 6; + constexpr static unsigned bytes_per_glyph = 2; + template<typename It> class_def_size_estimator_t (It glyph_and_class) - : gids_consecutive (true), num_ranges_per_class (), glyphs_per_class () + : num_ranges_per_class (), glyphs_per_class () { - unsigned last_gid = (unsigned) -1; + reset(); for (auto p : + glyph_and_class) { unsigned gid = p.first; unsigned klass = p.second; - if (last_gid != (unsigned) -1 && gid != last_gid + 1) - gids_consecutive = false; - last_gid = gid; - hb_set_t* glyphs; if (glyphs_per_class.has (klass, &glyphs) && glyphs) { glyphs->add (gid); @@ -177,28 +180,54 @@ struct class_def_size_estimator_t } } - // Incremental increase in the Coverage and ClassDef table size - // (worst case) if all glyphs associated with 'klass' were added. - unsigned incremental_coverage_size (unsigned klass) const + void reset() { + class_def_1_size = class_def_format1_base_size; + class_def_2_size = class_def_format2_base_size; + included_glyphs.clear(); + included_classes.clear(); + } + + // Compute the size of coverage for all glyphs added via 'add_class_def_size'. + unsigned coverage_size () const { - // Coverage takes 2 bytes per glyph worst case, - return 2 * glyphs_per_class.get (klass).get_population (); + unsigned format1_size = coverage_base_size + bytes_per_glyph * included_glyphs.get_population(); + unsigned format2_size = coverage_base_size + bytes_per_range * num_glyph_ranges(); + return hb_min(format1_size, format2_size); } - // Incremental increase in the Coverage and ClassDef table size - // (worst case) if all glyphs associated with 'klass' were added. - unsigned incremental_class_def_size (unsigned klass) const + // Compute the new size of the ClassDef table if all glyphs associated with 'klass' were added. + unsigned add_class_def_size (unsigned klass) { - // ClassDef takes 6 bytes per range - unsigned class_def_2_size = 6 * num_ranges_per_class.get (klass); - if (gids_consecutive) - { - // ClassDef1 takes 2 bytes per glyph, but only can be used - // when gids are consecutive. - return hb_min (2 * glyphs_per_class.get (klass).get_population (), class_def_2_size); + if (!included_classes.has(klass)) { + hb_set_t* glyphs = nullptr; + if (glyphs_per_class.has(klass, &glyphs)) { + included_glyphs.union_(*glyphs); + } + + class_def_1_size = class_def_format1_base_size; + if (!included_glyphs.is_empty()) { + unsigned min_glyph = included_glyphs.get_min(); + unsigned max_glyph = included_glyphs.get_max(); + class_def_1_size += bytes_per_glyph * (max_glyph - min_glyph + 1); + } + + class_def_2_size += bytes_per_range * num_ranges_per_class.get (klass); + + included_classes.add(klass); } - return class_def_2_size; + return hb_min (class_def_1_size, class_def_2_size); + } + + unsigned num_glyph_ranges() const { + hb_codepoint_t start = HB_SET_VALUE_INVALID; + hb_codepoint_t end = HB_SET_VALUE_INVALID; + + unsigned count = 0; + while (included_glyphs.next_range (&start, &end)) { + count++; + } + return count; } bool in_error () @@ -214,9 +243,12 @@ struct class_def_size_estimator_t } private: - bool gids_consecutive; hb_hashmap_t<unsigned, unsigned> num_ranges_per_class; hb_hashmap_t<unsigned, hb_set_t> glyphs_per_class; + hb_set_t included_classes; + hb_set_t included_glyphs; + unsigned class_def_1_size; + unsigned class_def_2_size; }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh index 26ad00bdd98..2a9d8346c0b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh @@ -195,6 +195,15 @@ struct graph_t return incoming_edges_; } + unsigned incoming_edges_from_parent (unsigned parent_index) const { + if (single_parent != (unsigned) -1) { + return single_parent == parent_index ? 1 : 0; + } + + unsigned* count; + return parents.has(parent_index, &count) ? *count : 0; + } + void reset_parents () { incoming_edges_ = 0; @@ -334,6 +343,16 @@ struct graph_t return true; } + bool give_max_priority () + { + bool result = false; + while (!has_max_priority()) { + result = true; + priority++; + } + return result; + } + bool has_max_priority () const { return priority >= 3; } @@ -1023,6 +1042,11 @@ struct graph_t * Creates a copy of child and re-assigns the link from * parent to the clone. The copy is a shallow copy, objects * linked from child are not duplicated. + * + * Returns the index of the newly created duplicate. + * + * If the child_idx only has incoming edges from parent_idx, this + * will do nothing and return the original child_idx. */ unsigned duplicate_if_shared (unsigned parent_idx, unsigned child_idx) { @@ -1036,18 +1060,20 @@ struct graph_t * Creates a copy of child and re-assigns the link from * parent to the clone. The copy is a shallow copy, objects * linked from child are not duplicated. + * + * Returns the index of the newly created duplicate. + * + * If the child_idx only has incoming edges from parent_idx, + * duplication isn't possible and this will return -1. */ unsigned duplicate (unsigned parent_idx, unsigned child_idx) { update_parents (); - unsigned links_to_child = 0; - for (const auto& l : vertices_[parent_idx].obj.all_links ()) - { - if (l.objidx == child_idx) links_to_child++; - } + const auto& child = vertices_[child_idx]; + unsigned links_to_child = child.incoming_edges_from_parent(parent_idx); - if (vertices_[child_idx].incoming_edges () <= links_to_child) + if (child.incoming_edges () <= links_to_child) { // Can't duplicate this node, doing so would orphan the original one as all remaining links // to child are from parent. @@ -1060,7 +1086,7 @@ struct graph_t parent_idx, child_idx); unsigned clone_idx = duplicate (child_idx); - if (clone_idx == (unsigned) -1) return false; + if (clone_idx == (unsigned) -1) return -1; // duplicate shifts the root node idx, so if parent_idx was root update it. if (parent_idx == clone_idx) parent_idx++; @@ -1076,6 +1102,62 @@ struct graph_t return clone_idx; } + /* + * Creates a copy of child and re-assigns the links from + * parents to the clone. The copy is a shallow copy, objects + * linked from child are not duplicated. + * + * Returns the index of the newly created duplicate. + * + * If the child_idx only has incoming edges from parents, + * duplication isn't possible or duplication fails and this will + * return -1. + */ + unsigned duplicate (const hb_set_t* parents, unsigned child_idx) + { + if (parents->is_empty()) { + return -1; + } + + update_parents (); + + const auto& child = vertices_[child_idx]; + unsigned links_to_child = 0; + unsigned last_parent = parents->get_max(); + unsigned first_parent = parents->get_min(); + for (unsigned parent_idx : *parents) { + links_to_child += child.incoming_edges_from_parent(parent_idx); + } + + if (child.incoming_edges () <= links_to_child) + { + // Can't duplicate this node, doing so would orphan the original one as all remaining links + // to child are from parent. + DEBUG_MSG (SUBSET_REPACK, nullptr, " Not duplicating %u, ..., %u => %u", first_parent, last_parent, child_idx); + return -1; + } + + DEBUG_MSG (SUBSET_REPACK, nullptr, " Duplicating %u, ..., %u => %u", first_parent, last_parent, child_idx); + + unsigned clone_idx = duplicate (child_idx); + if (clone_idx == (unsigned) -1) return false; + + for (unsigned parent_idx : *parents) { + // duplicate shifts the root node idx, so if parent_idx was root update it. + if (parent_idx == clone_idx) parent_idx++; + auto& parent = vertices_[parent_idx]; + for (auto& l : parent.obj.all_links_writer ()) + { + if (l.objidx != child_idx) + continue; + + reassign_link (l, parent_idx, clone_idx); + } + } + + return clone_idx; + } + /* * Adds a new node to the graph, not connected to anything. diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/pairpos-graph.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/pairpos-graph.hh index f7f74b18c9c..fd46861de46 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/pairpos-graph.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/pairpos-graph.hh @@ -247,8 +247,8 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4<SmallType for (unsigned i = 0; i < class1_count; i++) { unsigned accumulated_delta = class1_record_size; - coverage_size += estimator.incremental_coverage_size (i); - class_def_1_size += estimator.incremental_class_def_size (i); + class_def_1_size = estimator.add_class_def_size (i); + coverage_size = estimator.coverage_size (); max_coverage_size = hb_max (max_coverage_size, coverage_size); max_class_def_1_size = hb_max (max_class_def_1_size, class_def_1_size); @@ -280,8 +280,10 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4<SmallType split_points.push (i); // split does not include i, so add the size for i when we reset the size counters. accumulated = base_size + accumulated_delta; - coverage_size = 4 + estimator.incremental_coverage_size (i); - class_def_1_size = 4 + estimator.incremental_class_def_size (i); + + estimator.reset(); + class_def_1_size = estimator.add_class_def_size(i); + coverage_size = estimator.coverage_size(); visited.clear (); // node sharing isn't allowed between splits. } } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/test-classdef-graph.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/test-classdef-graph.cc index 266be5e2d40..2da93481115 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/test-classdef-graph.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/test-classdef-graph.cc @@ -26,27 +26,119 @@ #include "gsubgpos-context.hh" #include "classdef-graph.hh" +#include "hb-iter.hh" +#include "hb-serialize.hh" typedef hb_codepoint_pair_t gid_and_class_t; typedef hb_vector_t<gid_and_class_t> gid_and_class_list_t; +template<typename It> +static unsigned actual_class_def_size(It glyph_and_class) { + char buffer[100]; + hb_serialize_context_t serializer(buffer, 100); + OT::ClassDef_serialize (&serializer, glyph_and_class); + serializer.end_serialize (); + assert(!serializer.in_error()); -static bool incremental_size_is (const gid_and_class_list_t& list, unsigned klass, - unsigned cov_expected, unsigned class_def_expected) + hb_blob_t* blob = serializer.copy_blob(); + unsigned size = hb_blob_get_length(blob); + hb_blob_destroy(blob); + return size; +} + +static unsigned actual_class_def_size(gid_and_class_list_t consecutive_map, hb_vector_t<unsigned> classes) { + auto filtered_it = + + consecutive_map.as_sorted_array().iter() + | hb_filter([&] (unsigned c) { + for (unsigned klass : classes) { + if (c == klass) { + return true; + } + } + return false; + }, hb_second); + return actual_class_def_size(+ filtered_it); +} + +template<typename It> +static unsigned actual_coverage_size(It glyphs) { + char buffer[100]; + hb_serialize_context_t serializer(buffer, 100); + OT::Layout::Common::Coverage_serialize (&serializer, glyphs); + serializer.end_serialize (); + assert(!serializer.in_error()); + + hb_blob_t* blob = serializer.copy_blob(); + unsigned size = hb_blob_get_length(blob); + hb_blob_destroy(blob); + return size; +} + +static unsigned actual_coverage_size(gid_and_class_list_t consecutive_map, hb_vector_t<unsigned> classes) { + auto filtered_it = + + consecutive_map.as_sorted_array().iter() + | hb_filter([&] (unsigned c) { + for (unsigned klass : classes) { + if (c == klass) { + return true; + } + } + return false; + }, hb_second); + return actual_coverage_size(+ filtered_it | hb_map_retains_sorting(hb_first)); +} + +static bool check_coverage_size(graph::class_def_size_estimator_t& estimator, + const gid_and_class_list_t& map, + hb_vector_t<unsigned> klasses) +{ + unsigned result = estimator.coverage_size(); + unsigned expected = actual_coverage_size(map, klasses); + if (result != expected) { + printf ("FAIL: estimated coverage expected size %u but was %u\n", expected, result); + return false; + } + return true; +} + +static bool check_add_class_def_size(graph::class_def_size_estimator_t& estimator, + const gid_and_class_list_t& map, + unsigned klass, hb_vector_t<unsigned> klasses) +{ + unsigned result = estimator.add_class_def_size(klass); + unsigned expected = actual_class_def_size(map, klasses); + if (result != expected) { + printf ("FAIL: estimated class def expected size %u but was %u\n", expected, result); + return false; + } + + return check_coverage_size(estimator, map, klasses); +} + +static bool check_add_class_def_size (const gid_and_class_list_t& list, unsigned klass) { graph::class_def_size_estimator_t estimator (list.iter ()); - unsigned result = estimator.incremental_coverage_size (klass); - if (result != cov_expected) + unsigned result = estimator.add_class_def_size (klass); + auto filtered_it = + + list.as_sorted_array().iter() + | hb_filter([&] (unsigned c) { + return c == klass; + }, hb_second); + + unsigned expected = actual_class_def_size(filtered_it); + if (result != expected) { - printf ("FAIL: coverage expected size %u but was %u\n", cov_expected, result); + printf ("FAIL: class def expected size %u but was %u\n", expected, result); return false; } - result = estimator.incremental_class_def_size (klass); - if (result != class_def_expected) + auto cov_it = + filtered_it | hb_map_retains_sorting(hb_first); + result = estimator.coverage_size (); + expected = actual_coverage_size(cov_it); + if (result != expected) { - printf ("FAIL: class def expected size %u but was %u\n", class_def_expected, result); + printf ("FAIL: coverage expected size %u but was %u\n", expected, result); return false; } @@ -57,43 +149,45 @@ static void test_class_and_coverage_size_estimates () { gid_and_class_list_t empty = { }; - assert (incremental_size_is (empty, 0, 0, 0)); - assert (incremental_size_is (empty, 1, 0, 0)); + assert (check_add_class_def_size (empty, 0)); + assert (check_add_class_def_size (empty, 1)); gid_and_class_list_t class_zero = { {5, 0}, }; - assert (incremental_size_is (class_zero, 0, 2, 0)); + assert (check_add_class_def_size (class_zero, 0)); gid_and_class_list_t consecutive = { {4, 0}, {5, 0}, + {6, 1}, {7, 1}, + {8, 2}, {9, 2}, {10, 2}, {11, 2}, }; - assert (incremental_size_is (consecutive, 0, 4, 0)); - assert (incremental_size_is (consecutive, 1, 4, 4)); - assert (incremental_size_is (consecutive, 2, 8, 6)); + assert (check_add_class_def_size (consecutive, 0)); + assert (check_add_class_def_size (consecutive, 1)); + assert (check_add_class_def_size (consecutive, 2)); gid_and_class_list_t non_consecutive = { {4, 0}, - {5, 0}, + {6, 0}, - {6, 1}, - {7, 1}, + {8, 1}, + {10, 1}, {9, 2}, {10, 2}, {11, 2}, - {12, 2}, + {13, 2}, }; - assert (incremental_size_is (non_consecutive, 0, 4, 0)); - assert (incremental_size_is (non_consecutive, 1, 4, 6)); - assert (incremental_size_is (non_consecutive, 2, 8, 6)); + assert (check_add_class_def_size (non_consecutive, 0)); + assert (check_add_class_def_size (non_consecutive, 1)); + assert (check_add_class_def_size (non_consecutive, 2)); gid_and_class_list_t multiple_ranges = { {4, 0}, @@ -108,12 +202,95 @@ static void test_class_and_coverage_size_estimates () {12, 1}, {13, 1}, }; - assert (incremental_size_is (multiple_ranges, 0, 4, 0)); - assert (incremental_size_is (multiple_ranges, 1, 2 * 6, 3 * 6)); + assert (check_add_class_def_size (multiple_ranges, 0)); + assert (check_add_class_def_size (multiple_ranges, 1)); +} + +static void test_running_class_and_coverage_size_estimates () { + // #### With consecutive gids: switches formats ### + gid_and_class_list_t consecutive_map = { + // range 1-4 (f1: 8 bytes), (f2: 6 bytes) + {1, 1}, + {2, 1}, + {3, 1}, + {4, 1}, + + // (f1: 2 bytes), (f2: 6 bytes) + {5, 2}, + + // (f1: 14 bytes), (f2: 6 bytes) + {6, 3}, + {7, 3}, + {8, 3}, + {9, 3}, + {10, 3}, + {11, 3}, + {12, 3}, + }; + + graph::class_def_size_estimator_t estimator1(consecutive_map.iter()); + assert(check_add_class_def_size(estimator1, consecutive_map, 1, {1})); + assert(check_add_class_def_size(estimator1, consecutive_map, 2, {1, 2})); + assert(check_add_class_def_size(estimator1, consecutive_map, 2, {1, 2})); // check that adding the same class again works + assert(check_add_class_def_size(estimator1, consecutive_map, 3, {1, 2, 3})); + + estimator1.reset(); + assert(check_add_class_def_size(estimator1, consecutive_map, 2, {2})); + assert(check_add_class_def_size(estimator1, consecutive_map, 3, {2, 3})); + + // #### With non-consecutive gids: always uses format 2 ### + gid_and_class_list_t non_consecutive_map = { + // range 1-4 (f1: 8 bytes), (f2: 6 bytes) + {1, 1}, + {2, 1}, + {3, 1}, + {4, 1}, + + // (f1: 2 bytes), (f2: 12 bytes) + {6, 2}, + {8, 2}, + + // (f1: 14 bytes), (f2: 6 bytes) + {9, 3}, + {10, 3}, + {11, 3}, + {12, 3}, + {13, 3}, + {14, 3}, + {15, 3}, + }; + + graph::class_def_size_estimator_t estimator2(non_consecutive_map.iter()); + assert(check_add_class_def_size(estimator2, non_consecutive_map, 1, {1})); + assert(check_add_class_def_size(estimator2, non_consecutive_map, 2, {1, 2})); + assert(check_add_class_def_size(estimator2, non_consecutive_map, 3, {1, 2, 3})); + + estimator2.reset(); + assert(check_add_class_def_size(estimator2, non_consecutive_map, 2, {2})); + assert(check_add_class_def_size(estimator2, non_consecutive_map, 3, {2, 3})); +} + +static void test_running_class_size_estimates_with_locally_consecutive_glyphs () { + gid_and_class_list_t map = { + {1, 1}, + {6, 2}, + {7, 3}, + }; + + graph::class_def_size_estimator_t estimator(map.iter()); + assert(check_add_class_def_size(estimator, map, 1, {1})); + assert(check_add_class_def_size(estimator, map, 2, {1, 2})); + assert(check_add_class_def_size(estimator, map, 3, {1, 2, 3})); + + estimator.reset(); + assert(check_add_class_def_size(estimator, map, 2, {2})); + assert(check_add_class_def_size(estimator, map, 3, {2, 3})); } int main (int argc, char **argv) { test_class_and_coverage_size_estimates (); + test_running_class_and_coverage_size_estimates (); + test_running_class_size_estimates_with_locally_consecutive_glyphs (); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-cairo.pc.in b/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-cairo.pc.in index df97ff15128..06ba8047c45 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-cairo.pc.in +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-cairo.pc.in @@ -8,5 +8,6 @@ Description: HarfBuzz cairo integration Version: %VERSION% Requires: harfbuzz = %VERSION% +Requires.private: cairo Libs: -L${libdir} -lharfbuzz-cairo Cflags: -I${includedir}/harfbuzz diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-subset.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-subset.cc index c0e23b3eb82..f80c004cbb4 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-subset.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-subset.cc @@ -54,6 +54,7 @@ #include "hb-subset-cff1.cc" #include "hb-subset-cff2.cc" #include "hb-subset-input.cc" +#include "hb-subset-instancer-iup.cc" #include "hb-subset-instancer-solver.cc" #include "hb-subset-plan.cc" #include "hb-subset-repacker.cc" 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 06c9334b370..84365513240 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 @@ -552,6 +552,7 @@ struct LigatureSubtable { DEBUG_MSG (APPLY, nullptr, "Skipping ligature component"); if (unlikely (!buffer->move_to (match_positions[--match_length % ARRAY_LENGTH (match_positions)]))) return; + buffer->cur().unicode_props() |= UPROPS_MASK_IGNORABLE; if (unlikely (!buffer->replace_glyph (DELETED_GLYPH))) return; } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh index ea970571654..efa6074a422 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh @@ -671,7 +671,7 @@ struct hb_pair_t return 0; } - friend void swap (hb_pair_t& a, hb_pair_t& b) + friend void swap (hb_pair_t& a, hb_pair_t& b) noexcept { hb_swap (a.first, b.first); hb_swap (a.second, b.second); @@ -1053,6 +1053,18 @@ _hb_cmp_method (const void *pkey, const void *pval, Ts... ds) return val.cmp (key, ds...); } +template <typename K, typename V> +static int +_hb_cmp_operator (const void *pkey, const void *pval) +{ + const K& key = * (const K*) pkey; + const V& val = * (const V*) pval; + + if (key < val) return -1; + if (key > val) return 1; + return 0; +} + template <typename V, typename K, typename ...Ts> static inline bool hb_bsearch_impl (unsigned *pos, /* Out */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set-invertible.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set-invertible.hh index 26262518070..d5d1326d9fa 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set-invertible.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set-invertible.hh @@ -39,10 +39,10 @@ struct hb_bit_set_invertible_t hb_bit_set_invertible_t () = default; hb_bit_set_invertible_t (const hb_bit_set_invertible_t& o) = default; - hb_bit_set_invertible_t (hb_bit_set_invertible_t&& other) : hb_bit_set_invertible_t () { hb_swap (*this, other); } + hb_bit_set_invertible_t (hb_bit_set_invertible_t&& other) noexcept : hb_bit_set_invertible_t () { hb_swap (*this, other); } hb_bit_set_invertible_t& operator= (const hb_bit_set_invertible_t& o) = default; - hb_bit_set_invertible_t& operator= (hb_bit_set_invertible_t&& other) { hb_swap (*this, other); return *this; } - friend void swap (hb_bit_set_invertible_t &a, hb_bit_set_invertible_t &b) + hb_bit_set_invertible_t& operator= (hb_bit_set_invertible_t&& other) noexcept { hb_swap (*this, other); return *this; } + friend void swap (hb_bit_set_invertible_t &a, hb_bit_set_invertible_t &b) noexcept { if (likely (!a.s.successful || !b.s.successful)) return; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh index 1dbcce5cbd5..5f4c6f0afea 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh @@ -38,10 +38,10 @@ struct hb_bit_set_t ~hb_bit_set_t () = default; hb_bit_set_t (const hb_bit_set_t& other) : hb_bit_set_t () { set (other, true); } - hb_bit_set_t ( hb_bit_set_t&& other) : hb_bit_set_t () { hb_swap (*this, other); } + hb_bit_set_t ( hb_bit_set_t&& other) noexcept : hb_bit_set_t () { hb_swap (*this, other); } hb_bit_set_t& operator= (const hb_bit_set_t& other) { set (other); return *this; } - hb_bit_set_t& operator= (hb_bit_set_t&& other) { hb_swap (*this, other); return *this; } - friend void swap (hb_bit_set_t &a, hb_bit_set_t &b) + hb_bit_set_t& operator= (hb_bit_set_t&& other) noexcept { hb_swap (*this, other); return *this; } + friend void swap (hb_bit_set_t &a, hb_bit_set_t &b) noexcept { if (likely (!a.successful || !b.successful)) return; 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 265effba037..873d9b257ad 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc @@ -598,6 +598,11 @@ _open_resource_fork (const char *file_name, hb_mapped_file_t *file) * Creates a new blob containing the data from the * specified binary font file. * + * The filename is passed directly to the system on all platforms, + * except on Windows, where the filename is interpreted as UTF-8. + * Only if the filename is not valid UTF-8, it will be interpreted + * according to the system codepage. + * * Returns: An #hb_blob_t pointer with the content of the file, * or hb_blob_get_empty() if failed. * @@ -617,6 +622,11 @@ hb_blob_create_from_file (const char *file_name) * Creates a new blob containing the data from the * specified binary font file. * + * The filename is passed directly to the system on all platforms, + * except on Windows, where the filename is interpreted as UTF-8. + * Only if the filename is not valid UTF-8, it will be interpreted + * according to the system codepage. + * * Returns: An #hb_blob_t pointer with the content of the file, * or `NULL` if failed. * @@ -672,10 +682,19 @@ fail_without_close: if (unlikely (!file)) return nullptr; HANDLE fd; + int conversion; unsigned int size = strlen (file_name) + 1; wchar_t * wchar_file_name = (wchar_t *) hb_malloc (sizeof (wchar_t) * size); if (unlikely (!wchar_file_name)) goto fail_without_close; - mbstowcs (wchar_file_name, file_name, size); + + /* Assume file name is given in UTF-8 encoding */ + conversion = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, file_name, -1, wchar_file_name, size); + if (conversion <= 0) + { + /* Conversion failed due to invalid UTF-8 characters, + Repeat conversion based on system code page */ + mbstowcs(wchar_file_name, file_name, size); + } #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) { CREATEFILE2_EXTENDED_PARAMETERS ceparams = { 0 }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc index 15a53919def..671d6eda8c9 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc @@ -149,7 +149,7 @@ buffer_verify_unsafe_to_break (hb_buffer_t *buffer, } assert (text_start < text_end); - if (0) + if (false) printf("start %u end %u text start %u end %u\n", start, end, text_start, text_end); hb_buffer_clear_contents (fragment); @@ -288,7 +288,7 @@ buffer_verify_unsafe_to_concat (hb_buffer_t *buffer, } assert (text_start < text_end); - if (0) + if (false) printf("start %u end %u text start %u end %u\n", start, end, text_start, text_end); #if 0 diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-dict-common.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-dict-common.hh index 53226b227e9..a08b10b5ff1 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-dict-common.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-dict-common.hh @@ -54,8 +54,8 @@ struct top_dict_values_t : dict_values_t<OPSTR> } void fini () { dict_values_t<OPSTR>::fini (); } - unsigned int charStringsOffset; - unsigned int FDArrayOffset; + int charStringsOffset; + int FDArrayOffset; }; struct dict_opset_t : opset_t<number_t> @@ -157,11 +157,11 @@ struct top_dict_opset_t : dict_opset_t { switch (op) { case OpCode_CharStrings: - dictval.charStringsOffset = env.argStack.pop_uint (); + dictval.charStringsOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_FDArray: - dictval.FDArrayOffset = env.argStack.pop_uint (); + dictval.FDArrayOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_FontMatrix: diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff2-interp-cs.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff2-interp-cs.hh index 915b10cf39a..55b1d3bf8d4 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff2-interp-cs.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff2-interp-cs.hh @@ -168,7 +168,7 @@ struct cff2_cs_interp_env_t : cs_interp_env_t<ELEM, CFF2Subrs> protected: const int *coords; unsigned int num_coords; - const CFF2VariationStore *varStore; + const CFF2ItemVariationStore *varStore; unsigned int region_count; unsigned int ivs; hb_vector_t<float> scalars; 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 0c13c7d171f..4b8bae4422e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc @@ -996,7 +996,7 @@ hb_feature_to_string (hb_feature_t *feature, if (feature->value > 1) { s[len++] = '='; - len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->value)); + len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%" PRIu32, feature->value)); } assert (len < ARRAY_LENGTH (s)); len = hb_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 a9fe666b392..dfdefc627e9 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h @@ -47,14 +47,10 @@ # endif /* !__cplusplus */ #endif -#if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || \ - defined (_sgi) || defined (__sun) || defined (sun) || \ - defined (__digital__) || defined (__HP_cc) -# include <inttypes.h> -#elif defined (_AIX) +#if defined (_AIX) # include <sys/inttypes.h> -#elif defined (_MSC_VER) && _MSC_VER < 1600 -/* VS 2010 (_MSC_VER 1600) has stdint.h */ +#elif defined (_MSC_VER) && _MSC_VER < 1800 +/* VS 2013 (_MSC_VER 1800) has inttypes.h */ typedef __int8 int8_t; typedef unsigned __int8 uint8_t; typedef __int16 int16_t; @@ -63,10 +59,8 @@ typedef __int32 int32_t; typedef unsigned __int32 uint32_t; typedef __int64 int64_t; typedef unsigned __int64 uint64_t; -#elif defined (__KERNEL__) -# include <linux/types.h> #else -# include <stdint.h> +# include <inttypes.h> #endif #if defined(__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cplusplus.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cplusplus.hh index 531ef1b7c83..a640e192de7 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cplusplus.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cplusplus.hh @@ -56,15 +56,15 @@ struct shared_ptr explicit shared_ptr (T *p = nullptr) : p (p) {} shared_ptr (const shared_ptr &o) : p (v::reference (o.p)) {} - shared_ptr (shared_ptr &&o) : p (o.p) { o.p = nullptr; } + shared_ptr (shared_ptr &&o) noexcept : p (o.p) { o.p = nullptr; } shared_ptr& operator = (const shared_ptr &o) { if (p != o.p) { destroy (); p = o.p; reference (); } return *this; } - shared_ptr& operator = (shared_ptr &&o) { v::destroy (p); p = o.p; o.p = nullptr; return *this; } + shared_ptr& operator = (shared_ptr &&o) noexcept { v::destroy (p); p = o.p; o.p = nullptr; return *this; } ~shared_ptr () { v::destroy (p); p = nullptr; } T* get() const { return p; } - void swap (shared_ptr &o) { std::swap (p, o.p); } - friend void swap (shared_ptr &a, shared_ptr &b) { std::swap (a.p, b.p); } + void swap (shared_ptr &o) noexcept { std::swap (p, o.p); } + friend void swap (shared_ptr &a, shared_ptr &b) noexcept { std::swap (a.p, b.p); } operator T * () const { return p; } T& operator * () const { return *get (); } @@ -98,16 +98,16 @@ struct unique_ptr explicit unique_ptr (T *p = nullptr) : p (p) {} unique_ptr (const unique_ptr &o) = delete; - unique_ptr (unique_ptr &&o) : p (o.p) { o.p = nullptr; } + unique_ptr (unique_ptr &&o) noexcept : p (o.p) { o.p = nullptr; } unique_ptr& operator = (const unique_ptr &o) = delete; - unique_ptr& operator = (unique_ptr &&o) { v::destroy (p); p = o.p; o.p = nullptr; return *this; } + unique_ptr& operator = (unique_ptr &&o) noexcept { v::destroy (p); p = o.p; o.p = nullptr; return *this; } ~unique_ptr () { v::destroy (p); p = nullptr; } T* get() const { return p; } T* release () { T* v = p; p = nullptr; return v; } - void swap (unique_ptr &o) { std::swap (p, o.p); } - friend void swap (unique_ptr &a, unique_ptr &b) { std::swap (a.p, b.p); } + void swap (unique_ptr &o) noexcept { std::swap (p, o.p); } + friend void swap (unique_ptr &a, unique_ptr &b) noexcept { std::swap (a.p, b.p); } operator T * () const { return p; } T& operator * () const { return *get (); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc index 42764a244b1..6c90265d0b6 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc @@ -173,7 +173,7 @@ _hb_directwrite_shaper_face_data_create (hb_face_t *face) t_DWriteCreateFactory p_DWriteCreateFactory; -#if defined(__GNUC__) +#if defined(__GNUC__) || defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-function-type" #endif @@ -181,7 +181,7 @@ _hb_directwrite_shaper_face_data_create (hb_face_t *face) p_DWriteCreateFactory = (t_DWriteCreateFactory) GetProcAddress (data->dwrite_dll, "DWriteCreateFactory"); -#if defined(__GNUC__) +#if defined(__GNUC__) || defined(__clang__) #pragma GCC diagnostic pop #endif 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 f503575c34a..4c8190b0dd1 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh @@ -651,7 +651,7 @@ struct hb_font_t { if (get_glyph_name (glyph, s, size)) return; - if (size && snprintf (s, size, "gid%u", glyph) < 0) + if (size && snprintf (s, size, "gid%" PRIu32, glyph) < 0) *s = '\0'; } 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 955a9081e09..3de4a6d5d41 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc @@ -224,7 +224,7 @@ _hb_ft_hb_font_check_changed (hb_font_t *font, * * Sets the FT_Load_Glyph load flags for the specified #hb_font_t. * - * For more information, see + * For more information, see * <https://freetype.org/freetype2/docs/reference/ft2-glyph_retrieval.html#ft_load_xxx> * * This function works with #hb_font_t objects created by @@ -252,7 +252,7 @@ hb_ft_font_set_load_flags (hb_font_t *font, int load_flags) * * Fetches the FT_Load_Glyph load flags of the specified #hb_font_t. * - * For more information, see + * For more information, see * <https://freetype.org/freetype2/docs/reference/ft2-glyph_retrieval.html#ft_load_xxx> * * This function works with #hb_font_t objects created by @@ -1118,10 +1118,10 @@ _hb_ft_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data * This variant of the function does not provide any life-cycle management. * * Most client programs should use hb_ft_face_create_referenced() - * (or, perhaps, hb_ft_face_create_cached()) instead. + * (or, perhaps, hb_ft_face_create_cached()) instead. * * If you know you have valid reasons not to use hb_ft_face_create_referenced(), - * then it is the client program's responsibility to destroy @ft_face + * then it is the client program's responsibility to destroy @ft_face * after the #hb_face_t face object has been destroyed. * * Return value: (transfer full): the new #hb_face_t face object @@ -1215,7 +1215,7 @@ hb_ft_face_finalize (void *arg) hb_face_t * hb_ft_face_create_cached (FT_Face ft_face) { - if (unlikely (!ft_face->generic.data || ft_face->generic.finalizer != (FT_Generic_Finalizer) hb_ft_face_finalize)) + if (unlikely (!ft_face->generic.data || ft_face->generic.finalizer != hb_ft_face_finalize)) { if (ft_face->generic.finalizer) ft_face->generic.finalizer (ft_face); @@ -1241,13 +1241,13 @@ hb_ft_face_create_cached (FT_Face ft_face) * This variant of the function does not provide any life-cycle management. * * Most client programs should use hb_ft_font_create_referenced() - * instead. + * instead. * * If you know you have valid reasons not to use hb_ft_font_create_referenced(), - * then it is the client program's responsibility to destroy @ft_face + * then it is the client program's responsibility to destroy @ft_face * after the #hb_font_t font object has been destroyed. * - * HarfBuzz will use the @destroy callback on the #hb_font_t font object + * HarfBuzz will use the @destroy callback on the #hb_font_t font object * if it is supplied when you use this function. However, even if @destroy * is provided, it is the client program's responsibility to destroy @ft_face, * and it is the client program's responsibility to ensure that @ft_face is 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 e46401f7a61..3707ec30f84 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-icu.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-icu.cc @@ -93,15 +93,16 @@ hb_icu_script_to_script (UScriptCode script) UScriptCode hb_icu_script_from_script (hb_script_t script) { + UScriptCode out = USCRIPT_INVALID_CODE; + if (unlikely (script == HB_SCRIPT_INVALID)) - return USCRIPT_INVALID_CODE; + return out; - unsigned int numScriptCode = 1 + u_getIntPropertyMaxValue (UCHAR_SCRIPT); - for (unsigned int i = 0; i < numScriptCode; i++) - if (unlikely (hb_icu_script_to_script ((UScriptCode) i) == script)) - return (UScriptCode) i; + UErrorCode icu_err = U_ZERO_ERROR; + const unsigned char buf[5] = {HB_UNTAG (script), 0}; + uscript_getCode ((const char *) buf, &out, 1, &icu_err); - return USCRIPT_UNKNOWN; + return out; } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-limits.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-limits.hh index 25c1e71e133..7efc893eae0 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-limits.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-limits.hh @@ -106,7 +106,7 @@ #endif #ifndef HB_COLRV1_MAX_EDGE_COUNT -#define HB_COLRV1_MAX_EDGE_COUNT 65536 +#define HB_COLRV1_MAX_EDGE_COUNT 2048 #endif diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh index 45a02b830c3..6521b1a41d8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh @@ -70,9 +70,9 @@ struct hb_hashmap_t alloc (o.population); hb_copy (o, *this); } - hb_hashmap_t (hb_hashmap_t&& o) : hb_hashmap_t () { hb_swap (*this, o); } + hb_hashmap_t (hb_hashmap_t&& o) noexcept : hb_hashmap_t () { hb_swap (*this, o); } hb_hashmap_t& operator= (const hb_hashmap_t& o) { reset (); alloc (o.population); hb_copy (o, *this); return *this; } - hb_hashmap_t& operator= (hb_hashmap_t&& o) { hb_swap (*this, o); return *this; } + hb_hashmap_t& operator= (hb_hashmap_t&& o) noexcept { hb_swap (*this, o); return *this; } hb_hashmap_t (std::initializer_list<hb_pair_t<K, V>> lst) : hb_hashmap_t () { @@ -137,26 +137,23 @@ struct hb_hashmap_t }; hb_object_header_t header; - unsigned int successful : 1; /* Allocations successful */ - unsigned int population : 31; /* Not including tombstones. */ + bool successful; /* Allocations successful */ + unsigned short max_chain_length; + unsigned int population; /* Not including tombstones. */ unsigned int occupancy; /* Including tombstones. */ unsigned int mask; unsigned int prime; - unsigned int max_chain_length; item_t *items; - friend void swap (hb_hashmap_t& a, hb_hashmap_t& b) + friend void swap (hb_hashmap_t& a, hb_hashmap_t& b) noexcept { if (unlikely (!a.successful || !b.successful)) return; - unsigned tmp = a.population; - a.population = b.population; - b.population = tmp; - //hb_swap (a.population, b.population); + hb_swap (a.max_chain_length, b.max_chain_length); + hb_swap (a.population, b.population); hb_swap (a.occupancy, b.occupancy); hb_swap (a.mask, b.mask); hb_swap (a.prime, b.prime); - hb_swap (a.max_chain_length, b.max_chain_length); hb_swap (a.items, b.items); } void init () @@ -164,10 +161,10 @@ struct hb_hashmap_t hb_object_init (this); successful = true; + max_chain_length = 0; population = occupancy = 0; mask = 0; prime = 0; - max_chain_length = 0; items = nullptr; } void fini () @@ -558,7 +555,7 @@ struct hb_map_t : hb_hashmap_t<hb_codepoint_t, ~hb_map_t () = default; hb_map_t () : hashmap () {} hb_map_t (const hb_map_t &o) : hashmap ((hashmap &) o) {} - hb_map_t (hb_map_t &&o) : hashmap (std::move ((hashmap &) o)) {} + hb_map_t (hb_map_t &&o) noexcept : hashmap (std::move ((hashmap &) o)) {} hb_map_t& operator= (const hb_map_t&) = default; hb_map_t& operator= (hb_map_t&&) = default; hb_map_t (std::initializer_list<hb_codepoint_pair_t> lst) : hashmap (lst) {} diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object.hh index e2c2c3394cb..5cffe1666b9 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object.hh @@ -325,7 +325,7 @@ retry: hb_user_data_array_t *user_data = obj->header.user_data.get_acquire (); if (unlikely (!user_data)) { - user_data = (hb_user_data_array_t *) hb_calloc (sizeof (hb_user_data_array_t), 1); + user_data = (hb_user_data_array_t *) hb_calloc (1, sizeof (hb_user_data_array_t)); if (unlikely (!user_data)) return false; user_data->init (); 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 6967bca3d4b..9c11f14344c 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 @@ -985,6 +985,13 @@ struct SortedArrayOf : ArrayOf<Type, LenType> return_trace (ret); } + SortedArrayOf* copy (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); + SortedArrayOf* out = reinterpret_cast<SortedArrayOf *> (ArrayOf<Type, LenType>::copy (c)); + return_trace (out); + } + template <typename T> Type &bsearch (const T &x, Type ¬_found = Crap (Type)) { return *as_array ().bsearch (x, ¬_found); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff-common.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff-common.hh index 4fdba197ac7..c7c3264c086 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff-common.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff-common.hh @@ -41,10 +41,21 @@ using namespace OT; using objidx_t = hb_serialize_context_t::objidx_t; using whence_t = hb_serialize_context_t::whence_t; -/* utility macro */ -template<typename Type> -static inline const Type& StructAtOffsetOrNull (const void *P, unsigned int offset) -{ return offset ? StructAtOffset<Type> (P, offset) : Null (Type); } +/* CFF offsets can technically be negative */ +template<typename Type, typename ...Ts> +static inline const Type& StructAtOffsetOrNull (const void *P, int offset, hb_sanitize_context_t &sc, Ts&&... ds) +{ + if (!offset) return Null (Type); + + const char *p = (const char *) P + offset; + if (!sc.check_point (p)) return Null (Type); + + const Type &obj = *reinterpret_cast<const Type *> (p); + if (!obj.sanitize (&sc, std::forward<Ts> (ds)...)) return Null (Type); + + return obj; +} + struct code_pair_t { diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh index c869e90554b..1bbd4638410 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh @@ -763,9 +763,9 @@ struct cff1_top_dict_values_t : top_dict_values_t<cff1_top_dict_val_t> unsigned int ros_supplement; unsigned int cidCount; - unsigned int EncodingOffset; - unsigned int CharsetOffset; - unsigned int FDSelectOffset; + int EncodingOffset; + int CharsetOffset; + int FDSelectOffset; table_info_t privateDictInfo; }; @@ -821,24 +821,24 @@ struct cff1_top_dict_opset_t : top_dict_opset_t<cff1_top_dict_val_t> break; case OpCode_Encoding: - dictval.EncodingOffset = env.argStack.pop_uint (); + dictval.EncodingOffset = env.argStack.pop_int (); env.clear_args (); if (unlikely (dictval.EncodingOffset == 0)) return; break; case OpCode_charset: - dictval.CharsetOffset = env.argStack.pop_uint (); + dictval.CharsetOffset = env.argStack.pop_int (); env.clear_args (); if (unlikely (dictval.CharsetOffset == 0)) return; break; case OpCode_FDSelect: - dictval.FDSelectOffset = env.argStack.pop_uint (); + dictval.FDSelectOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_Private: - dictval.privateDictInfo.offset = env.argStack.pop_uint (); + dictval.privateDictInfo.offset = env.argStack.pop_int (); dictval.privateDictInfo.size = env.argStack.pop_uint (); env.clear_args (); break; @@ -913,7 +913,7 @@ struct cff1_private_dict_values_base_t : dict_values_t<VAL> } void fini () { dict_values_t<VAL>::fini (); } - unsigned int subrsOffset; + int subrsOffset; const CFF1Subrs *localSubrs; }; @@ -948,7 +948,7 @@ struct cff1_private_dict_opset_t : dict_opset_t env.clear_args (); break; case OpCode_Subrs: - dictval.subrsOffset = env.argStack.pop_uint (); + dictval.subrsOffset = env.argStack.pop_int (); env.clear_args (); break; @@ -990,7 +990,7 @@ struct cff1_private_dict_opset_subset_t : dict_opset_t break; case OpCode_Subrs: - dictval.subrsOffset = env.argStack.pop_uint (); + dictval.subrsOffset = env.argStack.pop_int (); env.clear_args (); break; @@ -1090,8 +1090,8 @@ struct cff1 goto fail; hb_barrier (); - topDictIndex = &StructAtOffset<CFF1TopDictIndex> (nameIndex, nameIndex->get_size ()); - if ((topDictIndex == &Null (CFF1TopDictIndex)) || !topDictIndex->sanitize (&sc) || (topDictIndex->count == 0)) + topDictIndex = &StructAtOffsetOrNull<CFF1TopDictIndex> (nameIndex, nameIndex->get_size (), sc); + if (topDictIndex == &Null (CFF1TopDictIndex) || (topDictIndex->count == 0)) goto fail; hb_barrier (); @@ -1108,20 +1108,18 @@ struct cff1 charset = &Null (Charset); else { - charset = &StructAtOffsetOrNull<Charset> (cff, topDict.CharsetOffset); - if (unlikely ((charset == &Null (Charset)) || !charset->sanitize (&sc, &num_charset_entries))) goto fail; - hb_barrier (); + charset = &StructAtOffsetOrNull<Charset> (cff, topDict.CharsetOffset, sc, &num_charset_entries); + if (unlikely (charset == &Null (Charset))) goto fail; } fdCount = 1; if (is_CID ()) { - fdArray = &StructAtOffsetOrNull<CFF1FDArray> (cff, topDict.FDArrayOffset); - fdSelect = &StructAtOffsetOrNull<CFF1FDSelect> (cff, topDict.FDSelectOffset); - if (unlikely ((fdArray == &Null (CFF1FDArray)) || !fdArray->sanitize (&sc) || - (fdSelect == &Null (CFF1FDSelect)) || !fdSelect->sanitize (&sc, fdArray->count))) + fdArray = &StructAtOffsetOrNull<CFF1FDArray> (cff, topDict.FDArrayOffset, sc); + fdSelect = &StructAtOffsetOrNull<CFF1FDSelect> (cff, topDict.FDSelectOffset, sc, fdArray->count); + if (unlikely (fdArray == &Null (CFF1FDArray) || + fdSelect == &Null (CFF1FDSelect))) goto fail; - hb_barrier (); fdCount = fdArray->count; } @@ -1140,27 +1138,19 @@ struct cff1 { if (!is_predef_encoding ()) { - encoding = &StructAtOffsetOrNull<Encoding> (cff, topDict.EncodingOffset); - if (unlikely ((encoding == &Null (Encoding)) || !encoding->sanitize (&sc))) goto fail; - hb_barrier (); + encoding = &StructAtOffsetOrNull<Encoding> (cff, topDict.EncodingOffset, sc); + if (unlikely (encoding == &Null (Encoding))) goto fail; } } - stringIndex = &StructAtOffset<CFF1StringIndex> (topDictIndex, topDictIndex->get_size ()); - if ((stringIndex == &Null (CFF1StringIndex)) || !stringIndex->sanitize (&sc)) + stringIndex = &StructAtOffsetOrNull<CFF1StringIndex> (topDictIndex, topDictIndex->get_size (), sc); + if (stringIndex == &Null (CFF1StringIndex)) goto fail; - hb_barrier (); - globalSubrs = &StructAtOffset<CFF1Subrs> (stringIndex, stringIndex->get_size ()); - if ((globalSubrs != &Null (CFF1Subrs)) && !globalSubrs->sanitize (&sc)) + globalSubrs = &StructAtOffsetOrNull<CFF1Subrs> (stringIndex, stringIndex->get_size (), sc); + charStrings = &StructAtOffsetOrNull<CFF1CharStrings> (cff, topDict.charStringsOffset, sc); + if (charStrings == &Null (CFF1CharStrings)) goto fail; - hb_barrier (); - - charStrings = &StructAtOffsetOrNull<CFF1CharStrings> (cff, topDict.charStringsOffset); - - if ((charStrings == &Null (CFF1CharStrings)) || unlikely (!charStrings->sanitize (&sc))) - goto fail; - hb_barrier (); num_glyphs = charStrings->count; if (num_glyphs != sc.get_num_glyphs ()) @@ -1188,19 +1178,13 @@ struct cff1 font->init (); if (unlikely (!font_interp.interpret (*font))) goto fail; PRIVDICTVAL *priv = &privateDicts[i]; - const hb_ubytes_t privDictStr = StructAtOffset<UnsizedByteStr> (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); - if (unlikely (!privDictStr.sanitize (&sc))) goto fail; - hb_barrier (); + const hb_ubytes_t privDictStr = StructAtOffsetOrNull<UnsizedByteStr> (cff, font->privateDictInfo.offset, sc, font->privateDictInfo.size).as_ubytes (font->privateDictInfo.size); num_interp_env_t env2 (privDictStr); dict_interpreter_t<PRIVOPSET, PRIVDICTVAL> priv_interp (env2); priv->init (); if (unlikely (!priv_interp.interpret (*priv))) goto fail; - priv->localSubrs = &StructAtOffsetOrNull<CFF1Subrs> (&privDictStr, priv->subrsOffset); - if (priv->localSubrs != &Null (CFF1Subrs) && - unlikely (!priv->localSubrs->sanitize (&sc))) - goto fail; - hb_barrier (); + priv->localSubrs = &StructAtOffsetOrNull<CFF1Subrs> (&privDictStr, priv->subrsOffset, sc); } } else /* non-CID */ @@ -1208,18 +1192,13 @@ struct cff1 cff1_top_dict_values_t *font = &topDict; PRIVDICTVAL *priv = &privateDicts[0]; - const hb_ubytes_t privDictStr = StructAtOffset<UnsizedByteStr> (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); - if (unlikely (!privDictStr.sanitize (&sc))) goto fail; - hb_barrier (); + const hb_ubytes_t privDictStr = StructAtOffsetOrNull<UnsizedByteStr> (cff, font->privateDictInfo.offset, sc, font->privateDictInfo.size).as_ubytes (font->privateDictInfo.size); num_interp_env_t env (privDictStr); dict_interpreter_t<PRIVOPSET, PRIVDICTVAL> priv_interp (env); priv->init (); if (unlikely (!priv_interp.interpret (*priv))) goto fail; - priv->localSubrs = &StructAtOffsetOrNull<CFF1Subrs> (&privDictStr, priv->subrsOffset); - if (priv->localSubrs != &Null (CFF1Subrs) && - unlikely (!priv->localSubrs->sanitize (&sc))) - goto fail; + priv->localSubrs = &StructAtOffsetOrNull<CFF1Subrs> (&privDictStr, priv->subrsOffset, sc); hb_barrier (); } @@ -1437,7 +1416,7 @@ struct cff1 hb_sorted_vector_t<gname_t> *names = glyph_names.get_acquire (); if (unlikely (!names)) { - names = (hb_sorted_vector_t<gname_t> *) hb_calloc (sizeof (hb_sorted_vector_t<gname_t>), 1); + names = (hb_sorted_vector_t<gname_t> *) hb_calloc (1, sizeof (hb_sorted_vector_t<gname_t>)); if (likely (names)) { names->init (); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.hh index 652748b7375..4b3bdc93159 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.hh @@ -111,7 +111,7 @@ struct CFF2FDSelect DEFINE_SIZE_MIN (2); }; -struct CFF2VariationStore +struct CFF2ItemVariationStore { bool sanitize (hb_sanitize_context_t *c) const { @@ -122,11 +122,11 @@ struct CFF2VariationStore varStore.sanitize (c)); } - bool serialize (hb_serialize_context_t *c, const CFF2VariationStore *varStore) + bool serialize (hb_serialize_context_t *c, const CFF2ItemVariationStore *varStore) { TRACE_SERIALIZE (this); unsigned int size_ = varStore->get_size (); - CFF2VariationStore *dest = c->allocate_size<CFF2VariationStore> (size_); + CFF2ItemVariationStore *dest = c->allocate_size<CFF2ItemVariationStore> (size_); if (unlikely (!dest)) return_trace (false); hb_memcpy (dest, varStore, size_); return_trace (true); @@ -135,9 +135,9 @@ struct CFF2VariationStore unsigned int get_size () const { return HBUINT16::static_size + size; } HBUINT16 size; - VariationStore varStore; + ItemVariationStore varStore; - DEFINE_SIZE_MIN (2 + VariationStore::min_size); + DEFINE_SIZE_MIN (2 + ItemVariationStore::min_size); }; struct cff2_top_dict_values_t : top_dict_values_t<> @@ -150,8 +150,8 @@ struct cff2_top_dict_values_t : top_dict_values_t<> } void fini () { top_dict_values_t<>::fini (); } - unsigned int vstoreOffset; - unsigned int FDSelectOffset; + int vstoreOffset; + int FDSelectOffset; }; struct cff2_top_dict_opset_t : top_dict_opset_t<> @@ -169,11 +169,11 @@ struct cff2_top_dict_opset_t : top_dict_opset_t<> break; case OpCode_vstore: - dictval.vstoreOffset = env.argStack.pop_uint (); + dictval.vstoreOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_FDSelect: - dictval.FDSelectOffset = env.argStack.pop_uint (); + dictval.FDSelectOffset = env.argStack.pop_int (); env.clear_args (); break; @@ -241,7 +241,7 @@ struct cff2_private_dict_values_base_t : dict_values_t<VAL> } void fini () { dict_values_t<VAL>::fini (); } - unsigned int subrsOffset; + int subrsOffset; const CFF2Subrs *localSubrs; unsigned int ivs; }; @@ -295,7 +295,7 @@ struct cff2_private_dict_opset_t : dict_opset_t env.clear_args (); break; case OpCode_Subrs: - dictval.subrsOffset = env.argStack.pop_uint (); + dictval.subrsOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_vsindexdict: @@ -344,7 +344,7 @@ struct cff2_private_dict_opset_subset_t : dict_opset_t return; case OpCode_Subrs: - dictval.subrsOffset = env.argStack.pop_uint (); + dictval.subrsOffset = env.argStack.pop_int (); env.clear_args (); break; @@ -426,18 +426,15 @@ struct cff2 if (unlikely (!top_interp.interpret (topDict))) goto fail; } - globalSubrs = &StructAtOffset<CFF2Subrs> (cff2, cff2->topDict + cff2->topDictSize); - varStore = &StructAtOffsetOrNull<CFF2VariationStore> (cff2, topDict.vstoreOffset); - charStrings = &StructAtOffsetOrNull<CFF2CharStrings> (cff2, topDict.charStringsOffset); - fdArray = &StructAtOffsetOrNull<CFF2FDArray> (cff2, topDict.FDArrayOffset); - fdSelect = &StructAtOffsetOrNull<CFF2FDSelect> (cff2, topDict.FDSelectOffset); - - if (((varStore != &Null (CFF2VariationStore)) && unlikely (!varStore->sanitize (&sc))) || - (charStrings == &Null (CFF2CharStrings)) || unlikely (!charStrings->sanitize (&sc)) || - (globalSubrs == &Null (CFF2Subrs)) || unlikely (!globalSubrs->sanitize (&sc)) || - (fdArray == &Null (CFF2FDArray)) || unlikely (!fdArray->sanitize (&sc)) || - !hb_barrier () || - (((fdSelect != &Null (CFF2FDSelect)) && unlikely (!fdSelect->sanitize (&sc, fdArray->count))))) + globalSubrs = &StructAtOffsetOrNull<CFF2Subrs> (cff2, cff2->topDict + cff2->topDictSize, sc); + varStore = &StructAtOffsetOrNull<CFF2ItemVariationStore> (cff2, topDict.vstoreOffset, sc); + charStrings = &StructAtOffsetOrNull<CFF2CharStrings> (cff2, topDict.charStringsOffset, sc); + fdArray = &StructAtOffsetOrNull<CFF2FDArray> (cff2, topDict.FDArrayOffset, sc); + fdSelect = &StructAtOffsetOrNull<CFF2FDSelect> (cff2, topDict.FDSelectOffset, sc, fdArray->count); + + if (charStrings == &Null (CFF2CharStrings) || + globalSubrs == &Null (CFF2Subrs) || + fdArray == &Null (CFF2FDArray)) goto fail; num_glyphs = charStrings->count; @@ -462,19 +459,13 @@ struct cff2 font->init (); if (unlikely (!font_interp.interpret (*font))) goto fail; - const hb_ubytes_t privDictStr = StructAtOffsetOrNull<UnsizedByteStr> (cff2, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); - if (unlikely (!privDictStr.sanitize (&sc))) goto fail; - hb_barrier (); + const hb_ubytes_t privDictStr = StructAtOffsetOrNull<UnsizedByteStr> (cff2, font->privateDictInfo.offset, sc, font->privateDictInfo.size).as_ubytes (font->privateDictInfo.size); cff2_priv_dict_interp_env_t env2 (privDictStr); dict_interpreter_t<PRIVOPSET, PRIVDICTVAL, cff2_priv_dict_interp_env_t> priv_interp (env2); privateDicts[i].init (); if (unlikely (!priv_interp.interpret (privateDicts[i]))) goto fail; - privateDicts[i].localSubrs = &StructAtOffsetOrNull<CFF2Subrs> (&privDictStr[0], privateDicts[i].subrsOffset); - if (privateDicts[i].localSubrs != &Null (CFF2Subrs) && - unlikely (!privateDicts[i].localSubrs->sanitize (&sc))) - goto fail; - hb_barrier (); + privateDicts[i].localSubrs = &StructAtOffsetOrNull<CFF2Subrs> (&privDictStr[0], privateDicts[i].subrsOffset, sc); } return; @@ -509,7 +500,7 @@ struct cff2 hb_blob_t *blob = nullptr; cff2_top_dict_values_t topDict; const CFF2Subrs *globalSubrs = nullptr; - const CFF2VariationStore *varStore = nullptr; + const CFF2ItemVariationStore *varStore = nullptr; const CFF2CharStrings *charStrings = nullptr; const CFF2FDArray *fdArray = nullptr; const CFF2FDSelect *fdSelect = nullptr; 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 e2e25818557..64d2b138804 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 @@ -41,6 +41,30 @@ namespace OT { +static inline uint8_t unicode_to_macroman (hb_codepoint_t u) +{ + uint16_t mapping[] = { + 0x00C4, 0x00C5, 0x00C7, 0x00C9, 0x00D1, 0x00D6, 0x00DC, 0x00E1, + 0x00E0, 0x00E2, 0x00E4, 0x00E3, 0x00E5, 0x00E7, 0x00E9, 0x00E8, + 0x00EA, 0x00EB, 0x00ED, 0x00EC, 0x00EE, 0x00EF, 0x00F1, 0x00F3, + 0x00F2, 0x00F4, 0x00F6, 0x00F5, 0x00FA, 0x00F9, 0x00FB, 0x00FC, + 0x2020, 0x00B0, 0x00A2, 0x00A3, 0x00A7, 0x2022, 0x00B6, 0x00DF, + 0x00AE, 0x00A9, 0x2122, 0x00B4, 0x00A8, 0x2260, 0x00C6, 0x00D8, + 0x221E, 0x00B1, 0x2264, 0x2265, 0x00A5, 0x00B5, 0x2202, 0x2211, + 0x220F, 0x03C0, 0x222B, 0x00AA, 0x00BA, 0x03A9, 0x00E6, 0x00F8, + 0x00BF, 0x00A1, 0x00AC, 0x221A, 0x0192, 0x2248, 0x2206, 0x00AB, + 0x00BB, 0x2026, 0x00A0, 0x00C0, 0x00C3, 0x00D5, 0x0152, 0x0153, + 0x2013, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x25CA, + 0x00FF, 0x0178, 0x2044, 0x20AC, 0x2039, 0x203A, 0xFB01, 0xFB02, + 0x2021, 0x00B7, 0x201A, 0x201E, 0x2030, 0x00C2, 0x00CA, 0x00C1, + 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x00D3, 0x00D4, + 0xF8FF, 0x00D2, 0x00DA, 0x00DB, 0x00D9, 0x0131, 0x02C6, 0x02DC, + 0x00AF, 0x02D8, 0x02D9, 0x02DA, 0x00B8, 0x02DD, 0x02DB, 0x02C7 + }; + uint16_t *c = hb_bsearch (u, mapping, ARRAY_LENGTH (mapping), sizeof (mapping[0]), + _hb_cmp_operator<uint16_t, uint16_t>); + return c ? (c - mapping) + 0x7F : 0; +} struct CmapSubtableFormat0 { @@ -1465,8 +1489,11 @@ struct EncodingRecord int ret; ret = platformID.cmp (other.platformID); if (ret) return ret; - ret = encodingID.cmp (other.encodingID); - if (ret) return ret; + if (other.encodingID != 0xFFFF) + { + ret = encodingID.cmp (other.encodingID); + if (ret) return ret; + } return 0; } @@ -1814,9 +1841,13 @@ struct cmap c->plan)); } - const CmapSubtable *find_best_subtable (bool *symbol = nullptr) const + const CmapSubtable *find_best_subtable (bool *symbol = nullptr, + bool *mac = nullptr, + bool *macroman = nullptr) const { if (symbol) *symbol = false; + if (mac) *mac = false; + if (macroman) *macroman = false; const CmapSubtable *subtable; @@ -1841,6 +1872,20 @@ struct cmap if ((subtable = this->find_subtable (0, 1))) return subtable; if ((subtable = this->find_subtable (0, 0))) return subtable; + /* MacRoman subtable. */ + if ((subtable = this->find_subtable (1, 0))) + { + if (mac) *mac = true; + if (macroman) *macroman = true; + return subtable; + } + /* Any other Mac subtable; we just map ASCII for these. */ + if ((subtable = this->find_subtable (1, 0xFFFF))) + { + if (mac) *mac = true; + return subtable; + } + /* Meh. */ return &Null (CmapSubtable); } @@ -1852,8 +1897,8 @@ struct cmap accelerator_t (hb_face_t *face) { this->table = hb_sanitize_context_t ().reference_table<cmap> (face); - bool symbol; - this->subtable = table->find_best_subtable (&symbol); + bool symbol, mac, macroman; + this->subtable = table->find_best_subtable (&symbol, &mac, ¯oman); this->subtable_uvs = &Null (CmapSubtableFormat14); { const CmapSubtable *st = table->find_subtable (0, 5); @@ -1862,6 +1907,7 @@ struct cmap } this->get_glyph_data = subtable; +#ifndef HB_NO_CMAP_LEGACY_SUBTABLES if (unlikely (symbol)) { switch ((unsigned) face->table.OS2->get_font_page ()) { @@ -1881,7 +1927,16 @@ struct cmap break; } } + else if (unlikely (macroman)) + { + this->get_glyph_funcZ = get_glyph_from_macroman<CmapSubtable>; + } + else if (unlikely (mac)) + { + this->get_glyph_funcZ = get_glyph_from_ascii<CmapSubtable>; + } else +#endif { switch (subtable->u.format) { /* Accelerate format 4 and format 12. */ @@ -1924,7 +1979,7 @@ struct cmap hb_codepoint_t *glyph, cache_t *cache = nullptr) const { - if (unlikely (!this->get_glyph_funcZ)) return 0; + if (unlikely (!this->get_glyph_funcZ)) return false; return _cached_get (unicode, glyph, cache); } @@ -2006,6 +2061,28 @@ struct cmap return false; } + template <typename Type> + HB_INTERNAL static bool get_glyph_from_ascii (const void *obj, + hb_codepoint_t codepoint, + hb_codepoint_t *glyph) + { + const Type *typed_obj = (const Type *) obj; + return codepoint < 0x80 && typed_obj->get_glyph (codepoint, glyph); + } + + template <typename Type> + HB_INTERNAL static bool get_glyph_from_macroman (const void *obj, + hb_codepoint_t codepoint, + hb_codepoint_t *glyph) + { + if (get_glyph_from_ascii<Type> (obj, codepoint, glyph)) + return true; + + const Type *typed_obj = (const Type *) obj; + unsigned c = unicode_to_macroman (codepoint); + return c && typed_obj->get_glyph (c, glyph); + } + private: hb_nonnull_ptr_t<const CmapSubtable> subtable; hb_nonnull_ptr_t<const CmapSubtableFormat14> subtable_uvs; @@ -2035,28 +2112,6 @@ struct cmap return &(this+result.subtable); } - const EncodingRecord *find_encodingrec (unsigned int platform_id, - unsigned int encoding_id) const - { - EncodingRecord key; - key.platformID = platform_id; - key.encodingID = encoding_id; - - return encodingRecord.as_array ().bsearch (key); - } - - bool find_subtable (unsigned format) const - { - auto it = - + hb_iter (encodingRecord) - | hb_map (&EncodingRecord::subtable) - | hb_map (hb_add (this)) - | hb_filter ([&] (const CmapSubtable& _) { return _.u.format == format; }) - ; - - return it.len (); - } - public: bool sanitize (hb_sanitize_context_t *c) const 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 b3677c6a4c0..1da869d697a 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 @@ -208,12 +208,12 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, #if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) const OT::HVAR &HVAR = *hmtx.var_table; - const OT::VariationStore &varStore = &HVAR + HVAR.varStore; - OT::VariationStore::cache_t *varStore_cache = font->num_coords * count >= 128 ? varStore.create_cache () : nullptr; + const OT::ItemVariationStore &varStore = &HVAR + HVAR.varStore; + OT::ItemVariationStore::cache_t *varStore_cache = font->num_coords * count >= 128 ? varStore.create_cache () : nullptr; bool use_cache = font->num_coords; #else - OT::VariationStore::cache_t *varStore_cache = nullptr; + OT::ItemVariationStore::cache_t *varStore_cache = nullptr; bool use_cache = false; #endif @@ -277,7 +277,7 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, } #if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) - OT::VariationStore::destroy_cache (varStore_cache); + OT::ItemVariationStore::destroy_cache (varStore_cache); #endif if (font->x_strength && !font->embolden_in_place) @@ -313,10 +313,10 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, { #if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) const OT::VVAR &VVAR = *vmtx.var_table; - const OT::VariationStore &varStore = &VVAR + VVAR.varStore; - OT::VariationStore::cache_t *varStore_cache = font->num_coords ? varStore.create_cache () : nullptr; + const OT::ItemVariationStore &varStore = &VVAR + VVAR.varStore; + OT::ItemVariationStore::cache_t *varStore_cache = font->num_coords ? varStore.create_cache () : nullptr; #else - OT::VariationStore::cache_t *varStore_cache = nullptr; + OT::ItemVariationStore::cache_t *varStore_cache = nullptr; #endif for (unsigned int i = 0; i < count; i++) @@ -327,7 +327,7 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, } #if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) - OT::VariationStore::destroy_cache (varStore_cache); + OT::ItemVariationStore::destroy_cache (varStore_cache); #endif } else 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 89640b43f15..48bd536121d 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 @@ -145,6 +145,29 @@ struct hmtxvmtx table->minTrailingBearing = min_rsb; table->maxExtent = max_extent; } + + if (T::is_horizontal) + { + const auto &OS2 = *c->plan->source->table.OS2; + if (OS2.has_data () && + table->ascender == OS2.sTypoAscender && + table->descender == OS2.sTypoDescender && + table->lineGap == OS2.sTypoLineGap) + { + table->ascender = static_cast<int> (roundf (OS2.sTypoAscender + + MVAR.get_var (HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER, + c->plan->normalized_coords.arrayZ, + c->plan->normalized_coords.length))); + table->descender = static_cast<int> (roundf (OS2.sTypoDescender + + MVAR.get_var (HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER, + c->plan->normalized_coords.arrayZ, + c->plan->normalized_coords.length))); + table->lineGap = static_cast<int> (roundf (OS2.sTypoLineGap + + MVAR.get_var (HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP, + c->plan->normalized_coords.arrayZ, + c->plan->normalized_coords.length))); + } + } } #endif @@ -374,7 +397,7 @@ struct hmtxvmtx unsigned get_advance_with_var_unscaled (hb_codepoint_t glyph, hb_font_t *font, - VariationStore::cache_t *store_cache = nullptr) const + ItemVariationStore::cache_t *store_cache = nullptr) const { unsigned int advance = get_advance_without_var_unscaled (glyph); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh index a23b6377d19..02783990698 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh @@ -46,6 +46,12 @@ struct BaseCoordFormat1 return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_y (coordinate) : font->em_scale_x (coordinate); } + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + return_trace ((bool) c->serializer->embed (*this)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -67,6 +73,17 @@ struct BaseCoordFormat2 return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_y (coordinate) : font->em_scale_x (coordinate); } + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + return_trace (c->serializer->check_assign (out->referenceGlyph, + c->plan->glyph_map->get (referenceGlyph), + HB_SERIALIZE_ERROR_INT_OVERFLOW)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -86,7 +103,7 @@ struct BaseCoordFormat2 struct BaseCoordFormat3 { hb_position_t get_coord (hb_font_t *font, - const VariationStore &var_store, + const ItemVariationStore &var_store, hb_direction_t direction) const { const Device &device = this+deviceTable; @@ -96,6 +113,23 @@ struct BaseCoordFormat3 : font->em_scale_x (coordinate) + device.get_x_delta (font, var_store); } + void collect_variation_indices (hb_set_t& varidx_set /* OUT */) const + { + unsigned varidx = (this+deviceTable).get_variation_index (); + varidx_set.add (varidx); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + return_trace (out->deviceTable.serialize_copy (c->serializer, deviceTable, + this, 0, + hb_serialize_context_t::Head, + &c->plan->base_variation_idx_map)); + } bool sanitize (hb_sanitize_context_t *c) const { @@ -120,7 +154,7 @@ struct BaseCoord bool has_data () const { return u.format; } hb_position_t get_coord (hb_font_t *font, - const VariationStore &var_store, + const ItemVariationStore &var_store, hb_direction_t direction) const { switch (u.format) { @@ -131,6 +165,27 @@ struct BaseCoord } } + void collect_variation_indices (hb_set_t& varidx_set /* OUT */) const + { + switch (u.format) { + case 3: u.format3.collect_variation_indices (varidx_set); + default:return; + } + } + + template <typename context_t, typename ...Ts> + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { + if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format); + switch (u.format) { + case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); + case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); + case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...)); + default:return_trace (c->default_return_value ()); + } + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -161,12 +216,37 @@ struct FeatMinMaxRecord bool has_data () const { return tag; } + hb_tag_t get_feature_tag () const { return tag; } + void get_min_max (const BaseCoord **min, const BaseCoord **max) const { if (likely (min)) *min = &(this+minCoord); if (likely (max)) *max = &(this+maxCoord); } + void collect_variation_indices (const hb_subset_plan_t* plan, + const void *base, + hb_set_t& varidx_set /* OUT */) const + { + if (!plan->layout_features.has (tag)) + return; + + (base+minCoord).collect_variation_indices (varidx_set); + (base+maxCoord).collect_variation_indices (varidx_set); + } + + bool subset (hb_subset_context_t *c, + const void *base) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + if (!(out->minCoord.serialize_subset (c, minCoord, base))) + return_trace (false); + + return_trace (out->maxCoord.serialize_subset (c, maxCoord, base)); + } + bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -206,6 +286,39 @@ struct MinMax } } + void collect_variation_indices (const hb_subset_plan_t* plan, + hb_set_t& varidx_set /* OUT */) const + { + (this+minCoord).collect_variation_indices (varidx_set); + (this+maxCoord).collect_variation_indices (varidx_set); + for (const FeatMinMaxRecord& record : featMinMaxRecords) + record.collect_variation_indices (plan, this, varidx_set); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + if (!(out->minCoord.serialize_subset (c, minCoord, this)) || + !(out->maxCoord.serialize_subset (c, maxCoord, this))) + return_trace (false); + + unsigned len = 0; + for (const FeatMinMaxRecord& _ : featMinMaxRecords) + { + hb_tag_t feature_tag = _.get_feature_tag (); + if (!c->plan->layout_features.has (feature_tag)) + continue; + + if (!_.subset (c, this)) return false; + len++; + } + return_trace (c->serializer->check_assign (out->featMinMaxRecords.len, len, + HB_SERIALIZE_ERROR_INT_OVERFLOW)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -240,6 +353,26 @@ struct BaseValues return this+baseCoords[baseline_tag_index]; } + void collect_variation_indices (hb_set_t& varidx_set /* OUT */) const + { + for (const auto& _ : baseCoords) + (this+_).collect_variation_indices (varidx_set); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + out->defaultIndex = defaultIndex; + + for (const auto& _ : baseCoords) + if (!subset_offset_array (c, out->baseCoords, this) (_)) + return_trace (false); + + return_trace (bool (out->baseCoords)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -270,6 +403,20 @@ struct BaseLangSysRecord const MinMax &get_min_max () const { return this+minMax; } + void collect_variation_indices (const hb_subset_plan_t* plan, + hb_set_t& varidx_set /* OUT */) const + { (this+minMax).collect_variation_indices (plan, varidx_set); } + + bool subset (hb_subset_context_t *c, + const void *base) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + return_trace (out->minMax.serialize_subset (c, minMax, base)); + } + bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -300,6 +447,35 @@ struct BaseScript bool has_values () const { return baseValues; } bool has_min_max () const { return defaultMinMax; /* TODO What if only per-language is present? */ } + void collect_variation_indices (const hb_subset_plan_t* plan, + hb_set_t& varidx_set /* OUT */) const + { + (this+baseValues).collect_variation_indices (varidx_set); + (this+defaultMinMax).collect_variation_indices (plan, varidx_set); + + for (const BaseLangSysRecord& _ : baseLangSysRecords) + _.collect_variation_indices (plan, varidx_set); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + if (baseValues && !out->baseValues.serialize_subset (c, baseValues, this)) + return_trace (false); + + if (defaultMinMax && !out->defaultMinMax.serialize_subset (c, defaultMinMax, this)) + return_trace (false); + + for (const auto& _ : baseLangSysRecords) + if (!_.subset (c, this)) return_trace (false); + + return_trace (c->serializer->check_assign (out->baseLangSysRecords.len, baseLangSysRecords.len, + HB_SERIALIZE_ERROR_INT_OVERFLOW)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -332,9 +508,31 @@ struct BaseScriptRecord bool has_data () const { return baseScriptTag; } + hb_tag_t get_script_tag () const { return baseScriptTag; } + const BaseScript &get_base_script (const BaseScriptList *list) const { return list+baseScript; } + void collect_variation_indices (const hb_subset_plan_t* plan, + const void* list, + hb_set_t& varidx_set /* OUT */) const + { + if (!plan->layout_scripts.has (baseScriptTag)) + return; + + (list+baseScript).collect_variation_indices (plan, varidx_set); + } + + bool subset (hb_subset_context_t *c, + const void *base) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + return_trace (out->baseScript.serialize_subset (c, baseScript, base)); + } + bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -361,6 +559,33 @@ struct BaseScriptList return record->has_data () ? record->get_base_script (this) : Null (BaseScript); } + void collect_variation_indices (const hb_subset_plan_t* plan, + hb_set_t& varidx_set /* OUT */) const + { + for (const BaseScriptRecord& _ : baseScriptRecords) + _.collect_variation_indices (plan, this, varidx_set); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + unsigned len = 0; + for (const BaseScriptRecord& _ : baseScriptRecords) + { + hb_tag_t script_tag = _.get_script_tag (); + if (!c->plan->layout_scripts.has (script_tag)) + continue; + + if (!_.subset (c, this)) return false; + len++; + } + return_trace (c->serializer->check_assign (out->baseScriptRecords.len, len, + HB_SERIALIZE_ERROR_INT_OVERFLOW)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -422,6 +647,20 @@ struct Axis return true; } + void collect_variation_indices (const hb_subset_plan_t* plan, + hb_set_t& varidx_set /* OUT */) const + { (this+baseScriptList).collect_variation_indices (plan, varidx_set); } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + out->baseTagList.serialize_copy (c->serializer, baseTagList, this); + return_trace (out->baseScriptList.serialize_subset (c, baseScriptList, this)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -453,8 +692,41 @@ struct BASE const Axis &get_axis (hb_direction_t direction) const { return HB_DIRECTION_IS_VERTICAL (direction) ? this+vAxis : this+hAxis; } - const VariationStore &get_var_store () const - { return version.to_int () < 0x00010001u ? Null (VariationStore) : this+varStore; } + bool has_var_store () const + { return version.to_int () >= 0x00010001u && varStore != 0; } + + const ItemVariationStore &get_var_store () const + { return version.to_int () < 0x00010001u ? Null (ItemVariationStore) : this+varStore; } + + void collect_variation_indices (const hb_subset_plan_t* plan, + hb_set_t& varidx_set /* OUT */) const + { + (this+hAxis).collect_variation_indices (plan, varidx_set); + (this+vAxis).collect_variation_indices (plan, varidx_set); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + out->version = version; + if (hAxis && !out->hAxis.serialize_subset (c, hAxis, this)) + return_trace (false); + + if (vAxis && !out->vAxis.serialize_subset (c, vAxis, this)) + return_trace (false); + + if (has_var_store ()) + { + if (!c->serializer->allocate_size<Offset32To<ItemVariationStore>> (Offset32To<ItemVariationStore>::static_size)) + return_trace (false); + return_trace (out->varStore.serialize_subset (c, varStore, this, c->plan->base_varstore_inner_maps.as_array ())); + } + + return_trace (true); + } bool get_baseline (hb_font_t *font, hb_tag_t baseline_tag, @@ -487,7 +759,7 @@ struct BASE &min_coord, &max_coord)) return false; - const VariationStore &var_store = get_var_store (); + const ItemVariationStore &var_store = get_var_store (); if (likely (min && min_coord)) *min = min_coord->get_coord (font, var_store, direction); if (likely (max && max_coord)) *max = max_coord->get_coord (font, var_store, direction); return true; @@ -510,7 +782,7 @@ struct BASE * of BASE table (may be NULL) */ Offset16To<Axis>vAxis; /* Offset to vertical Axis table, from beginning * of BASE table (may be NULL) */ - Offset32To<VariationStore> + Offset32To<ItemVariationStore> varStore; /* Offset to the table of Item Variation * Store--from beginning of BASE * header (may be NULL). Introduced 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 6b359cceb72..aba427368ca 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 @@ -188,7 +188,7 @@ struct hb_subset_layout_context_t : unsigned lookup_index_count; }; -struct VariationStore; +struct ItemVariationStore; struct hb_collect_variation_indices_context_t : hb_dispatch_context_t<hb_collect_variation_indices_context_t> { @@ -3036,7 +3036,7 @@ struct VarData DEFINE_SIZE_ARRAY (6, regionIndices); }; -struct VariationStore +struct ItemVariationStore { friend struct item_variations_t; using cache_t = VarRegionList::cache_t; @@ -3141,7 +3141,7 @@ struct VariationStore } bool serialize (hb_serialize_context_t *c, - const VariationStore *src, + const ItemVariationStore *src, const hb_array_t <const hb_inc_bimap_t> &inner_maps) { TRACE_SERIALIZE (this); @@ -3197,7 +3197,7 @@ struct VariationStore return_trace (true); } - VariationStore *copy (hb_serialize_context_t *c) const + ItemVariationStore *copy (hb_serialize_context_t *c) const { TRACE_SERIALIZE (this); auto *out = c->start_embed (this); @@ -3227,7 +3227,7 @@ struct VariationStore return_trace (false); #endif - VariationStore *varstore_prime = c->serializer->start_embed<VariationStore> (); + ItemVariationStore *varstore_prime = c->serializer->start_embed<ItemVariationStore> (); if (unlikely (!varstore_prime)) return_trace (false); varstore_prime->serialize (c->serializer, this, inner_maps); @@ -4030,13 +4030,13 @@ struct VariationDevice private: hb_position_t get_x_delta (hb_font_t *font, - const VariationStore &store, - VariationStore::cache_t *store_cache = nullptr) const + const ItemVariationStore &store, + ItemVariationStore::cache_t *store_cache = nullptr) const { return font->em_scalef_x (get_delta (font, store, store_cache)); } hb_position_t get_y_delta (hb_font_t *font, - const VariationStore &store, - VariationStore::cache_t *store_cache = nullptr) const + const ItemVariationStore &store, + ItemVariationStore::cache_t *store_cache = nullptr) const { return font->em_scalef_y (get_delta (font, store, store_cache)); } VariationDevice* copy (hb_serialize_context_t *c, @@ -4070,10 +4070,10 @@ struct VariationDevice private: float get_delta (hb_font_t *font, - const VariationStore &store, - VariationStore::cache_t *store_cache = nullptr) const + const ItemVariationStore &store, + ItemVariationStore::cache_t *store_cache = nullptr) const { - return store.get_delta (varIdx, font->coords, font->num_coords, (VariationStore::cache_t *) store_cache); + return store.get_delta (varIdx, font->coords, font->num_coords, (ItemVariationStore::cache_t *) store_cache); } protected: @@ -4097,8 +4097,8 @@ struct DeviceHeader struct Device { hb_position_t get_x_delta (hb_font_t *font, - const VariationStore &store=Null (VariationStore), - VariationStore::cache_t *store_cache = nullptr) const + const ItemVariationStore &store=Null (ItemVariationStore), + ItemVariationStore::cache_t *store_cache = nullptr) const { switch (u.b.format) { @@ -4115,8 +4115,8 @@ struct Device } } hb_position_t get_y_delta (hb_font_t *font, - const VariationStore &store=Null (VariationStore), - VariationStore::cache_t *store_cache = nullptr) const + const ItemVariationStore &store=Null (ItemVariationStore), + ItemVariationStore::cache_t *store_cache = nullptr) const { switch (u.b.format) { 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 499ad673e42..162179d08a7 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 @@ -708,8 +708,8 @@ struct hb_ot_apply_context_t : recurse_func_t recurse_func = nullptr; const GDEF &gdef; const GDEF::accelerator_t &gdef_accel; - const VariationStore &var_store; - VariationStore::cache_t *var_store_cache; + const ItemVariationStore &var_store; + ItemVariationStore::cache_t *var_store_cache; hb_set_digest_t digest; hb_direction_t direction; @@ -766,7 +766,7 @@ struct hb_ot_apply_context_t : ~hb_ot_apply_context_t () { #ifndef HB_NO_VAR - VariationStore::destroy_cache (var_store_cache); + ItemVariationStore::destroy_cache (var_store_cache); #endif } 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 2eb8535db5a..a4c13abadf2 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 @@ -2127,7 +2127,7 @@ hb_ot_layout_get_font_extents (hb_font_t *font, hb_tag_t language_tag, hb_font_extents_t *extents) { - hb_position_t min, max; + hb_position_t min = 0, max = 0; if (font->face->table.BASE->get_min_max (font, direction, script_tag, language_tag, HB_TAG_NONE, &min, &max)) { 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 32e497aef60..5839059fde0 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 @@ -344,27 +344,20 @@ struct MathKern 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 - * "between the two heights found at those indexes" for 0 < i < len as - * - * correctionHeight[i-1] < correction_height <= correctionHeight[i] - * - * makes the result consistent with the limit cases and we can just use the - * binary search algorithm of std::upper_bound: + /* According to OpenType spec (v1.9), except for the boundary cases, the index + * chosen for kern value should be i such that + * correctionHeight[i-1] <= correction_height < correctionHeight[i] + * We can use the binary search algorithm of std::upper_bound(). Or, we can + * use the internal hb_bsearch_impl. */ - unsigned int i = 0; - unsigned int count = heightCount; - while (count > 0) - { - unsigned int half = count / 2; - hb_position_t height = correctionHeight[i + half].get_y_value (font, this); - if (sign * height < sign * correction_height) - { - i += half + 1; - count -= half + 1; - } else - count = half; - } + unsigned int pos; + auto cmp = +[](const void* key, const void* p, + int sign, hb_font_t* font, const MathKern* mathKern) -> int { + return sign * *(hb_position_t*)key - sign * ((MathValueRecord*)p)->get_y_value(font, mathKern); + }; + unsigned int i = hb_bsearch_impl(&pos, correction_height, correctionHeight, + heightCount, MathValueRecord::static_size, + cmp, sign, font, this) ? pos + 1 : pos; return kernValue[i].get_x_value (font, this); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic.cc index 72dcc84df5e..d70746ed2bb 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic.cc @@ -560,9 +560,9 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED, DEBUG_MSG (ARABIC, nullptr, "%s stretch at (%u,%u,%u)", step == MEASURE ? "measuring" : "cutting", context, start, end); - DEBUG_MSG (ARABIC, nullptr, "rest of word: count=%u width %d", start - context, w_total); - DEBUG_MSG (ARABIC, nullptr, "fixed tiles: count=%d width=%d", n_fixed, w_fixed); - DEBUG_MSG (ARABIC, nullptr, "repeating tiles: count=%d width=%d", n_repeating, w_repeating); + DEBUG_MSG (ARABIC, nullptr, "rest of word: count=%u width %" PRId32, start - context, w_total); + DEBUG_MSG (ARABIC, nullptr, "fixed tiles: count=%d width=%" PRId32, n_fixed, w_fixed); + DEBUG_MSG (ARABIC, nullptr, "repeating tiles: count=%d width=%" PRId32, n_repeating, w_repeating); /* Number of additional times to repeat each repeating tile. */ int n_copies = 0; @@ -602,7 +602,7 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED, if (info[k - 1].arabic_shaping_action() == STCH_REPEATING) repeat += n_copies; - DEBUG_MSG (ARABIC, nullptr, "appending %u copies of glyph %u; j=%u", + DEBUG_MSG (ARABIC, nullptr, "appending %u copies of glyph %" PRIu32 "; j=%u", repeat, info[k - 1].codepoint, j); pos[k - 1].x_advance = 0; for (unsigned int n = 0; n < repeat; n++) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh index 58b3cd74dff..e88c82a13c7 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh @@ -349,7 +349,7 @@ struct AxisValueFormat4 struct AxisValue { - bool get_value (unsigned int axis_index) const + float get_value (unsigned int axis_index) const { switch (u.format) { @@ -357,7 +357,7 @@ struct AxisValue case 2: return u.format2.get_value (); case 3: return u.format3.get_value (); case 4: return u.format4.get_axis_record (axis_index).get_value (); - default:return 0; + default:return 0.f; } } @@ -485,7 +485,7 @@ struct STAT hb_array_t<const Offset16To<AxisValue>> axis_values = get_axis_value_offsets (); for (unsigned int i = 0; i < axis_values.length; i++) { - const AxisValue& axis_value = this+axis_values[i]; + const AxisValue& axis_value = this+offsetToAxisValueOffsets+axis_values[i]; if (axis_value.get_axis_index () == axis_index) { if (value) 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 index 032a7c866c5..db92f4664a9 100644 --- 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 @@ -6,8 +6,8 @@ * * on files with these headers: * - * <meta name="updated_at" content="2022-09-30 11:47 PM" /> - * File-Date: 2023-08-02 + * <meta name="updated_at" content="2023-09-30 01:21 AM" /> + * File-Date: 2024-03-07 */ #ifndef HB_OT_TAG_TABLE_HH @@ -31,7 +31,7 @@ static const LangTag ot_languages2[] = { {HB_TAG('b','i',' ',' '), HB_TAG('B','I','S',' ')}, /* Bislama */ {HB_TAG('b','i',' ',' '), HB_TAG('C','P','P',' ')}, /* Bislama -> Creoles */ {HB_TAG('b','m',' ',' '), HB_TAG('B','M','B',' ')}, /* Bambara (Bamanankan) */ - {HB_TAG('b','n',' ',' '), HB_TAG('B','E','N',' ')}, /* Bengali */ + {HB_TAG('b','n',' ',' '), HB_TAG('B','E','N',' ')}, /* Bangla */ {HB_TAG('b','o',' ',' '), HB_TAG('T','I','B',' ')}, /* Tibetan */ {HB_TAG('b','r',' ',' '), HB_TAG('B','R','E',' ')}, /* Breton */ {HB_TAG('b','s',' ',' '), HB_TAG('B','O','S',' ')}, /* Bosnian */ @@ -64,7 +64,7 @@ static const LangTag ot_languages2[] = { {HB_TAG('f','r',' ',' '), HB_TAG('F','R','A',' ')}, /* French */ {HB_TAG('f','y',' ',' '), HB_TAG('F','R','I',' ')}, /* Western Frisian -> Frisian */ {HB_TAG('g','a',' ',' '), HB_TAG('I','R','I',' ')}, /* Irish */ - {HB_TAG('g','d',' ',' '), HB_TAG('G','A','E',' ')}, /* Scottish Gaelic (Gaelic) */ + {HB_TAG('g','d',' ',' '), HB_TAG('G','A','E',' ')}, /* Scottish Gaelic */ {HB_TAG('g','l',' ',' '), HB_TAG('G','A','L',' ')}, /* Galician */ {HB_TAG('g','n',' ',' '), HB_TAG('G','U','A',' ')}, /* Guarani [macrolanguage] */ {HB_TAG('g','u',' ',' '), HB_TAG('G','U','J',' ')}, /* Gujarati */ @@ -132,7 +132,7 @@ static const LangTag ot_languages2[] = { {HB_TAG('m','l',' ',' '), HB_TAG('M','A','L',' ')}, /* Malayalam -> Malayalam Traditional */ {HB_TAG('m','l',' ',' '), HB_TAG('M','L','R',' ')}, /* Malayalam -> Malayalam Reformed */ {HB_TAG('m','n',' ',' '), HB_TAG('M','N','G',' ')}, /* Mongolian [macrolanguage] */ - {HB_TAG('m','o',' ',' '), HB_TAG('M','O','L',' ')}, /* Moldavian (retired code) */ + {HB_TAG('m','o',' ',' '), HB_TAG('M','O','L',' ')}, /* Moldavian (retired code) -> Romanian (Moldova) */ {HB_TAG('m','o',' ',' '), HB_TAG('R','O','M',' ')}, /* Moldavian (retired code) -> Romanian */ {HB_TAG('m','r',' ',' '), HB_TAG('M','A','R',' ')}, /* Marathi */ {HB_TAG('m','s',' ',' '), HB_TAG('M','L','Y',' ')}, /* Malay [macrolanguage] */ @@ -153,7 +153,7 @@ static const LangTag ot_languages2[] = { {HB_TAG('o','c',' ',' '), HB_TAG('O','C','I',' ')}, /* Occitan (post 1500) */ {HB_TAG('o','j',' ',' '), HB_TAG('O','J','B',' ')}, /* Ojibwa [macrolanguage] -> Ojibway */ {HB_TAG('o','m',' ',' '), HB_TAG('O','R','O',' ')}, /* Oromo [macrolanguage] */ - {HB_TAG('o','r',' ',' '), HB_TAG('O','R','I',' ')}, /* Odia (formerly Oriya) [macrolanguage] */ + {HB_TAG('o','r',' ',' '), HB_TAG('O','R','I',' ')}, /* Odia [macrolanguage] */ {HB_TAG('o','s',' ',' '), HB_TAG('O','S','S',' ')}, /* Ossetian */ {HB_TAG('p','a',' ',' '), HB_TAG('P','A','N',' ')}, /* Punjabi */ {HB_TAG('p','i',' ',' '), HB_TAG('P','A','L',' ')}, /* Pali */ @@ -166,7 +166,7 @@ static const LangTag ot_languages2[] = { {HB_TAG('r','o',' ',' '), HB_TAG('R','O','M',' ')}, /* Romanian */ {HB_TAG('r','u',' ',' '), HB_TAG('R','U','S',' ')}, /* Russian */ {HB_TAG('r','w',' ',' '), HB_TAG('R','U','A',' ')}, /* Kinyarwanda */ - {HB_TAG('s','a',' ',' '), HB_TAG('S','A','N',' ')}, /* Sanskrit */ + {HB_TAG('s','a',' ',' '), HB_TAG('S','A','N',' ')}, /* Sanskrit [macrolanguage] */ {HB_TAG('s','c',' ',' '), HB_TAG('S','R','D',' ')}, /* Sardinian [macrolanguage] */ {HB_TAG('s','d',' ',' '), HB_TAG('S','N','D',' ')}, /* Sindhi */ {HB_TAG('s','e',' ',' '), HB_TAG('N','S','M',' ')}, /* Northern Sami */ @@ -465,6 +465,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('c','l','d',' '), HB_TAG('S','Y','R',' ')}, /* Chaldean Neo-Aramaic -> Syriac */ {HB_TAG('c','l','e',' '), HB_TAG('C','C','H','N')}, /* Lealao Chinantec -> Chinantec */ {HB_TAG('c','l','j',' '), HB_TAG('Q','I','N',' ')}, /* Laitu Chin -> Chin */ + {HB_TAG('c','l','s',' '), HB_TAG('S','A','N',' ')}, /* Classical Sanskrit -> Sanskrit */ {HB_TAG('c','l','t',' '), HB_TAG('Q','I','N',' ')}, /* Lautu Chin -> Chin */ {HB_TAG('c','m','n',' '), HB_TAG('Z','H','S',' ')}, /* Mandarin Chinese -> Chinese, Simplified */ {HB_TAG('c','m','r',' '), HB_TAG('Q','I','N',' ')}, /* Mro-Khimi Chin -> Chin */ @@ -637,7 +638,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('g','a','a',' '), HB_TAG('G','A','D',' ')}, /* Ga */ {HB_TAG('g','a','c',' '), HB_TAG('C','P','P',' ')}, /* Mixed Great Andamanese -> Creoles */ {HB_TAG('g','a','d',' '), HB_TAG_NONE }, /* Gaddang != Ga */ - {HB_TAG('g','a','e',' '), HB_TAG_NONE }, /* Guarequena != Scottish Gaelic (Gaelic) */ + {HB_TAG('g','a','e',' '), HB_TAG_NONE }, /* Guarequena != Scottish Gaelic */ /*{HB_TAG('g','a','g',' '), HB_TAG('G','A','G',' ')},*/ /* Gagauz */ {HB_TAG('g','a','l',' '), HB_TAG_NONE }, /* Galolen != Galician */ {HB_TAG('g','a','n',' '), HB_TAG('Z','H','S',' ')}, /* Gan Chinese -> Chinese, Simplified */ @@ -1160,7 +1161,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('o','r','o',' '), HB_TAG_NONE }, /* Orokolo != Oromo */ {HB_TAG('o','r','r',' '), HB_TAG('I','J','O',' ')}, /* Oruma -> Ijo */ {HB_TAG('o','r','s',' '), HB_TAG('M','L','Y',' ')}, /* Orang Seletar -> Malay */ - {HB_TAG('o','r','y',' '), HB_TAG('O','R','I',' ')}, /* Odia (formerly Oriya) */ + {HB_TAG('o','r','y',' '), HB_TAG('O','R','I',' ')}, /* Odia */ {HB_TAG('o','t','w',' '), HB_TAG('O','J','B',' ')}, /* Ottawa -> Ojibway */ {HB_TAG('o','u','a',' '), HB_TAG('B','B','R',' ')}, /* Tagargrent -> Berber */ {HB_TAG('p','a','a',' '), HB_TAG_NONE }, /* Papuan [collection] != Palestinian Aramaic */ @@ -1395,7 +1396,7 @@ static const LangTag ot_languages3[] = { /*{HB_TAG('s','n','k',' '), HB_TAG('S','N','K',' ')},*/ /* Soninke */ {HB_TAG('s','o','g',' '), HB_TAG_NONE }, /* Sogdian != Sodo Gurage */ /*{HB_TAG('s','o','p',' '), HB_TAG('S','O','P',' ')},*/ /* Songe */ - {HB_TAG('s','p','v',' '), HB_TAG('O','R','I',' ')}, /* Sambalpuri -> Odia (formerly Oriya) */ + {HB_TAG('s','p','v',' '), HB_TAG('O','R','I',' ')}, /* Sambalpuri -> Odia */ {HB_TAG('s','p','y',' '), HB_TAG('K','A','L',' ')}, /* Sabaot -> Kalenjin */ {HB_TAG('s','r','b',' '), HB_TAG_NONE }, /* Sora != Serbian */ {HB_TAG('s','r','c',' '), HB_TAG('S','R','D',' ')}, /* Logudorese Sardinian -> Sardinian */ @@ -1533,6 +1534,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('v','l','s',' '), HB_TAG('F','L','E',' ')}, /* Vlaams -> Dutch (Flemish) */ {HB_TAG('v','m','w',' '), HB_TAG('M','A','K',' ')}, /* Makhuwa */ /*{HB_TAG('v','r','o',' '), HB_TAG('V','R','O',' ')},*/ /* Võro */ + {HB_TAG('v','s','n',' '), HB_TAG('S','A','N',' ')}, /* Vedic Sanskrit -> Sanskrit */ {HB_TAG('w','a','g',' '), HB_TAG_NONE }, /* Wa'ema != Wagdi */ /*{HB_TAG('w','a','r',' '), HB_TAG('W','A','R',' ')},*/ /* Waray (Philippines) -> Waray-Waray */ {HB_TAG('w','b','m',' '), HB_TAG('W','A',' ',' ')}, /* Wa */ @@ -2643,7 +2645,7 @@ out: /* Romanian; Moldova */ unsigned int i; hb_tag_t possible_tags[] = { - HB_TAG('M','O','L',' '), /* Moldavian */ + HB_TAG('M','O','L',' '), /* Romanian (Moldova) */ HB_TAG('R','O','M',' '), /* Romanian */ }; for (i = 0; i < 2 && i < *count; i++) @@ -2920,7 +2922,7 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag) return hb_language_from_string ("mn", -1); /* Mongolian [macrolanguage] */ case HB_TAG('M','N','K',' '): /* Maninka */ return hb_language_from_string ("man", -1); /* Mandingo [macrolanguage] */ - case HB_TAG('M','O','L',' '): /* Moldavian */ + case HB_TAG('M','O','L',' '): /* Romanian (Moldova) */ return hb_language_from_string ("ro-MD", -1); /* Romanian; Moldova */ case HB_TAG('M','O','N','T'): /* Thailand Mon */ return hb_language_from_string ("mnw-TH", -1); /* Mon; Thailand */ @@ -2958,6 +2960,8 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag) return hb_language_from_string ("ro", -1); /* Romanian */ case HB_TAG('R','O','Y',' '): /* Romany */ return hb_language_from_string ("rom", -1); /* Romany [macrolanguage] */ + case HB_TAG('S','A','N',' '): /* Sanskrit */ + return hb_language_from_string ("sa", -1); /* Sanskrit [macrolanguage] */ case HB_TAG('S','Q','I',' '): /* Albanian */ return hb_language_from_string ("sq", -1); /* Albanian [macrolanguage] */ case HB_TAG('S','R','B',' '): /* Serbian */ 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 53b6b38f66d..0c63756b14d 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 @@ -547,7 +547,7 @@ hb_ot_tag_to_language (hb_tag_t tag) buf[3] = '-'; str += 4; } - snprintf (str, 16, "x-hbot-%08x", tag); + snprintf (str, 16, "x-hbot-%08" PRIx32, tag); return hb_language_from_string (&*buf, -1); } } 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 b2e5d87a3cf..9149959d792 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 @@ -57,7 +57,7 @@ struct avarV2Tail protected: Offset32To<DeltaSetIndexMap> varIdxMap; /* Offset from the beginning of 'avar' table. */ - Offset32To<VariationStore> varStore; /* Offset from the beginning of 'avar' table. */ + Offset32To<ItemVariationStore> varStore; /* Offset from the beginning of 'avar' table. */ public: DEFINE_SIZE_STATIC (8); @@ -230,7 +230,7 @@ struct SegmentMaps : Array16Of<AxisValueMap> * duplicates here */ if (mapping.must_include ()) continue; - value_mappings.push (std::move (mapping)); + value_mappings.push (mapping); } AxisValueMap m; @@ -343,7 +343,7 @@ struct avar for (unsigned i = 0; i < coords_length; i++) coords[i] = out[i]; - OT::VariationStore::destroy_cache (var_store_cache); + OT::ItemVariationStore::destroy_cache (var_store_cache); #endif } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh index eff6df380f8..379e1640593 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh @@ -28,6 +28,7 @@ #include "hb-ot-layout-common.hh" #include "hb-priority-queue.hh" +#include "hb-subset-instancer-iup.hh" namespace OT { @@ -221,9 +222,9 @@ struct DeltaSetIndexMap }; -struct VarStoreInstancer +struct ItemVarStoreInstancer { - VarStoreInstancer (const VariationStore *varStore, + ItemVarStoreInstancer (const ItemVariationStore *varStore, const DeltaSetIndexMap *varIdxMap, hb_array_t<int> coords) : varStore (varStore), varIdxMap (varIdxMap), coords (coords) {} @@ -235,7 +236,7 @@ struct VarStoreInstancer float operator() (uint32_t varIdx, unsigned short offset = 0) const { return coords ? varStore->get_delta (varIdxMap ? varIdxMap->map (VarIdx::add (varIdx, offset)) : varIdx + offset, coords) : 0; } - const VariationStore *varStore; + const ItemVariationStore *varStore; const DeltaSetIndexMap *varIdxMap; hb_array_t<int> coords; }; @@ -460,7 +461,7 @@ struct tuple_delta_t tuple_delta_t () = default; tuple_delta_t (const tuple_delta_t& o) = default; - friend void swap (tuple_delta_t& a, tuple_delta_t& b) + friend void swap (tuple_delta_t& a, tuple_delta_t& b) noexcept { hb_swap (a.axis_tuples, b.axis_tuples); hb_swap (a.indices, b.indices); @@ -471,10 +472,10 @@ struct tuple_delta_t hb_swap (a.compiled_peak_coords, b.compiled_peak_coords); } - tuple_delta_t (tuple_delta_t&& o) : tuple_delta_t () + tuple_delta_t (tuple_delta_t&& o) noexcept : tuple_delta_t () { hb_swap (*this, o); } - tuple_delta_t& operator = (tuple_delta_t&& o) + tuple_delta_t& operator = (tuple_delta_t&& o) noexcept { hb_swap (*this, o); return *this; @@ -609,7 +610,9 @@ struct tuple_delta_t const hb_map_t& axes_old_index_tag_map, const hb_hashmap_t<const hb_vector_t<char>*, unsigned>* shared_tuples_idx_map) { - if (!compiled_deltas) return false; + /* compiled_deltas could be empty after iup delta optimization, we can skip + * compiling this tuple and return true */ + if (!compiled_deltas) return true; unsigned cur_axis_count = axes_index_map.get_population (); /* allocate enough memory: 1 peak + 2 intermediate coords + fixed header size */ @@ -723,22 +726,28 @@ struct tuple_delta_t } bool compile_deltas () + { return compile_deltas (indices, deltas_x, deltas_y, compiled_deltas); } + + bool compile_deltas (const hb_vector_t<bool> &point_indices, + const hb_vector_t<float> &x_deltas, + const hb_vector_t<float> &y_deltas, + hb_vector_t<char> &compiled_deltas /* OUT */) { hb_vector_t<int> rounded_deltas; - if (unlikely (!rounded_deltas.alloc (indices.length))) + if (unlikely (!rounded_deltas.alloc (point_indices.length))) return false; - for (unsigned i = 0; i < indices.length; i++) + for (unsigned i = 0; i < point_indices.length; i++) { - if (!indices[i]) continue; - int rounded_delta = (int) roundf (deltas_x[i]); + if (!point_indices[i]) continue; + int rounded_delta = (int) roundf (x_deltas.arrayZ[i]); rounded_deltas.push (rounded_delta); } - if (!rounded_deltas) return false; + if (!rounded_deltas) return true; /* allocate enough memories 3 * num_deltas */ unsigned alloc_len = 3 * rounded_deltas.length; - if (deltas_y) + if (y_deltas) alloc_len *= 2; if (unlikely (!compiled_deltas.resize (alloc_len))) return false; @@ -746,14 +755,14 @@ struct tuple_delta_t unsigned i = 0; unsigned encoded_len = encode_delta_run (i, compiled_deltas.as_array (), rounded_deltas); - if (deltas_y) + if (y_deltas) { - /* reuse the rounded_deltas vector, check that deltas_y have the same num of deltas as deltas_x */ + /* reuse the rounded_deltas vector, check that y_deltas have the same num of deltas as x_deltas */ unsigned j = 0; - for (unsigned idx = 0; idx < indices.length; idx++) + for (unsigned idx = 0; idx < point_indices.length; idx++) { - if (!indices[idx]) continue; - int rounded_delta = (int) roundf (deltas_y[idx]); + if (!point_indices[idx]) continue; + int rounded_delta = (int) roundf (y_deltas.arrayZ[idx]); if (j >= rounded_deltas.length) return false; @@ -761,7 +770,7 @@ struct tuple_delta_t } if (j != rounded_deltas.length) return false; - /* reset i because we reuse rounded_deltas for deltas_y */ + /* reset i because we reuse rounded_deltas for y_deltas */ i = 0; encoded_len += encode_delta_run (i, compiled_deltas.as_array ().sub_array (encoded_len), rounded_deltas); } @@ -1020,6 +1029,171 @@ struct tuple_delta_t return true; } + bool optimize (const contour_point_vector_t& contour_points, + bool is_composite, + float tolerance = 0.5f) + { + unsigned count = contour_points.length; + if (deltas_x.length != count || + deltas_y.length != count) + return false; + + hb_vector_t<bool> opt_indices; + hb_vector_t<int> rounded_x_deltas, rounded_y_deltas; + + if (unlikely (!rounded_x_deltas.alloc (count) || + !rounded_y_deltas.alloc (count))) + return false; + + for (unsigned i = 0; i < count; i++) + { + int rounded_x_delta = (int) roundf (deltas_x.arrayZ[i]); + int rounded_y_delta = (int) roundf (deltas_y.arrayZ[i]); + rounded_x_deltas.push (rounded_x_delta); + rounded_y_deltas.push (rounded_y_delta); + } + + if (!iup_delta_optimize (contour_points, rounded_x_deltas, rounded_y_deltas, opt_indices, tolerance)) + return false; + + unsigned ref_count = 0; + for (bool ref_flag : opt_indices) + ref_count += ref_flag; + + if (ref_count == count) return true; + + hb_vector_t<float> opt_deltas_x, opt_deltas_y; + bool is_comp_glyph_wo_deltas = (is_composite && ref_count == 0); + if (is_comp_glyph_wo_deltas) + { + if (unlikely (!opt_deltas_x.resize (count) || + !opt_deltas_y.resize (count))) + return false; + + opt_indices.arrayZ[0] = true; + for (unsigned i = 1; i < count; i++) + opt_indices.arrayZ[i] = false; + } + + hb_vector_t<char> opt_point_data; + if (!compile_point_set (opt_indices, opt_point_data)) + return false; + hb_vector_t<char> opt_deltas_data; + if (!compile_deltas (opt_indices, + is_comp_glyph_wo_deltas ? opt_deltas_x : deltas_x, + is_comp_glyph_wo_deltas ? opt_deltas_y : deltas_y, + opt_deltas_data)) + return false; + + hb_vector_t<char> point_data; + if (!compile_point_set (indices, point_data)) + return false; + hb_vector_t<char> deltas_data; + if (!compile_deltas (indices, deltas_x, deltas_y, deltas_data)) + return false; + + if (opt_point_data.length + opt_deltas_data.length < point_data.length + deltas_data.length) + { + indices.fini (); + indices = std::move (opt_indices); + + if (is_comp_glyph_wo_deltas) + { + deltas_x.fini (); + deltas_x = std::move (opt_deltas_x); + + deltas_y.fini (); + deltas_y = std::move (opt_deltas_y); + } + } + return !indices.in_error () && !deltas_x.in_error () && !deltas_y.in_error (); + } + + static bool compile_point_set (const hb_vector_t<bool> &point_indices, + hb_vector_t<char>& compiled_points /* OUT */) + { + unsigned num_points = 0; + for (bool i : point_indices) + if (i) num_points++; + + /* when iup optimization is enabled, num of referenced points could be 0 */ + if (!num_points) return true; + + unsigned indices_length = point_indices.length; + /* If the points set consists of all points in the glyph, it's encoded with a + * single zero byte */ + if (num_points == indices_length) + return compiled_points.resize (1); + + /* allocate enough memories: 2 bytes for count + 3 bytes for each point */ + unsigned num_bytes = 2 + 3 *num_points; + if (unlikely (!compiled_points.resize (num_bytes, false))) + return false; + + unsigned pos = 0; + /* binary data starts with the total number of reference points */ + if (num_points < 0x80) + compiled_points.arrayZ[pos++] = num_points; + else + { + compiled_points.arrayZ[pos++] = ((num_points >> 8) | 0x80); + compiled_points.arrayZ[pos++] = num_points & 0xFF; + } + + const unsigned max_run_length = 0x7F; + unsigned i = 0; + unsigned last_value = 0; + unsigned num_encoded = 0; + while (i < indices_length && num_encoded < num_points) + { + unsigned run_length = 0; + unsigned header_pos = pos; + compiled_points.arrayZ[pos++] = 0; + + bool use_byte_encoding = false; + bool new_run = true; + while (i < indices_length && num_encoded < num_points && + run_length <= max_run_length) + { + // find out next referenced point index + while (i < indices_length && !point_indices[i]) + i++; + + if (i >= indices_length) break; + + unsigned cur_value = i; + unsigned delta = cur_value - last_value; + + if (new_run) + { + use_byte_encoding = (delta <= 0xFF); + new_run = false; + } + + if (use_byte_encoding && delta > 0xFF) + break; + + if (use_byte_encoding) + compiled_points.arrayZ[pos++] = delta; + else + { + compiled_points.arrayZ[pos++] = delta >> 8; + compiled_points.arrayZ[pos++] = delta & 0xFF; + } + i++; + last_value = cur_value; + run_length++; + num_encoded++; + } + + if (use_byte_encoding) + compiled_points.arrayZ[header_pos] = run_length - 1; + else + compiled_points.arrayZ[header_pos] = (run_length - 1) | 0x80; + } + return compiled_points.resize (pos, false); + } + static float infer_delta (float target_val, float prev_val, float next_val, float prev_delta, float next_delta) { if (prev_val == next_val) @@ -1071,41 +1245,41 @@ struct TupleVariationData private: /* referenced point set->compiled point data map */ - hb_hashmap_t<const hb_vector_t<bool>*, hb_bytes_t> point_data_map; + hb_hashmap_t<const hb_vector_t<bool>*, hb_vector_t<char>> point_data_map; /* referenced point set-> count map, used in finding shared points */ hb_hashmap_t<const hb_vector_t<bool>*, unsigned> point_set_count_map; /* empty for non-gvar tuples. - * shared_points_bytes is just a copy of some value in the point_data_map, + * shared_points_bytes is a pointer to some value in the point_data_map, * which will be freed during map destruction. Save it for serialization, so * no need to do find_shared_points () again */ - hb_bytes_t shared_points_bytes; + hb_vector_t<char> *shared_points_bytes = nullptr; /* total compiled byte size as TupleVariationData format, initialized to its * min_size: 4 */ unsigned compiled_byte_size = 4; + /* for gvar iup delta optimization: whether this is a composite glyph */ + bool is_composite = false; + public: tuple_variations_t () = default; tuple_variations_t (const tuple_variations_t&) = delete; tuple_variations_t& operator=(const tuple_variations_t&) = delete; tuple_variations_t (tuple_variations_t&&) = default; tuple_variations_t& operator=(tuple_variations_t&&) = default; - ~tuple_variations_t () { fini (); } - void fini () - { - for (auto _ : point_data_map.values ()) - _.fini (); - - point_set_count_map.fini (); - tuple_vars.fini (); - } + ~tuple_variations_t () = default; explicit operator bool () const { return bool (tuple_vars); } unsigned get_var_count () const { - unsigned count = tuple_vars.length; - if (shared_points_bytes.length) + unsigned count = 0; + /* when iup delta opt is enabled, compiled_deltas could be empty and we + * should skip this tuple */ + for (auto& tuple: tuple_vars) + if (tuple.compiled_deltas) count++; + + if (shared_points_bytes && shared_points_bytes->length) count |= TupleVarCount::SharedPointNumbers; return count; } @@ -1119,26 +1293,27 @@ struct TupleVariationData bool is_gvar, const hb_map_t *axes_old_index_tag_map, const hb_vector_t<unsigned> &shared_indices, - const hb_array_t<const F2DOT14> shared_tuples) + const hb_array_t<const F2DOT14> shared_tuples, + bool is_composite_glyph) { do { const HBUINT8 *p = iterator.get_serialized_data (); unsigned int length = iterator.current_tuple->get_data_size (); if (unlikely (!iterator.var_data_bytes.check_range (p, length))) - { fini (); return false; } + return false; hb_hashmap_t<hb_tag_t, Triple> axis_tuples; if (!iterator.current_tuple->unpack_axis_tuples (iterator.get_axis_count (), shared_tuples, axes_old_index_tag_map, axis_tuples) || axis_tuples.is_empty ()) - { fini (); return false; } + return false; hb_vector_t<unsigned> private_indices; bool has_private_points = iterator.current_tuple->has_private_points (); const HBUINT8 *end = p + length; if (has_private_points && !TupleVariationData::unpack_points (p, private_indices, end)) - { fini (); return false; } + return false; const hb_vector_t<unsigned> &indices = has_private_points ? private_indices : shared_indices; bool apply_to_all = (indices.length == 0); @@ -1148,24 +1323,24 @@ struct TupleVariationData if (unlikely (!deltas_x.resize (num_deltas, false) || !TupleVariationData::unpack_deltas (p, deltas_x, end))) - { fini (); return false; } + return false; hb_vector_t<int> deltas_y; if (is_gvar) { if (unlikely (!deltas_y.resize (num_deltas, false) || !TupleVariationData::unpack_deltas (p, deltas_y, end))) - { fini (); return false; } + return false; } tuple_delta_t var; var.axis_tuples = std::move (axis_tuples); if (unlikely (!var.indices.resize (point_count) || !var.deltas_x.resize (point_count, false))) - { fini (); return false; } + return false; if (is_gvar && unlikely (!var.deltas_y.resize (point_count, false))) - { fini (); return false; } + return false; for (unsigned i = 0; i < num_deltas; i++) { @@ -1178,6 +1353,8 @@ struct TupleVariationData } tuple_vars.push (std::move (var)); } while (iterator.move_to_next ()); + + is_composite = is_composite_glyph; return true; } @@ -1261,7 +1438,7 @@ struct TupleVariationData unsigned new_len = new_vars.length + out.length; if (unlikely (!new_vars.alloc (new_len, false))) - { fini (); return false;} + return false; for (unsigned i = 0; i < out.length; i++) new_vars.push (std::move (out[i])); @@ -1272,8 +1449,9 @@ struct TupleVariationData return true; } - /* merge tuple variations with overlapping tents */ - void merge_tuple_variations () + /* merge tuple variations with overlapping tents, if iup delta optimization + * is enabled, add default deltas to contour_points */ + bool merge_tuple_variations (contour_point_vector_t* contour_points = nullptr) { hb_vector_t<tuple_delta_t> new_vars; hb_hashmap_t<const hb_hashmap_t<hb_tag_t, Triple>*, unsigned> m; @@ -1281,7 +1459,15 @@ struct TupleVariationData for (const tuple_delta_t& var : tuple_vars) { /* if all axes are pinned, drop the tuple variation */ - if (var.axis_tuples.is_empty ()) continue; + if (var.axis_tuples.is_empty ()) + { + /* if iup_delta_optimize is enabled, add deltas to contour coords */ + if (contour_points && !contour_points->add_deltas (var.deltas_x, + var.deltas_y, + var.indices)) + return false; + continue; + } unsigned *idx; if (m.has (&(var.axis_tuples), &idx)) @@ -1291,98 +1477,14 @@ struct TupleVariationData else { new_vars.push (var); - m.set (&(var.axis_tuples), i); + if (!m.set (&(var.axis_tuples), i)) + return false; i++; } } tuple_vars.fini (); tuple_vars = std::move (new_vars); - } - - hb_bytes_t compile_point_set (const hb_vector_t<bool> &point_indices) - { - unsigned num_points = 0; - for (bool i : point_indices) - if (i) num_points++; - - unsigned indices_length = point_indices.length; - /* If the points set consists of all points in the glyph, it's encoded with a - * single zero byte */ - if (num_points == indices_length) - { - char *p = (char *) hb_calloc (1, sizeof (char)); - if (unlikely (!p)) return hb_bytes_t (); - - return hb_bytes_t (p, 1); - } - - /* allocate enough memories: 2 bytes for count + 3 bytes for each point */ - unsigned num_bytes = 2 + 3 *num_points; - char *p = (char *) hb_calloc (num_bytes, sizeof (char)); - if (unlikely (!p)) return hb_bytes_t (); - - unsigned pos = 0; - /* binary data starts with the total number of reference points */ - if (num_points < 0x80) - p[pos++] = num_points; - else - { - p[pos++] = ((num_points >> 8) | 0x80); - p[pos++] = num_points & 0xFF; - } - - const unsigned max_run_length = 0x7F; - unsigned i = 0; - unsigned last_value = 0; - unsigned num_encoded = 0; - while (i < indices_length && num_encoded < num_points) - { - unsigned run_length = 0; - unsigned header_pos = pos; - p[pos++] = 0; - - bool use_byte_encoding = false; - bool new_run = true; - while (i < indices_length && num_encoded < num_points && - run_length <= max_run_length) - { - // find out next referenced point index - while (i < indices_length && !point_indices[i]) - i++; - - if (i >= indices_length) break; - - unsigned cur_value = i; - unsigned delta = cur_value - last_value; - - if (new_run) - { - use_byte_encoding = (delta <= 0xFF); - new_run = false; - } - - if (use_byte_encoding && delta > 0xFF) - break; - - if (use_byte_encoding) - p[pos++] = delta; - else - { - p[pos++] = delta >> 8; - p[pos++] = delta & 0xFF; - } - i++; - last_value = cur_value; - run_length++; - num_encoded++; - } - - if (use_byte_encoding) - p[header_pos] = run_length - 1; - else - p[header_pos] = (run_length - 1) | 0x80; - } - return hb_bytes_t (p, pos); + return true; } /* compile all point set and store byte data in a point_set->hb_bytes_t hashmap, @@ -1402,11 +1504,11 @@ struct TupleVariationData continue; } - hb_bytes_t compiled_data = compile_point_set (*points_set); - if (unlikely (compiled_data == hb_bytes_t ())) + hb_vector_t<char> compiled_point_data; + if (!tuple_delta_t::compile_point_set (*points_set, compiled_point_data)) return false; - if (!point_data_map.set (points_set, compiled_data) || + if (!point_data_map.set (points_set, std::move (compiled_point_data)) || !point_set_count_map.set (points_set, 1)) return false; } @@ -1414,31 +1516,33 @@ struct TupleVariationData } /* find shared points set which saves most bytes */ - hb_bytes_t find_shared_points () + void find_shared_points () { unsigned max_saved_bytes = 0; - hb_bytes_t res{}; - for (const auto& _ : point_data_map.iter ()) + for (const auto& _ : point_data_map.iter_ref ()) { const hb_vector_t<bool>* points_set = _.first; unsigned data_length = _.second.length; + if (!data_length) continue; unsigned *count; if (unlikely (!point_set_count_map.has (points_set, &count) || *count <= 1)) - return hb_bytes_t (); + { + shared_points_bytes = nullptr; + return; + } unsigned saved_bytes = data_length * ((*count) -1); if (saved_bytes > max_saved_bytes) { max_saved_bytes = saved_bytes; - res = _.second; + shared_points_bytes = &(_.second); } } - return res; } - bool calc_inferred_deltas (contour_point_vector_t& contour_points) + bool calc_inferred_deltas (const contour_point_vector_t& contour_points) { for (tuple_delta_t& var : tuple_vars) if (!var.calc_inferred_deltas (contour_points)) @@ -1447,10 +1551,21 @@ struct TupleVariationData return true; } + bool iup_optimize (const contour_point_vector_t& contour_points) + { + for (tuple_delta_t& var : tuple_vars) + { + if (!var.optimize (contour_points, is_composite)) + return false; + } + return true; + } + public: bool instantiate (const hb_hashmap_t<hb_tag_t, Triple>& normalized_axes_location, const hb_hashmap_t<hb_tag_t, TripleDistances>& axes_triple_distances, - contour_point_vector_t* contour_points = nullptr) + contour_point_vector_t* contour_points = nullptr, + bool optimize = false) { if (!tuple_vars) return true; if (!change_tuple_variations_axis_limits (normalized_axes_location, axes_triple_distances)) @@ -1460,7 +1575,14 @@ struct TupleVariationData if (!calc_inferred_deltas (*contour_points)) return false; - merge_tuple_variations (); + /* if iup delta opt is on, contour_points can't be null */ + if (optimize && !contour_points) + return false; + + if (!merge_tuple_variations (optimize ? contour_points : nullptr)) + return false; + + if (optimize && !iup_optimize (*contour_points)) return false; return !tuple_vars.in_error (); } @@ -1475,21 +1597,27 @@ struct TupleVariationData if (use_shared_points) { - shared_points_bytes = find_shared_points (); - compiled_byte_size += shared_points_bytes.length; + find_shared_points (); + if (shared_points_bytes) + compiled_byte_size += shared_points_bytes->length; } // compile delta and tuple var header for each tuple variation for (auto& tuple: tuple_vars) { const hb_vector_t<bool>* points_set = &(tuple.indices); - hb_bytes_t *points_data; + hb_vector_t<char> *points_data; if (unlikely (!point_data_map.has (points_set, &points_data))) return false; + /* when iup optimization is enabled, num of referenced points could be 0 + * and thus the compiled points bytes is empty, we should skip compiling + * this tuple */ + if (!points_data->length) + continue; if (!tuple.compile_deltas ()) return false; - unsigned points_data_length = (*points_data != shared_points_bytes) ? points_data->length : 0; + unsigned points_data_length = (points_data != shared_points_bytes) ? points_data->length : 0; if (!tuple.compile_tuple_var_header (axes_index_map, points_data_length, axes_old_index_tag_map, shared_tuples_idx_map)) return false; @@ -1513,18 +1641,24 @@ struct TupleVariationData bool serialize_var_data (hb_serialize_context_t *c, bool is_gvar) const { TRACE_SERIALIZE (this); - if (is_gvar) - shared_points_bytes.copy (c); + if (is_gvar && shared_points_bytes) + { + hb_bytes_t s (shared_points_bytes->arrayZ, shared_points_bytes->length); + s.copy (c); + } for (const auto& tuple: tuple_vars) { const hb_vector_t<bool>* points_set = &(tuple.indices); - hb_bytes_t *point_data; + hb_vector_t<char> *point_data; if (!point_data_map.has (points_set, &point_data)) return_trace (false); - if (!is_gvar || *point_data != shared_points_bytes) - point_data->copy (c); + if (!is_gvar || point_data != shared_points_bytes) + { + hb_bytes_t s (point_data->arrayZ, point_data->length); + s.copy (c); + } tuple.compiled_deltas.as_array ().copy (c); if (c->in_error ()) return_trace (false); @@ -1711,13 +1845,15 @@ struct TupleVariationData const hb_map_t *axes_old_index_tag_map, const hb_vector_t<unsigned> &shared_indices, const hb_array_t<const F2DOT14> shared_tuples, - tuple_variations_t& tuple_variations /* OUT */) const + tuple_variations_t& tuple_variations, /* OUT */ + bool is_composite_glyph = false) const { return tuple_variations.create_from_tuple_var_data (iterator, tupleVarCount, point_count, is_gvar, axes_old_index_tag_map, shared_indices, - shared_tuples); + shared_tuples, + is_composite_glyph); } bool serialize (hb_serialize_context_t *c, @@ -1831,7 +1967,7 @@ struct item_variations_t const hb_map_t& get_varidx_map () const { return varidx_map; } - bool instantiate (const VariationStore& varStore, + bool instantiate (const ItemVariationStore& varStore, const hb_subset_plan_t *plan, bool optimize=true, bool use_no_variation_idx=true, @@ -1845,7 +1981,7 @@ struct item_variations_t } /* keep below APIs public only for unit test: test-item-varstore */ - bool create_from_item_varstore (const VariationStore& varStore, + bool create_from_item_varstore (const ItemVariationStore& varStore, const hb_map_t& axes_old_index_tag_map, const hb_array_t <const hb_inc_bimap_t> inner_maps = hb_array_t<const hb_inc_bimap_t> ()) { diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh index 1c7a1f6c1e9..59aad57e37c 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh @@ -101,10 +101,15 @@ struct glyph_variations_t continue; } + bool is_composite_glyph = false; +#ifdef HB_EXPERIMENTAL_API + is_composite_glyph = plan->composite_new_gids.has (new_gid); +#endif if (!p->decompile_tuple_variations (all_contour_points->length, true /* is_gvar */, iterator, &(plan->axes_old_index_tag_map), shared_indices, shared_tuples, - tuple_vars /* OUT */)) + tuple_vars, /* OUT */ + is_composite_glyph)) return false; glyph_variations.push (std::move (tuple_vars)); } @@ -114,13 +119,17 @@ struct glyph_variations_t bool instantiate (const hb_subset_plan_t *plan) { unsigned count = plan->new_to_old_gid_list.length; + bool iup_optimize = false; +#ifdef HB_EXPERIMENTAL_API + iup_optimize = plan->flags & HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS; +#endif for (unsigned i = 0; i < count; i++) { hb_codepoint_t new_gid = plan->new_to_old_gid_list[i].first; contour_point_vector_t *all_points; if (!plan->new_gid_contour_points_map.has (new_gid, &all_points)) return false; - if (!glyph_variations[i].instantiate (plan->axes_location, plan->axes_triple_distances, all_points)) + if (!glyph_variations[i].instantiate (plan->axes_location, plan->axes_triple_distances, all_points, iup_optimize)) return false; } return true; @@ -340,7 +349,8 @@ struct gvar const glyph_variations_t& glyph_vars, Iterator it, unsigned axis_count, - unsigned num_glyphs) const + unsigned num_glyphs, + bool force_long_offsets) const { TRACE_SERIALIZE (this); gvar *out = c->allocate_min<gvar> (); @@ -352,7 +362,7 @@ struct gvar out->glyphCountX = hb_min (0xFFFFu, num_glyphs); unsigned glyph_var_data_size = glyph_vars.compiled_byte_size (); - bool long_offset = glyph_var_data_size & ~0xFFFFu; + bool long_offset = glyph_var_data_size & ~0xFFFFu || force_long_offsets; out->flags = long_offset ? 1 : 0; HBUINT8 *glyph_var_data_offsets = c->allocate_size<HBUINT8> ((long_offset ? 4 : 2) * (num_glyphs + 1), false); @@ -393,7 +403,12 @@ struct gvar unsigned axis_count = c->plan->axes_index_map.get_population (); unsigned num_glyphs = c->plan->num_output_glyphs (); auto it = hb_iter (c->plan->new_to_old_gid_list); - return_trace (serialize (c->serializer, glyph_vars, it, axis_count, num_glyphs)); + + bool force_long_offsets = false; +#ifdef HB_EXPERIMENTAL_API + force_long_offsets = c->plan->flags & HB_SUBSET_FLAGS_IFTB_REQUIREMENTS; +#endif + return_trace (serialize (c->serializer, glyph_vars, it, axis_count, num_glyphs, force_long_offsets)); } bool subset (hb_subset_context_t *c) const @@ -429,7 +444,7 @@ struct gvar } bool long_offset = (subset_data_size & ~0xFFFFu); - #ifdef HB_EXPERIMENTAL_API +#ifdef HB_EXPERIMENTAL_API long_offset = long_offset || (c->plan->flags & HB_SUBSET_FLAGS_IFTB_REQUIREMENTS); #endif out->flags = long_offset ? 1 : 0; 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 53a4642d383..33a4e1a40e6 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 @@ -188,7 +188,7 @@ struct hvarvvar_subset_plan_t ~hvarvvar_subset_plan_t() { fini (); } void init (const hb_array_t<const DeltaSetIndexMap *> &index_maps, - const VariationStore &_var_store, + const ItemVariationStore &_var_store, const hb_subset_plan_t *plan) { index_map_plans.resize (index_maps.length); @@ -263,7 +263,7 @@ struct hvarvvar_subset_plan_t hb_inc_bimap_t outer_map; hb_vector_t<hb_inc_bimap_t> inner_maps; hb_vector_t<index_map_subset_plan_t> index_map_plans; - const VariationStore *var_store; + const ItemVariationStore *var_store; protected: hb_vector_t<hb_set_t *> inner_sets; @@ -296,7 +296,7 @@ struct HVARVVAR rsbMap.sanitize (c, this)); } - const VariationStore& get_var_store () const + const ItemVariationStore& get_var_store () const { return this+varStore; } void listup_index_maps (hb_vector_t<const DeltaSetIndexMap *> &index_maps) const @@ -384,7 +384,7 @@ struct HVARVVAR float get_advance_delta_unscaled (hb_codepoint_t glyph, const int *coords, unsigned int coord_count, - VariationStore::cache_t *store_cache = nullptr) const + ItemVariationStore::cache_t *store_cache = nullptr) const { uint32_t varidx = (this+advMap).map (glyph); return (this+varStore).get_delta (varidx, @@ -405,7 +405,7 @@ struct HVARVVAR public: FixedVersion<>version; /* Version of the metrics variation table * initially set to 0x00010000u */ - Offset32To<VariationStore> + Offset32To<ItemVariationStore> varStore; /* Offset to item variation store table. */ Offset32To<DeltaSetIndexMap> advMap; /* Offset to advance var-idx mapping. */ 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 6d697776189..1f0401d1d33 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 @@ -56,7 +56,7 @@ struct VariationValueRecord public: Tag valueTag; /* Four-byte tag identifying a font-wide measure. */ - VarIdx varIdx; /* Outer/inner index into VariationStore item. */ + VarIdx varIdx; /* Outer/inner index into ItemVariationStore item. */ public: DEFINE_SIZE_STATIC (8); @@ -106,7 +106,7 @@ struct MVAR out->valueRecordCount = valueRecordCount; item_variations_t item_vars; - const VariationStore& src_var_store = this+varStore; + const ItemVariationStore& src_var_store = this+varStore; if (!item_vars.instantiate (src_var_store, c->plan)) return_trace (false); @@ -159,7 +159,7 @@ protected: HBUINT16 valueRecordSize;/* The size in bytes of each value record — * must be greater than zero. */ HBUINT16 valueRecordCount;/* The number of value records — may be zero. */ - Offset16To<VariationStore> + Offset16To<ItemVariationStore> varStore; /* Offset to item variation store table. */ UnsizedArrayOf<HBUINT8> valuesZ; /* Array of value records. The records must be diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-priority-queue.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-priority-queue.hh index 9b962a29d9b..274d5df4c54 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-priority-queue.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-priority-queue.hh @@ -163,7 +163,7 @@ struct hb_priority_queue_t goto repeat; } - void swap (unsigned a, unsigned b) + void swap (unsigned a, unsigned b) noexcept { assert (a < heap.length); assert (b < heap.length); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh index e9cd376ad37..ed40f271ccb 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh @@ -239,6 +239,54 @@ bool _try_isolating_subgraphs (const hb_vector_t<graph::overflow_record_t>& over } static inline +bool _resolve_shared_overflow(const hb_vector_t<graph::overflow_record_t>& overflows, + int overflow_index, + graph_t& sorted_graph) +{ + const graph::overflow_record_t& r = overflows[overflow_index]; + + // Find all of the parents in overflowing links that link to this + // same child node. We will then try duplicating the child node and + // re-assigning all of these parents to the duplicate. + hb_set_t parents; + parents.add(r.parent); + for (int i = overflow_index - 1; i >= 0; i--) { + const graph::overflow_record_t& r2 = overflows[i]; + if (r2.child == r.child) { + parents.add(r2.parent); + } + } + + unsigned result = sorted_graph.duplicate(&parents, r.child); + if (result == (unsigned) -1 && parents.get_population() > 2) { + // All links to the child are overflowing, so we can't include all + // in the duplication. Remove one parent from the duplication. + // Remove the lowest index parent, which will be the closest to the child. + parents.del(parents.get_min()); + result = sorted_graph.duplicate(&parents, r.child); + } + + if (result == (unsigned) -1) return result; + + if (parents.get_population() > 1) { + // If the duplicated node has more than one parent pre-emptively raise it's priority to the maximum. + // This will place it close to the parents. Node's with only one parent, don't need this as normal overflow + // resolution will raise priority if needed. + // + // Reasoning: most of the parents to this child are likely at the same layer in the graph. Duplicating + // the child will theoretically allow it to be placed closer to it's parents. However, due to the shortest + // distance sort by default it's placement will remain in the same layer, thus it will remain in roughly the + // same position (and distance from parents) as the original child node. The overflow resolution will attempt + // to move nodes closer, but only for non-shared nodes. Since this node is shared, it will simply be given + // further duplication which defeats the attempt to duplicate with multiple parents. To fix this we + // pre-emptively raise priority now which allows the duplicated node to pack into the same layer as it's parents. + sorted_graph.vertices_[result].give_max_priority(); + } + + return result; +} + +static inline bool _process_overflows (const hb_vector_t<graph::overflow_record_t>& overflows, hb_set_t& priority_bumped_parents, graph_t& sorted_graph) @@ -254,7 +302,7 @@ bool _process_overflows (const hb_vector_t<graph::overflow_record_t>& overflows, { // The child object is shared, we may be able to eliminate the overflow // by duplicating it. - if (sorted_graph.duplicate (r.parent, r.child) == (unsigned) -1) continue; + if (!_resolve_shared_overflow(overflows, i, sorted_graph)) continue; return true; } @@ -388,7 +436,7 @@ template<typename T> inline hb_blob_t* hb_resolve_overflows (const T& packed, hb_tag_t table_tag, - unsigned max_rounds = 20, + unsigned max_rounds = 32, bool recalculate_extensions = false) { graph_t sorted_graph (packed); if (sorted_graph.in_error ()) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh index 15eccb6a09a..73634e6b933 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh @@ -91,7 +91,7 @@ struct hb_serialize_context_t } #endif - friend void swap (object_t& a, object_t& b) + friend void swap (object_t& a, object_t& b) noexcept { hb_swap (a.head, b.head); hb_swap (a.tail, b.tail); @@ -156,9 +156,9 @@ struct hb_serialize_context_t object_t *next; auto all_links () const HB_AUTO_RETURN - (( hb_concat (this->real_links, this->virtual_links) )); + (( hb_concat (real_links, virtual_links) )); auto all_links_writer () HB_AUTO_RETURN - (( hb_concat (this->real_links.writer (), this->virtual_links.writer ()) )); + (( hb_concat (real_links.writer (), virtual_links.writer ()) )); }; struct snapshot_t 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 ff2a170d2d1..ce69ea2c9b2 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh @@ -44,10 +44,10 @@ struct hb_sparseset_t ~hb_sparseset_t () { fini (); } hb_sparseset_t (const hb_sparseset_t& other) : hb_sparseset_t () { set (other); } - hb_sparseset_t (hb_sparseset_t&& other) : hb_sparseset_t () { s = std::move (other.s); } + hb_sparseset_t (hb_sparseset_t&& other) noexcept : hb_sparseset_t () { s = std::move (other.s); } hb_sparseset_t& operator = (const hb_sparseset_t& other) { set (other); return *this; } - hb_sparseset_t& operator = (hb_sparseset_t&& other) { s = std::move (other.s); return *this; } - friend void swap (hb_sparseset_t& a, hb_sparseset_t& b) { hb_swap (a.s, b.s); } + hb_sparseset_t& operator = (hb_sparseset_t&& other) noexcept { s = std::move (other.s); return *this; } + friend void swap (hb_sparseset_t& a, hb_sparseset_t& b) noexcept { hb_swap (a.s, b.s); } hb_sparseset_t (std::initializer_list<hb_codepoint_t> lst) : hb_sparseset_t () { @@ -166,7 +166,7 @@ struct hb_set_t : hb_sparseset_t<hb_bit_set_invertible_t> ~hb_set_t () = default; hb_set_t () : sparseset () {}; hb_set_t (const hb_set_t &o) : sparseset ((sparseset &) o) {}; - hb_set_t (hb_set_t&& o) : sparseset (std::move ((sparseset &) o)) {} + hb_set_t (hb_set_t&& o) noexcept : sparseset (std::move ((sparseset &) o)) {} hb_set_t& operator = (const hb_set_t&) = default; hb_set_t& operator = (hb_set_t&&) = default; hb_set_t (std::initializer_list<hb_codepoint_t> lst) : sparseset (lst) {} diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff2.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff2.cc index abc108e5715..eb5cb0c625e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff2.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff2.cc @@ -248,7 +248,7 @@ struct cff2_subr_subsetter_t : subr_subsetter_t<cff2_subr_subsetter_t, CFF2Subrs struct cff2_private_blend_encoder_param_t { cff2_private_blend_encoder_param_t (hb_serialize_context_t *c, - const CFF2VariationStore *varStore, + const CFF2ItemVariationStore *varStore, hb_array_t<int> normalized_coords) : c (c), varStore (varStore), normalized_coords (normalized_coords) {} @@ -284,7 +284,7 @@ struct cff2_private_blend_encoder_param_t unsigned ivs = 0; unsigned region_count = 0; hb_vector_t<float> scalars; - const CFF2VariationStore *varStore = nullptr; + const CFF2ItemVariationStore *varStore = nullptr; hb_array_t<int> normalized_coords; }; @@ -378,7 +378,7 @@ struct cff2_private_dict_blend_opset_t : dict_opset_t struct cff2_private_dict_op_serializer_t : op_serializer_t { cff2_private_dict_op_serializer_t (bool desubroutinize_, bool drop_hints_, bool pinned_, - const CFF::CFF2VariationStore* varStore_, + const CFF::CFF2ItemVariationStore* varStore_, hb_array_t<int> normalized_coords_) : desubroutinize (desubroutinize_), drop_hints (drop_hints_), pinned (pinned_), varStore (varStore_), normalized_coords (normalized_coords_) {} @@ -416,7 +416,7 @@ struct cff2_private_dict_op_serializer_t : op_serializer_t const bool desubroutinize; const bool drop_hints; const bool pinned; - const CFF::CFF2VariationStore* varStore; + const CFF::CFF2ItemVariationStore* varStore; hb_array_t<int> normalized_coords; }; @@ -628,10 +628,10 @@ OT::cff2::accelerator_subset_t::serialize (hb_serialize_context_t *c, } /* variation store */ - if (varStore != &Null (CFF2VariationStore) && + if (varStore != &Null (CFF2ItemVariationStore) && !plan.pinned) { - auto *dest = c->push<CFF2VariationStore> (); + auto *dest = c->push<CFF2ItemVariationStore> (); if (unlikely (!dest->serialize (c, varStore))) { c->pop_discard (); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc index 1e0a89a630d..68a3e77788e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc @@ -24,6 +24,7 @@ * Google Author(s): Garret Rieger, Rod Sheeter, Behdad Esfahbod */ +#include "hb-subset-instancer-solver.hh" #include "hb-subset.hh" #include "hb-set.hh" #include "hb-utf.hh" @@ -50,7 +51,6 @@ hb_subset_input_t::hb_subset_input_t () HB_TAG ('k', 'e', 'r', 'n'), // Copied from fontTools: - HB_TAG ('B', 'A', 'S', 'E'), HB_TAG ('J', 'S', 'T', 'F'), HB_TAG ('D', 'S', 'I', 'G'), HB_TAG ('E', 'B', 'D', 'T'), @@ -418,6 +418,46 @@ hb_subset_input_keep_everything (hb_subset_input_t *input) #ifndef HB_NO_VAR /** + * hb_subset_input_pin_all_axes_to_default: (skip) + * @input: a #hb_subset_input_t object. + * @face: a #hb_face_t object. + * + * Pin all axes to default locations in the given subset input object. + * + * All axes in a font must be pinned. Additionally, `CFF2` table, if present, + * will be de-subroutinized. + * + * Return value: `true` if success, `false` otherwise + * + * Since: 8.3.1 + **/ +HB_EXTERN hb_bool_t +hb_subset_input_pin_all_axes_to_default (hb_subset_input_t *input, + hb_face_t *face) +{ + unsigned axis_count = hb_ot_var_get_axis_count (face); + if (!axis_count) return false; + + hb_ot_var_axis_info_t *axis_infos = (hb_ot_var_axis_info_t *) hb_calloc (axis_count, sizeof (hb_ot_var_axis_info_t)); + if (unlikely (!axis_infos)) return false; + + (void) hb_ot_var_get_axis_infos (face, 0, &axis_count, axis_infos); + + for (unsigned i = 0; i < axis_count; i++) + { + hb_tag_t axis_tag = axis_infos[i].tag; + float default_val = axis_infos[i].default_value; + if (!input->axes_location.set (axis_tag, Triple (default_val, default_val, default_val))) + { + hb_free (axis_infos); + return false; + } + } + hb_free (axis_infos); + return true; +} + +/** * hb_subset_input_pin_axis_to_default: (skip) * @input: a #hb_subset_input_t object. * @face: a #hb_face_t object. @@ -481,16 +521,13 @@ hb_subset_input_pin_axis_location (hb_subset_input_t *input, * @input: a #hb_subset_input_t object. * @face: a #hb_face_t object. * @axis_tag: Tag of the axis - * @axis_min_value: Minimum value of the axis variation range to set - * @axis_max_value: Maximum value of the axis variation range to set - * @axis_def_value: Default value of the axis variation range to set, in case of - * null, it'll be determined automatically + * @axis_min_value: Minimum value of the axis variation range to set, if NaN the existing min will be used. + * @axis_max_value: Maximum value of the axis variation range to set if NaN the existing max will be used. + * @axis_def_value: Default value of the axis variation range to set, if NaN the existing default will be used. * * Restricting the range of variation on an axis in the given subset input object. * New min/default/max values will be clamped if they're not within the fvar axis range. - * If the new default value is null: - * If the fvar axis default value is within the new range, then new default - * value is the same as original default value. + * * If the fvar axis default value is not within the new range, the new default * value will be changed to the new min or max value, whichever is closer to the fvar * axis default. @@ -509,21 +546,57 @@ hb_subset_input_set_axis_range (hb_subset_input_t *input, hb_tag_t axis_tag, float axis_min_value, float axis_max_value, - float *axis_def_value /* IN, maybe NULL */) + float axis_def_value) { - if (axis_min_value > axis_max_value) - return false; - hb_ot_var_axis_info_t axis_info; if (!hb_ot_var_find_axis_info (face, axis_tag, &axis_info)) return false; - float new_min_val = hb_clamp(axis_min_value, axis_info.min_value, axis_info.max_value); - float new_max_val = hb_clamp(axis_max_value, axis_info.min_value, axis_info.max_value); - float new_default_val = axis_def_value ? *axis_def_value : axis_info.default_value; - new_default_val = hb_clamp(new_default_val, new_min_val, new_max_val); + float min = !std::isnan(axis_min_value) ? axis_min_value : axis_info.min_value; + float max = !std::isnan(axis_max_value) ? axis_max_value : axis_info.max_value; + float def = !std::isnan(axis_def_value) ? axis_def_value : axis_info.default_value; + + if (min > max) + return false; + + float new_min_val = hb_clamp(min, axis_info.min_value, axis_info.max_value); + float new_max_val = hb_clamp(max, axis_info.min_value, axis_info.max_value); + float new_default_val = hb_clamp(def, new_min_val, new_max_val); return input->axes_location.set (axis_tag, Triple (new_min_val, new_default_val, new_max_val)); } + +/** + * hb_subset_input_get_axis_range: (skip) + * @input: a #hb_subset_input_t object. + * @axis_tag: Tag of the axis + * @axis_min_value: Set to the previously configured minimum value of the axis variation range. + * @axis_max_value: Set to the previously configured maximum value of the axis variation range. + * @axis_def_value: Set to the previously configured default value of the axis variation range. + * + * Gets the axis range assigned by previous calls to hb_subset_input_set_axis_range. + * + * Return value: `true` if a range has been set for this axis tag, `false` otherwise. + * + * XSince: EXPERIMENTAL + **/ +HB_EXTERN hb_bool_t +hb_subset_input_get_axis_range (hb_subset_input_t *input, + hb_tag_t axis_tag, + float *axis_min_value, + float *axis_max_value, + float *axis_def_value) + +{ + Triple* triple; + if (!input->axes_location.has(axis_tag, &triple)) { + return false; + } + + *axis_min_value = triple->minimum; + *axis_def_value = triple->middle; + *axis_max_value = triple->maximum; + return true; +} #endif #endif diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-instancer-iup.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-instancer-iup.cc new file mode 100644 index 00000000000..35a964d0826 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-instancer-iup.cc @@ -0,0 +1,532 @@ +/* + * Copyright © 2024 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. + */ + +#include "hb-subset-instancer-iup.hh" + +/* This file is a straight port of the following: + * + * https://github.com/fonttools/fonttools/blob/main/Lib/fontTools/varLib/iup.py + * + * Where that file returns optimzied deltas vector, we return optimized + * referenced point indices. + */ + +constexpr static unsigned MAX_LOOKBACK = 8; + +static void _iup_contour_bound_forced_set (const hb_array_t<const contour_point_t> contour_points, + const hb_array_t<const int> x_deltas, + const hb_array_t<const int> y_deltas, + hb_set_t& forced_set, /* OUT */ + float tolerance = 0.f) +{ + unsigned len = contour_points.length; + unsigned next_i = 0; + for (int i = len - 1; i >= 0; i--) + { + unsigned last_i = (len + i -1) % len; + for (unsigned j = 0; j < 2; j++) + { + float cj, lcj, ncj; + int dj, ldj, ndj; + if (j == 0) + { + cj = contour_points.arrayZ[i].x; + dj = x_deltas.arrayZ[i]; + lcj = contour_points.arrayZ[last_i].x; + ldj = x_deltas.arrayZ[last_i]; + ncj = contour_points.arrayZ[next_i].x; + ndj = x_deltas.arrayZ[next_i]; + } + else + { + cj = contour_points.arrayZ[i].y; + dj = y_deltas.arrayZ[i]; + lcj = contour_points.arrayZ[last_i].y; + ldj = y_deltas.arrayZ[last_i]; + ncj = contour_points.arrayZ[next_i].y; + ndj = y_deltas.arrayZ[next_i]; + } + + float c1, c2; + int d1, d2; + if (lcj <= ncj) + { + c1 = lcj; + c2 = ncj; + d1 = ldj; + d2 = ndj; + } + else + { + c1 = ncj; + c2 = lcj; + d1 = ndj; + d2 = ldj; + } + + bool force = false; + if (c1 == c2) + { + if (abs (d1 - d2) > tolerance && abs (dj) > tolerance) + force = true; + } + else if (c1 <= cj && cj <= c2) + { + if (!(hb_min (d1, d2) - tolerance <= dj && + dj <= hb_max (d1, d2) + tolerance)) + force = true; + } + else + { + if (d1 != d2) + { + if (cj < c1) + { + if (abs (dj) > tolerance && + abs (dj - d1) > tolerance && + ((dj - tolerance < d1) != (d1 < d2))) + force = true; + } + else + { + if (abs (dj) > tolerance && + abs (dj - d2) > tolerance && + ((d2 < dj + tolerance) != (d1 < d2))) + force = true; + } + } + } + + if (force) + { + forced_set.add (i); + break; + } + } + next_i = i; + } +} + +template <typename T, + hb_enable_if (hb_is_trivially_copyable (T))> +static bool rotate_array (const hb_array_t<const T>& org_array, + int k, + hb_vector_t<T>& out) +{ + unsigned n = org_array.length; + if (!n) return true; + if (unlikely (!out.resize (n, false))) + return false; + + unsigned item_size = hb_static_size (T); + if (k < 0) + k = n - (-k) % n; + else + k %= n; + + hb_memcpy ((void *) out.arrayZ, (const void *) (org_array.arrayZ + n - k), k * item_size); + hb_memcpy ((void *) (out.arrayZ + k), (const void *) org_array.arrayZ, (n - k) * item_size); + return true; +} + +static bool rotate_set (const hb_set_t& org_set, + int k, + unsigned n, + hb_set_t& out) +{ + if (!n) return false; + k %= n; + if (k < 0) + k = n + k; + + if (k == 0) + { + out.set (org_set); + } + else + { + for (auto v : org_set) + out.add ((v + k) % n); + } + return !out.in_error (); +} + +/* Given two reference coordinates (start and end of contour_points array), + * output interpolated deltas for points in between */ +static bool _iup_segment (const hb_array_t<const contour_point_t> contour_points, + const hb_array_t<const int> x_deltas, + const hb_array_t<const int> y_deltas, + const contour_point_t& p1, const contour_point_t& p2, + int p1_dx, int p2_dx, + int p1_dy, int p2_dy, + hb_vector_t<float>& interp_x_deltas, /* OUT */ + hb_vector_t<float>& interp_y_deltas /* OUT */) +{ + unsigned n = contour_points.length; + if (unlikely (!interp_x_deltas.resize (n, false) || + !interp_y_deltas.resize (n, false))) + return false; + + for (unsigned j = 0; j < 2; j++) + { + float x1, x2, d1, d2; + float *out; + if (j == 0) + { + x1 = p1.x; + x2 = p2.x; + d1 = p1_dx; + d2 = p2_dx; + out = interp_x_deltas.arrayZ; + } + else + { + x1 = p1.y; + x2 = p2.y; + d1 = p1_dy; + d2 = p2_dy; + out = interp_y_deltas.arrayZ; + } + + if (x1 == x2) + { + if (d1 == d2) + { + for (unsigned i = 0; i < n; i++) + out[i] = d1; + } + else + { + for (unsigned i = 0; i < n; i++) + out[i] = 0.f; + } + continue; + } + + if (x1 > x2) + { + hb_swap (x1, x2); + hb_swap (d1, d2); + } + + float scale = (d2 - d1) / (x2 - x1); + for (unsigned i = 0; i < n; i++) + { + float x = j == 0 ? contour_points.arrayZ[i].x : contour_points.arrayZ[i].y; + float d; + if (x <= x1) + d = d1; + else if (x >= x2) + d = d2; + else + d = d1 + (x - x1) * scale; + + out[i] = d; + } + } + return true; +} + +static bool _can_iup_in_between (const hb_array_t<const contour_point_t> contour_points, + const hb_array_t<const int> x_deltas, + const hb_array_t<const int> y_deltas, + const contour_point_t& p1, const contour_point_t& p2, + int p1_dx, int p2_dx, + int p1_dy, int p2_dy, + float tolerance) +{ + hb_vector_t<float> interp_x_deltas, interp_y_deltas; + if (!_iup_segment (contour_points, x_deltas, y_deltas, + p1, p2, p1_dx, p2_dx, p1_dy, p2_dy, + interp_x_deltas, interp_y_deltas)) + return false; + + unsigned num = contour_points.length; + + for (unsigned i = 0; i < num; i++) + { + float dx = x_deltas.arrayZ[i] - interp_x_deltas.arrayZ[i]; + float dy = y_deltas.arrayZ[i] - interp_y_deltas.arrayZ[i]; + + if (sqrtf ((float)dx * dx + (float)dy * dy) > tolerance) + return false; + } + return true; +} + +static bool _iup_contour_optimize_dp (const contour_point_vector_t& contour_points, + const hb_vector_t<int>& x_deltas, + const hb_vector_t<int>& y_deltas, + const hb_set_t& forced_set, + float tolerance, + unsigned lookback, + hb_vector_t<unsigned>& costs, /* OUT */ + hb_vector_t<int>& chain /* OUT */) +{ + unsigned n = contour_points.length; + if (unlikely (!costs.resize (n, false) || + !chain.resize (n, false))) + return false; + + lookback = hb_min (lookback, MAX_LOOKBACK); + + for (unsigned i = 0; i < n; i++) + { + unsigned best_cost = (i == 0 ? 1 : costs.arrayZ[i-1] + 1); + + costs.arrayZ[i] = best_cost; + chain.arrayZ[i] = (i == 0 ? -1 : i - 1); + + if (i > 0 && forced_set.has (i - 1)) + continue; + + int lookback_index = hb_max ((int) i - (int) lookback + 1, -1); + for (int j = i - 2; j >= lookback_index; j--) + { + unsigned cost = j == -1 ? 1 : costs.arrayZ[j] + 1; + /* num points between i and j */ + unsigned num_points = i - j - 1; + unsigned p1 = (j == -1 ? n - 1 : j); + if (cost < best_cost && + _can_iup_in_between (contour_points.as_array ().sub_array (j + 1, num_points), + x_deltas.as_array ().sub_array (j + 1, num_points), + y_deltas.as_array ().sub_array (j + 1, num_points), + contour_points.arrayZ[p1], contour_points.arrayZ[i], + x_deltas.arrayZ[p1], x_deltas.arrayZ[i], + y_deltas.arrayZ[p1], y_deltas.arrayZ[i], + tolerance)) + { + best_cost = cost; + costs.arrayZ[i] = best_cost; + chain.arrayZ[i] = j; + } + + if (j > 0 && forced_set.has (j)) + break; + } + } + return true; +} + +static bool _iup_contour_optimize (const hb_array_t<const contour_point_t> contour_points, + const hb_array_t<const int> x_deltas, + const hb_array_t<const int> y_deltas, + hb_array_t<bool> opt_indices, /* OUT */ + float tolerance = 0.f) +{ + unsigned n = contour_points.length; + if (opt_indices.length != n || + x_deltas.length != n || + y_deltas.length != n) + return false; + + bool all_within_tolerance = true; + for (unsigned i = 0; i < n; i++) + { + int dx = x_deltas.arrayZ[i]; + int dy = y_deltas.arrayZ[i]; + if (sqrtf ((float)dx * dx + (float)dy * dy) > tolerance) + { + all_within_tolerance = false; + break; + } + } + + /* If all are within tolerance distance, do nothing, opt_indices is + * initilized to false */ + if (all_within_tolerance) + return true; + + /* If there's exactly one point, return it */ + if (n == 1) + { + opt_indices.arrayZ[0] = true; + return true; + } + + /* If all deltas are exactly the same, return just one (the first one) */ + bool all_deltas_are_equal = true; + for (unsigned i = 1; i < n; i++) + if (x_deltas.arrayZ[i] != x_deltas.arrayZ[0] || + y_deltas.arrayZ[i] != y_deltas.arrayZ[0]) + { + all_deltas_are_equal = false; + break; + } + + if (all_deltas_are_equal) + { + opt_indices.arrayZ[0] = true; + return true; + } + + /* else, solve the general problem using Dynamic Programming */ + hb_set_t forced_set; + _iup_contour_bound_forced_set (contour_points, x_deltas, y_deltas, forced_set, tolerance); + + if (!forced_set.is_empty ()) + { + int k = n - 1 - forced_set.get_max (); + if (k < 0) + return false; + + hb_vector_t<int> rot_x_deltas, rot_y_deltas; + contour_point_vector_t rot_points; + hb_set_t rot_forced_set; + if (!rotate_array (contour_points, k, rot_points) || + !rotate_array (x_deltas, k, rot_x_deltas) || + !rotate_array (y_deltas, k, rot_y_deltas) || + !rotate_set (forced_set, k, n, rot_forced_set)) + return false; + + hb_vector_t<unsigned> costs; + hb_vector_t<int> chain; + + if (!_iup_contour_optimize_dp (rot_points, rot_x_deltas, rot_y_deltas, + rot_forced_set, tolerance, n, + costs, chain)) + return false; + + hb_set_t solution; + int index = n - 1; + while (index != -1) + { + solution.add (index); + index = chain.arrayZ[index]; + } + + if (solution.is_empty () || + forced_set.get_population () > solution.get_population ()) + return false; + + for (unsigned i : solution) + opt_indices.arrayZ[i] = true; + + hb_vector_t<bool> rot_indices; + const hb_array_t<const bool> opt_indices_array (opt_indices.arrayZ, opt_indices.length); + rotate_array (opt_indices_array, -k, rot_indices); + + for (unsigned i = 0; i < n; i++) + opt_indices.arrayZ[i] = rot_indices.arrayZ[i]; + } + else + { + hb_vector_t<int> repeat_x_deltas, repeat_y_deltas; + contour_point_vector_t repeat_points; + + if (unlikely (!repeat_x_deltas.resize (n * 2, false) || + !repeat_y_deltas.resize (n * 2, false) || + !repeat_points.resize (n * 2, false))) + return false; + + unsigned contour_point_size = hb_static_size (contour_point_t); + for (unsigned i = 0; i < n; i++) + { + hb_memcpy ((void *) repeat_x_deltas.arrayZ, (const void *) x_deltas.arrayZ, n * sizeof (float)); + hb_memcpy ((void *) (repeat_x_deltas.arrayZ + n), (const void *) x_deltas.arrayZ, n * sizeof (float)); + + hb_memcpy ((void *) repeat_y_deltas.arrayZ, (const void *) y_deltas.arrayZ, n * sizeof (float)); + hb_memcpy ((void *) (repeat_y_deltas.arrayZ + n), (const void *) y_deltas.arrayZ, n * sizeof (float)); + + hb_memcpy ((void *) repeat_points.arrayZ, (const void *) contour_points.arrayZ, n * contour_point_size); + hb_memcpy ((void *) (repeat_points.arrayZ + n), (const void *) contour_points.arrayZ, n * contour_point_size); + } + + hb_vector_t<unsigned> costs; + hb_vector_t<int> chain; + if (!_iup_contour_optimize_dp (repeat_points, repeat_x_deltas, repeat_y_deltas, + forced_set, tolerance, n, + costs, chain)) + return false; + + unsigned best_cost = n + 1; + int len = costs.length; + hb_set_t best_sol; + for (int start = n - 1; start < len; start++) + { + hb_set_t solution; + int i = start; + int lookback = start - (int) n; + while (i > lookback) + { + solution.add (i % n); + i = chain.arrayZ[i]; + } + if (i == lookback) + { + unsigned cost_i = i < 0 ? 0 : costs.arrayZ[i]; + unsigned cost = costs.arrayZ[start] - cost_i; + if (cost <= best_cost) + { + best_sol.set (solution); + best_cost = cost; + } + } + } + + for (unsigned i = 0; i < n; i++) + if (best_sol.has (i)) + opt_indices.arrayZ[i] = true; + } + return true; +} + +bool iup_delta_optimize (const contour_point_vector_t& contour_points, + const hb_vector_t<int>& x_deltas, + const hb_vector_t<int>& y_deltas, + hb_vector_t<bool>& opt_indices, /* OUT */ + float tolerance) +{ + if (!opt_indices.resize (contour_points.length)) + return false; + + hb_vector_t<unsigned> end_points; + unsigned count = contour_points.length; + if (unlikely (!end_points.alloc (count))) + return false; + + for (unsigned i = 0; i < count - 4; i++) + if (contour_points.arrayZ[i].is_end_point) + end_points.push (i); + + /* phantom points */ + for (unsigned i = count - 4; i < count; i++) + end_points.push (i); + + if (end_points.in_error ()) return false; + + unsigned start = 0; + for (unsigned end : end_points) + { + unsigned len = end - start + 1; + if (!_iup_contour_optimize (contour_points.as_array ().sub_array (start, len), + x_deltas.as_array ().sub_array (start, len), + y_deltas.as_array ().sub_array (start, len), + opt_indices.as_array ().sub_array (start, len), + tolerance)) + return false; + start = end + 1; + } + return true; +} diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-instancer-iup.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-instancer-iup.hh new file mode 100644 index 00000000000..7eac5935a46 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-instancer-iup.hh @@ -0,0 +1,37 @@ +/* + * Copyright © 2024 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. + */ + +#ifndef HB_SUBSET_INSTANCER_IUP_HH +#define HB_SUBSET_INSTANCER_IUP_HH + +#include "hb-subset-plan.hh" +/* given contour points and deltas, optimize a set of referenced points within error + * tolerance. Returns optimized referenced point indices */ +HB_INTERNAL bool iup_delta_optimize (const contour_point_vector_t& contour_points, + const hb_vector_t<int>& x_deltas, + const hb_vector_t<int>& y_deltas, + hb_vector_t<bool>& opt_indices, /* OUT */ + float tolerance = 0.f); + +#endif /* HB_SUBSET_INSTANCER_IUP_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-instancer-solver.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-instancer-solver.cc index 4876bc43797..70783c0a0d8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-instancer-solver.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-instancer-solver.cc @@ -256,7 +256,10 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) */ float newUpper = peak + (1 - gain) * (upper - peak); assert (axisMax <= newUpper); // Because outGain > gain - if (newUpper <= axisDef + (axisMax - axisDef) * 2) + /* Disabled because ots doesn't like us: + * https://github.com/fonttools/fonttools/issues/3350 */ + + if (false && (newUpper <= axisDef + (axisMax - axisDef) * 2)) { upper = newUpper; if (!negative && axisDef + (axisMax - axisDef) * MAX_F2DOT14 < upper) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan-member-list.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan-member-list.hh index 71da80e3875..74416b92f98 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan-member-list.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan-member-list.hh @@ -140,6 +140,15 @@ HB_SUBSET_PLAN_MEMBER (mutable hb_vector_t<unsigned>, bounds_height_vec) //map: new_gid -> contour points vector HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E(<hb_codepoint_t, contour_point_vector_t>), new_gid_contour_points_map) +//new gids set for composite glyphs +HB_SUBSET_PLAN_MEMBER (hb_set_t, composite_new_gids) + +//Old BASE item variation index -> (New varidx, 0) mapping +HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<unsigned, hb_pair_t E(<unsigned, int>)>), base_variation_idx_map) + +//BASE table varstore retained varidx mapping +HB_SUBSET_PLAN_MEMBER (hb_vector_t<hb_inc_bimap_t>, base_varstore_inner_maps) + #ifdef HB_EXPERIMENTAL_API // name table overrides map: hb_ot_name_record_ids_t-> name string new value or // None to indicate should remove diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc index 5786223196d..068fddaeddd 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc @@ -32,6 +32,7 @@ #include "hb-ot-cmap-table.hh" #include "hb-ot-glyf-table.hh" +#include "hb-ot-layout-base-table.hh" #include "hb-ot-layout-gdef-table.hh" #include "hb-ot-layout-gpos-table.hh" #include "hb-ot-layout-gsub-table.hh" @@ -431,6 +432,52 @@ _collect_layout_variation_indices (hb_subset_plan_t* plan) gdef.destroy (); gpos.destroy (); } + +#ifndef HB_NO_BASE +/* used by BASE table only, delta is always set to 0 in the output map */ +static inline void +_remap_variation_indices (const hb_set_t& indices, + unsigned subtable_count, + hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>>& variation_idx_delta_map /* OUT */) +{ + unsigned new_major = 0, new_minor = 0; + unsigned last_major = (indices.get_min ()) >> 16; + for (unsigned idx : indices) + { + uint16_t major = idx >> 16; + if (major >= subtable_count) break; + if (major != last_major) + { + new_minor = 0; + ++new_major; + } + + unsigned new_idx = (new_major << 16) + new_minor; + variation_idx_delta_map.set (idx, hb_pair_t<unsigned, int> (new_idx, 0)); + ++new_minor; + last_major = major; + } +} + +static inline void +_collect_base_variation_indices (hb_subset_plan_t* plan) +{ + hb_blob_ptr_t<OT::BASE> base = plan->source_table<OT::BASE> (); + if (!base->has_var_store ()) + { + base.destroy (); + return; + } + + hb_set_t varidx_set; + base->collect_variation_indices (plan, varidx_set); + unsigned subtable_count = base->get_var_store ().get_sub_table_count (); + base.destroy (); + + _remap_variation_indices (varidx_set, subtable_count, plan->base_variation_idx_map); + _generate_varstore_inner_maps (varidx_set, subtable_count, plan->base_varstore_inner_maps); +} +#endif #endif static inline void @@ -994,8 +1041,8 @@ _update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan) OT::cff2::accelerator_t cff2 (plan->source); if (!cff2.is_valid ()) return; - hb_font_t *font = nullptr; - if (unlikely (!plan->check_success (font = _get_hb_font_with_variations (plan)))) + hb_font_t *font = _get_hb_font_with_variations (plan); + if (unlikely (!plan->check_success (font != nullptr))) { hb_font_destroy (font); return; @@ -1073,8 +1120,8 @@ _update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan) static bool _get_instance_glyphs_contour_points (hb_subset_plan_t *plan) { - /* contour_points vector only needed for updating gvar table (infer delta) - * during partial instancing */ + /* contour_points vector only needed for updating gvar table (infer delta and + * iup delta optimization) during partial instancing */ if (plan->user_axes_location.is_empty () || plan->all_axes_pinned) return true; @@ -1092,10 +1139,17 @@ _get_instance_glyphs_contour_points (hb_subset_plan_t *plan) } hb_codepoint_t old_gid = _.second; - if (unlikely (!glyf.glyph_for_gid (old_gid).get_all_points_without_var (plan->source, all_points))) + auto glyph = glyf.glyph_for_gid (old_gid); + if (unlikely (!glyph.get_all_points_without_var (plan->source, all_points))) return false; if (unlikely (!plan->new_gid_contour_points_map.set (new_gid, all_points))) return false; + +#ifdef HB_EXPERIMENTAL_API + /* composite new gids are only needed by iup delta optimization */ + if ((plan->flags & HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS) && glyph.is_composite ()) + plan->composite_new_gids.add (new_gid); +#endif } return true; } @@ -1205,6 +1259,13 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, if (!drop_tables.has (HB_OT_TAG_GDEF)) _remap_used_mark_sets (this, used_mark_sets_map); +#ifndef HB_NO_VAR +#ifndef HB_NO_BASE + if (!drop_tables.has (HB_OT_TAG_BASE)) + _collect_base_variation_indices (this); +#endif +#endif + if (unlikely (in_error ())) return; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh index 1f19a58c1ed..19a9fa69182 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh @@ -78,6 +78,13 @@ struct contour_point_t y = x * matrix[1] + y * matrix[3]; x = x_; } + + void add_delta (float delta_x, float delta_y) + { + x += delta_x; + y += delta_y; + } + HB_ALWAYS_INLINE void translate (const contour_point_t &p) { x += p.x; y += p.y; } @@ -99,6 +106,22 @@ struct contour_point_vector_t : hb_vector_t<contour_point_t> unsigned count = a.length; hb_memcpy (arrayZ, a.arrayZ, count * sizeof (arrayZ[0])); } + + bool add_deltas (const hb_vector_t<float> deltas_x, + const hb_vector_t<float> deltas_y, + const hb_vector_t<bool> indices) + { + if (indices.length != deltas_x.length || + indices.length != deltas_y.length) + return false; + + for (unsigned i = 0; i < indices.length; i++) + { + if (!indices.arrayZ[i]) continue; + arrayZ[i].add_delta (deltas_x.arrayZ[i], deltas_y.arrayZ[i]); + } + return true; + } }; namespace OT { @@ -147,7 +170,7 @@ struct hb_subset_plan_t bool gsub_insert_catch_all_feature_variation_rec; bool gpos_insert_catch_all_feature_variation_rec; - // whether GDEF VarStore is retained + // whether GDEF ItemVariationStore is retained mutable bool has_gdef_varstore; #define HB_SUBSET_PLAN_MEMBER(Type, Name) Type Name; 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 06e77dd8eb5..f10ef54dbdc 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc @@ -48,6 +48,7 @@ #include "hb-ot-cff2-table.hh" #include "hb-ot-vorg-table.hh" #include "hb-ot-name-table.hh" +#include "hb-ot-layout-base-table.hh" #include "hb-ot-layout-gsub-table.hh" #include "hb-ot-layout-gpos-table.hh" #include "hb-ot-var-avar-table.hh" @@ -503,6 +504,7 @@ _subset_table (hb_subset_plan_t *plan, case HB_OT_TAG_CBLC: return _subset<const OT::CBLC> (plan, buf); case HB_OT_TAG_CBDT: return true; /* skip CBDT, handled by CBLC */ case HB_OT_TAG_MATH: return _subset<const OT::MATH> (plan, buf); + case HB_OT_TAG_BASE: return _subset<const OT::BASE> (plan, buf); #ifndef HB_NO_SUBSET_CFF case HB_OT_TAG_CFF1: return _subset<const OT::cff1> (plan, buf); @@ -548,6 +550,7 @@ _subset_table (hb_subset_plan_t *plan, } #endif return _passthrough (plan, tag); + default: if (plan->flags & HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED) return _passthrough (plan, tag); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h index d79e7f762a0..73dcae4660b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h @@ -76,6 +76,8 @@ typedef struct hb_subset_plan_t hb_subset_plan_t; * @HB_SUBSET_FLAGS_IFTB_REQUIREMENTS: If set enforce requirements on the output subset * to allow it to be used with incremental font transfer IFTB patches. Primarily, * this forces all outline data to use long (32 bit) offsets. Since: EXPERIMENTAL + * @HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS: If set perform IUP delta optimization on the + * remaining gvar table's deltas. Since: EXPERIMENTAL * * List of boolean properties that can be configured on the subset input. * @@ -95,6 +97,7 @@ typedef enum { /*< flags >*/ HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE = 0x00000200u, #ifdef HB_EXPERIMENTAL_API HB_SUBSET_FLAGS_IFTB_REQUIREMENTS = 0x00000400u, + HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS = 0x00000800u, #endif } hb_subset_flags_t; @@ -171,6 +174,10 @@ hb_subset_input_set_flags (hb_subset_input_t *input, unsigned value); HB_EXTERN hb_bool_t +hb_subset_input_pin_all_axes_to_default (hb_subset_input_t *input, + hb_face_t *face); + +HB_EXTERN hb_bool_t hb_subset_input_pin_axis_to_default (hb_subset_input_t *input, hb_face_t *face, hb_tag_t axis_tag); @@ -183,12 +190,19 @@ hb_subset_input_pin_axis_location (hb_subset_input_t *input, #ifdef HB_EXPERIMENTAL_API HB_EXTERN hb_bool_t +hb_subset_input_get_axis_range (hb_subset_input_t *input, + hb_tag_t axis_tag, + float *axis_min_value, + float *axis_max_value, + float *axis_def_value); + +HB_EXTERN hb_bool_t hb_subset_input_set_axis_range (hb_subset_input_t *input, hb_face_t *face, hb_tag_t axis_tag, float axis_min_value, float axis_max_value, - float *axis_def_value); + float axis_def_value); HB_EXTERN hb_bool_t hb_subset_input_override_name_table (hb_subset_input_t *input, 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 dfe1b7d1c7e..c0cc7063ff0 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh @@ -78,7 +78,7 @@ struct hb_vector_t if (unlikely (in_error ())) return; copy_array (o); } - hb_vector_t (hb_vector_t &&o) + hb_vector_t (hb_vector_t &&o) noexcept { allocated = o.allocated; length = o.length; @@ -122,7 +122,7 @@ struct hb_vector_t resize (0); } - friend void swap (hb_vector_t& a, hb_vector_t& b) + friend void swap (hb_vector_t& a, hb_vector_t& b) noexcept { hb_swap (a.allocated, b.allocated); hb_swap (a.length, b.length); @@ -139,7 +139,7 @@ struct hb_vector_t return *this; } - hb_vector_t& operator = (hb_vector_t &&o) + hb_vector_t& operator = (hb_vector_t &&o) noexcept { hb_swap (*this, o); return *this; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh index 972608d6a30..0ceeb99f500 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh @@ -64,6 +64,7 @@ #pragma GCC diagnostic error "-Wbitwise-instead-of-logical" #pragma GCC diagnostic error "-Wcast-align" #pragma GCC diagnostic error "-Wcast-function-type" +#pragma GCC diagnostic error "-Wcast-function-type-strict" #pragma GCC diagnostic error "-Wconstant-conversion" #pragma GCC diagnostic error "-Wcomma" #pragma GCC diagnostic error "-Wdelete-non-virtual-dtor" @@ -177,6 +178,11 @@ #define HB_EXTERN __declspec (dllexport) extern #endif +// https://github.com/harfbuzz/harfbuzz/pull/4619 +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS 1 +#endif + #include "hb.h" #define HB_H_IN #include "hb-ot.h" @@ -212,6 +218,12 @@ #include <winapifamily.h> #endif +#ifndef PRId32 +# define PRId32 "d" +# define PRIu32 "u" +# define PRIx32 "x" +#endif + #define HB_PASTE1(a,b) a##b #define HB_PASTE(a,b) HB_PASTE1(a,b) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build b/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build index 77c7e750178..daa9198058c 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build @@ -371,6 +371,8 @@ hb_subset_sources = files( 'hb-subset-cff2.cc', 'hb-subset-input.cc', 'hb-subset-input.hh', + 'hb-subset-instancer-iup.hh', + 'hb-subset-instancer-iup.cc', 'hb-subset-instancer-solver.hh', 'hb-subset-instancer-solver.cc', 'hb-subset-plan.cc', @@ -680,7 +682,8 @@ if conf.get('HAVE_CAIRO', 0) == 1 endif if get_option('tests').enabled() - # TODO: MSVC gives the following, + # TODO: Microsoft LINK gives the following because extern, non dllexport + # symbols can only be used when linking against a static library # error LNK2019: unresolved external symbol "unsigned __int64 const * const _hb_NullPool" if cpp.get_define('_MSC_FULL_VER') == '' noinst_programs = { @@ -722,13 +725,13 @@ if get_option('tests').enabled() 'test-repacker': ['test-repacker.cc', 'hb-static.cc', 'graph/gsubgpos-context.cc'], 'test-instancer-solver': ['test-subset-instancer-solver.cc', 'hb-subset-instancer-solver.cc', 'hb-static.cc'], 'test-priority-queue': ['test-priority-queue.cc', 'hb-static.cc'], - 'test-tuple-varstore': ['test-tuple-varstore.cc', 'hb-subset-instancer-solver.cc', 'hb-static.cc'], - 'test-item-varstore': ['test-item-varstore.cc', 'hb-subset-instancer-solver.cc', 'hb-static.cc'], + 'test-tuple-varstore': ['test-tuple-varstore.cc', 'hb-subset-instancer-solver.cc', 'hb-subset-instancer-iup.cc', 'hb-static.cc'], + 'test-item-varstore': ['test-item-varstore.cc', 'hb-subset-instancer-solver.cc', 'hb-subset-instancer-iup.cc', 'hb-static.cc'], 'test-unicode-ranges': ['test-unicode-ranges.cc'], } foreach name, source : compiled_tests - if cpp.get_argument_syntax() == 'msvc' and source.contains('hb-static.cc') - # TODO: MSVC doesn't like tests having hb-static.cc, fix them + if cpp.get_define('_MSC_FULL_VER') != '' and source.contains('hb-static.cc') + # TODO: Microsoft compilers cannot link tests using hb-static.cc, fix them continue endif test(name, executable(name, source, diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/test-item-varstore.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/test-item-varstore.cc index 3e0875ecb1e..99656b8d0ef 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/test-item-varstore.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/test-item-varstore.cc @@ -40,7 +40,7 @@ test_item_variations () axis_idx_tag_map.set (1, axis_tag); OT::item_variations_t item_vars; - const OT::VariationStore& src_var_store = hvar_table+(hvar_table->varStore); + const OT::ItemVariationStore& src_var_store = hvar_table+(hvar_table->varStore); bool result = item_vars.create_from_item_varstore (src_var_store, axis_idx_tag_map); assert (result); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/test-repacker.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/test-repacker.cc index 950e7d26705..7f57d8eac1d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/test-repacker.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/test-repacker.cc @@ -597,6 +597,31 @@ populate_serializer_with_dedup_overflow (hb_serialize_context_t* c) } static void +populate_serializer_with_multiple_dedup_overflow (hb_serialize_context_t* c) +{ + std::string large_string(70000, 'a'); + c->start_serialize<char> (); + + unsigned leaf = add_object("def", 3, c); + + constexpr unsigned num_mid_nodes = 20; + unsigned mid_nodes[num_mid_nodes]; + for (unsigned i = 0; i < num_mid_nodes; i++) { + start_object(large_string.c_str(), 10000 + i, c); + add_offset(leaf, c); + mid_nodes[i] = c->pop_pack(false); + } + + start_object("abc", 3, c); + for (unsigned i = 0; i < num_mid_nodes; i++) { + add_wide_offset(mid_nodes[i], c); + } + c->pop_pack(false); + + c->end_serialize(); +} + +static void populate_serializer_with_isolation_overflow (hb_serialize_context_t* c) { std::string large_string(70000, 'a'); @@ -1682,6 +1707,21 @@ static void test_resolve_overflows_via_duplication () hb_blob_destroy (out); } +static void test_resolve_overflows_via_multiple_duplications () +{ + size_t buffer_size = 300000; + void* buffer = malloc (buffer_size); + hb_serialize_context_t c (buffer, buffer_size); + populate_serializer_with_multiple_dedup_overflow (&c); + graph_t graph (c.object_graph ()); + + hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG_NONE, 5); + assert (out); + + free (buffer); + hb_blob_destroy (out); +} + static void test_resolve_overflows_via_space_assignment () { size_t buffer_size = 160000; @@ -1946,12 +1986,12 @@ static void test_resolve_with_close_to_limit_pair_pos_2_split () void* buffer = malloc (buffer_size); assert (buffer); hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_with_large_pair_pos_2 <1, 1596, 10>(&c, true, false, false); + populate_serializer_with_large_pair_pos_2 <1, 1636, 10>(&c, true, false, false); void* expected_buffer = malloc (buffer_size); assert (expected_buffer); hb_serialize_context_t e (expected_buffer, buffer_size); - populate_serializer_with_large_pair_pos_2 <2, 798, 10>(&e, true, false, false); + populate_serializer_with_large_pair_pos_2 <2, 818, 10>(&e, true, false, false); run_resolve_overflow_test ("test_resolve_with_close_to_limit_pair_pos_2_split", c, @@ -2141,6 +2181,7 @@ main (int argc, char **argv) test_will_overflow_3 (); test_resolve_overflows_via_sort (); test_resolve_overflows_via_duplication (); + test_resolve_overflows_via_multiple_duplications (); test_resolve_overflows_via_priority (); test_resolve_overflows_via_space_assignment (); test_resolve_overflows_via_isolation (); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/test-subset-instancer-solver.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/test-subset-instancer-solver.cc index 0a0aea8c2e3..c7cba3415e6 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/test-subset-instancer-solver.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/test-subset-instancer-solver.cc @@ -95,9 +95,11 @@ main (int argc, char **argv) Triple tent (0.f, 0.2f, 1.f); Triple axis_range (-1.f, 0.f, 0.8f); result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 1); + assert (out.length == 2); assert (out[0].first == 1.f); - assert (out[0].second == Triple (0.f, 0.25f, 1.25f)); + assert (out[0].second == Triple (0.f, 0.25f, 1.f)); + assert (approx (out[1].first, 0.25f)); + assert (out[1].second == Triple (0.25f, 1.f, 1.f)); } /* Case 3 boundary */ @@ -105,9 +107,11 @@ main (int argc, char **argv) Triple tent (0.f, 0.4f, 1.f); Triple axis_range (-1.f, 0.f, 0.5f); result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 1); + assert (out.length == 2); assert (out[0].first == 1.f); - assert (out[0].second == Triple (0.f, 0.8f, 32767/(float) (1 << 14))); + assert (out[0].second == Triple (0.f, 0.8f, 1.f)); + assert (approx (out[1].first, 2.5f/3)); + assert (out[1].second == Triple (0.8f, 1.f, 1.f)); } /* Case 4 */ @@ -353,9 +357,11 @@ main (int argc, char **argv) Triple tent (0.f, 0.2f, 1.f); Triple axis_range (0.f, 0.f, 0.5f); result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 1); + assert (out.length == 2); assert (out[0].first == 1.f); - assert (out[0].second == Triple (0.f, 0.4f, 32767/(float) (1 << 14))); + assert (out[0].second == Triple (0.f, 0.4f, 1.f)); + assert (out[1].first == 0.625f); + assert (out[1].second == Triple (0.4f, 1.f, 1.f)); } |