diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2021-03-23 07:45:57 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-04-06 19:07:59 +0000 |
commit | c197629f8035023353c2ab678a46e212477f1536 (patch) | |
tree | 3efd476247198973779acbc3591dcad6e2a1ae6e /src/3rdparty | |
parent | a0def9b90dd9eb18692b35df12e5a43ca0e5fa32 (diff) |
Update to Harfbuzz 2.8.0
This updates Harfbuzz to the latest version and also
adds an import script to help with this work in the
future.
Task-number: QTBUG-90217
Change-Id: I23eae7b7bbbd5001df9873e4784a0c4213de5508
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
(cherry picked from commit 70af64433f491ee28e8b4ff19ebf413d45960155)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src/3rdparty')
245 files changed, 23386 insertions, 15037 deletions
diff --git a/src/3rdparty/harfbuzz-ng/CMakeLists.txt b/src/3rdparty/harfbuzz-ng/CMakeLists.txt index 37e07f2350..5ac9b33b62 100644 --- a/src/3rdparty/harfbuzz-ng/CMakeLists.txt +++ b/src/3rdparty/harfbuzz-ng/CMakeLists.txt @@ -24,6 +24,7 @@ qt_internal_add_3rdparty_library(BundledHarfbuzz src/hb-common.h src/hb-debug.hh src/hb-deprecated.h + src/hb-draw.cc src/hb-draw.h src/hb-draw.hh src/hb-face.cc src/hb-face.h src/hb-face.hh src/hb-fallback-shape.cc src/hb-font.cc src/hb-font.h src/hb-font.hh @@ -41,6 +42,7 @@ qt_internal_add_3rdparty_library(BundledHarfbuzz src/hb-shaper-impl.hh src/hb-shaper-list.hh src/hb-string-array.hh + src/hb-style.cc src/hb-style.h src/hb-subset.cc src/hb-subset-cff-common.cc src/hb-subset-cff1.cc @@ -91,6 +93,7 @@ qt_internal_extend_target(BundledHarfbuzz CONDITION WIN32 qt_internal_extend_target(BundledHarfbuzz CONDITION TRUE # special case SOURCES src/hb-ot.h + src/hb-ot-cff1-std-str.hh src/hb-ot-cff1-table.cc src/hb-ot-cff2-table.cc src/hb-ot-cmap-table.hh @@ -122,6 +125,7 @@ qt_internal_extend_target(BundledHarfbuzz CONDITION TRUE # special case src/hb-ot-shape.cc src/hb-ot-shape.h src/hb-ot-shape.hh src/hb-ot-shape-complex-arabic.cc src/hb-ot-shape-complex-arabic.hh src/hb-ot-shape-complex-arabic-fallback.hh + src/hb-ot-shape-complex-arabic-joining-list.hh src/hb-ot-shape-complex-arabic-table.hh src/hb-ot-shape-complex-default.cc src/hb-ot-shape-complex-hangul.cc @@ -132,10 +136,11 @@ qt_internal_extend_target(BundledHarfbuzz CONDITION TRUE # special case src/hb-ot-shape-complex-khmer.cc src/hb-ot-shape-complex-myanmar.cc src/hb-ot-shape-complex-myanmar-machine.hh + src/hb-ot-shape-complex-syllabic.cc src/hb-ot-shape-complex-syllabic.hh src/hb-ot-shape-complex-thai.cc - src/hb-ot-shape-complex-use.cc src/hb-ot-shape-complex-use.hh + src/hb-ot-shape-complex-use.cc src/hb-ot-shape-complex-use-machine.hh - src/hb-ot-shape-complex-use-table.cc + src/hb-ot-shape-complex-use-table.hh src/hb-ot-shape-complex-vowel-constraints.cc src/hb-ot-shape-fallback.cc src/hb-ot-shape-fallback.hh src/hb-ot-shape-normalize.cc src/hb-ot-shape-normalize.hh diff --git a/src/3rdparty/harfbuzz-ng/COPYING b/src/3rdparty/harfbuzz-ng/COPYING index 0278e60a5c..57343164f2 100644 --- a/src/3rdparty/harfbuzz-ng/COPYING +++ b/src/3rdparty/harfbuzz-ng/COPYING @@ -2,8 +2,9 @@ HarfBuzz is licensed under the so-called "Old MIT" license. Details follow. For parts of HarfBuzz that are licensed under different licenses see individual files names COPYING in subdirectories where applicable. -Copyright © 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019 Google, Inc. -Copyright © 2019 Facebook, Inc. +Copyright © 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020 Google, Inc. +Copyright © 2018,2019,2020 Ebrahim Byagowi +Copyright © 2019,2020 Facebook, Inc. Copyright © 2012 Mozilla Foundation Copyright © 2011 Codethink Limited Copyright © 2008,2010 Nokia Corporation and/or its subsidiary(-ies) diff --git a/src/3rdparty/harfbuzz-ng/NEWS b/src/3rdparty/harfbuzz-ng/NEWS index 7dde1193f3..321c550188 100644 --- a/src/3rdparty/harfbuzz-ng/NEWS +++ b/src/3rdparty/harfbuzz-ng/NEWS @@ -1,3 +1,129 @@ +Overview of changes leading to 2.8.0 +Tuesday, March 16, 2021 +==================================== +- Shape joining scripts other than Arabic/Syriac using the Universal Shaping Engine. + 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) +- 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) +- Removed most atomic implementations now that we have C++11 atomic impl. (Behdad) +- General codebase upkeep; using more C++11 features: constexpr constructors, etc. (Behdad) + + +Overview of changes leading to 2.7.4 +Sunday, December 27, 2020 +==================================== +- Fix missing --enable-introspection configure option from previous release + tarball. +- Documentation updates. + +Overview of changes leading to 2.7.3 +Wednesday, December 23, 2020 +==================================== +- Update USE shaper to 2020-08-13 specification, and other improvements. +- Don’t disable liga feature in myanmar shaper, to match Uniscribe. +- Improvements to language and script tags handling. +- Update language system tag registry to OpenType 1.8.4 +- Support for serializing and deserializing Unicode buffers. Serialized buffers + are now delimited with `<>` or `[]` based on whether it is a Unicode or + glyphs buffer. +- Increase buffer work limits to handle fonts with many complex lookups. +- Handle more shaping operations in trace output. +- Memory access fixes. +- More OOM fixes. +- Improved documentation. +- Build system improvements. +- New API: ++hb_buffer_has_positions() ++hb_buffer_serialize() ++hb_buffer_serialize_unicode() ++hb_buffer_deserialize_unicode() + + +Overview of changes leading to 2.7.2 +Saturday, August 29, 2020 +==================================== +- Fix a regression in the previous release that caused a crash with Kaithi. +- More OOM fixes. + + +Overview of changes leading to 2.7.1 +Thursday, August 13, 2020 +==================================== +- ot-funcs now handles variable empty glyphs better when hvar/vvar isn't present. +- Reverted a GDEF processing regression. +- A couple of fixes to handle OOM better. + + +Overview of changes leading to 2.7.0 +Saturday, July 25, 2020 +==================================== +- Use an implementation for round that always rounds up, some minor fluctuations + are expected on var font specially when hb-ot callback is used. +- Fix an AAT's `kerx` issue on broken rendering of Devanagari Sangam MN. +- Remove AAT's `lcar` table support from _get_ligature_carets API, not even much + use on macOS installed fonts (only two files). GDEF support is the recommended + one and expected to work properly after issues fixed two releases ago. +- Minor memory fixes to handle OOM better specially in hb-ft. +- Minor .so files versioning scheme change and remove stable/unstable scheme + differences, was never used in practice (always default to stable scheme). +- We are now suggesting careful packaging of the library using meson, + https://github.com/harfbuzz/harfbuzz/wiki/Notes-on-migration-to-meson + for more information. +- Distribution package URL is changed, either use GitHub generated tarballs, + `https://github.com/harfbuzz/harfbuzz/archive/$pkgver.tar.gz` + or, even more preferably use commit hash of the release and git checkouts like, + `git+https://github.com/harfbuzz/harfbuzz#commit=$commit` + + +Overview of changes leading to 2.6.8 +Monday, June 22, 2020 +==================================== +- New API to fetch glyph alternates from GSUB table. +- hb-coretext build fix for macOS < 10.10. +- Meson build fixes, cmake port removal is postponed but please prepare for + it and give us feedback. + Autotools is still our main build system however please consider + experimenting with meson also for packaging the library. +- New API: ++hb_ot_layout_lookup_get_glyph_alternates() + + +Overview of changes leading to 2.6.7 +Wednesday, June 3, 2020 +==================================== +- Update to Unicode 13.0.0. +- Fix hb_ot_layout_get_ligature_carets for fonts without lcar table, it was + completely broken for all the other fonts since 2.1.2. +- As a part of our migration to meson, this release will be the last one + to provide cmake port files but autotools still is our main build system. + There is a possibility that the next version or the after be released + using meson. + + +Overview of changes leading to 2.6.6 +Tuesday, May 12, 2020 +==================================== +- A fix in AAT kerning for Geeza Pro. +- Better support for resource fork fonts on macOS. + + +Overview of changes leading to 2.6.5 +Friday, April 17, 2020 +==================================== +- Add experimental meson build system. Autotools is still the primary + and supported build system. +- AAT is now always preferred for horizontal scripts when both AAT and OT + layout tables exist at the same time. +- Subsetter improvements. +- New API: ++hb_ft_font_lock_face() ++hb_ft_font_unlock_face() + + Overview of changes leading to 2.6.4 Monday, October 29, 2019 ==================================== diff --git a/src/3rdparty/harfbuzz-ng/README.md b/src/3rdparty/harfbuzz-ng/README.md index e0ef93576b..0df556de37 100644 --- a/src/3rdparty/harfbuzz-ng/README.md +++ b/src/3rdparty/harfbuzz-ng/README.md @@ -1,5 +1,4 @@ -[![Travis Build Status](https://travis-ci.org/harfbuzz/harfbuzz.svg?branch=master)](https://travis-ci.org/harfbuzz/harfbuzz) -[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/0t0flrxpstj9lb9w?svg=true&branch=master)](https://ci.appveyor.com/project/harfbuzz/harfbuzz) +[![Linux CI Status](https://github.com/harfbuzz/harfbuzz/workflows/linux-ci/badge.svg)](https://github.com/harfbuzz/harfbuzz/workflows/linux-ci/badge.svg) [![CircleCI Build Status](https://circleci.com/gh/harfbuzz/harfbuzz/tree/master.svg?style=svg)](https://circleci.com/gh/harfbuzz/harfbuzz/tree/master) [![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 Code Health](https://img.shields.io/coverity/scan/5450.svg)](https://scan.coverity.com/projects/behdad-harfbuzz) @@ -27,8 +26,8 @@ Documentation: https://harfbuzz.github.io <details> - <summary>Packaging status of HarfBuzz</summary + <summary>Packaging status of HarfBuzz</summary> -[![Packaging status](https://repology.org/badge/vertical-allrepos/harfbuzz.svg?header=harfbuzz)](https://repology.org/project/harfbuzz/versions) +[![Packaging status](https://repology.org/badge/vertical-allrepos/harfbuzz.svg?header=harfbuzz)](https://repology.org/project/harfbuzz/versions) </details> diff --git a/src/3rdparty/harfbuzz-ng/import_from_tarball.sh b/src/3rdparty/harfbuzz-ng/import_from_tarball.sh new file mode 100644 index 0000000000..db0e6004a4 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/import_from_tarball.sh @@ -0,0 +1,100 @@ +#! /bin/sh + +############################################################################# +## +## Copyright (C) 2021 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is the build configuration utility of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +# This is a small script to copy the required files from a harfbuzz tarball +# into 3rdparty/harfbuzz-ng/ . Documentation, tests, demos etc. are not imported. +# Steps: +# 1. rm $QTDIR/src/3rdparty/harfbuzz-ng/src/* +# 2. source import_from_tarball.sh harfbuzz_tarball_dir/ $QTDIR/src/3rdparty/harfbuzz-ng/ +# 3. Check that CMakeLists contains everything + +if [ $# -ne 2 ]; then + echo "Usage: $0 harfbuzz_tarball_dir/ \$QTDIR/src/3rdparty/harfbuzz-ng/" + exit 1 +fi + +HB_DIR=$1 +TARGET_DIR=$2 + +if [ ! -d "$HB_DIR" -o ! -r "$HB_DIR" -o ! -d "$TARGET_DIR" -o ! -w "$TARGET_DIR" ]; then + echo "Either the harfbuzz source dir or the target dir do not exist," + echo "are not directories or have the wrong permissions." + exit 2 +fi + +# with 1 argument, copies HB_DIR/$1 to TARGET_DIR/$1 +# with 2 arguments, copies HB_DIR/$1 to TARGET_DIR/$2 +copy_file_or_dir() { + if [ $# -lt 1 -o $# -gt 2 ]; then + echo "Wrong number of arguments to copy_file_or_dir" + exit 3 + fi + + SOURCE_FILE=$1 + if [ -n "$2" ]; then + DEST_FILE=$2 + else + DEST_FILE=$1 + fi + + mkdir -p "$TARGET_DIR/$(dirname "$SOURCE_FILE")" + cp -R "$HB_DIR/$SOURCE_FILE" "$TARGET_DIR/$DEST_FILE" +} + +FILES=(AUTHORS + COPYING + NEWS + README.md + THANKS + TODO + ) + +for i in ${FILES[*]}; do + copy_file_or_dir "$i" +done + +CODEFILES=($HB_DIR/src/*.cc + $HB_DIR/src/*.hh + $HB_DIR/src/*.h) + +for i in ${CODEFILES[*]}; do + cp $i $TARGET_DIR/src/ +done diff --git a/src/3rdparty/harfbuzz-ng/qt_attribution.json b/src/3rdparty/harfbuzz-ng/qt_attribution.json index 8614e3a17c..96808bf35d 100644 --- a/src/3rdparty/harfbuzz-ng/qt_attribution.json +++ b/src/3rdparty/harfbuzz-ng/qt_attribution.json @@ -6,7 +6,7 @@ "Description": "HarfBuzz is an OpenType text shaping engine.", "Homepage": "http://harfbuzz.org", - "Version": "2.6.4", + "Version": "2.8.0", "License": "MIT License", "LicenseId": "MIT", diff --git a/src/3rdparty/harfbuzz-ng/src/dump-indic-data.cc b/src/3rdparty/harfbuzz-ng/src/dump-indic-data.cc deleted file mode 100644 index 8ddc9d5a4e..0000000000 --- a/src/3rdparty/harfbuzz-ng/src/dump-indic-data.cc +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright © 2018 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ - -#include "hb-ot-shape-complex-indic.hh" - -int -main () -{ - for (hb_codepoint_t u = 0; u <= 0x10FFFF; u++) - { - hb_glyph_info_t info; - info.codepoint = u; - set_indic_properties (info); - if (info.indic_category() != INDIC_SYLLABIC_CATEGORY_OTHER || - info.indic_position() != INDIC_MATRA_CATEGORY_NOT_APPLICABLE) - printf("U+%04X %u %u\n", u, - info.indic_category(), - info.indic_position()); - } -} diff --git a/src/3rdparty/harfbuzz-ng/src/dump-myanmar-data.cc b/src/3rdparty/harfbuzz-ng/src/dump-myanmar-data.cc deleted file mode 100644 index c1a303f8f1..0000000000 --- a/src/3rdparty/harfbuzz-ng/src/dump-myanmar-data.cc +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright © 2018 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ - -#include "hb-ot-shape-complex-myanmar.hh" - -int -main () -{ - for (hb_codepoint_t u = 0; u <= 0x10FFFF; u++) - { - hb_glyph_info_t info; - info.codepoint = u; - set_myanmar_properties (info); - if (info.myanmar_category() != INDIC_SYLLABIC_CATEGORY_OTHER || - info.myanmar_position() != INDIC_MATRA_CATEGORY_NOT_APPLICABLE) - printf("U+%04X %u %u\n", u, - info.myanmar_category(), - info.myanmar_position()); - } -} diff --git a/src/3rdparty/harfbuzz-ng/src/harfbuzz-config.cmake.in b/src/3rdparty/harfbuzz-ng/src/harfbuzz-config.cmake.in deleted file mode 100644 index 304410d9ba..0000000000 --- a/src/3rdparty/harfbuzz-ng/src/harfbuzz-config.cmake.in +++ /dev/null @@ -1,86 +0,0 @@ -# Set these variables so that the `${prefix}/lib` expands to something we can -# remove. -set(_harfbuzz_remove_string "REMOVE_ME") -set(exec_prefix "${_harfbuzz_remove_string}") -set(prefix "${_harfbuzz_remove_string}") - -# Compute the installation prefix by stripping components from our current -# location. -get_filename_component(_harfbuzz_prefix "${CMAKE_CURRENT_LIST_DIR}" DIRECTORY) -get_filename_component(_harfbuzz_prefix "${_harfbuzz_prefix}" DIRECTORY) -set(_harfbuzz_libdir "@libdir@") -string(REPLACE "${_harfbuzz_remove_string}/" "" _harfbuzz_libdir "${_harfbuzz_libdir}") -set(_harfbuzz_libdir_iter "${_harfbuzz_libdir}") -while (_harfbuzz_libdir_iter) - set(_harfbuzz_libdir_prev_iter "${_harfbuzz_libdir_iter}") - get_filename_component(_harfbuzz_libdir_iter "${_harfbuzz_libdir_iter}" DIRECTORY) - if (_harfbuzz_libdir_prev_iter STREQUAL _harfbuzz_libdir_iter) - break() - endif () - get_filename_component(_harfbuzz_prefix "${_harfbuzz_prefix}" DIRECTORY) -endwhile () -unset(_harfbuzz_libdir_iter) - -# Get the include subdir. -set(_harfbuzz_includedir "@includedir@") -string(REPLACE "${_harfbuzz_remove_string}/" "" _harfbuzz_includedir "${_harfbuzz_includedir}") - -# Extract version information from libtool. -set(_harfbuzz_version_info "@HB_LIBTOOL_VERSION_INFO@") -string(REPLACE ":" ";" _harfbuzz_version_info "${_harfbuzz_version_info}") -list(GET _harfbuzz_version_info 0 - _harfbuzz_current) -list(GET _harfbuzz_version_info 1 - _harfbuzz_revision) -list(GET _harfbuzz_version_info 2 - _harfbuzz_age) -unset(_harfbuzz_version_info) - -if (APPLE) - set(_harfbuzz_lib_suffix ".0${CMAKE_SHARED_LIBRARY_SUFFIX}") -elseif (UNIX) - set(_harfbuzz_lib_suffix "${CMAKE_SHARED_LIBRARY_SUFFIX}.0.${_harfbuzz_current}.${_harfbuzz_revision}") -else () - # Unsupported. - set(harfbuzz_FOUND 0) -endif () - -# Add the libraries. -add_library(harfbuzz::harfbuzz SHARED IMPORTED) -set_target_properties(harfbuzz::harfbuzz PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_prefix}/${_harfbuzz_includedir}/harfbuzz" - IMPORTED_LOCATION "${_harfbuzz_prefix}/${_harfbuzz_libdir}/libharfbuzz${_harfbuzz_lib_suffix}") - -add_library(harfbuzz::icu SHARED IMPORTED) -set_target_properties(harfbuzz::icu PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_prefix}/${_harfbuzz_includedir}/harfbuzz" - INTERFACE_LINK_LIBRARIES "harfbuzz::harfbuzz" - IMPORTED_LOCATION "${_harfbuzz_prefix}/${_harfbuzz_libdir}/libharfbuzz-icu${_harfbuzz_lib_suffix}") - -add_library(harfbuzz::subset SHARED IMPORTED) -set_target_properties(harfbuzz::subset PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_prefix}/${_harfbuzz_includedir}/harfbuzz" - INTERFACE_LINK_LIBRARIES "harfbuzz::harfbuzz" - IMPORTED_LOCATION "${_harfbuzz_prefix}/${_harfbuzz_libdir}/libharfbuzz-subset${_harfbuzz_lib_suffix}") - -# Only add the gobject library if it was built. -set(_harfbuzz_have_gobject "@have_gobject@") -if (_harfbuzz_have_gobject) - add_library(harfbuzz::gobject SHARED IMPORTED) - set_target_properties(harfbuzz::gobject PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_prefix}/${_harfbuzz_includedir}/harfbuzz" - INTERFACE_LINK_LIBRARIES "harfbuzz::harfbuzz" - IMPORTED_LOCATION "${_harfbuzz_prefix}/${_harfbuzz_libdir}/libharfbuzz-gobject${_harfbuzz_lib_suffix}") -endif () - -# Clean out variables we used in our scope. -unset(_harfbuzz_lib_suffix) -unset(_harfbuzz_current) -unset(_harfbuzz_revision) -unset(_harfbuzz_age) -unset(_harfbuzz_includedir) -unset(_harfbuzz_libdir) -unset(_harfbuzz_prefix) -unset(exec_prefix) -unset(prefix) -unset(_harfbuzz_remove_string) diff --git a/src/3rdparty/harfbuzz-ng/src/harfbuzz-gobject.pc.in b/src/3rdparty/harfbuzz-ng/src/harfbuzz-gobject.pc.in deleted file mode 100644 index 7008360190..0000000000 --- a/src/3rdparty/harfbuzz-ng/src/harfbuzz-gobject.pc.in +++ /dev/null @@ -1,12 +0,0 @@ -prefix=%prefix% -exec_prefix=%exec_prefix% -libdir=%libdir% -includedir=%includedir% - -Name: harfbuzz -Description: HarfBuzz text shaping library GObject integration -Version: %VERSION% - -Requires: harfbuzz gobject-2.0 glib-2.0 -Libs: -L${libdir} -lharfbuzz-gobject -Cflags: -I${includedir}/harfbuzz diff --git a/src/3rdparty/harfbuzz-ng/src/harfbuzz-icu.pc.in b/src/3rdparty/harfbuzz-ng/src/harfbuzz-icu.pc.in deleted file mode 100644 index 949869a356..0000000000 --- a/src/3rdparty/harfbuzz-ng/src/harfbuzz-icu.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=%prefix% -exec_prefix=%exec_prefix% -libdir=%libdir% -includedir=%includedir% - -Name: harfbuzz -Description: HarfBuzz text shaping library ICU integration -Version: %VERSION% - -Requires: harfbuzz -Requires.private: icu-uc -Libs: -L${libdir} -lharfbuzz-icu -Cflags: -I${includedir}/harfbuzz diff --git a/src/3rdparty/harfbuzz-ng/src/harfbuzz-subset.pc.in b/src/3rdparty/harfbuzz-ng/src/harfbuzz-subset.pc.in deleted file mode 100644 index 5da64b3f12..0000000000 --- a/src/3rdparty/harfbuzz-ng/src/harfbuzz-subset.pc.in +++ /dev/null @@ -1,12 +0,0 @@ -prefix=%prefix% -exec_prefix=%exec_prefix% -libdir=%libdir% -includedir=%includedir% - -Name: harfbuzz -Description: HarfBuzz font subsetter -Version: %VERSION% - -Requires: harfbuzz -Libs: -L${libdir} -lharfbuzz-subset -Cflags: -I${includedir}/harfbuzz diff --git a/src/3rdparty/harfbuzz-ng/src/harfbuzz.cc b/src/3rdparty/harfbuzz-ng/src/harfbuzz.cc index 251a0654dc..fe00100974 100644 --- a/src/3rdparty/harfbuzz-ng/src/harfbuzz.cc +++ b/src/3rdparty/harfbuzz-ng/src/harfbuzz.cc @@ -4,6 +4,7 @@ #include "hb-buffer-serialize.cc" #include "hb-buffer.cc" #include "hb-common.cc" +#include "hb-draw.cc" #include "hb-face.cc" #include "hb-fallback-shape.cc" #include "hb-font.cc" @@ -28,8 +29,8 @@ #include "hb-ot-shape-complex-indic.cc" #include "hb-ot-shape-complex-khmer.cc" #include "hb-ot-shape-complex-myanmar.cc" +#include "hb-ot-shape-complex-syllabic.cc" #include "hb-ot-shape-complex-thai.cc" -#include "hb-ot-shape-complex-use-table.cc" #include "hb-ot-shape-complex-use.cc" #include "hb-ot-shape-complex-vowel-constraints.cc" #include "hb-ot-shape-fallback.cc" @@ -42,6 +43,7 @@ #include "hb-shape.cc" #include "hb-shaper.cc" #include "hb-static.cc" +#include "hb-style.cc" #include "hb-ucd.cc" #include "hb-unicode.cc" #include "hb-glib.cc" diff --git a/src/3rdparty/harfbuzz-ng/src/harfbuzz.pc.in b/src/3rdparty/harfbuzz-ng/src/harfbuzz.pc.in deleted file mode 100644 index 661251c2d4..0000000000 --- a/src/3rdparty/harfbuzz-ng/src/harfbuzz.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=%prefix% -exec_prefix=%exec_prefix% -libdir=%libdir% -includedir=%includedir% - -Name: harfbuzz -Description: HarfBuzz text shaping library -Version: %VERSION% - -Libs: -L${libdir} -lharfbuzz -Libs.private: -lm %libs_private% -Requires.private: %requires_private% -Cflags: -I${includedir}/harfbuzz diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-fdsc-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-fdsc-table.hh deleted file mode 100644 index 604d5bcf05..0000000000 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-fdsc-table.hh +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright © 2018 Ebrahim Byagowi - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - */ - -#ifndef HB_AAT_FDSC_TABLE_HH -#define HB_AAT_FDSC_TABLE_HH - -#include "hb-aat-layout-common.hh" -#include "hb-open-type.hh" - -/* - * fdsc -- Font descriptors - * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6fdsc.html - */ -#define HB_AAT_TAG_fdsc HB_TAG('f','d','s','c') - - -namespace AAT { - - -struct FontDescriptor -{ - bool has_data () const { return tag; } - - int cmp (hb_tag_t a) const { return tag.cmp (a); } - - float get_value () const { return u.value.to_float (); } - - enum non_alphabetic_value_t { - Alphabetic = 0, - Dingbats = 1, - PiCharacters = 2, - Fleurons = 3, - DecorativeBorders = 4, - InternationalSymbols= 5, - MathSymbols = 6 - }; - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); - } - - protected: - Tag tag; /* The 4-byte table tag name. */ - union { - HBFixed value; /* The value for the descriptor tag. */ - HBUINT32 nalfType; /* If the tag is `nalf`, see non_alphabetic_value_t */ - } u; - public: - DEFINE_SIZE_STATIC (8); -}; - -struct fdsc -{ - static constexpr hb_tag_t tableTag = HB_AAT_TAG_fdsc; - - enum { - Weight = HB_TAG ('w','g','h','t'), - /* Percent weight relative to regular weight. - * (defaul value: 1.0) */ - Width = HB_TAG ('w','d','t','h'), - /* Percent width relative to regular width. - * (default value: 1.0) */ - Slant = HB_TAG ('s','l','n','t'), - /* Angle of slant in degrees, where positive - * is clockwise from straight up. - * (default value: 0.0) */ - OpticalSize = HB_TAG ('o','p','s','z'), - /* Point size the font was designed for. - * (default value: 12.0) */ - NonAlphabetic= HB_TAG ('n','a','l','f') - /* These values are treated as integers, - * not fixed32s. 0 means alphabetic, and greater - * integers mean the font is non-alphabetic (e.g. symbols). - * (default value: 0) */ - }; - - const FontDescriptor &get_descriptor (hb_tag_t style) const - { return descriptors.lsearch (style); } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - descriptors.sanitize (c)); - } - - protected: - HBFixed version; /* Version number of the font descriptors - * table (0x00010000 for the current version). */ - LArrayOf<FontDescriptor> - descriptors; /* List of tagged-coordinate pairs style descriptors - * that will be included to characterize this font. - * Each descriptor consists of a <tag, value> pair. - * These pairs are located in the gxFontDescriptor - * array that follows. */ - public: - DEFINE_SIZE_ARRAY (8, descriptors); -}; - -} /* namespace AAT */ - - -#endif /* HB_AAT_FDSC_TABLE_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-ankr-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-ankr-table.hh index ef988841a9..f2785a6f58 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-ankr-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-ankr-table.hh @@ -66,7 +66,7 @@ struct ankr { const NNOffsetTo<GlyphAnchors> *offset = (this+lookupTable).get_value (glyph_id, num_glyphs); if (!offset) - return Null(Anchor); + return Null (Anchor); const GlyphAnchors &anchors = &(this+anchorData) + *offset; return anchors[i]; } @@ -81,7 +81,7 @@ struct ankr } protected: - HBUINT16 version; /* Version number (set to zero) */ + HBUINT16 version; /* Version number (set to zero) */ HBUINT16 flags; /* Flags (currently unused; set to zero) */ LOffsetTo<Lookup<NNOffsetTo<GlyphAnchors>>> lookupTable; /* Offset to the table's lookup table */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-bsln-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-bsln-table.hh index 15ef2da657..cd36fc8953 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-bsln-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-bsln-table.hh @@ -101,7 +101,7 @@ struct BaselineTableFormat3Part bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && lookupTable.sanitize (c)); + return_trace (likely (c->check_struct (this) && lookupTable.sanitize (c))); } protected: diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-common.hh index 473f2cdcd2..98ed20d8eb 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-common.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-common.hh @@ -303,7 +303,7 @@ struct LookupFormat10 const typename T::type get_value_or_null (hb_codepoint_t glyph_id) const { if (!(firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount)) - return Null(T); + return Null (T); const HBUINT8 *p = &valueArrayZ[(glyph_id - firstGlyph) * valueSize]; @@ -358,7 +358,7 @@ struct Lookup case 10: return u.format10.get_value_or_null (glyph_id); default: const T *v = get_value (glyph_id, num_glyphs); - return v ? *v : Null(T); + return v ? *v : Null (T); } } @@ -510,7 +510,7 @@ struct StateTable const Entry<Extra> &get_entry (int state, unsigned int klass) const { if (unlikely (klass >= nClasses)) - klass = StateTable<Types, Entry<Extra>>::CLASS_OUT_OF_BOUNDS; + klass = StateTable::CLASS_OUT_OF_BOUNDS; const HBUSHORT *states = (this+stateArrayTable).arrayZ; const Entry<Extra> *entries = (this+entryTable).arrayZ; @@ -576,7 +576,7 @@ struct StateTable if (unlikely (stop > states)) return_trace (false); for (const HBUSHORT *p = states; stop < p; p--) - num_entries = hb_max (num_entries, *(p - 1) + 1); + num_entries = hb_max (num_entries, *(p - 1) + 1u); state_neg = min_state; } } @@ -597,7 +597,7 @@ struct StateTable if (unlikely (stop < states)) return_trace (false); for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++) - num_entries = hb_max (num_entries, *p + 1); + num_entries = hb_max (num_entries, *p + 1u); state_pos = max_state + 1; } } @@ -729,7 +729,10 @@ struct ExtendedTypes template <typename Types, typename EntryData> struct StateTableDriver { - StateTableDriver (const StateTable<Types, EntryData> &machine_, + using StateTableT = StateTable<Types, EntryData>; + using EntryT = Entry<EntryData>; + + StateTableDriver (const StateTableT &machine_, hb_buffer_t *buffer_, hb_face_t *face_) : machine (machine_), @@ -742,59 +745,101 @@ struct StateTableDriver if (!c->in_place) buffer->clear_output (); - int state = StateTable<Types, EntryData>::STATE_START_OF_TEXT; + int state = StateTableT::STATE_START_OF_TEXT; for (buffer->idx = 0; buffer->successful;) { unsigned int klass = buffer->idx < buffer->len ? machine.get_class (buffer->info[buffer->idx].codepoint, num_glyphs) : - (unsigned) StateTable<Types, EntryData>::CLASS_END_OF_TEXT; + (unsigned) StateTableT::CLASS_END_OF_TEXT; DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx); - const Entry<EntryData> &entry = machine.get_entry (state, klass); + const EntryT &entry = machine.get_entry (state, klass); + const int next_state = machine.new_state (entry.newState); - /* Unsafe-to-break before this if not in state 0, as things might - * go differently if we start from state 0 here. + /* Conditions under which it's guaranteed safe-to-break before current glyph: * - * Ugh. The indexing here is ugly... */ - if (state && buffer->backtrack_len () && buffer->idx < buffer->len) - { - /* If there's no action and we're just epsilon-transitioning to state 0, - * safe to break. */ - if (c->is_actionable (this, entry) || - !(entry.newState == StateTable<Types, EntryData>::STATE_START_OF_TEXT && - entry.flags == context_t::DontAdvance)) - buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1); - } - - /* Unsafe-to-break if end-of-text would kick in here. */ - if (buffer->idx + 2 <= buffer->len) - { - const Entry<EntryData> &end_entry = machine.get_entry (state, StateTable<Types, EntryData>::CLASS_END_OF_TEXT); - if (c->is_actionable (this, end_entry)) - buffer->unsafe_to_break (buffer->idx, buffer->idx + 2); - } + * 1. There was no action in this transition; and + * + * 2. If we break before current glyph, the results will be the same. That + * is guaranteed if: + * + * 2a. We were already in start-of-text state; or + * + * 2b. We are epsilon-transitioning to start-of-text state; or + * + * 2c. Starting from start-of-text state seeing current glyph: + * + * 2c'. There won't be any actions; and + * + * 2c". We would end up in the same state that we were going to end up + * in now, including whether epsilon-transitioning. + * + * and + * + * 3. If we break before current glyph, there won't be any end-of-text action + * after previous glyph. + * + * This triples the transitions we need to look up, but is worth returning + * granular unsafe-to-break results. See eg.: + * + * https://github.com/harfbuzz/harfbuzz/issues/2860 + */ + const EntryT *wouldbe_entry; + bool safe_to_break = + /* 1. */ + !c->is_actionable (this, entry) + && + /* 2. */ + ( + /* 2a. */ + state == StateTableT::STATE_START_OF_TEXT + || + /* 2b. */ + ( + (entry.flags & context_t::DontAdvance) && + next_state == StateTableT::STATE_START_OF_TEXT + ) + || + /* 2c. */ + ( + wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass) + , + /* 2c'. */ + !c->is_actionable (this, *wouldbe_entry) + && + /* 2c". */ + ( + next_state == machine.new_state (wouldbe_entry->newState) + && + (entry.flags & context_t::DontAdvance) == (wouldbe_entry->flags & context_t::DontAdvance) + ) + ) + ) + && + /* 3. */ + !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT)) + ; + + if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len) + buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1); c->transition (this, entry); - state = machine.new_state (entry.newState); + state = next_state; DEBUG_MSG (APPLY, nullptr, "s%d", state); - if (buffer->idx == buffer->len) + if (buffer->idx == buffer->len || unlikely (!buffer->successful)) break; if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0) - buffer->next_glyph (); + (void) buffer->next_glyph (); } if (!c->in_place) - { - for (; buffer->successful && buffer->idx < buffer->len;) - buffer->next_glyph (); buffer->swap_buffers (); - } } public: - const StateTable<Types, EntryData> &machine; + const StateTableT &machine; hb_buffer_t *buffer; unsigned int num_glyphs; }; @@ -820,12 +865,11 @@ struct hb_aat_apply_context_t : /* Unused. For debug tracing only. */ unsigned int lookup_index; - unsigned int debug_depth; HB_INTERNAL hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_, hb_font_t *font_, hb_buffer_t *buffer_, - hb_blob_t *blob = const_cast<hb_blob_t *> (&Null(hb_blob_t))); + hb_blob_t *blob = const_cast<hb_blob_t *> (&Null (hb_blob_t))); HB_INTERNAL ~hb_aat_apply_context_t (); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-feat-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-feat-table.hh index 788d4084a1..359e859cfc 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-feat-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-feat-table.hh @@ -129,6 +129,11 @@ struct FeatureName hb_ot_name_id_t get_feature_name_id () const { return nameIndex; } + bool is_exclusive () const { return featureFlags & Exclusive; } + + /* A FeatureName with no settings is meaningless */ + bool has_data () const { return nSettings; } + bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -139,7 +144,7 @@ struct FeatureName protected: HBUINT16 feature; /* Feature type. */ HBUINT16 nSettings; /* The number of records in the setting name array. */ - LOffsetTo<UnsizedArrayOf<SettingName>, false> + LNNOffsetTo<UnsizedArrayOf<SettingName>> settingTableZ; /* Offset in bytes from the beginning of this table to * this feature's setting name array. The actual type of * record this offset refers to will depend on the @@ -172,6 +177,9 @@ struct feat return featureNameCount; } + bool exposes_feature (hb_aat_layout_feature_type_t feature_type) const + { return get_feature (feature_type).has_data (); } + const FeatureName& get_feature (hb_aat_layout_feature_type_t feature_type) const { return namesZ.bsearch (featureNameCount, feature_type); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-just-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-just-table.hh index e1787d10c6..49506e9f5a 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-just-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-just-table.hh @@ -51,10 +51,10 @@ struct ActionSubrecordHeader return_trace (likely (c->check_struct (this))); } - HBUINT16 actionClass; /* The JustClass value associated with this + HBUINT16 actionClass; /* The JustClass value associated with this * ActionSubrecord. */ - HBUINT16 actionType; /* The type of postcompensation action. */ - HBUINT16 actionLength; /* Length of this ActionSubrecord record, which + HBUINT16 actionType; /* The type of postcompensation action. */ + HBUINT16 actionLength; /* Length of this ActionSubrecord record, which * must be a multiple of 4. */ public: DEFINE_SIZE_STATIC (6); @@ -70,11 +70,11 @@ struct DecompositionAction ActionSubrecordHeader header; - HBFixed lowerLimit; /* If the distance factor is less than this value, + HBFixed lowerLimit; /* If the distance factor is less than this value, * then the ligature is decomposed. */ - HBFixed upperLimit; /* If the distance factor is greater than this value, + HBFixed upperLimit; /* If the distance factor is greater than this value, * then the ligature is decomposed. */ - HBUINT16 order; /* Numerical order in which this ligature will + HBUINT16 order; /* Numerical order in which this ligature will * be decomposed; you may want infrequent ligatures * to decompose before more frequent ones. The ligatures * on the line of text will decompose in increasing @@ -118,14 +118,14 @@ struct ConditionalAddGlyphAction protected: ActionSubrecordHeader header; - HBFixed substThreshold; /* Distance growth factor (in ems) at which + HBFixed substThreshold; /* Distance growth factor (in ems) at which * this glyph is replaced and the growth factor * recalculated. */ - HBGlyphID addGlyph; /* Glyph to be added as kashida. If this value is + HBGlyphID addGlyph; /* Glyph to be added as kashida. If this value is * 0xFFFF, no extra glyph will be added. Note that * generally when a glyph is added, justification * will need to be redone. */ - HBGlyphID substGlyph; /* Glyph to be substituted for this glyph if the + HBGlyphID substGlyph; /* Glyph to be substituted for this glyph if the * growth factor equals or exceeds the value of * substThreshold. */ public: @@ -143,16 +143,16 @@ struct DuctileGlyphAction protected: ActionSubrecordHeader header; - HBUINT32 variationAxis; /* The 4-byte tag identifying the ductile axis. + HBUINT32 variationAxis; /* The 4-byte tag identifying the ductile axis. * This would normally be 0x64756374 ('duct'), * but you may use any axis the font contains. */ - HBFixed minimumLimit; /* The lowest value for the ductility axis tha + HBFixed minimumLimit; /* The lowest value for the ductility axis tha * still yields an acceptable appearance. Normally * this will be 1.0. */ - HBFixed noStretchValue; /* This is the default value that corresponds to + HBFixed noStretchValue; /* This is the default value that corresponds to * no change in appearance. Normally, this will * be 1.0. */ - HBFixed maximumLimit; /* The highest value for the ductility axis that + HBFixed maximumLimit; /* The highest value for the ductility axis that * still yields an acceptable appearance. */ public: DEFINE_SIZE_STATIC (22); @@ -169,8 +169,8 @@ struct RepeatedAddGlyphAction protected: ActionSubrecordHeader header; - HBUINT16 flags; /* Currently unused; set to 0. */ - HBGlyphID glyph; /* Glyph that should be added if the distance factor + HBUINT16 flags; /* Currently unused; set to 0. */ + HBGlyphID glyph; /* Glyph that should be added if the distance factor * is growing. */ public: DEFINE_SIZE_STATIC (10); @@ -271,14 +271,14 @@ struct JustWidthDeltaEntry }; protected: - HBFixed beforeGrowLimit;/* The ratio by which the advance width of the + HBFixed beforeGrowLimit;/* The ratio by which the advance width of the * glyph is permitted to grow on the left or top side. */ - HBFixed beforeShrinkLimit; + HBFixed beforeShrinkLimit; /* The ratio by which the advance width of the * glyph is permitted to shrink on the left or top side. */ - HBFixed afterGrowLimit; /* The ratio by which the advance width of the glyph + HBFixed afterGrowLimit; /* The ratio by which the advance width of the glyph * is permitted to shrink on the left or top side. */ - HBFixed afterShrinkLimit; + HBFixed afterShrinkLimit; /* The ratio by which the advance width of the glyph * is at most permitted to shrink on the right or * bottom side. */ @@ -361,7 +361,7 @@ struct JustificationHeader OffsetTo<JustificationCategory> justClassTable; /* Offset to the justification category state table. */ OffsetTo<WidthDeltaCluster> - wdcTable; /* Offset from start of justification table to start + wdcTable; /* Offset from start of justification table to start * of the subtable containing the width delta factors * for the glyphs in your font. * @@ -372,7 +372,7 @@ struct JustificationHeader * * The postcompensation subtable, if present in the font. */ Lookup<OffsetTo<WidthDeltaCluster>> - lookupTable; /* Lookup table associating glyphs with width delta + lookupTable; /* Lookup table associating glyphs with width delta * clusters. See the description of Width Delta Clusters * table for details on how to interpret the lookup values. */ @@ -397,7 +397,7 @@ struct just protected: FixedVersion<>version; /* Version of the justification table * (0x00010000u for version 1.0). */ - HBUINT16 format; /* Format of the justification table (set to 0). */ + HBUINT16 format; /* Format of the justification table (set to 0). */ OffsetTo<JustificationHeader> horizData; /* Byte offset from the start of the justification table * to the header for tables that contain justification diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-kerx-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-kerx-table.hh index be1b339aa3..1cd412164e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-kerx-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-kerx-table.hh @@ -229,9 +229,7 @@ struct KerxSubTableFormat1 bool is_actionable (StateTableDriver<Types, EntryData> *driver HB_UNUSED, const Entry<EntryData> &entry) - { - return Format1EntryT::performAction (entry); - } + { return Format1EntryT::performAction (entry); } void transition (StateTableDriver<Types, EntryData> *driver, const Entry<EntryData> &entry) { @@ -281,35 +279,28 @@ struct KerxSubTableFormat1 hb_glyph_position_t &o = buffer->pos[idx]; - /* Testing shows that CoreText only applies kern (cross-stream or not) - * if none has been applied by previous subtables. That is, it does - * NOT seem to accumulate as otherwise implied by specs. */ - - /* The following flag is undocumented in the spec, but described - * in the 'kern' table example. */ - if (v == -0x8000) - { - o.attach_type() = ATTACH_TYPE_NONE; - o.attach_chain() = 0; - o.x_offset = o.y_offset = 0; - } - else if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) + if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) { if (crossStream) { - if (buffer->pos[idx].attach_type() && !buffer->pos[idx].y_offset) + /* The following flag is undocumented in the spec, but described + * in the 'kern' table example. */ + if (v == -0x8000) { - o.y_offset = c->font->em_scale_y (v); + o.attach_type() = ATTACH_TYPE_NONE; + o.attach_chain() = 0; + o.y_offset = 0; + } + else if (o.attach_type()) + { + o.y_offset += c->font->em_scale_y (v); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; } } else if (buffer->info[idx].mask & kern_mask) { - if (!buffer->pos[idx].x_offset) - { - buffer->pos[idx].x_advance += c->font->em_scale_x (v); - buffer->pos[idx].x_offset += c->font->em_scale_x (v); - } + o.x_advance += c->font->em_scale_x (v); + o.x_offset += c->font->em_scale_x (v); } } else @@ -317,19 +308,22 @@ struct KerxSubTableFormat1 if (crossStream) { /* CoreText doesn't do crossStream kerning in vertical. We do. */ - if (buffer->pos[idx].attach_type() && !buffer->pos[idx].x_offset) + if (v == -0x8000) { - o.x_offset = c->font->em_scale_x (v); + o.attach_type() = ATTACH_TYPE_NONE; + o.attach_chain() = 0; + o.x_offset = 0; + } + else if (o.attach_type()) + { + o.x_offset += c->font->em_scale_x (v); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; } } else if (buffer->info[idx].mask & kern_mask) { - if (!buffer->pos[idx].y_offset) - { - buffer->pos[idx].y_advance += c->font->em_scale_y (v); - buffer->pos[idx].y_offset += c->font->em_scale_y (v); - } + o.y_advance += c->font->em_scale_y (v); + o.y_offset += c->font->em_scale_y (v); } } } @@ -488,7 +482,7 @@ struct KerxSubTableFormat4 }; driver_context_t (const KerxSubTableFormat4 *table, - hb_aat_apply_context_t *c_) : + hb_aat_apply_context_t *c_) : c (c_), action_type ((table->flags & ActionType) >> 30), ankrData ((HBUINT16 *) ((const char *) &table->machine + (table->flags & Offset))), @@ -497,9 +491,7 @@ struct KerxSubTableFormat4 bool is_actionable (StateTableDriver<Types, EntryData> *driver HB_UNUSED, const Entry<EntryData> &entry) - { - return entry.data.ankrActionIndex != 0xFFFF; - } + { return entry.data.ankrActionIndex != 0xFFFF; } void transition (StateTableDriver<Types, EntryData> *driver, const Entry<EntryData> &entry) { @@ -512,11 +504,13 @@ struct KerxSubTableFormat4 { case 0: /* Control Point Actions.*/ { - /* indexed into glyph outline. */ - const HBUINT16 *data = &ankrData[entry.data.ankrActionIndex]; + /* Indexed into glyph outline. */ + /* Each action (record in ankrData) contains two 16-bit fields, so we must + double the ankrActionIndex to get the correct offset here. */ + const HBUINT16 *data = &ankrData[entry.data.ankrActionIndex * 2]; if (!c->sanitizer.check_array (data, 2)) return; - HB_UNUSED unsigned int markControlPoint = *data++; - HB_UNUSED unsigned int currControlPoint = *data++; + unsigned int markControlPoint = *data++; + unsigned int currControlPoint = *data++; hb_position_t markX = 0; hb_position_t markY = 0; hb_position_t currX = 0; @@ -538,8 +532,10 @@ struct KerxSubTableFormat4 case 1: /* Anchor Point Actions. */ { - /* Indexed into 'ankr' table. */ - const HBUINT16 *data = &ankrData[entry.data.ankrActionIndex]; + /* Indexed into 'ankr' table. */ + /* Each action (record in ankrData) contains two 16-bit fields, so we must + double the ankrActionIndex to get the correct offset here. */ + const HBUINT16 *data = &ankrData[entry.data.ankrActionIndex * 2]; if (!c->sanitizer.check_array (data, 2)) return; unsigned int markAnchorPoint = *data++; unsigned int currAnchorPoint = *data++; @@ -557,7 +553,9 @@ struct KerxSubTableFormat4 case 2: /* Control Point Coordinate Actions. */ { - const FWORD *data = (const FWORD *) &ankrData[entry.data.ankrActionIndex]; + /* Each action contains four 16-bit fields, so we multiply the ankrActionIndex + by 4 to get the correct offset for the given action. */ + const FWORD *data = (const FWORD *) &ankrData[entry.data.ankrActionIndex * 4]; if (!c->sanitizer.check_array (data, 4)) return; int markX = *data++; int markY = *data++; @@ -628,7 +626,7 @@ struct KerxSubTableFormat6 bool is_long () const { return flags & ValuesAreLong; } int get_kerning (hb_codepoint_t left, hb_codepoint_t right, - hb_aat_apply_context_t *c) const + hb_aat_apply_context_t *c) const { unsigned int num_glyphs = c->sanitizer.get_num_glyphs (); if (is_long ()) @@ -891,7 +889,7 @@ struct KerxTable reverse = bool (st->u.header.coverage & st->u.header.Backwards) != HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction); - if (!c->buffer->message (c->font, "start %c%c%c%c subtable %d", HB_UNTAG (thiz()->tableTag), c->lookup_index)) + if (!c->buffer->message (c->font, "start subtable %d", c->lookup_index)) goto skip; if (!seenCrossStream && @@ -923,7 +921,7 @@ struct KerxTable if (reverse) c->buffer->reverse (); - (void) c->buffer->message (c->font, "end %c%c%c%c subtable %d", HB_UNTAG (thiz()->tableTag), c->lookup_index); + (void) c->buffer->message (c->font, "end subtable %d", c->lookup_index); skip: st = &StructAfter<SubTable> (*st); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-lcar-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-lcar-table.hh deleted file mode 100644 index 7063b386c2..0000000000 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-lcar-table.hh +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright © 2018 Ebrahim Byagowi - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - */ -#ifndef HB_AAT_LAYOUT_LCAR_TABLE_HH -#define HB_AAT_LAYOUT_LCAR_TABLE_HH - -#include "hb-open-type.hh" -#include "hb-aat-layout-common.hh" - -/* - * lcar -- Ligature caret - * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6lcar.html - */ -#define HB_AAT_TAG_lcar HB_TAG('l','c','a','r') - - -namespace AAT { - -typedef ArrayOf<HBINT16> LigCaretClassEntry; - -struct lcarFormat0 -{ - unsigned int get_lig_carets (hb_font_t *font, - hb_direction_t direction, - hb_codepoint_t glyph, - unsigned int start_offset, - unsigned int *caret_count /* IN/OUT */, - hb_position_t *caret_array /* OUT */, - const void *base) const - { - const OffsetTo<LigCaretClassEntry>* entry_offset = lookupTable.get_value (glyph, - font->face->get_num_glyphs ()); - const LigCaretClassEntry& array = entry_offset ? base+*entry_offset : Null (LigCaretClassEntry); - if (caret_count) - { - hb_array_t<const HBINT16> arr = array.sub_array (start_offset, caret_count); - for (unsigned int i = 0; i < arr.length; ++i) - caret_array[i] = font->em_scale_dir (arr[i], direction); - } - return array.len; - } - - bool sanitize (hb_sanitize_context_t *c, const void *base) const - { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && lookupTable.sanitize (c, base))); - } - - protected: - Lookup<OffsetTo<LigCaretClassEntry>> - lookupTable; /* data Lookup table associating glyphs */ - public: - DEFINE_SIZE_MIN (2); -}; - -struct lcarFormat1 -{ - unsigned int get_lig_carets (hb_font_t *font, - hb_direction_t direction, - hb_codepoint_t glyph, - unsigned int start_offset, - unsigned int *caret_count /* IN/OUT */, - hb_position_t *caret_array /* OUT */, - const void *base) const - { - const OffsetTo<LigCaretClassEntry>* entry_offset = lookupTable.get_value (glyph, - font->face->get_num_glyphs ()); - const LigCaretClassEntry& array = entry_offset ? base+*entry_offset : Null (LigCaretClassEntry); - if (caret_count) - { - hb_array_t<const HBINT16> arr = array.sub_array (start_offset, caret_count); - for (unsigned int i = 0; i < arr.length; ++i) - { - hb_position_t x = 0, y = 0; - font->get_glyph_contour_point_for_origin (glyph, arr[i], direction, &x, &y); - caret_array[i] = HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y; - } - } - return array.len; - } - - bool sanitize (hb_sanitize_context_t *c, const void *base) const - { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && lookupTable.sanitize (c, base))); - } - - protected: - Lookup<OffsetTo<LigCaretClassEntry>> - lookupTable; /* data Lookup table associating glyphs */ - public: - DEFINE_SIZE_MIN (2); -}; - -struct lcar -{ - static constexpr hb_tag_t tableTag = HB_AAT_TAG_lcar; - - unsigned int get_lig_carets (hb_font_t *font, - hb_direction_t direction, - hb_codepoint_t glyph, - unsigned int start_offset, - unsigned int *caret_count /* IN/OUT */, - hb_position_t *caret_array /* OUT */) const - { - switch (format) - { - case 0: return u.format0.get_lig_carets (font, direction, glyph, start_offset, - caret_count, caret_array, this); - case 1: return u.format1.get_lig_carets (font, direction, glyph, start_offset, - caret_count, caret_array, this); - default:if (caret_count) *caret_count = 0; return 0; - } - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (this) || version.major != 1)) - return_trace (false); - - switch (format) { - case 0: return_trace (u.format0.sanitize (c, this)); - case 1: return_trace (u.format1.sanitize (c, this)); - default:return_trace (true); - } - } - - protected: - FixedVersion<>version; /* Version number of the ligature caret table */ - HBUINT16 format; /* Format of the ligature caret table. */ - union { - lcarFormat0 format0; - lcarFormat0 format1; - } u; - public: - DEFINE_SIZE_MIN (8); -}; - -} /* namespace AAT */ - -#endif /* HB_AAT_LAYOUT_LCAR_TABLE_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-morx-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-morx-table.hh index d8df579f50..e3bc268d26 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-morx-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-morx-table.hh @@ -337,9 +337,9 @@ struct ContextualSubtable const EntryData &data = entries[i].data; if (data.markIndex != 0xFFFF) - num_lookups = hb_max (num_lookups, 1 + data.markIndex); + num_lookups = hb_max (num_lookups, 1u + data.markIndex); if (data.currentIndex != 0xFFFF) - num_lookups = hb_max (num_lookups, 1 + data.currentIndex); + num_lookups = hb_max (num_lookups, 1u + data.currentIndex); } return_trace (substitutionTables.sanitize (c, this, num_lookups)); @@ -499,7 +499,7 @@ struct LigatureSubtable } DEBUG_MSG (APPLY, nullptr, "Moving to stack position %u", cursor - 1); - buffer->move_to (match_positions[--cursor % ARRAY_LENGTH (match_positions)]); + if (unlikely (!buffer->move_to (match_positions[--cursor % ARRAY_LENGTH (match_positions)]))) return; if (unlikely (!actionData->sanitize (&c->sanitizer))) break; action = *actionData; @@ -525,25 +525,25 @@ struct LigatureSubtable hb_codepoint_t lig = ligatureData; DEBUG_MSG (APPLY, nullptr, "Produced ligature %u", lig); - buffer->replace_glyph (lig); + if (unlikely (!buffer->replace_glyph (lig))) return; unsigned int lig_end = match_positions[(match_length - 1u) % ARRAY_LENGTH (match_positions)] + 1u; /* Now go and delete all subsequent components. */ while (match_length - 1u > cursor) { DEBUG_MSG (APPLY, nullptr, "Skipping ligature component"); - buffer->move_to (match_positions[--match_length % ARRAY_LENGTH (match_positions)]); - buffer->replace_glyph (DELETED_GLYPH); + if (unlikely (!buffer->move_to (match_positions[--match_length % ARRAY_LENGTH (match_positions)]))) return; + if (unlikely (!buffer->replace_glyph (DELETED_GLYPH))) return; } - buffer->move_to (lig_end); + if (unlikely (!buffer->move_to (lig_end))) return; buffer->merge_out_clusters (match_positions[cursor % ARRAY_LENGTH (match_positions)], buffer->out_len); } actionData++; } while (!(action & LigActionLast)); - buffer->move_to (end); + if (unlikely (!buffer->move_to (end))) return; } } @@ -725,6 +725,7 @@ struct InsertionSubtable if (entry.data.markedInsertIndex != 0xFFFF) { unsigned int count = (flags & MarkedInsertCount); + if (unlikely ((buffer->max_ops -= count) <= 0)) return; unsigned int start = entry.data.markedInsertIndex; const HBGlyphID *glyphs = &insertionAction[start]; if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0; @@ -732,17 +733,16 @@ struct InsertionSubtable bool before = flags & MarkedInsertBefore; unsigned int end = buffer->out_len; - buffer->move_to (mark); + if (unlikely (!buffer->move_to (mark))) return; if (buffer->idx < buffer->len && !before) - buffer->copy_glyph (); + if (unlikely (!buffer->copy_glyph ())) return; /* TODO We ignore KashidaLike setting. */ - for (unsigned int i = 0; i < count; i++) - buffer->output_glyph (glyphs[i]); + if (unlikely (!buffer->replace_glyphs (0, count, glyphs))) return; if (buffer->idx < buffer->len && !before) buffer->skip_glyph (); - buffer->move_to (end + count); + if (unlikely (!buffer->move_to (end + count))) return; buffer->unsafe_to_break_from_outbuffer (mark, hb_min (buffer->idx + 1, buffer->len)); } @@ -753,6 +753,7 @@ struct InsertionSubtable if (entry.data.currentInsertIndex != 0xFFFF) { unsigned int count = (flags & CurrentInsertCount) >> 5; + if (unlikely ((buffer->max_ops -= count) <= 0)) return; unsigned int start = entry.data.currentInsertIndex; const HBGlyphID *glyphs = &insertionAction[start]; if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0; @@ -762,10 +763,9 @@ struct InsertionSubtable unsigned int end = buffer->out_len; if (buffer->idx < buffer->len && !before) - buffer->copy_glyph (); + if (unlikely (!buffer->copy_glyph ())) return; /* TODO We ignore KashidaLike setting. */ - for (unsigned int i = 0; i < count; i++) - buffer->output_glyph (glyphs[i]); + if (unlikely (!buffer->replace_glyphs (0, count, glyphs))) return; if (buffer->idx < buffer->len && !before) buffer->skip_glyph (); @@ -784,7 +784,7 @@ struct InsertionSubtable * * https://github.com/harfbuzz/harfbuzz/issues/1224#issuecomment-427691417 */ - buffer->move_to ((flags & DontAdvance) ? end : end + count); + if (unlikely (!buffer->move_to ((flags & DontAdvance) ? end : end + count))) return; } } @@ -948,8 +948,10 @@ struct Chain hb_aat_layout_feature_type_t type = (hb_aat_layout_feature_type_t) (unsigned int) feature.featureType; hb_aat_layout_feature_selector_t setting = (hb_aat_layout_feature_selector_t) (unsigned int) feature.featureSetting; retry: - const hb_aat_map_builder_t::feature_info_t *info = map->features.bsearch (type); - if (info && info->setting == setting) + // Check whether this type/setting pair was requested in the map, and if so, apply its flags. + // (The search here only looks at the type and setting fields of feature_info_t.) + hb_aat_map_builder_t::feature_info_t info = { type, setting, false, 0 }; + if (map->features.bsearch (info)) { flags &= feature.disableFlags; flags |= feature.enableFlags; @@ -967,7 +969,7 @@ struct Chain } void apply (hb_aat_apply_context_t *c, - hb_mask_t flags) const + hb_mask_t flags) const { const ChainSubtable<Types> *subtable = &StructAfter<ChainSubtable<Types>> (featureZ.as_array (featureCount)); unsigned int count = subtableCount; @@ -1015,7 +1017,7 @@ struct Chain bool (subtable->get_coverage () & ChainSubtable<Types>::Backwards) != HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction); - if (!c->buffer->message (c->font, "start chain subtable %d", c->lookup_index)) + if (!c->buffer->message (c->font, "start chainsubtable %d", c->lookup_index)) goto skip; if (reverse) @@ -1026,7 +1028,7 @@ struct Chain if (reverse) c->buffer->reverse (); - (void) c->buffer->message (c->font, "end chain subtable %d", c->lookup_index); + (void) c->buffer->message (c->font, "end chainsubtable %d", c->lookup_index); if (unlikely (!c->buffer->successful)) return; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-opbd-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-opbd-table.hh index 4e0234074f..8c04a6482f 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-opbd-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-opbd-table.hh @@ -160,8 +160,8 @@ struct opbd * Format 0 indicates distance and Format 1 indicates * control point. */ union { - opbdFormat0 format0; - opbdFormat1 format1; + opbdFormat0 format0; + opbdFormat1 format1; } u; public: DEFINE_SIZE_MIN (8); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-trak-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-trak-table.hh index 99dddd8826..baa1c72020 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-trak-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-trak-table.hh @@ -62,7 +62,7 @@ struct TrackTableEntry } protected: - HBFixed track; /* Track value for this record. */ + HBFixed track; /* Track value for this record. */ NameID trackNameID; /* The 'name' table index for this track. * (a short word or phrase like "loose" * or "very tight") */ @@ -141,7 +141,7 @@ struct TrackData protected: HBUINT16 nTracks; /* Number of separate tracks included in this table. */ HBUINT16 nSizes; /* Number of point sizes included in this table. */ - LOffsetTo<UnsizedArrayOf<HBFixed>, false> + LNNOffsetTo<UnsizedArrayOf<HBFixed>> sizeTable; /* Offset from start of the tracking table to * Array[nSizes] of size values.. */ UnsizedArrayOf<TrackTableEntry> @@ -210,8 +210,8 @@ struct trak protected: FixedVersion<>version; /* Version of the tracking table - * (0x00010000u for version 1.0). */ - HBUINT16 format; /* Format of the tracking table (set to 0). */ + * (0x00010000u for version 1.0). */ + HBUINT16 format; /* Format of the tracking table (set to 0). */ OffsetTo<TrackData> horizData; /* Offset from start of tracking table to TrackData * for horizontal text (or 0 if none). */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.cc b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.cc index 4e506de16e..0e9f2b4954 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.cc @@ -28,7 +28,6 @@ #include "hb.hh" #include "hb-aat-layout.hh" -#include "hb-aat-fdsc-table.hh" // Just so we compile it; unused otherwise. #include "hb-aat-layout-ankr-table.hh" #include "hb-aat-layout-bsln-table.hh" // Just so we compile it; unused otherwise. #include "hb-aat-layout-feat-table.hh" @@ -55,9 +54,8 @@ AAT::hb_aat_apply_context_t::hb_aat_apply_context_t (const hb_ot_shape_plan_t *p face (font->face), buffer (buffer_), sanitizer (), - ankr_table (&Null(AAT::ankr)), - lookup_index (0), - debug_depth (0) + ankr_table (&Null (AAT::ankr)), + lookup_index (0) { sanitizer.init (blob); sanitizer.set_num_glyphs (face->get_num_glyphs ()); @@ -81,13 +79,18 @@ AAT::hb_aat_apply_context_t::set_ankr_table (const AAT::ankr *ankr_table_) * @short_description: Apple Advanced Typography Layout * @include: hb-aat.h * - * Functions for querying OpenType Layout features in the font face. + * Functions for querying AAT Layout features in the font face. + * + * HarfBuzz supports all of the AAT tables used to implement shaping. Other + * AAT tables and their associated features are not supported. **/ #if !defined(HB_NO_AAT) || defined(HAVE_CORETEXT) -/* Table data courtesy of Apple. Converted from mnemonics to integers +/* Mapping from OpenType feature tags to AAT feature names and selectors. + * + * Table data courtesy of Apple. Converted from mnemonics to integers * when moving to this file. */ static const hb_aat_feature_mapping_t feature_mappings[] = { @@ -169,14 +172,21 @@ static const hb_aat_feature_mapping_t feature_mappings[] = {HB_TAG ('z','e','r','o'), HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_OFF}, }; +/** + * hb_aat_layout_find_feature_mapping: + * @tag: The requested #hb_tag_t feature tag + * + * Fetches the AAT feature-and-selector combination that corresponds + * to a given OpenType feature tag. + * + * Return value: the AAT features and selectors corresponding to the + * OpenType feature tag queried + * + **/ const hb_aat_feature_mapping_t * hb_aat_layout_find_feature_mapping (hb_tag_t tag) { - return (const hb_aat_feature_mapping_t *) hb_bsearch (&tag, - feature_mappings, - ARRAY_LENGTH (feature_mappings), - sizeof (feature_mappings[0]), - hb_aat_feature_mapping_t::cmp); + return hb_sorted_array (feature_mappings).bsearch (tag); } #endif @@ -208,11 +218,17 @@ hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper, } -/* +/** * hb_aat_layout_has_substitution: - * @face: + * @face: #hb_face_t to work upon + * + * Tests whether the specified face includes any substitutions in the + * `morx` or `mort` tables. + * + * <note>Note: does not examine the `GSUB` table.</note> + * + * Return value: %true if data found, %false otherwise * - * Returns: * Since: 2.3.0 */ hb_bool_t @@ -269,11 +285,17 @@ hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer) hb_ot_layout_delete_glyphs_inplace (buffer, is_deleted_glyph); } -/* +/** * hb_aat_layout_has_positioning: - * @face: + * @face: #hb_face_t to work upon + * + * Tests whether the specified face includes any positioning information + * in the `kerx` table. + * + * <note>Note: does not examine the `GPOS` table.</note> + * + * Return value: %true if data found, %false otherwise * - * Returns: * Since: 2.3.0 */ hb_bool_t @@ -296,11 +318,15 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan, } -/* +/** * hb_aat_layout_has_tracking: - * @face: + * @face:: #hb_face_t to work upon + * + * Tests whether the specified face includes any tracking information + * in the `trak` table. + * + * Return value: %true if data found, %false otherwise * - * Returns: * Since: 2.3.0 */ hb_bool_t @@ -322,10 +348,13 @@ hb_aat_layout_track (const hb_ot_shape_plan_t *plan, /** * hb_aat_layout_get_feature_types: - * @face: a face object - * @start_offset: iteration's start offset - * @feature_count:(inout) (allow-none): buffer size as input, filled size as output - * @features: (out caller-allocates) (array length=feature_count): features buffer + * @face: #hb_face_t to work upon + * @start_offset: offset of the first feature type to retrieve + * @feature_count: (inout) (optional): Input = the maximum number of feature types to return; + * Output = the actual number of feature types returned (may be zero) + * @features: (out caller-allocates) (array length=feature_count): Array of feature types found + * + * Fetches a list of the AAT feature types included in the specified face. * * Return value: Number of all available feature types. * @@ -342,10 +371,12 @@ hb_aat_layout_get_feature_types (hb_face_t *face, /** * hb_aat_layout_feature_type_get_name_id: - * @face: a face object - * @feature_type: feature id + * @face: #hb_face_t to work upon + * @feature_type: The #hb_aat_layout_feature_type_t of the requested feature type * - * Return value: Name ID index + * Fetches the name identifier of the specified feature type in the face's `name` table. + * + * Return value: Name identifier of the requested feature type * * Since: 2.2.0 */ @@ -357,19 +388,23 @@ hb_aat_layout_feature_type_get_name_id (hb_face_t *face, } /** - * hb_aat_layout_feature_type_get_selectors: - * @face: a face object - * @feature_type: feature id - * @start_offset: iteration's start offset - * @selector_count: (inout) (allow-none): buffer size as input, filled size as output - * @selectors: (out caller-allocates) (array length=selector_count): settings buffer - * @default_index: (out) (allow-none): index of default selector if any + * hb_aat_layout_feature_type_get_selector_infos: + * @face: #hb_face_t to work upon + * @feature_type: The #hb_aat_layout_feature_type_t of the requested feature type + * @start_offset: offset of the first feature type to retrieve + * @selector_count: (inout) (optional): Input = the maximum number of selectors to return; + * Output = the actual number of selectors returned (may be zero) + * @selectors: (out caller-allocates) (array length=selector_count) (optional): + * A buffer pointer. The selectors available for the feature type queries. + * @default_index: (out) (optional): The index of the feature's default selector, if any + * + * Fetches a list of the selectors available for the specified feature in the given face. * * If upon return, @default_index is set to #HB_AAT_LAYOUT_NO_SELECTOR_INDEX, then * the feature type is non-exclusive. Otherwise, @default_index is the index of * the selector that is selected by default. * - * Return value: Number of all available feature selectors. + * Return value: Number of all available feature selectors * * Since: 2.2.0 */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.h b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.h index b617e8b703..9af2740088 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.h @@ -22,7 +22,7 @@ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ -#ifndef HB_AAT_H_IN +#if !defined(HB_AAT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb-aat.h> instead." #endif @@ -37,7 +37,48 @@ HB_BEGIN_DECLS /** * hb_aat_layout_feature_type_t: + * @HB_AAT_LAYOUT_FEATURE_TYPE_INVALID: Initial, unset feature type + * @HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC: [All Typographic Features](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type0) + * @HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES: [Ligatures](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type1) + * @HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION: [Cursive Connection](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type2) + * @HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE: [Letter Case](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type3) + * @HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION: [Vertical Substitution](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type4) + * @HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT: [Linguistic Rearrangement](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type5) + * @HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING: [Number Spacing](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type6) + * @HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE: [Smart Swash](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type8) + * @HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE: [Diacritics](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type9) + * @HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION: [Vertical Position](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type10) + * @HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS: [Fractions](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type11) + * @HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE: [Overlapping Characters](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type13) + * @HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS: [Typographic Extras](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type14) + * @HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS: [Mathematical Extras](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type15) + * @HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE: [Ornament Sets](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type16) + * @HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES: [Character Alternatives](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type17) + * @HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE: [Design Complexity](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type18) + * @HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS: [Style Options](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type19) + * @HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE: [Character Shape](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type20) + * @HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE: [Number Case](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type21) + * @HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING: [Text Spacing](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type22) + * @HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION: [Transliteration](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type23) + * @HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE: [Annotation](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type24) + * @HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE: [Kana Spacing](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type25) + * @HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE: [Ideographic Spacing](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type26) + * @HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE: [Unicode Decomposition](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type27) + * @HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA: [Ruby Kana](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type28) + * @HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE: [CJK Symbol Alternatives](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type29) + * @HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE: [Ideographic Alternatives](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type30) + * @HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE: [CJK Vertical Roman Placement](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type31) + * @HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN: [Italic CJK Roman](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type32) + * @HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT: [Case Sensitive Layout](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type33) + * @HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA: [Alternate Kana](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type34) + * @HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES: [Stylistic Alternatives](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type35) + * @HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES: [Contextual Alternatives](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type36) + * @HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE: [Lower Case](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type37) + * @HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE: [Upper Case](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type38) + * @HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE: [Language Tag](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type39) + * @HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE: [CJK Roman Spacing](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type103) * + * The possible feature types defined for AAT shaping, from Apple [Font Feature Registry](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html). * * Since: 2.2.0 */ @@ -85,12 +126,265 @@ typedef enum HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE = 39, HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE = 103, + /*< private >*/ _HB_AAT_LAYOUT_FEATURE_TYPE_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/ } hb_aat_layout_feature_type_t; /** * hb_aat_layout_feature_selector_t: + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INVALID: Initial, unset feature selector + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_TYPE_FEATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_TYPE_FEATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_REQUIRED_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_REQUIRED_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LOGOS_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LOGOS_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_REBUS_PICTURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_REBUS_PICTURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DIPHTHONG_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DIPHTHONG_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SQUARED_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SQUARED_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ABBREV_SQUARED_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ABBREV_SQUARED_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SYMBOL_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SYMBOL_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_UNCONNECTED: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PARTIALLY_CONNECTED: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CURSIVE: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_AND_LOWER_CASE: Deprecated + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_CAPS: Deprecated + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_LOWER_CASE: Deprecated + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SMALL_CAPS: Deprecated + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INITIAL_CAPS: Deprecated + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INITIAL_CAPS_AND_SMALL_CAPS: Deprecated + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LINGUISTIC_REARRANGEMENT_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LINGUISTIC_REARRANGEMENT_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_NUMBERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_NUMBERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_THIRD_WIDTH_NUMBERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_QUARTER_WIDTH_NUMBERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_INITIAL_SWASHES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_INITIAL_SWASHES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_FINAL_SWASHES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_FINAL_SWASHES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_INITIAL_SWASHES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_INITIAL_SWASHES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_FINAL_SWASHES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_FINAL_SWASHES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NON_FINAL_SWASHES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NON_FINAL_SWASHES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SHOW_DIACRITICS: for #HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HIDE_DIACRITICS: for #HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DECOMPOSE_DIACRITICS: for #HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SUPERIORS: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INFERIORS: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ORDINALS: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SCIENTIFIC_INFERIORS: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_FRACTIONS: for #HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_VERTICAL_FRACTIONS: for #HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DIAGONAL_FRACTIONS: for #HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PREVENT_OVERLAP_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PREVENT_OVERLAP_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHENS_TO_EM_DASH_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHENS_TO_EM_DASH_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_EN_DASH_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_EN_DASH_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_FORM_INTERROBANG_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_FORM_INTERROBANG_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SMART_QUOTES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SMART_QUOTES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIODS_TO_ELLIPSIS_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIODS_TO_ELLIPSIS_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_MINUS_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_MINUS_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ASTERISK_TO_MULTIPLY_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ASTERISK_TO_MULTIPLY_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASH_TO_DIVIDE_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASH_TO_DIVIDE_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INEQUALITY_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INEQUALITY_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPONENTS_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPONENTS_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ORNAMENTS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DINGBATS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PI_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_FLEURONS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DECORATIVE_BORDERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INTERNATIONAL_SYMBOLS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_MATH_SYMBOLS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ALTERNATES: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL1: for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL2: for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL3: for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL4: for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL5: for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_STYLE_OPTIONS: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DISPLAY_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ENGRAVED_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ILLUMINATED_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TITLING_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TALL_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SIMPLIFIED_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1978_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1983_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1990_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_ONE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_TWO: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_THREE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_FOUR: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_FIVE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPERT_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS2004_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HOJO_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NLCCHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_NAMES_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_NUMBERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_NUMBERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_THIRD_WIDTH_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_QUARTER_WIDTH_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_HALF_WIDTH_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_TRANSLITERATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HIRAGANA_TO_KATAKANA: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_KATAKANA_TO_HIRAGANA: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_KANA_TO_ROMANIZATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMANIZATION_TO_HIRAGANA: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMANIZATION_TO_KATAKANA: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_ONE: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_TWO: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_THREE: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_BOX_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ROUNDED_BOX_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CIRCLE_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_CIRCLE_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PARENTHESIS_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIOD_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMAN_NUMERAL_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DIAMOND_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_BOX_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_ROUNDED_BOX_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_KANA: for #HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_KANA: for #HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_IDEOGRAPHS: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_IDEOGRAPHS: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_IDEOGRAPHS: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CANONICAL_COMPOSITION_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CANONICAL_COMPOSITION_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_COMPATIBILITY_COMPOSITION_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_COMPATIBILITY_COMPOSITION_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRANSCODING_COMPOSITION_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRANSCODING_COMPOSITION_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_RUBY_KANA: Deprecated; use #HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_OFF instead + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA: Deprecated; use #HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_ON instead + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_CJK_SYMBOL_ALTERNATIVES: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_ONE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_TWO: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_THREE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_FOUR: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_FIVE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_IDEOGRAPHIC_ALTERNATIVES: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_ONE: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_TWO: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_THREE: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_FOUR: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_FIVE: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_VERTICAL_ROMAN_CENTERED: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_VERTICAL_ROMAN_HBASELINE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_CJK_ITALIC_ROMAN: Deprecated; use #HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_OFF instead + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN: Deprecated; use #HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_ON instead + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_STYLISTIC_ALTERNATES: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_LOWER_CASE: for #HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_PETITE_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_UPPER_CASE: for #HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_SMALL_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_PETITE_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_CJK_ROMAN: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_CJK_ROMAN: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_CJK_ROMAN: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE + * @HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_CJK_ROMAN: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE * + * The selectors defined for specifying AAT feature settings. * * Since: 2.2.0 */ @@ -424,6 +718,7 @@ typedef enum HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_CJK_ROMAN = 2, HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_CJK_ROMAN = 3, + /*< private >*/ _HB_AAT_LAYOUT_FEATURE_SELECTOR_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/ } hb_aat_layout_feature_selector_t; @@ -437,8 +732,15 @@ HB_EXTERN hb_ot_name_id_t hb_aat_layout_feature_type_get_name_id (hb_face_t *face, hb_aat_layout_feature_type_t feature_type); -typedef struct hb_aat_layout_feature_selector_info_t -{ +/** + * hb_aat_layout_feature_selector_info_t: + * @name_id: The selector's name identifier + * @enable: The value to turn the selector on + * @disable: The value to turn the selector off + * + * Structure representing a setting for an #hb_aat_layout_feature_type_t. + */ +typedef struct hb_aat_layout_feature_selector_info_t { hb_ot_name_id_t name_id; hb_aat_layout_feature_selector_t enable; hb_aat_layout_feature_selector_t disable; @@ -446,6 +748,13 @@ typedef struct hb_aat_layout_feature_selector_info_t unsigned int reserved; } hb_aat_layout_feature_selector_info_t; +/** + * HB_AAT_LAYOUT_NO_SELECTOR_INDEX + * + * Used when getting or setting AAT feature selectors. Indicates that + * there is no selector index corresponding to the selector of interest. + * + */ #define HB_AAT_LAYOUT_NO_SELECTOR_INDEX 0xFFFFu HB_EXTERN unsigned int diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.hh index 8310bfcc2d..5e4e3bda15 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.hh @@ -39,14 +39,8 @@ struct hb_aat_feature_mapping_t hb_aat_layout_feature_selector_t selectorToEnable; hb_aat_layout_feature_selector_t selectorToDisable; - HB_INTERNAL static int cmp (const void *key_, const void *entry_) - { - hb_tag_t key = * (unsigned int *) key_; - const hb_aat_feature_mapping_t * entry = (const hb_aat_feature_mapping_t *) entry_; - return key < entry->otFeatureTag ? -1 : - key > entry->otFeatureTag ? 1 : - 0; - } + int cmp (hb_tag_t key) const + { return key < otFeatureTag ? -1 : key > otFeatureTag ? 1 : 0; } }; HB_INTERNAL const hb_aat_feature_mapping_t * diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-map.cc b/src/3rdparty/harfbuzz-ng/src/hb-aat-map.cc index bc879359aa..2c38c35029 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-map.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-map.cc @@ -33,25 +33,48 @@ #include "hb-aat-map.hh" #include "hb-aat-layout.hh" +#include "hb-aat-layout-feat-table.hh" -void hb_aat_map_builder_t::add_feature (hb_tag_t tag, - unsigned int value) +void hb_aat_map_builder_t::add_feature (hb_tag_t tag, unsigned value) { + if (!face->table.feat->has_data ()) return; + if (tag == HB_TAG ('a','a','l','t')) { + if (!face->table.feat->exposes_feature (HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES)) + return; feature_info_t *info = features.push(); info->type = HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES; info->setting = (hb_aat_layout_feature_selector_t) value; + info->seq = features.length; + info->is_exclusive = true; return; } const hb_aat_feature_mapping_t *mapping = hb_aat_layout_find_feature_mapping (tag); if (!mapping) return; + const AAT::FeatureName* feature = &face->table.feat->get_feature (mapping->aatFeatureType); + if (!feature->has_data ()) + { + /* Special case: Chain::compile_flags will fall back to the deprecated version of + * small-caps if necessary, so we need to check for that possibility. + * https://github.com/harfbuzz/harfbuzz/issues/2307 */ + if (mapping->aatFeatureType == HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE && + mapping->selectorToEnable == HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS) + { + feature = &face->table.feat->get_feature (HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE); + if (!feature->has_data ()) return; + } + else return; + } + feature_info_t *info = features.push(); info->type = mapping->aatFeatureType; info->setting = value ? mapping->selectorToEnable : mapping->selectorToDisable; + info->seq = features.length; + info->is_exclusive = feature->is_exclusive (); } void @@ -63,7 +86,11 @@ hb_aat_map_builder_t::compile (hb_aat_map_t &m) features.qsort (); unsigned int j = 0; for (unsigned int i = 1; i < features.length; i++) - if (features[i].type != features[j].type) + if (features[i].type != features[j].type || + /* Nonexclusive feature selectors come in even/odd pairs to turn a setting on/off + * respectively, so we mask out the low-order bit when checking for "duplicates" + * (selectors referring to the same feature setting) here. */ + (!features[i].is_exclusive && ((features[i].setting & ~1) != (features[j].setting & ~1)))) features[++j] = features[i]; features.shrink (j + 1); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-map.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-map.hh index 984a59cca5..5a0fa70544 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-map.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-map.hh @@ -64,19 +64,24 @@ struct hb_aat_map_builder_t { hb_aat_layout_feature_type_t type; hb_aat_layout_feature_selector_t setting; + bool is_exclusive; unsigned seq; /* For stable sorting only. */ HB_INTERNAL static int cmp (const void *pa, const void *pb) { const feature_info_t *a = (const feature_info_t *) pa; const feature_info_t *b = (const feature_info_t *) pb; - return (a->type != b->type) ? (a->type < b->type ? -1 : 1) : - (a->seq < b->seq ? -1 : a->seq > b->seq ? 1 : 0); + if (a->type != b->type) return (a->type < b->type ? -1 : 1); + if (!a->is_exclusive && + (a->setting & ~1) != (b->setting & ~1)) return (a->setting < b->setting ? -1 : 1); + return (a->seq < b->seq ? -1 : a->seq > b->seq ? 1 : 0); } - int cmp (hb_aat_layout_feature_type_t ty) const + /* compares type & setting only, not is_exclusive flag or seq number */ + int cmp (const feature_info_t& f) const { - return (type != ty) ? (type < ty ? -1 : 1) : 0; + return (f.type != type) ? (f.type < type ? -1 : 1) : + (f.setting != setting) ? (f.setting < setting ? -1 : 1) : 0; } }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-algs.hh b/src/3rdparty/harfbuzz-ng/src/hb-algs.hh index 042e1c20d5..bc170b0546 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-algs.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-algs.hh @@ -35,6 +35,132 @@ #include "hb-number.hh" +/* + * Flags + */ + +/* Enable bitwise ops on enums marked as flags_t */ +/* To my surprise, looks like the function resolver is happy to silently cast + * one enum to another... So this doesn't provide the type-checking that I + * originally had in mind... :(. + * + * For MSVC warnings, see: https://github.com/harfbuzz/harfbuzz/pull/163 + */ +#ifdef _MSC_VER +# pragma warning(disable:4200) +# pragma warning(disable:4800) +#endif +#define HB_MARK_AS_FLAG_T(T) \ + extern "C++" { \ + static inline constexpr T operator | (T l, T r) { return T ((unsigned) l | (unsigned) r); } \ + static inline constexpr T operator & (T l, T r) { return T ((unsigned) l & (unsigned) r); } \ + static inline constexpr T operator ^ (T l, T r) { return T ((unsigned) l ^ (unsigned) r); } \ + static inline constexpr T operator ~ (T r) { return T (~(unsigned int) r); } \ + static inline T& operator |= (T &l, T r) { l = l | r; return l; } \ + static inline T& operator &= (T& l, T r) { l = l & r; return l; } \ + static inline T& operator ^= (T& l, T r) { l = l ^ r; return l; } \ + } \ + static_assert (true, "") + +/* Useful for set-operations on small enums. + * For example, for testing "x ∈ {x1, x2, x3}" use: + * (FLAG_UNSAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3))) + */ +#define FLAG(x) (static_assert_expr ((unsigned)(x) < 32) + (((uint32_t) 1U) << (unsigned)(x))) +#define FLAG_UNSAFE(x) ((unsigned)(x) < 32 ? (((uint32_t) 1U) << (unsigned)(x)) : 0) +#define FLAG_RANGE(x,y) (static_assert_expr ((x) < (y)) + FLAG(y+1) - FLAG(x)) +#define FLAG64(x) (static_assert_expr ((unsigned)(x) < 64) + (((uint64_t) 1ULL) << (unsigned)(x))) +#define FLAG64_UNSAFE(x) ((unsigned)(x) < 64 ? (((uint64_t) 1ULL) << (unsigned)(x)) : 0) + + +/* + * Big-endian integers. + */ + +/* Endian swap, used in Windows related backends */ +static inline constexpr uint16_t hb_uint16_swap (uint16_t v) +{ return (v >> 8) | (v << 8); } +static inline constexpr uint32_t hb_uint32_swap (uint32_t v) +{ return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); } + +template <typename Type, int Bytes = sizeof (Type)> +struct BEInt; +template <typename Type> +struct BEInt<Type, 1> +{ + public: + BEInt () = default; + constexpr BEInt (Type V) : v {uint8_t (V)} {} + constexpr operator Type () const { return v; } + private: uint8_t v; +}; +template <typename Type> +struct BEInt<Type, 2> +{ + public: + BEInt () = default; + constexpr BEInt (Type V) : v {uint8_t ((V >> 8) & 0xFF), + uint8_t ((V ) & 0xFF)} {} + + struct __attribute__((packed)) packed_uint16_t { uint16_t v; }; + constexpr operator Type () const + { +#if ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \ + defined(__BYTE_ORDER) && \ + (__BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __BIG_ENDIAN) + /* Spoon-feed the compiler a big-endian integer with alignment 1. + * https://github.com/harfbuzz/harfbuzz/pull/1398 */ +#if __BYTE_ORDER == __LITTLE_ENDIAN + return __builtin_bswap16 (((packed_uint16_t *) this)->v); +#else /* __BYTE_ORDER == __BIG_ENDIAN */ + return ((packed_uint16_t *) this)->v; +#endif +#else + return (v[0] << 8) + + (v[1] ); +#endif + } + private: uint8_t v[2]; +}; +template <typename Type> +struct BEInt<Type, 3> +{ + static_assert (!hb_is_signed (Type), ""); + public: + BEInt () = default; + constexpr BEInt (Type V) : v {uint8_t ((V >> 16) & 0xFF), + uint8_t ((V >> 8) & 0xFF), + uint8_t ((V ) & 0xFF)} {} + + constexpr operator Type () const { return (v[0] << 16) + + (v[1] << 8) + + (v[2] ); } + private: uint8_t v[3]; +}; +template <typename Type> +struct BEInt<Type, 4> +{ + public: + BEInt () = default; + constexpr BEInt (Type V) : v {uint8_t ((V >> 24) & 0xFF), + uint8_t ((V >> 16) & 0xFF), + uint8_t ((V >> 8) & 0xFF), + uint8_t ((V ) & 0xFF)} {} + constexpr operator Type () const { return (v[0] << 24) + + (v[1] << 16) + + (v[2] << 8) + + (v[3] ); } + private: uint8_t v[4]; +}; + +/* Floats. */ + +/* We want our rounding towards +infinity. */ +static inline float +_hb_roundf (float x) { return floorf (x + .5f); } +#define roundf(x) _hb_roundf(x) + + /* Encodes three unsigned integers in one 64-bit number. If the inputs have more than 21 bits, * values will be truncated / overlap, and might not decode exactly. */ #define HB_CODEPOINT_ENCODE3(x,y,z) (((uint64_t) (x) << 42) | ((uint64_t) (y) << 21) | (uint64_t) (z)) @@ -48,6 +174,7 @@ #define HB_CODEPOINT_DECODE3_11_7_14_2(v) ((hb_codepoint_t) (((v) >> 14) & 0x007Fu) | 0x0300) #define HB_CODEPOINT_DECODE3_11_7_14_3(v) ((hb_codepoint_t) (v) & 0x3FFFu) + struct { /* Note. This is dangerous in that if it's passed an rvalue, it returns rvalue-reference. */ @@ -215,7 +342,9 @@ struct template <typename Pred, typename Val> auto impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN - (hb_deref (hb_forward<Pred> (p)).has (hb_forward<Val> (v))) + ( + hb_deref (hb_forward<Pred> (p)).has (hb_forward<Val> (v)) + ) template <typename Pred, typename Val> auto impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN @@ -269,7 +398,9 @@ struct template <typename Proj, typename Val> auto impl (Proj&& f, Val &&v, hb_priority<2>) const HB_AUTO_RETURN - (hb_deref (hb_forward<Proj> (f)).get (hb_forward<Val> (v))) + ( + hb_deref (hb_forward<Proj> (f)).get (hb_forward<Val> (v)) + ) template <typename Proj, typename Val> auto impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN @@ -296,6 +427,40 @@ struct } HB_FUNCOBJ (hb_get); +struct +{ + private: + + template <typename T1, typename T2> auto + impl (T1&& v1, T2 &&v2, hb_priority<2>) const HB_AUTO_RETURN + ( + hb_forward<T2> (v2).cmp (hb_forward<T1> (v1)) == 0 + ) + + template <typename T1, typename T2> auto + impl (T1&& v1, T2 &&v2, hb_priority<1>) const HB_AUTO_RETURN + ( + hb_forward<T1> (v1).cmp (hb_forward<T2> (v2)) == 0 + ) + + template <typename T1, typename T2> auto + impl (T1&& v1, T2 &&v2, hb_priority<0>) const HB_AUTO_RETURN + ( + hb_forward<T1> (v1) == hb_forward<T2> (v2) + ) + + public: + + template <typename T1, typename T2> auto + operator () (T1&& v1, T2 &&v2) const HB_AUTO_RETURN + ( + impl (hb_forward<T1> (v1), + hb_forward<T2> (v2), + hb_prioritize) + ) +} +HB_FUNCOBJ (hb_equal); + template <typename T1, typename T2> struct hb_pair_t @@ -350,16 +515,23 @@ struct { template <typename T, typename T2> constexpr auto operator () (T&& a, T2&& b) const HB_AUTO_RETURN - (hb_forward<T> (a) <= hb_forward<T2> (b) ? hb_forward<T> (a) : hb_forward<T2> (b)) + (a <= b ? hb_forward<T> (a) : hb_forward<T2> (b)) } HB_FUNCOBJ (hb_min); struct { template <typename T, typename T2> constexpr auto operator () (T&& a, T2&& b) const HB_AUTO_RETURN - (hb_forward<T> (a) >= hb_forward<T2> (b) ? hb_forward<T> (a) : hb_forward<T2> (b)) + (a >= b ? hb_forward<T> (a) : hb_forward<T2> (b)) } HB_FUNCOBJ (hb_max); +struct +{ + template <typename T, typename T2, typename T3> constexpr auto + operator () (T&& x, T2&& min, T3&& max) const HB_AUTO_RETURN + (hb_min (hb_max (hb_forward<T> (x), hb_forward<T2> (min)), hb_forward<T3> (max))) +} +HB_FUNCOBJ (hb_clamp); /* @@ -368,7 +540,7 @@ HB_FUNCOBJ (hb_max); /* Return the number of 1 bits in v. */ template <typename T> -static inline HB_CONST_FUNC unsigned int +static inline unsigned int hb_popcount (T v) { #if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) @@ -409,7 +581,7 @@ hb_popcount (T v) /* Returns the number of bits needed to store number */ template <typename T> -static inline HB_CONST_FUNC unsigned int +static inline unsigned int hb_bit_storage (T v) { if (unlikely (!v)) return 0; @@ -483,10 +655,10 @@ hb_bit_storage (T v) /* Returns the number of zero bits in the least significant side of v */ template <typename T> -static inline HB_CONST_FUNC unsigned int +static inline unsigned int hb_ctz (T v) { - if (unlikely (!v)) return 0; + if (unlikely (!v)) return 8 * sizeof (T); #if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) if (sizeof (T) <= sizeof (unsigned int)) @@ -570,6 +742,12 @@ static inline unsigned char TOUPPER (unsigned char c) { return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; } static inline unsigned char TOLOWER (unsigned char c) { return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; } +static inline bool ISHEX (unsigned char c) +{ return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); } +static inline unsigned char TOHEX (uint8_t c) +{ return (c & 0xF) <= 9 ? (c & 0xF) + '0' : (c & 0xF) + 'a' - 10; } +static inline uint8_t FROMHEX (unsigned char c) +{ return (c >= '0' && c <= '9') ? c - '0' : TOLOWER (c) - 'a' + 10; } static inline unsigned int DIV_CEIL (const unsigned int a, unsigned int b) { return (a + (b - 1)) / b; } @@ -600,12 +778,6 @@ hb_memset (void *s, int c, unsigned int n) return memset (s, c, n); } -static inline bool -hb_unsigned_mul_overflows (unsigned int count, unsigned int size) -{ - return (size > 0) && (count >= ((unsigned int) -1) / size); -} - static inline unsigned int hb_ceil_to_4 (unsigned int v) { @@ -634,29 +806,90 @@ hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3) /* + * Overflow checking. + */ + +/* Consider __builtin_mul_overflow use here also */ +static inline bool +hb_unsigned_mul_overflows (unsigned int count, unsigned int size) +{ + return (size > 0) && (count >= ((unsigned int) -1) / size); +} + + +/* * Sort and search. */ -template <typename ...Ts> -static inline void * -hb_bsearch (const void *key, const void *base, - size_t nmemb, size_t size, - int (*compar)(const void *_key, const void *_item, Ts... _ds), - Ts... ds) + +template <typename K, typename V, typename ...Ts> +static int +_hb_cmp_method (const void *pkey, const void *pval, Ts... ds) +{ + const K& key = * (const K*) pkey; + const V& val = * (const V*) pval; + + return val.cmp (key, ds...); +} + +template <typename V, typename K, typename ...Ts> +static inline bool +hb_bsearch_impl (unsigned *pos, /* Out */ + const K& key, + V* base, size_t nmemb, size_t stride, + int (*compar)(const void *_key, const void *_item, Ts... _ds), + Ts... ds) { + /* This is our *only* bsearch implementation. */ + int min = 0, max = (int) nmemb - 1; while (min <= max) { int mid = ((unsigned int) min + (unsigned int) max) / 2; - const void *p = (const void *) (((const char *) base) + (mid * size)); - int c = compar (key, p, ds...); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-align" + V* p = (V*) (((const char *) base) + (mid * stride)); +#pragma GCC diagnostic pop + int c = compar ((const void *) hb_addressof (key), (const void *) p, ds...); if (c < 0) max = mid - 1; else if (c > 0) min = mid + 1; else - return (void *) p; + { + *pos = mid; + return true; + } } - return nullptr; + *pos = min; + return false; +} + +template <typename V, typename K> +static inline V* +hb_bsearch (const K& key, V* base, + size_t nmemb, size_t stride = sizeof (V), + int (*compar)(const void *_key, const void *_item) = _hb_cmp_method<K, V>) +{ + unsigned pos; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-align" + return hb_bsearch_impl (&pos, key, base, nmemb, stride, compar) ? + (V*) (((const char *) base) + (pos * stride)) : nullptr; +#pragma GCC diagnostic pop +} +template <typename V, typename K, typename ...Ts> +static inline V* +hb_bsearch (const K& key, V* base, + size_t nmemb, size_t stride, + int (*compar)(const void *_key, const void *_item, Ts... _ds), + Ts... ds) +{ + unsigned pos; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-align" + return hb_bsearch_impl (&pos, key, base, nmemb, stride, compar, ds...) ? + (V*) (((const char *) base) + (pos * stride)) : nullptr; +#pragma GCC diagnostic pop } @@ -920,32 +1153,24 @@ hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *o struct hb_bitwise_and { HB_PARTIALIZE(2); - static constexpr bool passthru_left = false; - static constexpr bool passthru_right = false; template <typename T> constexpr auto operator () (const T &a, const T &b) const HB_AUTO_RETURN (a & b) } HB_FUNCOBJ (hb_bitwise_and); struct hb_bitwise_or { HB_PARTIALIZE(2); - static constexpr bool passthru_left = true; - static constexpr bool passthru_right = true; template <typename T> constexpr auto operator () (const T &a, const T &b) const HB_AUTO_RETURN (a | b) } HB_FUNCOBJ (hb_bitwise_or); struct hb_bitwise_xor { HB_PARTIALIZE(2); - static constexpr bool passthru_left = true; - static constexpr bool passthru_right = true; template <typename T> constexpr auto operator () (const T &a, const T &b) const HB_AUTO_RETURN (a ^ b) } HB_FUNCOBJ (hb_bitwise_xor); struct hb_bitwise_sub { HB_PARTIALIZE(2); - static constexpr bool passthru_left = true; - static constexpr bool passthru_right = false; template <typename T> constexpr auto operator () (const T &a, const T &b) const HB_AUTO_RETURN (a & ~b) } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-array.hh b/src/3rdparty/harfbuzz-ng/src/hb-array.hh index d9adf2c728..02bd8d81c2 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-array.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-array.hh @@ -129,20 +129,27 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&> template <typename T> Type *lsearch (const T &x, Type *not_found = nullptr) { - unsigned int count = length; - for (unsigned int i = 0; i < count; i++) - if (!this->arrayZ[i].cmp (x)) - return &this->arrayZ[i]; - return not_found; + unsigned i; + return lfind (x, &i) ? &this->arrayZ[i] : not_found; } template <typename T> const Type *lsearch (const T &x, const Type *not_found = nullptr) const { - unsigned int count = length; - for (unsigned int i = 0; i < count; i++) - if (!this->arrayZ[i].cmp (x)) - return &this->arrayZ[i]; - return not_found; + unsigned i; + return lfind (x, &i) ? &this->arrayZ[i] : not_found; + } + template <typename T> + bool lfind (const T &x, unsigned *pos = nullptr) const + { + for (unsigned i = 0; i < length; ++i) + if (hb_equal (x, this->arrayZ[i])) + { + if (pos) + *pos = i; + return true; + } + + return false; } hb_sorted_array_t<Type> qsort (int (*cmp_)(const void*, const void*)) @@ -171,6 +178,24 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&> unsigned int get_size () const { return length * this->get_item_size (); } + /* + * Reverse the order of items in this array in the range [start, end). + */ + void reverse (unsigned start = 0, unsigned end = -1) + { + start = hb_min (start, length); + end = hb_min (end, length); + + if (end < start + 2) + return; + + for (unsigned lhs = start, rhs = end - 1; lhs < rhs; lhs++, rhs--) { + Type temp = arrayZ[rhs]; + arrayZ[rhs] = arrayZ[lhs]; + arrayZ[lhs] = temp; + } + } + hb_array_t sub_array (unsigned int start_offset = 0, unsigned int *seg_count = nullptr /* IN/OUT */) const { if (!start_offset && !seg_count) @@ -199,10 +224,11 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&> template <typename T, unsigned P = sizeof (Type), hb_enable_if (P == 1)> - bool in_range (const T *p, unsigned int size = T::static_size) const + bool check_range (const T *p, unsigned int size = T::static_size) const { - return ((const char *) p) >= arrayZ - && ((const char *) p + size) <= arrayZ + length; + return arrayZ <= ((const char *) p) + && ((const char *) p) <= arrayZ + length + && (unsigned int) (arrayZ + length - (const char *) p) >= size; } /* Only call if you allocated the underlying array using malloc() or similar. */ @@ -300,23 +326,15 @@ struct hb_sorted_array_t : hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE, unsigned int to_store = (unsigned int) -1) const { - int min = 0, max = (int) this->length - 1; - const Type *array = this->arrayZ; - while (min <= max) + unsigned pos; + + if (bsearch_impl (x, &pos)) { - int mid = ((unsigned int) min + (unsigned int) max) / 2; - int c = array[mid].cmp (x); - if (c < 0) - max = mid - 1; - else if (c > 0) - min = mid + 1; - else - { - if (i) - *i = mid; - return true; - } + if (i) + *i = pos; + return true; } + if (i) { switch (not_found) @@ -329,14 +347,22 @@ struct hb_sorted_array_t : break; case HB_BFIND_NOT_FOUND_STORE_CLOSEST: - if (max < 0 || (max < (int) this->length && array[max].cmp (x) > 0)) - max++; - *i = max; + *i = pos; break; } } return false; } + template <typename T> + bool bsearch_impl (const T &x, unsigned *pos) const + { + return hb_bsearch_impl (pos, + x, + this->arrayZ, + this->length, + sizeof (Type), + _hb_cmp_method<T, Type>); + } }; template <typename T> inline hb_sorted_array_t<T> hb_sorted_array (T *array, unsigned int length) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-atomic.hh b/src/3rdparty/harfbuzz-ng/src/hb-atomic.hh index b3fb296b4e..93265f655f 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-atomic.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-atomic.hh @@ -52,7 +52,7 @@ #elif !defined(HB_NO_MT) && defined(__ATOMIC_ACQUIRE) -/* C++11-style GCC primitives. */ +/* C++11-style GCC primitives. We prefer these as they don't require linking to libstdc++ / libc++. */ #define _hb_memory_barrier() __sync_synchronize () @@ -73,7 +73,8 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) } #define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N)) -#elif !defined(HB_NO_MT) && __cplusplus >= 201103L + +#elif !defined(HB_NO_MT) /* C++11 atomics. */ @@ -101,117 +102,6 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) #define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N)) -#elif !defined(HB_NO_MT) && defined(_WIN32) - -#include <windows.h> - -static inline void _hb_memory_barrier () -{ -#if !defined(MemoryBarrier) && !defined(__MINGW32_VERSION) - /* MinGW has a convoluted history of supporting MemoryBarrier. */ - LONG dummy = 0; - InterlockedExchange (&dummy, 1); -#else - MemoryBarrier (); -#endif -} -#define _hb_memory_barrier() _hb_memory_barrier () - -#define hb_atomic_int_impl_add(AI, V) InterlockedExchangeAdd ((LONG *) (AI), (V)) -static_assert ((sizeof (LONG) == sizeof (int)), ""); - -#define hb_atomic_ptr_impl_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((P), (N), (O)) == (O)) - - -#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES) - -#define _hb_memory_barrier() __sync_synchronize () - -#define hb_atomic_int_impl_add(AI, V) __sync_fetch_and_add ((AI), (V)) - -#define hb_atomic_ptr_impl_cmpexch(P,O,N) __sync_bool_compare_and_swap ((P), (O), (N)) - - -#elif !defined(HB_NO_MT) && defined(HAVE_SOLARIS_ATOMIC_OPS) - -#include <atomic.h> -#include <mbarrier.h> - -#define _hb_memory_r_barrier() __machine_r_barrier () -#define _hb_memory_w_barrier() __machine_w_barrier () -#define _hb_memory_barrier() __machine_rw_barrier () - -static inline int _hb_fetch_and_add (int *AI, int V) -{ - _hb_memory_w_barrier (); - int result = atomic_add_int_nv ((uint_t *) AI, V) - V; - _hb_memory_r_barrier (); - return result; -} -static inline bool _hb_compare_and_swap_ptr (void **P, void *O, void *N) -{ - _hb_memory_w_barrier (); - bool result = atomic_cas_ptr (P, O, N) == O; - _hb_memory_r_barrier (); - return result; -} - -#define hb_atomic_int_impl_add(AI, V) _hb_fetch_and_add ((AI), (V)) - -#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_compare_and_swap_ptr ((P), (O), (N)) - - -#elif !defined(HB_NO_MT) && defined(__APPLE__) - -#include <libkern/OSAtomic.h> -#ifdef __MAC_OS_X_MIN_REQUIRED -#include <AvailabilityMacros.h> -#elif defined(__IPHONE_OS_MIN_REQUIRED) -#include <Availability.h> -#endif - -#define _hb_memory_barrier() OSMemoryBarrier () - -#define hb_atomic_int_impl_add(AI, V) (OSAtomicAdd32Barrier ((V), (AI)) - (V)) - -#if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100) -#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((O), (N), (P)) -#else -#if __ppc64__ || __x86_64__ || __aarch64__ -#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P)) -#else -#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P)) -#endif -#endif - - -#elif !defined(HB_NO_MT) && defined(_AIX) && (defined(__IBMCPP__) || defined(__ibmxl__)) - -#include <builtins.h> - -#define _hb_memory_barrier() __lwsync () - -static inline int _hb_fetch_and_add (int *AI, int V) -{ - _hb_memory_barrier (); - int result = __fetch_and_add (AI, V); - _hb_memory_barrier (); - return result; -} -static inline bool _hb_compare_and_swaplp (long *P, long O, long N) -{ - _hb_memory_barrier (); - bool result = __compare_and_swaplp (P, &O, N); - _hb_memory_barrier (); - return result; -} - -#define hb_atomic_int_impl_add(AI, V) _hb_fetch_and_add ((AI), (V)) - -#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_compare_and_swaplp ((long *) (P), (long) (O), (long) (N)) -static_assert ((sizeof (long) == sizeof (void *)), ""); - - #elif defined(HB_NO_MT) #define hb_atomic_int_impl_add(AI, V) ((*(AI) += (V)) - (V)) @@ -259,9 +149,11 @@ inline void *hb_atomic_ptr_impl_get (void ** const P) { void *v = *P; _hb_memory #endif -#define HB_ATOMIC_INT_INIT(V) {V} struct hb_atomic_int_t { + hb_atomic_int_t () = default; + constexpr hb_atomic_int_t (int v) : v (v) {} + void set_relaxed (int v_) { hb_atomic_int_impl_set_relaxed (&v, v_); } void set (int v_) { hb_atomic_int_impl_set (&v, v_); } int get_relaxed () const { return hb_atomic_int_impl_get_relaxed (&v); } @@ -269,16 +161,17 @@ struct hb_atomic_int_t int inc () { return hb_atomic_int_impl_add (&v, 1); } int dec () { return hb_atomic_int_impl_add (&v, -1); } - int v; + int v = 0; }; - -#define HB_ATOMIC_PTR_INIT(V) {V} template <typename P> struct hb_atomic_ptr_t { typedef hb_remove_pointer<P> T; + hb_atomic_ptr_t () = default; + constexpr hb_atomic_ptr_t (T* v) : v (v) {} + void init (T* v_ = nullptr) { set_relaxed (v_); } void set_relaxed (T* v_) { hb_atomic_ptr_impl_set_relaxed (&v, v_); } T *get_relaxed () const { return (T *) hb_atomic_ptr_impl_get_relaxed (&v); } @@ -288,7 +181,7 @@ struct hb_atomic_ptr_t T * operator -> () const { return get (); } template <typename C> operator C * () const { return get (); } - T *v; + T *v = nullptr; }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-bimap.hh b/src/3rdparty/harfbuzz-ng/src/hb-bimap.hh index cae0a4dea4..e9f3a6a52d 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-bimap.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-bimap.hh @@ -151,9 +151,9 @@ struct hb_inc_bimap_t : hb_bimap_t for (hb_codepoint_t rhs = 0; rhs < count; rhs++) work[rhs] = back_map[rhs]; - + work.qsort (cmp_id); - + clear (); for (hb_codepoint_t rhs = 0; rhs < count; rhs++) set (work[rhs], rhs); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-blob.cc b/src/3rdparty/harfbuzz-ng/src/hb-blob.cc index 2e72683c8b..71b1b1fc4f 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-blob.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-blob.cc @@ -25,18 +25,6 @@ * Red Hat Author(s): Behdad Esfahbod */ - -/* https://github.com/harfbuzz/harfbuzz/issues/1308 - * http://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html - * https://www.oracle.com/technetwork/articles/servers-storage-dev/standardheaderfiles-453865.html - */ -#if !defined(_POSIX_C_SOURCE) && !defined(_MSC_VER) && !defined(__NetBSD__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-macros" -#define _POSIX_C_SOURCE 200809L -#pragma GCC diagnostic pop -#endif - #include "hb.hh" #include "hb-blob.hh" @@ -47,9 +35,6 @@ #include <sys/mman.h> #endif /* HAVE_SYS_MMAN_H */ -#include <stdio.h> -#include <stdlib.h> - /** * SECTION: hb-blob @@ -70,7 +55,7 @@ * @length: Length of @data in bytes. * @mode: Memory mode for @data. * @user_data: Data parameter to pass to @destroy. - * @destroy: Callback to call when @data is not needed anymore. + * @destroy: (nullable): Callback to call when @data is not needed anymore. * * Creates a new "blob" object wrapping @data. The @mode parameter is used * to negotiate ownership and lifecycle of @data. @@ -128,7 +113,7 @@ _hb_blob_destroy (void *data) * @length: Length of sub-blob. * * Returns a blob that represents a range of bytes in @parent. The new - * blob is always created with %HB_MEMORY_MODE_READONLY, meaning that it + * blob is always created with #HB_MEMORY_MODE_READONLY, meaning that it * will never modify data in the parent blob. The parent data is not * expected to be modified, and will result in undefined behavior if it * is. @@ -168,7 +153,7 @@ hb_blob_create_sub_blob (hb_blob_t *parent, * * Makes a writable copy of @blob. * - * Return value: New blob, or nullptr if allocation failed. + * Return value: The new blob, or nullptr if allocation failed * * Since: 1.8.0 **/ @@ -194,14 +179,14 @@ hb_blob_copy_writable_or_fail (hb_blob_t *blob) * * See TODO:link object types for more information. * - * Return value: (transfer full): the empty blob. + * Return value: (transfer full): The empty blob. * * Since: 0.9.2 **/ hb_blob_t * hb_blob_get_empty () { - return const_cast<hb_blob_t *> (&Null(hb_blob_t)); + return const_cast<hb_blob_t *> (&Null (hb_blob_t)); } /** @@ -246,13 +231,15 @@ hb_blob_destroy (hb_blob_t *blob) /** * hb_blob_set_user_data: (skip) - * @blob: a blob. - * @key: key for data to set. - * @data: data to set. - * @destroy: callback to call when @data is not needed anymore. - * @replace: whether to replace an existing data with the same key. + * @blob: An #hb_blob_t + * @key: The user-data key to set + * @data: A pointer to the user data to set + * @destroy: (nullable): A callback to call when @data is not needed anymore + * @replace: Whether to replace an existing data with the same key * - * Return value: + * Attaches a user-data key/data pair to the specified blob. + * + * Return value: %true if success, %false otherwise * * Since: 0.9.2 **/ @@ -268,12 +255,13 @@ hb_blob_set_user_data (hb_blob_t *blob, /** * hb_blob_get_user_data: (skip) - * @blob: a blob. - * @key: key for data to get. - * + * @blob: a blob + * @key: The user-data key to query * + * Fetches the user data associated with the specified key, + * attached to the specified font-functions structure. * - * Return value: (transfer none): + * Return value: (transfer none): A pointer to the user data * * Since: 0.9.2 **/ @@ -287,9 +275,9 @@ hb_blob_get_user_data (hb_blob_t *blob, /** * hb_blob_make_immutable: - * @blob: a blob. - * + * @blob: a blob * + * Makes a blob immutable. * * Since: 0.9.2 **/ @@ -306,9 +294,9 @@ hb_blob_make_immutable (hb_blob_t *blob) * hb_blob_is_immutable: * @blob: a blob. * + * Tests whether a blob is immutable. * - * - * Return value: TODO + * Return value: %true if @blob is immutable, %false otherwise * * Since: 0.9.2 **/ @@ -323,9 +311,9 @@ hb_blob_is_immutable (hb_blob_t *blob) * hb_blob_get_length: * @blob: a blob. * + * Fetches the length of a blob's data. * - * - * Return value: the length of blob data in bytes. + * Return value: the length of @blob data in bytes. * * Since: 0.9.2 **/ @@ -338,11 +326,11 @@ hb_blob_get_length (hb_blob_t *blob) /** * hb_blob_get_data: * @blob: a blob. - * @length: (out): - * + * @length: (out): The length in bytes of the data retrieved * + * Fetches the data from a blob. * - * Returns: (transfer none) (array length=length): + * Returns: (transfer none) (array length=length): the byte data of @blob. * * Since: 0.9.2 **/ @@ -374,16 +362,14 @@ hb_blob_get_data (hb_blob_t *blob, unsigned int *length) char * hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length) { - if (!blob->try_make_writable ()) { - if (length) - *length = 0; - + if (hb_object_is_immutable (blob) || + !blob->try_make_writable ()) + { + if (length) *length = 0; return nullptr; } - if (length) - *length = blob->length; - + if (length) *length = blob->length; return const_cast<char *> (blob->data); } @@ -449,8 +435,8 @@ hb_blob_t::try_make_writable_inplace () bool hb_blob_t::try_make_writable () { - if (hb_object_is_immutable (this)) - return false; + if (unlikely (!length)) + mode = HB_MEMORY_MODE_WRITABLE; if (this->mode == HB_MEMORY_MODE_WRITABLE) return true; @@ -488,6 +474,9 @@ hb_blob_t::try_make_writable () #ifndef HB_NO_OPEN #ifdef HAVE_MMAP +# if !defined(HB_NO_RESOURCE_FORK) && defined(__APPLE__) +# include <sys/paths.h> +# endif # include <sys/types.h> # include <sys/stat.h> # include <fcntl.h> @@ -532,11 +521,47 @@ _hb_mapped_file_destroy (void *file_) } #endif +#ifdef _PATH_RSRCFORKSPEC +static int +_open_resource_fork (const char *file_name, hb_mapped_file_t *file) +{ + size_t name_len = strlen (file_name); + size_t len = name_len + sizeof (_PATH_RSRCFORKSPEC); + + char *rsrc_name = (char *) malloc (len); + if (unlikely (!rsrc_name)) return -1; + + strncpy (rsrc_name, file_name, name_len); + strncpy (rsrc_name + name_len, _PATH_RSRCFORKSPEC, + sizeof (_PATH_RSRCFORKSPEC) - 1); + + int fd = open (rsrc_name, O_RDONLY | O_BINARY, 0); + free (rsrc_name); + + if (fd != -1) + { + struct stat st; + if (fstat (fd, &st) != -1) + file->length = (unsigned long) st.st_size; + else + { + close (fd); + fd = -1; + } + } + + return fd; +} +#endif + /** * hb_blob_create_from_file: - * @file_name: font filename. + * @file_name: A font filename + * + * Creates a new blob containing the data from the + * specified binary font file. * - * Returns: A hb_blob_t pointer with the content of the file + * Returns: An #hb_blob_t pointer with the content of the file * * Since: 1.7.7 **/ @@ -556,6 +581,19 @@ hb_blob_create_from_file (const char *file_name) if (unlikely (fstat (fd, &st) == -1)) goto fail; file->length = (unsigned long) st.st_size; + +#ifdef _PATH_RSRCFORKSPEC + if (unlikely (file->length == 0)) + { + int rfd = _open_resource_fork (file_name, file); + if (rfd != -1) + { + close (fd); + fd = rfd; + } + } +#endif + file->contents = (char *) mmap (nullptr, file->length, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, fd, 0); @@ -579,9 +617,9 @@ fail_without_close: HANDLE fd; unsigned int size = strlen (file_name) + 1; wchar_t * wchar_file_name = (wchar_t *) malloc (sizeof (wchar_t) * size); - if (unlikely (wchar_file_name == nullptr)) goto fail_without_close; + if (unlikely (!wchar_file_name)) goto fail_without_close; mbstowcs (wchar_file_name, file_name, size); -#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) +#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) { CREATEFILE2_EXTENDED_PARAMETERS ceparams = { 0 }; ceparams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS); @@ -602,7 +640,7 @@ fail_without_close: if (unlikely (fd == INVALID_HANDLE_VALUE)) goto fail_without_close; -#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) +#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) { LARGE_INTEGER length; GetFileSizeEx (fd, &length); @@ -613,14 +651,14 @@ fail_without_close: file->length = (unsigned long) GetFileSize (fd, nullptr); file->mapping = CreateFileMapping (fd, nullptr, PAGE_READONLY, 0, 0, nullptr); #endif - if (unlikely (file->mapping == nullptr)) goto fail; + if (unlikely (!file->mapping)) goto fail; -#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) +#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) file->contents = (char *) MapViewOfFileFromApp (file->mapping, FILE_MAP_READ, 0, 0); #else file->contents = (char *) MapViewOfFile (file->mapping, FILE_MAP_READ, 0, 0, 0); #endif - if (unlikely (file->contents == nullptr)) goto fail; + if (unlikely (!file->contents)) goto fail; CloseHandle (fd); return hb_blob_create (file->contents, file->length, @@ -638,10 +676,10 @@ fail_without_close: It's used as a fallback for systems without mmap or to read from pipes */ unsigned long len = 0, allocated = BUFSIZ * 16; char *data = (char *) malloc (allocated); - if (unlikely (data == nullptr)) return hb_blob_get_empty (); + if (unlikely (!data)) return hb_blob_get_empty (); FILE *fp = fopen (file_name, "rb"); - if (unlikely (fp == nullptr)) goto fread_fail_without_close; + if (unlikely (!fp)) goto fread_fail_without_close; while (!feof (fp)) { @@ -652,7 +690,7 @@ fail_without_close: can cover files like that but lets limit our fallback reader */ if (unlikely (allocated > (2 << 28))) goto fread_fail; char *new_data = (char *) realloc (data, allocated); - if (unlikely (new_data == nullptr)) goto fread_fail; + if (unlikely (!new_data)) goto fread_fail; data = new_data; } @@ -666,6 +704,7 @@ fail_without_close: len += addition; } + fclose (fp); return hb_blob_create (data, len, HB_MEMORY_MODE_WRITABLE, data, (hb_destroy_func_t) free); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-blob.h b/src/3rdparty/harfbuzz-ng/src/hb-blob.h index f80e9af2d9..86f12788d2 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-blob.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-blob.h @@ -24,7 +24,7 @@ * Red Hat Author(s): Behdad Esfahbod */ -#ifndef HB_H_IN +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb.h> instead." #endif @@ -36,25 +36,36 @@ HB_BEGIN_DECLS -/* - * Note re various memory-modes: +/** + * hb_memory_mode_t: + * @HB_MEMORY_MODE_DUPLICATE: HarfBuzz immediately makes a copy of the data. + * @HB_MEMORY_MODE_READONLY: HarfBuzz client will never modify the data, + * and HarfBuzz will never modify the data. + * @HB_MEMORY_MODE_WRITABLE: HarfBuzz client made a copy of the data solely + * for HarfBuzz, so HarfBuzz may modify the data. + * @HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE: See above + * + * Data type holding the memory modes available to + * client programs. + * + * Regarding these various memory-modes: * * - In no case shall the HarfBuzz client modify memory * that is passed to HarfBuzz in a blob. If there is - * any such possibility, MODE_DUPLICATE should be used + * any such possibility, @HB_MEMORY_MODE_DUPLICATE should be used * such that HarfBuzz makes a copy immediately, * - * - Use MODE_READONLY otherwise, unless you really really + * - Use @HB_MEMORY_MODE_READONLY otherwise, unless you really really * really know what you are doing, * - * - MODE_WRITABLE is appropriate if you really made a + * - @HB_MEMORY_MODE_WRITABLE is appropriate if you really made a * copy of data solely for the purpose of passing to * HarfBuzz and doing that just once (no reuse!), * - * - If the font is mmap()ed, it's ok to use - * READONLY_MAY_MAKE_WRITABLE, however, using that mode - * correctly is very tricky. Use MODE_READONLY instead. - */ + * - If the font is mmap()ed, it's okay to use + * @HB_MEMORY_READONLY_MAY_MAKE_WRITABLE, however, using that mode + * correctly is very tricky. Use @HB_MEMORY_MODE_READONLY instead. + **/ typedef enum { HB_MEMORY_MODE_DUPLICATE, HB_MEMORY_MODE_READONLY, @@ -62,6 +73,14 @@ typedef enum { HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE } hb_memory_mode_t; +/** + * hb_blob_t: + * + * Data type for blobs. A blob wraps a chunk of binary + * data and facilitates its lifecycle management between + * a client program and HarfBuzz. + * + **/ typedef struct hb_blob_t hb_blob_t; HB_EXTERN hb_blob_t * diff --git a/src/3rdparty/harfbuzz-ng/src/hb-blob.hh b/src/3rdparty/harfbuzz-ng/src/hb-blob.hh index d85bd823b0..b03dfc1380 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-blob.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-blob.hh @@ -90,6 +90,7 @@ struct hb_blob_ptr_t unsigned int get_length () const { return b.get ()->length; } void destroy () { hb_blob_destroy (b.get ()); b = nullptr; } + private: hb_nonnull_ptr_t<hb_blob_t> b; }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-json.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-json.hh index 1f9e2e91db..01db295498 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-json.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-json.hh @@ -1,30 +1,29 @@ - #line 1 "hb-buffer-deserialize-json.rl" /* - * Copyright © 2013 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ +* Copyright © 2013 Google, Inc. +* +* This is part of HarfBuzz, a text shaping library. +* +* Permission is hereby granted, without written agreement and without +* license or royalty fees, to use, copy, modify, and distribute this +* software and its documentation for any purpose, provided that the +* above copyright notice and the following two paragraphs appear in +* all copies of this software. +* +* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR +* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN +* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +* DAMAGE. +* +* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, +* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS +* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO +* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. +* +* Google Author(s): Behdad Esfahbod +*/ #ifndef HB_BUFFER_DESERIALIZE_JSON_HH #define HB_BUFFER_DESERIALIZE_JSON_HH @@ -32,612 +31,577 @@ #include "hb.hh" -#line 36 "hb-buffer-deserialize-json.hh" +#line 35 "hb-buffer-deserialize-json.hh" static const unsigned char _deserialize_json_trans_keys[] = { - 0u, 0u, 9u, 123u, 9u, 34u, 97u, 103u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, - 48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, - 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, - 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, - 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, - 65u, 122u, 34u, 122u, 9u, 125u, 9u, 125u, 9u, 93u, 9u, 123u, 0u, 0u, 0 + 1u, 0u, 0u, 18u, 0u, 2u, 10u, 15u, + 16u, 17u, 2u, 2u, 0u, 7u, 0u, 6u, + 5u, 6u, 0u, 19u, 0u, 19u, 0u, 19u, + 2u, 2u, 0u, 7u, 0u, 6u, 5u, 6u, + 0u, 19u, 0u, 19u, 14u, 14u, 2u, 2u, + 0u, 7u, 0u, 6u, 0u, 19u, 0u, 19u, + 16u, 17u, 2u, 2u, 0u, 7u, 0u, 6u, + 5u, 6u, 0u, 19u, 0u, 19u, 2u, 2u, + 0u, 7u, 0u, 6u, 5u, 6u, 0u, 19u, + 0u, 19u, 2u, 2u, 0u, 7u, 0u, 6u, + 2u, 8u, 0u, 19u, 2u, 8u, 0u, 19u, + 0u, 19u, 2u, 2u, 0u, 7u, 0u, 6u, + 0u, 19u, 0u, 9u, 0u, 18u, 1u, 0u, + 0u }; -static const char _deserialize_json_key_spans[] = { - 0, 115, 26, 7, 2, 1, 50, 49, - 10, 117, 117, 117, 1, 50, 49, 10, - 117, 117, 1, 1, 50, 49, 117, 117, - 2, 1, 50, 49, 10, 117, 117, 1, - 50, 49, 10, 117, 117, 1, 50, 49, - 58, 89, 117, 117, 85, 115, 0 +static const signed char _deserialize_json_char_class[] = { + 0, 0, 0, 0, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 0, + 1, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 3, 4, 1, 1, 5, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 7, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 8, 9, 1, 1, 1, + 10, 1, 11, 12, 1, 1, 13, 1, + 1, 1, 1, 14, 1, 1, 1, 1, + 1, 1, 1, 1, 15, 1, 1, 16, + 17, 1, 18, 1, 19, 0 }; static const short _deserialize_json_index_offsets[] = { - 0, 0, 116, 143, 151, 154, 156, 207, - 257, 268, 386, 504, 622, 624, 675, 725, - 736, 854, 972, 974, 976, 1027, 1077, 1195, - 1313, 1316, 1318, 1369, 1419, 1430, 1548, 1666, - 1668, 1719, 1769, 1780, 1898, 2016, 2018, 2069, - 2119, 2178, 2268, 2386, 2504, 2590, 2706 + 0, 0, 19, 22, 28, 30, 31, 39, + 46, 48, 68, 88, 108, 109, 117, 124, + 126, 146, 166, 167, 168, 176, 183, 203, + 223, 225, 226, 234, 241, 243, 263, 283, + 284, 292, 299, 301, 321, 341, 342, 350, + 357, 364, 384, 391, 411, 431, 432, 440, + 447, 467, 477, 496, 0 +}; + +static const signed char _deserialize_json_indicies[] = { + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 3, 0, 4, 5, 6, + 7, 8, 0, 9, 10, 11, 12, 12, + 0, 0, 0, 0, 0, 0, 13, 13, + 0, 0, 0, 14, 15, 16, 18, 19, + 20, 0, 0, 21, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 22, 23, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 24, + 20, 0, 0, 21, 0, 19, 19, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 22, 25, 25, 0, 0, + 0, 0, 0, 0, 26, 26, 0, 0, + 0, 27, 28, 29, 31, 32, 33, 0, + 0, 34, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 35, 33, 0, 0, 34, 0, 32, + 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 35, 36, 37, + 37, 0, 0, 0, 0, 0, 0, 38, + 38, 0, 0, 0, 0, 39, 40, 42, + 0, 0, 43, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 44, 42, 0, 0, 43, 0, + 45, 45, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 44, 46, + 47, 48, 48, 0, 0, 0, 0, 0, + 0, 49, 49, 0, 0, 0, 50, 51, + 52, 54, 55, 56, 0, 0, 57, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 58, 56, + 0, 0, 57, 0, 55, 55, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 58, 59, 59, 0, 0, 0, + 0, 0, 0, 60, 60, 0, 0, 0, + 61, 62, 63, 65, 66, 67, 0, 0, + 68, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 69, 67, 0, 0, 68, 0, 66, 66, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 69, 70, 70, 0, + 0, 0, 0, 0, 0, 71, 71, 0, + 72, 0, 0, 73, 74, 76, 75, 75, + 75, 75, 75, 77, 79, 0, 0, 80, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 81, + 75, 0, 0, 0, 0, 0, 75, 83, + 0, 0, 84, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 85, 83, 0, 0, 84, 0, + 87, 87, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 85, 88, + 88, 0, 0, 0, 0, 0, 0, 89, + 89, 0, 0, 0, 0, 90, 91, 83, + 0, 0, 84, 0, 93, 93, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 85, 94, 0, 0, 95, 0, + 0, 0, 0, 0, 96, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, + 0 }; -static const char _deserialize_json_indicies[] = { - 0, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 2, 1, 3, 3, 3, - 3, 3, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 1, 4, 1, - 5, 1, 6, 7, 1, 1, 8, 1, - 9, 10, 1, 11, 1, 11, 11, 11, - 11, 11, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 11, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 12, 1, - 12, 12, 12, 12, 12, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 12, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 13, 1, 1, 14, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 1, 16, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 1, 18, 18, 18, - 18, 18, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 18, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 19, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 20, 1, 21, 21, 21, 21, 21, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 21, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 3, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 22, - 1, 18, 18, 18, 18, 18, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 18, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 19, 1, 1, 1, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 20, 1, 23, - 1, 23, 23, 23, 23, 23, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 23, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 24, 1, 24, 24, 24, 24, - 24, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 24, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 25, 1, 1, 26, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 1, 28, 29, - 29, 29, 29, 29, 29, 29, 29, 29, - 1, 30, 30, 30, 30, 30, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 30, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 31, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 32, 1, 30, - 30, 30, 30, 30, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 30, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 31, 1, 1, 1, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 32, 1, 33, 1, 34, - 1, 34, 34, 34, 34, 34, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 34, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 35, 1, 35, 35, 35, 35, - 35, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 35, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 36, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 1, 38, 38, - 38, 38, 38, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 38, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 39, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 40, 1, 38, 38, 38, 38, - 38, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 38, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 39, - 1, 1, 1, 41, 41, 41, 41, 41, - 41, 41, 41, 41, 41, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 40, 1, 42, 43, 1, 44, 1, 44, - 44, 44, 44, 44, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 44, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 45, 1, 45, 45, 45, 45, 45, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 45, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 46, 1, - 1, 47, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 1, 49, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 1, 51, - 51, 51, 51, 51, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 51, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 52, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 53, 1, 51, 51, 51, - 51, 51, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 51, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 52, 1, 1, 1, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 53, 1, 54, 1, 54, 54, 54, - 54, 54, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 54, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 55, 1, - 55, 55, 55, 55, 55, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 55, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 56, 1, 1, 57, - 58, 58, 58, 58, 58, 58, 58, 58, - 58, 1, 59, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 1, 61, 61, 61, - 61, 61, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 61, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 62, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 63, 1, 61, 61, 61, 61, 61, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 61, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 62, 1, - 1, 1, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 63, - 1, 64, 1, 64, 64, 64, 64, 64, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 64, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 65, 1, 65, 65, - 65, 65, 65, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 65, 1, 66, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 67, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 1, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 1, 1, 1, 1, 1, 1, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 1, 70, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 71, 71, - 1, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 1, 1, 1, 1, 1, - 1, 1, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 1, 1, 1, 1, - 71, 1, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 1, 72, 72, 72, - 72, 72, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 72, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 73, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 74, 1, 72, 72, 72, 72, 72, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 72, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 73, 1, - 1, 1, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 75, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 74, - 1, 76, 76, 76, 76, 76, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 76, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 77, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 78, 1, 0, - 0, 0, 0, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 0, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 1, 1, 0 +static const signed char _deserialize_json_index_defaults[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 75, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 }; -static const char _deserialize_json_trans_targs[] = { - 1, 0, 2, 2, 3, 4, 18, 24, - 37, 5, 12, 6, 7, 8, 9, 11, - 9, 11, 10, 2, 44, 10, 44, 13, - 14, 15, 16, 17, 16, 17, 10, 2, - 44, 19, 20, 21, 22, 23, 10, 2, - 44, 23, 25, 31, 26, 27, 28, 29, - 30, 29, 30, 10, 2, 44, 32, 33, - 34, 35, 36, 35, 36, 10, 2, 44, - 38, 39, 40, 42, 43, 41, 10, 41, - 10, 2, 44, 43, 44, 45, 46 +static const signed char _deserialize_json_cond_targs[] = { + 0, 1, 2, 2, 3, 4, 18, 24, + 37, 45, 5, 12, 6, 7, 8, 9, + 11, 8, 9, 11, 10, 2, 49, 10, + 49, 13, 14, 15, 16, 17, 15, 16, + 17, 10, 2, 49, 19, 20, 21, 22, + 23, 22, 10, 2, 49, 23, 25, 31, + 26, 27, 28, 29, 30, 28, 29, 30, + 10, 2, 49, 32, 33, 34, 35, 36, + 34, 35, 36, 10, 2, 49, 38, 39, + 40, 43, 44, 40, 41, 42, 41, 10, + 2, 49, 43, 10, 2, 49, 44, 44, + 46, 47, 43, 48, 48, 48, 49, 50, + 51, 0 }; -static const char _deserialize_json_trans_actions[] = { - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2, 2, 2, - 0, 0, 3, 3, 4, 0, 5, 0, - 0, 2, 2, 2, 0, 0, 6, 6, - 7, 0, 0, 0, 2, 2, 8, 8, - 9, 0, 0, 0, 0, 0, 2, 2, - 2, 0, 0, 10, 10, 11, 0, 0, - 2, 2, 2, 0, 0, 12, 12, 13, - 0, 0, 0, 2, 2, 2, 14, 0, - 15, 15, 16, 0, 0, 0, 0 +static const signed char _deserialize_json_cond_actions[] = { + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 2, + 2, 0, 0, 0, 3, 3, 4, 0, + 5, 0, 0, 2, 2, 2, 0, 0, + 0, 6, 6, 7, 0, 0, 0, 2, + 2, 0, 8, 8, 9, 0, 0, 0, + 0, 0, 2, 2, 2, 0, 0, 0, + 10, 10, 11, 0, 0, 2, 2, 2, + 0, 0, 0, 12, 12, 13, 0, 0, + 2, 14, 14, 0, 15, 0, 0, 16, + 16, 17, 0, 18, 18, 19, 0, 15, + 0, 0, 20, 20, 0, 21, 0, 0, + 0, 0 }; static const int deserialize_json_start = 1; -static const int deserialize_json_first_final = 44; +static const int deserialize_json_first_final = 49; static const int deserialize_json_error = 0; static const int deserialize_json_en_main = 1; -#line 97 "hb-buffer-deserialize-json.rl" +#line 108 "hb-buffer-deserialize-json.rl" static hb_bool_t -_hb_buffer_deserialize_glyphs_json (hb_buffer_t *buffer, - const char *buf, - unsigned int buf_len, - const char **end_ptr, - hb_font_t *font) +_hb_buffer_deserialize_json (hb_buffer_t *buffer, +const char *buf, +unsigned int buf_len, +const char **end_ptr, +hb_font_t *font) { - const char *p = buf, *pe = buf + buf_len; - - /* Ensure we have positions. */ - (void) hb_buffer_get_glyph_positions (buffer, nullptr); - - while (p < pe && ISSPACE (*p)) - p++; - if (p < pe && *p == (buffer->len ? ',' : '[')) - { - *end_ptr = ++p; - } - - const char *tok = nullptr; - int cs; - hb_glyph_info_t info = {0}; - hb_glyph_position_t pos = {0}; - -#line 466 "hb-buffer-deserialize-json.hh" + const char *p = buf, *pe = buf + buf_len; + + /* Ensure we have positions. */ + (void) hb_buffer_get_glyph_positions (buffer, nullptr); + + while (p < pe && ISSPACE (*p)) + p++; + if (p < pe && *p == (buffer->len ? ',' : '[')) + { + *end_ptr = ++p; + } + + const char *tok = nullptr; + int cs; + hb_glyph_info_t info = {0}; + hb_glyph_position_t pos = {0}; + +#line 223 "hb-buffer-deserialize-json.hh" { - cs = deserialize_json_start; + cs = (int)deserialize_json_start; } - -#line 471 "hb-buffer-deserialize-json.hh" + +#line 228 "hb-buffer-deserialize-json.hh" { - int _slen; - int _trans; - const unsigned char *_keys; - const char *_inds; - if ( p == pe ) - goto _test_eof; - if ( cs == 0 ) - goto _out; -_resume: - _keys = _deserialize_json_trans_keys + (cs<<1); - _inds = _deserialize_json_indicies + _deserialize_json_index_offsets[cs]; - - _slen = _deserialize_json_key_spans[cs]; - _trans = _inds[ _slen > 0 && _keys[0] <=(*p) && - (*p) <= _keys[1] ? - (*p) - _keys[0] : _slen ]; - - cs = _deserialize_json_trans_targs[_trans]; - - if ( _deserialize_json_trans_actions[_trans] == 0 ) - goto _again; - - switch ( _deserialize_json_trans_actions[_trans] ) { - case 1: + unsigned int _trans = 0; + const unsigned char * _keys; + const signed char * _inds; + int _ic; + _resume: {} + if ( p == pe ) + goto _out; + _keys = ( _deserialize_json_trans_keys + ((cs<<1))); + _inds = ( _deserialize_json_indicies + (_deserialize_json_index_offsets[cs])); + + if ( ( (*( p))) <= 125 && ( (*( p))) >= 9 ) { + _ic = (int)_deserialize_json_char_class[(int)( (*( p))) - 9]; + if ( _ic <= (int)(*( _keys+1)) && _ic >= (int)(*( _keys)) ) + _trans = (unsigned int)(*( _inds + (int)( _ic - (int)(*( _keys)) ) )); + else + _trans = (unsigned int)_deserialize_json_index_defaults[cs]; + } + else { + _trans = (unsigned int)_deserialize_json_index_defaults[cs]; + } + + cs = (int)_deserialize_json_cond_targs[_trans]; + + if ( _deserialize_json_cond_actions[_trans] != 0 ) { + + switch ( _deserialize_json_cond_actions[_trans] ) { + case 1: { + { #line 38 "hb-buffer-deserialize-json.rl" - { - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); -} - break; - case 5: + + memset (&info, 0, sizeof (info)); + memset (&pos , 0, sizeof (pos )); + } + +#line 264 "hb-buffer-deserialize-json.hh" + + + break; + } + case 5: { + { #line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 2: + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + +#line 280 "hb-buffer-deserialize-json.hh" + + + break; + } + case 2: { + { #line 51 "hb-buffer-deserialize-json.rl" - { - tok = p; -} - break; - case 14: + + tok = p; + } + +#line 292 "hb-buffer-deserialize-json.hh" + + + break; + } + case 15: { + { #line 55 "hb-buffer-deserialize-json.rl" - { - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} - break; - case 15: -#line 62 "hb-buffer-deserialize-json.rl" - { if (!parse_uint (tok, p, &info.codepoint)) return false; } - break; - case 8: -#line 63 "hb-buffer-deserialize-json.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } - break; - case 10: -#line 64 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.x_offset )) return false; } - break; - case 12: -#line 65 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } - break; - case 3: + if (unlikely (!buffer->ensure_glyphs ())) return false; } + +#line 302 "hb-buffer-deserialize-json.hh" + + + break; + } + case 21: { + { +#line 56 "hb-buffer-deserialize-json.rl" + if (unlikely (!buffer->ensure_unicode ())) return false; } + +#line 312 "hb-buffer-deserialize-json.hh" + + + break; + } + case 16: { + { +#line 58 "hb-buffer-deserialize-json.rl" + + /* TODO Unescape \" and \\ if found. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; + } + +#line 328 "hb-buffer-deserialize-json.hh" + + + break; + } + case 18: { + { #line 66 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } - break; - case 6: + if (!parse_uint (tok, p, &info.codepoint)) return false; } + +#line 338 "hb-buffer-deserialize-json.hh" + + + break; + } + case 8: { + { #line 67 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.y_advance)) return false; } - break; - case 16: -#line 62 "hb-buffer-deserialize-json.rl" - { if (!parse_uint (tok, p, &info.codepoint)) return false; } + if (!parse_uint (tok, p, &info.cluster )) return false; } + +#line 348 "hb-buffer-deserialize-json.hh" + + + break; + } + case 10: { + { +#line 68 "hb-buffer-deserialize-json.rl" + if (!parse_int (tok, p, &pos.x_offset )) return false; } + +#line 358 "hb-buffer-deserialize-json.hh" + + + break; + } + case 12: { + { +#line 69 "hb-buffer-deserialize-json.rl" + if (!parse_int (tok, p, &pos.y_offset )) return false; } + +#line 368 "hb-buffer-deserialize-json.hh" + + + break; + } + case 3: { + { +#line 70 "hb-buffer-deserialize-json.rl" + if (!parse_int (tok, p, &pos.x_advance)) return false; } + +#line 378 "hb-buffer-deserialize-json.hh" + + + break; + } + case 6: { + { +#line 71 "hb-buffer-deserialize-json.rl" + if (!parse_int (tok, p, &pos.y_advance)) return false; } + +#line 388 "hb-buffer-deserialize-json.hh" + + + break; + } + case 14: { + { +#line 51 "hb-buffer-deserialize-json.rl" + + tok = p; + } + +#line 400 "hb-buffer-deserialize-json.hh" + + { +#line 55 "hb-buffer-deserialize-json.rl" + if (unlikely (!buffer->ensure_glyphs ())) return false; } + +#line 406 "hb-buffer-deserialize-json.hh" + + + break; + } + case 20: { + { +#line 51 "hb-buffer-deserialize-json.rl" + + tok = p; + } + +#line 418 "hb-buffer-deserialize-json.hh" + + { +#line 56 "hb-buffer-deserialize-json.rl" + if (unlikely (!buffer->ensure_unicode ())) return false; } + +#line 424 "hb-buffer-deserialize-json.hh" + + + break; + } + case 17: { + { +#line 58 "hb-buffer-deserialize-json.rl" + + /* TODO Unescape \" and \\ if found. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; + } + +#line 440 "hb-buffer-deserialize-json.hh" + + { #line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 9: -#line 63 "hb-buffer-deserialize-json.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + +#line 452 "hb-buffer-deserialize-json.hh" + + + break; + } + case 19: { + { +#line 66 "hb-buffer-deserialize-json.rl" + if (!parse_uint (tok, p, &info.codepoint)) return false; } + +#line 462 "hb-buffer-deserialize-json.hh" + + { #line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 11: -#line 64 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.x_offset )) return false; } + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + +#line 474 "hb-buffer-deserialize-json.hh" + + + break; + } + case 9: { + { +#line 67 "hb-buffer-deserialize-json.rl" + if (!parse_uint (tok, p, &info.cluster )) return false; } + +#line 484 "hb-buffer-deserialize-json.hh" + + { #line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 13: -#line 65 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + +#line 496 "hb-buffer-deserialize-json.hh" + + + break; + } + case 11: { + { +#line 68 "hb-buffer-deserialize-json.rl" + if (!parse_int (tok, p, &pos.x_offset )) return false; } + +#line 506 "hb-buffer-deserialize-json.hh" + + { #line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 4: -#line 66 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + +#line 518 "hb-buffer-deserialize-json.hh" + + + break; + } + case 13: { + { +#line 69 "hb-buffer-deserialize-json.rl" + if (!parse_int (tok, p, &pos.y_offset )) return false; } + +#line 528 "hb-buffer-deserialize-json.hh" + + { #line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 7: -#line 67 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.y_advance)) return false; } + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + +#line 540 "hb-buffer-deserialize-json.hh" + + + break; + } + case 4: { + { +#line 70 "hb-buffer-deserialize-json.rl" + if (!parse_int (tok, p, &pos.x_advance)) return false; } + +#line 550 "hb-buffer-deserialize-json.hh" + + { #line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; -#line 624 "hb-buffer-deserialize-json.hh" - } - -_again: - if ( cs == 0 ) - goto _out; - if ( ++p != pe ) - goto _resume; - _test_eof: {} - _out: {} + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + +#line 562 "hb-buffer-deserialize-json.hh" + + + break; + } + case 7: { + { +#line 71 "hb-buffer-deserialize-json.rl" + if (!parse_int (tok, p, &pos.y_advance)) return false; } + +#line 572 "hb-buffer-deserialize-json.hh" + + { +#line 43 "hb-buffer-deserialize-json.rl" + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + +#line 584 "hb-buffer-deserialize-json.hh" + + + break; + } + } + + } + + if ( cs != 0 ) { + p += 1; + goto _resume; + } + _out: {} } - -#line 125 "hb-buffer-deserialize-json.rl" - - - *end_ptr = p; - - return p == pe && *(p-1) != ']'; + +#line 136 "hb-buffer-deserialize-json.rl" + + + *end_ptr = p; + + return p == pe && *(p-1) != ']'; } #endif /* HB_BUFFER_DESERIALIZE_JSON_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-json.rl b/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-json.rl deleted file mode 100644 index f3abb027b2..0000000000 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-json.rl +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright © 2013 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ - -#ifndef HB_BUFFER_DESERIALIZE_JSON_HH -#define HB_BUFFER_DESERIALIZE_JSON_HH - -#include "hb.hh" - -%%{ - -machine deserialize_json; -alphtype unsigned char; -write data; - -action clear_item { - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); -} - -action add_item { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - -action tok { - tok = p; -} - -action parse_glyph { - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} - -action parse_gid { if (!parse_uint (tok, p, &info.codepoint)) return false; } -action parse_cluster { if (!parse_uint (tok, p, &info.cluster )) return false; } -action parse_x_offset { if (!parse_int (tok, p, &pos.x_offset )) return false; } -action parse_y_offset { if (!parse_int (tok, p, &pos.y_offset )) return false; } -action parse_x_advance { if (!parse_int (tok, p, &pos.x_advance)) return false; } -action parse_y_advance { if (!parse_int (tok, p, &pos.y_advance)) return false; } - -unum = '0' | [1-9] digit*; -num = '-'? unum; - -comma = space* ',' space*; -colon = space* ':' space*; - -glyph_id = unum; -glyph_name = alpha (alnum|'_'|'.'|'-')*; - -glyph_string = '"' (glyph_name >tok %parse_glyph) '"'; -glyph_number = (glyph_id >tok %parse_gid); - -glyph = "\"g\"" colon (glyph_string | glyph_number); -cluster = "\"cl\"" colon (unum >tok %parse_cluster); -xoffset = "\"dx\"" colon (num >tok %parse_x_offset); -yoffset = "\"dy\"" colon (num >tok %parse_y_offset); -xadvance= "\"ax\"" colon (num >tok %parse_x_advance); -yadvance= "\"ay\"" colon (num >tok %parse_y_advance); - -element = glyph | cluster | xoffset | yoffset | xadvance | yadvance; -item = - ( '{' space* element (comma element)* space* '}') - >clear_item - @add_item - ; - -main := space* item (comma item)* space* (','|']')?; - -}%% - -static hb_bool_t -_hb_buffer_deserialize_glyphs_json (hb_buffer_t *buffer, - const char *buf, - unsigned int buf_len, - const char **end_ptr, - hb_font_t *font) -{ - const char *p = buf, *pe = buf + buf_len; - - /* Ensure we have positions. */ - (void) hb_buffer_get_glyph_positions (buffer, nullptr); - - while (p < pe && ISSPACE (*p)) - p++; - if (p < pe && *p == (buffer->len ? ',' : '[')) - { - *end_ptr = ++p; - } - - const char *tok = nullptr; - int cs; - hb_glyph_info_t info = {0}; - hb_glyph_position_t pos = {0}; - %%{ - write init; - write exec; - }%% - - *end_ptr = p; - - return p == pe && *(p-1) != ']'; -} - -#endif /* HB_BUFFER_DESERIALIZE_JSON_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text.hh index 67f0a1252f..fb36f56015 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text.hh @@ -1,30 +1,29 @@ - #line 1 "hb-buffer-deserialize-text.rl" /* - * Copyright © 2013 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ +* Copyright © 2013 Google, Inc. +* +* This is part of HarfBuzz, a text shaping library. +* +* Permission is hereby granted, without written agreement and without +* license or royalty fees, to use, copy, modify, and distribute this +* software and its documentation for any purpose, provided that the +* above copyright notice and the following two paragraphs appear in +* all copies of this software. +* +* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR +* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN +* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +* DAMAGE. +* +* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, +* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS +* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO +* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. +* +* Google Author(s): Behdad Esfahbod +*/ #ifndef HB_BUFFER_DESERIALIZE_TEXT_HH #define HB_BUFFER_DESERIALIZE_TEXT_HH @@ -32,540 +31,734 @@ #include "hb.hh" -#line 36 "hb-buffer-deserialize-text.hh" +#line 35 "hb-buffer-deserialize-text.hh" static const unsigned char _deserialize_text_trans_keys[] = { - 0u, 0u, 9u, 122u, 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u, - 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, 9u, 124u, 9u, 124u, 0u, 0u, - 9u, 122u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, - 9u, 124u, 9u, 124u, 9u, 124u, 0 + 1u, 0u, 0u, 13u, 12u, 12u, 2u, 2u, + 5u, 11u, 0u, 12u, 5u, 6u, 4u, 6u, + 5u, 6u, 5u, 6u, 4u, 6u, 5u, 6u, + 3u, 3u, 4u, 6u, 5u, 6u, 3u, 6u, + 2u, 16u, 4u, 6u, 5u, 6u, 0u, 16u, + 0u, 16u, 1u, 0u, 0u, 12u, 0u, 16u, + 0u, 16u, 0u, 16u, 0u, 16u, 0u, 16u, + 0u, 16u, 0u, 16u, 0u, 16u, 0u, 16u, + 0u, 16u, 0u, 16u, 0u, 16u, 0u, 16u, + 0u, 16u, 0u }; -static const char _deserialize_text_key_spans[] = { - 0, 114, 13, 10, 13, 10, 10, 13, - 10, 1, 13, 10, 14, 116, 116, 0, - 114, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 116 +static const signed char _deserialize_text_char_class[] = { + 0, 0, 0, 0, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 3, 4, 1, 1, 5, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 1, 1, 7, 8, 9, 1, 10, + 11, 11, 11, 11, 11, 11, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 12, 1, 1, 1, + 1, 1, 13, 14, 15, 1, 1, 1, + 11, 11, 11, 11, 11, 11, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 16, 0 }; static const short _deserialize_text_index_offsets[] = { - 0, 0, 115, 129, 140, 154, 165, 176, - 190, 201, 203, 217, 228, 243, 360, 477, - 478, 593, 710, 827, 944, 1061, 1178, 1295, - 1412, 1529, 1646 + 0, 0, 14, 15, 16, 23, 36, 38, + 41, 43, 45, 48, 50, 51, 54, 56, + 60, 75, 78, 80, 97, 114, 114, 127, + 144, 161, 178, 195, 212, 229, 246, 263, + 280, 297, 314, 331, 348, 0 +}; + +static const signed char _deserialize_text_indicies[] = { + 1, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 3, 4, 6, + 7, 7, 0, 0, 0, 0, 7, 8, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 10, 11, 13, 14, + 15, 17, 18, 20, 21, 23, 24, 25, + 27, 28, 29, 31, 32, 33, 35, 36, + 29, 0, 28, 28, 38, 38, 0, 0, + 0, 0, 38, 0, 38, 0, 0, 0, + 38, 38, 38, 40, 41, 42, 44, 45, + 47, 0, 0, 0, 0, 48, 48, 0, + 49, 50, 0, 48, 0, 0, 0, 0, + 51, 52, 0, 0, 0, 0, 0, 0, + 0, 0, 53, 0, 0, 0, 0, 0, + 0, 54, 8, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4, 56, + 0, 0, 0, 0, 0, 0, 0, 0, + 57, 0, 0, 0, 0, 0, 0, 58, + 56, 0, 0, 0, 0, 60, 60, 0, + 0, 57, 0, 0, 0, 0, 0, 0, + 58, 63, 62, 64, 0, 62, 62, 62, + 62, 65, 62, 66, 62, 62, 62, 67, + 68, 69, 71, 38, 72, 0, 38, 38, + 38, 38, 73, 38, 74, 38, 38, 38, + 37, 75, 76, 78, 0, 0, 79, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 80, 81, 82, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 53, 83, 84, 62, 64, + 0, 62, 62, 62, 62, 65, 62, 66, + 62, 62, 62, 67, 68, 69, 86, 0, + 87, 0, 0, 0, 0, 0, 0, 0, + 88, 0, 0, 0, 0, 57, 89, 91, + 0, 92, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 93, 94, + 91, 0, 92, 0, 0, 36, 36, 0, + 0, 0, 0, 0, 0, 0, 0, 93, + 94, 86, 0, 87, 0, 0, 97, 97, + 0, 0, 0, 88, 0, 0, 0, 0, + 57, 89, 99, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 100, 101, 99, 0, 0, 0, 0, + 45, 45, 0, 0, 0, 0, 0, 0, + 0, 0, 100, 101, 78, 0, 0, 79, + 0, 18, 18, 0, 0, 0, 0, 0, + 0, 0, 0, 80, 81, 0 }; -static const char _deserialize_text_indicies[] = { - 0, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 2, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 1, 1, 1, 1, 1, 1, - 1, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 1, 1, 1, 1, 1, - 1, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 1, 5, 1, 1, 6, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 1, 8, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 1, 10, 1, 1, - 11, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 1, 13, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 1, 15, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 1, 17, 1, 1, 18, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 1, 20, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 1, 22, 1, 23, 1, 1, 24, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 1, 26, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 1, 22, 1, 1, - 1, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 1, 28, 28, 28, 28, - 28, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 28, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 29, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 30, 1, 1, 31, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 32, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 33, - 1, 34, 34, 34, 34, 34, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 34, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 35, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 36, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 0, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 2, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 1, 1, 1, 1, 1, 1, 1, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 1, 1, 1, 1, 1, 1, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 1, 28, 28, 28, 28, 28, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 28, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 29, 1, 1, 1, - 1, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 1, 1, 1, 30, 1, - 1, 31, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 32, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 33, 1, 38, - 38, 38, 38, 38, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 38, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 39, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 40, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 41, 1, 42, 42, 42, 42, - 42, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 42, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 43, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 44, - 1, 42, 42, 42, 42, 42, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 42, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 43, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 44, 1, 38, 38, - 38, 38, 38, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 38, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 39, 1, 1, 1, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 40, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 41, 1, 45, 45, 45, 45, 45, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 45, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 46, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 47, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 48, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 49, 1, - 50, 50, 50, 50, 50, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 50, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 51, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 52, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 53, 1, 50, 50, 50, - 50, 50, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 50, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 51, - 1, 1, 1, 1, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 52, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 53, 1, 45, 45, 45, 45, 45, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 45, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 46, 1, 1, 1, - 1, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 1, 1, 1, 1, 1, - 1, 47, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 48, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 49, 1, 28, - 28, 28, 28, 28, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 28, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 29, 1, 55, 55, 1, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 1, 1, 1, 30, 1, 1, 31, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 1, 1, 32, 1, 55, 1, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 1, 33, 1, 0 +static const signed char _deserialize_text_index_defaults[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 62, 38, 0, 0, 62, 0, 0, + 0, 0, 0, 0, 0, 0 }; -static const char _deserialize_text_trans_targs[] = { - 1, 0, 13, 17, 26, 3, 18, 21, - 18, 21, 5, 19, 20, 19, 20, 22, - 25, 8, 9, 12, 9, 12, 10, 11, - 23, 24, 23, 24, 14, 2, 6, 7, - 15, 16, 14, 15, 16, 17, 14, 4, - 15, 16, 14, 15, 16, 14, 2, 7, - 15, 16, 14, 2, 15, 16, 25, 26 +static const signed char _deserialize_text_cond_targs[] = { + 0, 1, 2, 25, 3, 3, 4, 19, + 5, 6, 23, 24, 7, 8, 27, 36, + 8, 27, 36, 9, 30, 33, 10, 11, + 12, 15, 11, 12, 15, 13, 13, 14, + 31, 32, 14, 31, 32, 16, 26, 17, + 18, 34, 35, 18, 34, 35, 19, 20, + 19, 6, 21, 22, 20, 21, 22, 23, + 20, 21, 22, 24, 24, 25, 26, 26, + 7, 9, 10, 16, 21, 29, 26, 26, + 7, 9, 10, 21, 29, 27, 28, 17, + 21, 29, 28, 29, 29, 30, 28, 7, + 10, 29, 31, 28, 7, 21, 29, 32, + 33, 33, 34, 28, 21, 29, 35, 36, + 0 }; -static const char _deserialize_text_trans_actions[] = { - 0, 0, 1, 1, 1, 2, 2, 2, - 0, 0, 2, 2, 2, 0, 0, 2, - 2, 2, 2, 2, 0, 0, 3, 2, - 2, 2, 0, 0, 4, 5, 5, 5, - 4, 4, 0, 0, 0, 0, 6, 7, - 6, 6, 8, 8, 8, 9, 10, 10, - 9, 9, 11, 12, 11, 11, 0, 0 +static const signed char _deserialize_text_cond_actions[] = { + 0, 0, 0, 0, 1, 0, 0, 2, + 0, 0, 2, 2, 0, 3, 4, 4, + 0, 5, 5, 0, 4, 4, 0, 3, + 3, 3, 0, 0, 0, 6, 0, 3, + 4, 4, 0, 5, 5, 0, 5, 0, + 3, 4, 4, 0, 5, 5, 7, 7, + 8, 9, 7, 7, 0, 0, 0, 10, + 10, 10, 10, 10, 8, 11, 12, 13, + 14, 14, 14, 15, 11, 11, 16, 17, + 18, 18, 18, 16, 16, 19, 19, 20, + 19, 19, 0, 0, 13, 10, 10, 21, + 21, 10, 22, 22, 23, 22, 22, 22, + 10, 5, 24, 24, 24, 24, 24, 19, + 0 }; -static const char _deserialize_text_eof_actions[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4, 0, 0, - 0, 4, 6, 8, 8, 6, 9, 11, - 11, 9, 4 +static const signed char _deserialize_text_eof_trans[] = { + 1, 2, 3, 6, 7, 9, 10, 13, + 17, 20, 23, 27, 28, 31, 35, 29, + 38, 40, 44, 47, 53, 54, 55, 56, + 60, 62, 71, 78, 83, 70, 86, 91, + 96, 97, 99, 103, 104, 0 }; static const int deserialize_text_start = 1; -static const int deserialize_text_first_final = 13; +static const int deserialize_text_first_final = 19; static const int deserialize_text_error = 0; static const int deserialize_text_en_main = 1; -#line 91 "hb-buffer-deserialize-text.rl" +#line 114 "hb-buffer-deserialize-text.rl" static hb_bool_t -_hb_buffer_deserialize_glyphs_text (hb_buffer_t *buffer, - const char *buf, - unsigned int buf_len, - const char **end_ptr, - hb_font_t *font) +_hb_buffer_deserialize_text (hb_buffer_t *buffer, +const char *buf, +unsigned int buf_len, +const char **end_ptr, +hb_font_t *font) { - const char *p = buf, *pe = buf + buf_len; - - /* Ensure we have positions. */ - (void) hb_buffer_get_glyph_positions (buffer, nullptr); - - while (p < pe && ISSPACE (*p)) - p++; - if (p < pe && *p == (buffer->len ? '|' : '[')) - { - *end_ptr = ++p; - } - - const char *eof = pe, *tok = nullptr; - int cs; - hb_glyph_info_t info = {0}; - hb_glyph_position_t pos = {0}; - -#line 343 "hb-buffer-deserialize-text.hh" + const char *p = buf, *pe = buf + buf_len; + + /* Ensure we have positions. */ + (void) hb_buffer_get_glyph_positions (buffer, nullptr); + + while (p < pe && ISSPACE (*p)) + p++; + + const char *eof = pe, *tok = nullptr; + int cs; + hb_glyph_info_t info = {0}; + hb_glyph_position_t pos = {0}; + +#line 204 "hb-buffer-deserialize-text.hh" { - cs = deserialize_text_start; + cs = (int)deserialize_text_start; } - -#line 348 "hb-buffer-deserialize-text.hh" + +#line 209 "hb-buffer-deserialize-text.hh" { - int _slen; - int _trans; - const unsigned char *_keys; - const char *_inds; - if ( p == pe ) - goto _test_eof; - if ( cs == 0 ) - goto _out; -_resume: - _keys = _deserialize_text_trans_keys + (cs<<1); - _inds = _deserialize_text_indicies + _deserialize_text_index_offsets[cs]; - - _slen = _deserialize_text_key_spans[cs]; - _trans = _inds[ _slen > 0 && _keys[0] <=(*p) && - (*p) <= _keys[1] ? - (*p) - _keys[0] : _slen ]; - - cs = _deserialize_text_trans_targs[_trans]; - - if ( _deserialize_text_trans_actions[_trans] == 0 ) - goto _again; - - switch ( _deserialize_text_trans_actions[_trans] ) { - case 2: + unsigned int _trans = 0; + const unsigned char * _keys; + const signed char * _inds; + int _ic; + _resume: {} + if ( p == pe && p != eof ) + goto _out; + if ( p == eof ) { + if ( _deserialize_text_eof_trans[cs] > 0 ) { + _trans = (unsigned int)_deserialize_text_eof_trans[cs] - 1; + } + } + else { + _keys = ( _deserialize_text_trans_keys + ((cs<<1))); + _inds = ( _deserialize_text_indicies + (_deserialize_text_index_offsets[cs])); + + if ( ( (*( p))) <= 124 && ( (*( p))) >= 9 ) { + _ic = (int)_deserialize_text_char_class[(int)( (*( p))) - 9]; + if ( _ic <= (int)(*( _keys+1)) && _ic >= (int)(*( _keys)) ) + _trans = (unsigned int)(*( _inds + (int)( _ic - (int)(*( _keys)) ) )); + else + _trans = (unsigned int)_deserialize_text_index_defaults[cs]; + } + else { + _trans = (unsigned int)_deserialize_text_index_defaults[cs]; + } + + } + cs = (int)_deserialize_text_cond_targs[_trans]; + + if ( _deserialize_text_cond_actions[_trans] != 0 ) { + + switch ( _deserialize_text_cond_actions[_trans] ) { + case 1: { + { +#line 38 "hb-buffer-deserialize-text.rl" + + memset (&info, 0, sizeof (info)); + memset (&pos , 0, sizeof (pos )); + } + +#line 252 "hb-buffer-deserialize-text.hh" + + + break; + } + case 3: { + { #line 51 "hb-buffer-deserialize-text.rl" - { - tok = p; -} - break; - case 5: + + tok = p; + } + +#line 264 "hb-buffer-deserialize-text.hh" + + + break; + } + case 5: { + { #line 55 "hb-buffer-deserialize-text.rl" - { - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} - break; - case 10: -#line 62 "hb-buffer-deserialize-text.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } - break; - case 3: -#line 63 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.x_offset )) return false; } - break; - case 12: -#line 64 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } - break; - case 7: -#line 65 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } - break; - case 1: + if (unlikely (!buffer->ensure_glyphs ())) return false; } + +#line 274 "hb-buffer-deserialize-text.hh" + + + break; + } + case 8: { + { +#line 56 "hb-buffer-deserialize-text.rl" + if (unlikely (!buffer->ensure_unicode ())) return false; } + +#line 284 "hb-buffer-deserialize-text.hh" + + + break; + } + case 18: { + { +#line 58 "hb-buffer-deserialize-text.rl" + + /* TODO Unescape delimeters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; + } + +#line 300 "hb-buffer-deserialize-text.hh" + + + break; + } + case 9: { + { +#line 66 "hb-buffer-deserialize-text.rl" + if (!parse_hex (tok, p, &info.codepoint )) return false; } + +#line 310 "hb-buffer-deserialize-text.hh" + + + break; + } + case 21: { + { +#line 68 "hb-buffer-deserialize-text.rl" + if (!parse_uint (tok, p, &info.cluster )) return false; } + +#line 320 "hb-buffer-deserialize-text.hh" + + + break; + } + case 6: { + { +#line 69 "hb-buffer-deserialize-text.rl" + if (!parse_int (tok, p, &pos.x_offset )) return false; } + +#line 330 "hb-buffer-deserialize-text.hh" + + + break; + } + case 23: { + { +#line 70 "hb-buffer-deserialize-text.rl" + if (!parse_int (tok, p, &pos.y_offset )) return false; } + +#line 340 "hb-buffer-deserialize-text.hh" + + + break; + } + case 20: { + { +#line 71 "hb-buffer-deserialize-text.rl" + if (!parse_int (tok, p, &pos.x_advance)) return false; } + +#line 350 "hb-buffer-deserialize-text.hh" + + + break; + } + case 15: { + { #line 38 "hb-buffer-deserialize-text.rl" - { - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); -} + + memset (&info, 0, sizeof (info)); + memset (&pos , 0, sizeof (pos )); + } + +#line 363 "hb-buffer-deserialize-text.hh" + + { #line 51 "hb-buffer-deserialize-text.rl" - { - tok = p; -} - break; - case 4: + + tok = p; + } + +#line 371 "hb-buffer-deserialize-text.hh" + + + break; + } + case 4: { + { +#line 51 "hb-buffer-deserialize-text.rl" + + tok = p; + } + +#line 383 "hb-buffer-deserialize-text.hh" + + { #line 55 "hb-buffer-deserialize-text.rl" - { - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 9: -#line 62 "hb-buffer-deserialize-text.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } + if (unlikely (!buffer->ensure_glyphs ())) return false; } + +#line 389 "hb-buffer-deserialize-text.hh" + + + break; + } + case 2: { + { +#line 51 "hb-buffer-deserialize-text.rl" + + tok = p; + } + +#line 401 "hb-buffer-deserialize-text.hh" + + { +#line 56 "hb-buffer-deserialize-text.rl" + if (unlikely (!buffer->ensure_unicode ())) return false; } + +#line 407 "hb-buffer-deserialize-text.hh" + + + break; + } + case 16: { + { +#line 58 "hb-buffer-deserialize-text.rl" + + /* TODO Unescape delimeters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; + } + +#line 423 "hb-buffer-deserialize-text.hh" + + { #line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 11: -#line 64 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + +#line 435 "hb-buffer-deserialize-text.hh" + + + break; + } + case 7: { + { +#line 66 "hb-buffer-deserialize-text.rl" + if (!parse_hex (tok, p, &info.codepoint )) return false; } + +#line 445 "hb-buffer-deserialize-text.hh" + + { #line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 6: -#line 65 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + +#line 457 "hb-buffer-deserialize-text.hh" + + + break; + } + case 10: { + { +#line 68 "hb-buffer-deserialize-text.rl" + if (!parse_uint (tok, p, &info.cluster )) return false; } + +#line 467 "hb-buffer-deserialize-text.hh" + + { #line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 8: -#line 66 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.y_advance)) return false; } + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + +#line 479 "hb-buffer-deserialize-text.hh" + + + break; + } + case 22: { + { +#line 70 "hb-buffer-deserialize-text.rl" + if (!parse_int (tok, p, &pos.y_offset )) return false; } + +#line 489 "hb-buffer-deserialize-text.hh" + + { #line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; -#line 480 "hb-buffer-deserialize-text.hh" - } - -_again: - if ( cs == 0 ) - goto _out; - if ( ++p != pe ) - goto _resume; - _test_eof: {} - if ( p == eof ) - { - switch ( _deserialize_text_eof_actions[cs] ) { - case 4: -#line 55 "hb-buffer-deserialize-text.rl" - { - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + +#line 501 "hb-buffer-deserialize-text.hh" + + + break; + } + case 19: { + { +#line 71 "hb-buffer-deserialize-text.rl" + if (!parse_int (tok, p, &pos.x_advance)) return false; } + +#line 511 "hb-buffer-deserialize-text.hh" + + { #line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 9: -#line 62 "hb-buffer-deserialize-text.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + +#line 523 "hb-buffer-deserialize-text.hh" + + + break; + } + case 24: { + { +#line 72 "hb-buffer-deserialize-text.rl" + if (!parse_int (tok, p, &pos.y_advance)) return false; } + +#line 533 "hb-buffer-deserialize-text.hh" + + { #line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 11: -#line 64 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + +#line 545 "hb-buffer-deserialize-text.hh" + + + break; + } + case 12: { + { +#line 38 "hb-buffer-deserialize-text.rl" + + memset (&info, 0, sizeof (info)); + memset (&pos , 0, sizeof (pos )); + } + +#line 558 "hb-buffer-deserialize-text.hh" + + { +#line 51 "hb-buffer-deserialize-text.rl" + + tok = p; + } + +#line 566 "hb-buffer-deserialize-text.hh" + + { +#line 55 "hb-buffer-deserialize-text.rl" + if (unlikely (!buffer->ensure_glyphs ())) return false; } + +#line 572 "hb-buffer-deserialize-text.hh" + + + break; + } + case 14: { + { +#line 38 "hb-buffer-deserialize-text.rl" + + memset (&info, 0, sizeof (info)); + memset (&pos , 0, sizeof (pos )); + } + +#line 585 "hb-buffer-deserialize-text.hh" + + { +#line 51 "hb-buffer-deserialize-text.rl" + + tok = p; + } + +#line 593 "hb-buffer-deserialize-text.hh" + + { +#line 58 "hb-buffer-deserialize-text.rl" + + /* TODO Unescape delimeters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; + } + +#line 605 "hb-buffer-deserialize-text.hh" + + + break; + } + case 17: { + { +#line 58 "hb-buffer-deserialize-text.rl" + + /* TODO Unescape delimeters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; + } + +#line 621 "hb-buffer-deserialize-text.hh" + + { +#line 55 "hb-buffer-deserialize-text.rl" + if (unlikely (!buffer->ensure_glyphs ())) return false; } + +#line 627 "hb-buffer-deserialize-text.hh" + + { #line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 6: -#line 65 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + +#line 639 "hb-buffer-deserialize-text.hh" + + + break; + } + case 11: { + { +#line 38 "hb-buffer-deserialize-text.rl" + + memset (&info, 0, sizeof (info)); + memset (&pos , 0, sizeof (pos )); + } + +#line 652 "hb-buffer-deserialize-text.hh" + + { +#line 51 "hb-buffer-deserialize-text.rl" + + tok = p; + } + +#line 660 "hb-buffer-deserialize-text.hh" + + { +#line 58 "hb-buffer-deserialize-text.rl" + + /* TODO Unescape delimeters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; + } + +#line 672 "hb-buffer-deserialize-text.hh" + + { #line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 8: -#line 66 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.y_advance)) return false; } + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + +#line 684 "hb-buffer-deserialize-text.hh" + + + break; + } + case 13: { + { +#line 38 "hb-buffer-deserialize-text.rl" + + memset (&info, 0, sizeof (info)); + memset (&pos , 0, sizeof (pos )); + } + +#line 697 "hb-buffer-deserialize-text.hh" + + { +#line 51 "hb-buffer-deserialize-text.rl" + + tok = p; + } + +#line 705 "hb-buffer-deserialize-text.hh" + + { +#line 58 "hb-buffer-deserialize-text.rl" + + /* TODO Unescape delimeters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; + } + +#line 717 "hb-buffer-deserialize-text.hh" + + { +#line 55 "hb-buffer-deserialize-text.rl" + if (unlikely (!buffer->ensure_glyphs ())) return false; } + +#line 723 "hb-buffer-deserialize-text.hh" + + { #line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; -#line 557 "hb-buffer-deserialize-text.hh" - } - } - - _out: {} + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + +#line 735 "hb-buffer-deserialize-text.hh" + + + break; + } + } + + } + + if ( p == eof ) { + if ( cs >= 19 ) + goto _out; + } + else { + if ( cs != 0 ) { + p += 1; + goto _resume; + } + } + _out: {} } - -#line 119 "hb-buffer-deserialize-text.rl" - - - *end_ptr = p; - - return p == pe && *(p-1) != ']'; + +#line 138 "hb-buffer-deserialize-text.rl" + + + *end_ptr = p; + + return p == pe && *(p-1) != ']'; } #endif /* HB_BUFFER_DESERIALIZE_TEXT_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text.rl b/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text.rl deleted file mode 100644 index 6268a6c503..0000000000 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text.rl +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright © 2013 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ - -#ifndef HB_BUFFER_DESERIALIZE_TEXT_HH -#define HB_BUFFER_DESERIALIZE_TEXT_HH - -#include "hb.hh" - -%%{ - -machine deserialize_text; -alphtype unsigned char; -write data; - -action clear_item { - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); -} - -action add_item { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - -action tok { - tok = p; -} - -action parse_glyph { - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} - -action parse_cluster { if (!parse_uint (tok, p, &info.cluster )) return false; } -action parse_x_offset { if (!parse_int (tok, p, &pos.x_offset )) return false; } -action parse_y_offset { if (!parse_int (tok, p, &pos.y_offset )) return false; } -action parse_x_advance { if (!parse_int (tok, p, &pos.x_advance)) return false; } -action parse_y_advance { if (!parse_int (tok, p, &pos.y_advance)) return false; } - -unum = '0' | [1-9] digit*; -num = '-'? unum; - -glyph_id = unum; -glyph_name = alpha (alnum|'_'|'.'|'-')*; - -glyph = (glyph_id | glyph_name) >tok %parse_glyph; -cluster = '=' (unum >tok %parse_cluster); -offsets = '@' (num >tok %parse_x_offset) ',' (num >tok %parse_y_offset ); -advances= '+' (num >tok %parse_x_advance) (',' (num >tok %parse_y_advance))?; -item = - ( - glyph - cluster? - offsets? - advances? - ) - >clear_item - %add_item - ; - -main := space* item (space* '|' space* item)* space* ('|'|']')?; - -}%% - -static hb_bool_t -_hb_buffer_deserialize_glyphs_text (hb_buffer_t *buffer, - const char *buf, - unsigned int buf_len, - const char **end_ptr, - hb_font_t *font) -{ - const char *p = buf, *pe = buf + buf_len; - - /* Ensure we have positions. */ - (void) hb_buffer_get_glyph_positions (buffer, nullptr); - - while (p < pe && ISSPACE (*p)) - p++; - if (p < pe && *p == (buffer->len ? '|' : '[')) - { - *end_ptr = ++p; - } - - const char *eof = pe, *tok = nullptr; - int cs; - hb_glyph_info_t info = {0}; - hb_glyph_position_t pos = {0}; - %%{ - write init; - write exec; - }%% - - *end_ptr = p; - - return p == pe && *(p-1) != ']'; -} - -#endif /* HB_BUFFER_DESERIALIZE_TEXT_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc index e64eb0ee65..6539b89640 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc @@ -91,26 +91,26 @@ hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format) { switch ((unsigned) format) { - case HB_BUFFER_SERIALIZE_FORMAT_TEXT: return serialize_formats[0]; - case HB_BUFFER_SERIALIZE_FORMAT_JSON: return serialize_formats[1]; + case HB_BUFFER_SERIALIZE_FORMAT_TEXT: return serialize_formats[0]; + case HB_BUFFER_SERIALIZE_FORMAT_JSON: return serialize_formats[1]; default: - case HB_BUFFER_SERIALIZE_FORMAT_INVALID: return nullptr; + case HB_BUFFER_SERIALIZE_FORMAT_INVALID: return nullptr; } } static unsigned int _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer, - unsigned int start, - unsigned int end, - char *buf, - unsigned int buf_size, - unsigned int *buf_consumed, - hb_font_t *font, - hb_buffer_serialize_flags_t flags) + unsigned int start, + unsigned int end, + char *buf, + unsigned int buf_size, + unsigned int *buf_consumed, + hb_font_t *font, + hb_buffer_serialize_flags_t flags) { hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr); hb_glyph_position_t *pos = (flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS) ? - nullptr : hb_buffer_get_glyph_positions (buffer, nullptr); + nullptr : hb_buffer_get_glyph_positions (buffer, nullptr); *buf_consumed = 0; hb_position_t x = 0, y = 0; @@ -125,6 +125,8 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer, if (i) *p++ = ','; + else + *p++ = '['; *p++ = '{'; @@ -134,8 +136,9 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer, char g[128]; hb_font_glyph_to_string (font, info[i].codepoint, g, sizeof (g)); *p++ = '"'; - for (char *q = g; *q; q++) { - if (*q == '"') + for (char *q = g; *q; q++) + { + if (unlikely (*q == '"' || *q == '\\')) *p++ = '\\'; *p++ = *q; } @@ -151,16 +154,16 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer, if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS)) { p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d", - x+pos[i].x_offset, y+pos[i].y_offset)); + x+pos[i].x_offset, y+pos[i].y_offset)); if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES)) - p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d", - pos[i].x_advance, pos[i].y_advance)); + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d", + pos[i].x_advance, pos[i].y_advance)); } if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS) { if (info[i].mask & HB_GLYPH_FLAG_DEFINED) - p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"fl\":%u", info[i].mask & HB_GLYPH_FLAG_DEFINED)); + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"fl\":%u", info[i].mask & HB_GLYPH_FLAG_DEFINED)); } if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS) @@ -168,12 +171,14 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer, hb_glyph_extents_t extents; hb_font_get_glyph_extents(font, info[i].codepoint, &extents); p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d", - extents.x_bearing, extents.y_bearing)); + extents.x_bearing, extents.y_bearing)); p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d", - extents.width, extents.height)); + extents.width, extents.height)); } *p++ = '}'; + if (i == end-1) + *p++ = ']'; unsigned int l = p - b; if (buf_size > l) @@ -197,18 +202,71 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer, } static unsigned int +_hb_buffer_serialize_unicode_json (hb_buffer_t *buffer, + unsigned int start, + unsigned int end, + char *buf, + unsigned int buf_size, + unsigned int *buf_consumed, + hb_buffer_serialize_flags_t flags) +{ + hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr); + + *buf_consumed = 0; + for (unsigned int i = start; i < end; i++) + { + char b[1024]; + char *p = b; + + if (i) + *p++ = ','; + else + *p++ = '['; + + *p++ = '{'; + + APPEND ("\"u\":"); + + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint)); + + if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) { + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster)); + } + + *p++ = '}'; + + if (i == end-1) + *p++ = ']'; + + unsigned int l = p - b; + if (buf_size > l) + { + memcpy (buf, b, l); + buf += l; + buf_size -= l; + *buf_consumed += l; + *buf = '\0'; + } else + return i - start; + + } + + return end - start; +} + +static unsigned int _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, - unsigned int start, - unsigned int end, - char *buf, - unsigned int buf_size, - unsigned int *buf_consumed, - hb_font_t *font, - hb_buffer_serialize_flags_t flags) + unsigned int start, + unsigned int end, + char *buf, + unsigned int buf_size, + unsigned int *buf_consumed, + hb_font_t *font, + hb_buffer_serialize_flags_t flags) { hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr); hb_glyph_position_t *pos = (flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS) ? - nullptr : hb_buffer_get_glyph_positions (buffer, nullptr); + nullptr : hb_buffer_get_glyph_positions (buffer, nullptr); *buf_consumed = 0; hb_position_t x = 0, y = 0; @@ -221,9 +279,12 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, if (i) *p++ = '|'; + else + *p++ = '['; if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES)) { + /* TODO Escape delimiters we use. */ hb_font_glyph_to_string (font, info[i].codepoint, p, 128); p += strlen (p); } @@ -237,21 +298,21 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS)) { if (x+pos[i].x_offset || y+pos[i].y_offset) - p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", x+pos[i].x_offset, y+pos[i].y_offset)); + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", x+pos[i].x_offset, y+pos[i].y_offset)); if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES)) { - *p++ = '+'; - p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance)); - if (pos[i].y_advance) - p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance)); + *p++ = '+'; + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance)); + if (pos[i].y_advance) + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance)); } } if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS) { if (info[i].mask & HB_GLYPH_FLAG_DEFINED) - p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "#%X", info[i].mask &HB_GLYPH_FLAG_DEFINED)); + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "#%X", info[i].mask &HB_GLYPH_FLAG_DEFINED)); } if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS) @@ -261,6 +322,10 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "<%d,%d,%d,%d>", extents.x_bearing, extents.y_bearing, extents.width, extents.height)); } + if (i == end-1) { + *p++ = ']'; + } + unsigned int l = p - b; if (buf_size > l) { @@ -282,6 +347,51 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, return end - start; } + +static unsigned int +_hb_buffer_serialize_unicode_text (hb_buffer_t *buffer, + unsigned int start, + unsigned int end, + char *buf, + unsigned int buf_size, + unsigned int *buf_consumed, + hb_buffer_serialize_flags_t flags) +{ + hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr); + *buf_consumed = 0; + for (unsigned int i = start; i < end; i++) + { + char b[1024]; + char *p = b; + + if (i) + *p++ = '|'; + else + *p++ = '<'; + + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "U+%04X", info[i].codepoint)); + + if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) { + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster)); + } + + if (i == end-1) + *p++ = '>'; + + unsigned int l = p - b; + if (buf_size > l) + { + memcpy (buf, b, l); + buf += l; + buf_size -= l; + *buf_consumed += l; + *buf = '\0'; + } else + return i - start; + } + return end - start; +} + /** * hb_buffer_serialize_glyphs: * @buffer: an #hb_buffer_t buffer. @@ -290,8 +400,8 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, * @buf: (out) (array length=buf_size) (element-type uint8_t): output string to * write serialized buffer into. * @buf_size: the size of @buf. - * @buf_consumed: (out) (allow-none): if not %NULL, will be set to the number of byes written into @buf. - * @font: (allow-none): the #hb_font_t used to shape this buffer, needed to + * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of byes written into @buf. + * @font: (nullable): the #hb_font_t used to shape this buffer, needed to * read glyph names and extents. If %NULL, and empty font will be used. * @format: the #hb_buffer_serialize_format_t to use for formatting the output. * @flags: the #hb_buffer_serialize_flags_t that control what glyph properties @@ -308,6 +418,7 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, * ``` * [uni0651=0@518,0+0|uni0628=0+1897] * ``` + * * - The serialized glyphs are delimited with `[` and `]`. * - Glyphs are separated with `|` * - Each glyph starts with glyph name, or glyph index if @@ -316,12 +427,28 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, * - If #HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS is not set, the #hb_glyph_position_t in the format: * - If both #hb_glyph_position_t.x_offset and #hb_glyph_position_t.y_offset are not 0, `@x_offset,y_offset`. Then, * - `+x_advance`, then `,y_advance` if #hb_glyph_position_t.y_advance is not 0. Then, - * - If #HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS is set, the - * #hb_glyph_extents_t in the format - * `<x_bearing,y_bearing,width,height>` + * - If #HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS is set, the #hb_glyph_extents_t in the format `<x_bearing,y_bearing,width,height>` * * ## json - * TODO. + * A machine-readable, structured format. + * The serialized glyphs will look something like: + * + * ``` + * [{"g":"uni0651","cl":0,"dx":518,"dy":0,"ax":0,"ay":0}, + * {"g":"uni0628","cl":0,"dx":0,"dy":0,"ax":1897,"ay":0}] + * ``` + * + * Each glyph is a JSON object, with the following properties: + * - `g`: the glyph name or glyph index if + * #HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES flag is set. + * - `cl`: #hb_glyph_info_t.cluster if + * #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set. + * - `dx`,`dy`,`ax`,`ay`: #hb_glyph_position_t.x_offset, #hb_glyph_position_t.y_offset, + * #hb_glyph_position_t.x_advance and #hb_glyph_position_t.y_advance + * respectively, if #HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS is not set. + * - `xb`,`yb`,`w`,`h`: #hb_glyph_extents_t.x_bearing, #hb_glyph_extents_t.y_bearing, + * #hb_glyph_extents_t.width and #hb_glyph_extents_t.height respectively if + * #HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS is set. * * Return value: * The number of serialized items. @@ -330,16 +457,17 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, **/ unsigned int hb_buffer_serialize_glyphs (hb_buffer_t *buffer, - unsigned int start, - unsigned int end, - char *buf, - unsigned int buf_size, - unsigned int *buf_consumed, - hb_font_t *font, - hb_buffer_serialize_format_t format, - hb_buffer_serialize_flags_t flags) + unsigned int start, + unsigned int end, + char *buf, + unsigned int buf_size, + unsigned int *buf_consumed, + hb_font_t *font, + hb_buffer_serialize_format_t format, + hb_buffer_serialize_flags_t flags) { - assert (start <= end && end <= buffer->len); + end = hb_clamp (end, start, buffer->len); + start = hb_min (start, end); unsigned int sconsumed; if (!buf_consumed) @@ -348,8 +476,7 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer, if (buf_size) *buf = '\0'; - assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) || - buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS); + buffer->assert_glyphs (); if (!buffer->have_positions) flags |= HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS; @@ -364,13 +491,106 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer, { case HB_BUFFER_SERIALIZE_FORMAT_TEXT: return _hb_buffer_serialize_glyphs_text (buffer, start, end, - buf, buf_size, buf_consumed, - font, flags); + buf, buf_size, buf_consumed, + font, flags); case HB_BUFFER_SERIALIZE_FORMAT_JSON: return _hb_buffer_serialize_glyphs_json (buffer, start, end, - buf, buf_size, buf_consumed, - font, flags); + buf, buf_size, buf_consumed, + font, flags); + + default: + case HB_BUFFER_SERIALIZE_FORMAT_INVALID: + return 0; + + } +} + +/** + * hb_buffer_serialize_unicode: + * @buffer: an #hb_buffer_t buffer. + * @start: the first item in @buffer to serialize. + * @end: the last item in @buffer to serialize. + * @buf: (out) (array length=buf_size) (element-type uint8_t): output string to + * write serialized buffer into. + * @buf_size: the size of @buf. + * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of byes written into @buf. + * @format: the #hb_buffer_serialize_format_t to use for formatting the output. + * @flags: the #hb_buffer_serialize_flags_t that control what glyph properties + * to serialize. + * + * Serializes @buffer into a textual representation of its content, + * when the buffer contains Unicode codepoints (i.e., before shaping). This is + * useful for showing the contents of the buffer, for example during debugging. + * There are currently two supported serialization formats: + * + * ## text + * A human-readable, plain text format. + * The serialized codepoints will look something like: + * + * ``` + * <U+0651=0|U+0628=1> + * ``` + * + * - Glyphs are separated with `|` + * - Unicode codepoints are expressed as zero-padded four (or more) + * digit hexadecimal numbers preceded by `U+` + * - If #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set, the cluster + * will be indicated with a `=` then #hb_glyph_info_t.cluster. + * + * ## json + * A machine-readable, structured format. + * The serialized codepoints will be a list of objects with the following + * properties: + * - `u`: the Unicode codepoint as a decimal integer + * - `cl`: #hb_glyph_info_t.cluster if + * #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set. + * + * For example: + * + * ``` + * [{u:1617,cl:0},{u:1576,cl:1}] + * ``` + * + * Return value: + * The number of serialized items. + * + * Since: 2.7.3 + **/ +unsigned int +hb_buffer_serialize_unicode (hb_buffer_t *buffer, + unsigned int start, + unsigned int end, + char *buf, + unsigned int buf_size, + unsigned int *buf_consumed, + hb_buffer_serialize_format_t format, + hb_buffer_serialize_flags_t flags) +{ + end = hb_clamp (end, start, buffer->len); + start = hb_min (start, end); + + unsigned int sconsumed; + if (!buf_consumed) + buf_consumed = &sconsumed; + *buf_consumed = 0; + if (buf_size) + *buf = '\0'; + + buffer->assert_unicode (); + + if (unlikely (start == end)) + return 0; + + switch (format) + { + case HB_BUFFER_SERIALIZE_FORMAT_TEXT: + return _hb_buffer_serialize_unicode_text (buffer, start, end, + buf, buf_size, buf_consumed, flags); + + case HB_BUFFER_SERIALIZE_FORMAT_JSON: + return _hb_buffer_serialize_unicode_json (buffer, start, end, + buf, buf_size, buf_consumed, flags); default: case HB_BUFFER_SERIALIZE_FORMAT_INVALID: @@ -379,6 +599,91 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer, } } +static unsigned int +_hb_buffer_serialize_invalid (hb_buffer_t *buffer, + unsigned int start, + unsigned int end, + char *buf, + unsigned int buf_size, + unsigned int *buf_consumed, + hb_buffer_serialize_format_t format, + hb_buffer_serialize_flags_t flags) +{ + assert (!buffer->len); + + unsigned int sconsumed; + if (!buf_consumed) + buf_consumed = &sconsumed; + if (buf_size < 3) + return 0; + if (format == HB_BUFFER_SERIALIZE_FORMAT_JSON) { + *buf++ = '['; + *buf++ = ']'; + *buf = '\0'; + } else if (format == HB_BUFFER_SERIALIZE_FORMAT_TEXT) { + *buf++ = '!'; + *buf++ = '!'; + *buf = '\0'; + } + *buf_consumed = 2; + return 0; +} + +/** + * hb_buffer_serialize: + * @buffer: an #hb_buffer_t buffer. + * @start: the first item in @buffer to serialize. + * @end: the last item in @buffer to serialize. + * @buf: (out) (array length=buf_size) (element-type uint8_t): output string to + * write serialized buffer into. + * @buf_size: the size of @buf. + * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of byes written into @buf. + * @font: (nullable): the #hb_font_t used to shape this buffer, needed to + * read glyph names and extents. If %NULL, and empty font will be used. + * @format: the #hb_buffer_serialize_format_t to use for formatting the output. + * @flags: the #hb_buffer_serialize_flags_t that control what glyph properties + * to serialize. + * + * Serializes @buffer into a textual representation of its content, whether + * Unicode codepoints or glyph identifiers and positioning information. This is + * useful for showing the contents of the buffer, for example during debugging. + * See the documentation of hb_buffer_serialize_unicode() and + * hb_buffer_serialize_glyphs() for a description of the output format. + * + * Return value: + * The number of serialized items. + * + * Since: 2.7.3 + **/ +unsigned int +hb_buffer_serialize (hb_buffer_t *buffer, + unsigned int start, + unsigned int end, + char *buf, + unsigned int buf_size, + unsigned int *buf_consumed, + hb_font_t *font, + hb_buffer_serialize_format_t format, + hb_buffer_serialize_flags_t flags) +{ + switch (buffer->content_type) + { + + case HB_BUFFER_CONTENT_TYPE_GLYPHS: + return hb_buffer_serialize_glyphs (buffer, start, end, buf, buf_size, + buf_consumed, font, format, flags); + + case HB_BUFFER_CONTENT_TYPE_UNICODE: + return hb_buffer_serialize_unicode (buffer, start, end, buf, buf_size, + buf_consumed, format, flags); + + case HB_BUFFER_CONTENT_TYPE_INVALID: + default: + return _hb_buffer_serialize_invalid (buffer, start, end, buf, buf_size, + buf_consumed, format, flags); + } +} + static bool parse_int (const char *pp, const char *end, int32_t *pv) { @@ -403,39 +708,59 @@ parse_uint (const char *pp, const char *end, uint32_t *pv) return true; } +static bool +parse_hex (const char *pp, const char *end, uint32_t *pv) +{ + unsigned int v; + const char *p = pp; + if (unlikely (!hb_parse_uint (&p, end, &v, true/* whole buffer */, 16))) + return false; + + *pv = v; + return true; +} + #include "hb-buffer-deserialize-json.hh" #include "hb-buffer-deserialize-text.hh" /** * hb_buffer_deserialize_glyphs: * @buffer: an #hb_buffer_t buffer. - * @buf: (array length=buf_len): - * @buf_len: - * @end_ptr: (out): - * @font: - * @format: + * @buf: (array length=buf_len): string to deserialize + * @buf_len: the size of @buf, or -1 if it is %NULL-terminated + * @end_ptr: (out) (optional): output pointer to the character after last + * consumed one. + * @font: (nullable): font for getting glyph IDs + * @format: the #hb_buffer_serialize_format_t of the input @buf * + * Deserializes glyphs @buffer from textual representation in the format + * produced by hb_buffer_serialize_glyphs(). * - * - * Return value: + * Return value: %true if @buf is not fully consumed, %false otherwise. * * Since: 0.9.7 **/ hb_bool_t hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, - const char *buf, - int buf_len, /* -1 means nul-terminated */ - const char **end_ptr, /* May be NULL */ - hb_font_t *font, /* May be NULL */ - hb_buffer_serialize_format_t format) + const char *buf, + int buf_len, /* -1 means nul-terminated */ + const char **end_ptr, /* May be NULL */ + hb_font_t *font, /* May be NULL */ + hb_buffer_serialize_format_t format) { const char *end; if (!end_ptr) end_ptr = &end; *end_ptr = buf; - assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) || - buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS); + buffer->assert_glyphs (); + + if (unlikely (hb_object_is_immutable (buffer))) + { + if (end_ptr) + *end_ptr = buf; + return false; + } if (buf_len == -1) buf_len = strlen (buf); @@ -454,14 +779,84 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, switch (format) { case HB_BUFFER_SERIALIZE_FORMAT_TEXT: - return _hb_buffer_deserialize_glyphs_text (buffer, - buf, buf_len, end_ptr, - font); + return _hb_buffer_deserialize_text (buffer, + buf, buf_len, end_ptr, + font); + + case HB_BUFFER_SERIALIZE_FORMAT_JSON: + return _hb_buffer_deserialize_json (buffer, + buf, buf_len, end_ptr, + font); + + default: + case HB_BUFFER_SERIALIZE_FORMAT_INVALID: + return false; + + } +} + + +/** + * hb_buffer_deserialize_unicode: + * @buffer: an #hb_buffer_t buffer. + * @buf: (array length=buf_len): string to deserialize + * @buf_len: the size of @buf, or -1 if it is %NULL-terminated + * @end_ptr: (out) (optional): output pointer to the character after last + * consumed one. + * @format: the #hb_buffer_serialize_format_t of the input @buf + * + * Deserializes Unicode @buffer from textual representation in the format + * produced by hb_buffer_serialize_unicode(). + * + * Return value: %true if @buf is not fully consumed, %false otherwise. + * + * Since: 2.7.3 + **/ +hb_bool_t +hb_buffer_deserialize_unicode (hb_buffer_t *buffer, + const char *buf, + int buf_len, /* -1 means nul-terminated */ + const char **end_ptr, /* May be NULL */ + hb_buffer_serialize_format_t format) +{ + const char *end; + if (!end_ptr) + end_ptr = &end; + *end_ptr = buf; + + buffer->assert_unicode (); + + if (unlikely (hb_object_is_immutable (buffer))) + { + if (end_ptr) + *end_ptr = buf; + return false; + } + + if (buf_len == -1) + buf_len = strlen (buf); + + if (!buf_len) + { + *end_ptr = buf; + return false; + } + + hb_buffer_set_content_type (buffer, HB_BUFFER_CONTENT_TYPE_UNICODE); + + hb_font_t* font = hb_font_get_empty (); + + switch (format) + { + case HB_BUFFER_SERIALIZE_FORMAT_TEXT: + return _hb_buffer_deserialize_text (buffer, + buf, buf_len, end_ptr, + font); case HB_BUFFER_SERIALIZE_FORMAT_JSON: - return _hb_buffer_deserialize_glyphs_json (buffer, - buf, buf_len, end_ptr, - font); + return _hb_buffer_deserialize_json (buffer, + buf, buf_len, end_ptr, + font); default: case HB_BUFFER_SERIALIZE_FORMAT_INVALID: diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc index 6131c86177..8cad6ab8e6 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc @@ -37,8 +37,9 @@ * @short_description: Input and output buffers * @include: hb.h * - * Buffers serve dual role in HarfBuzz; they hold the input characters that are - * passed to hb_shape(), and after shaping they hold the output glyphs. + * Buffers serve a dual role in HarfBuzz; before shaping, they hold + * the input characters that are passed to hb_shape(), and after + * shaping they hold the output glyphs. **/ @@ -50,7 +51,7 @@ * Checks the equality of two #hb_segment_properties_t's. * * Return value: - * %true if all properties of @a equal those of @b, false otherwise. + * %true if all properties of @a equal those of @b, %false otherwise. * * Since: 0.9.7 **/ @@ -217,9 +218,6 @@ hb_buffer_t::get_scratch_buffer (unsigned int *size) void hb_buffer_t::reset () { - if (unlikely (hb_object_is_immutable (this))) - return; - hb_unicode_funcs_destroy (unicode); unicode = hb_unicode_funcs_reference (hb_unicode_funcs_get_default ()); flags = HB_BUFFER_FLAG_DEFAULT; @@ -232,9 +230,6 @@ hb_buffer_t::reset () void hb_buffer_t::clear () { - if (unlikely (hb_object_is_immutable (this))) - return; - hb_segment_properties_t default_props = HB_SEGMENT_PROPERTIES_DEFAULT; props = default_props; scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT; @@ -289,9 +284,6 @@ hb_buffer_t::add_info (const hb_glyph_info_t &glyph_info) void hb_buffer_t::remove_output () { - if (unlikely (hb_object_is_immutable (this))) - return; - have_output = false; have_positions = false; @@ -302,9 +294,6 @@ hb_buffer_t::remove_output () void hb_buffer_t::clear_output () { - if (unlikely (hb_object_is_immutable (this))) - return; - have_output = true; have_positions = false; @@ -315,9 +304,6 @@ hb_buffer_t::clear_output () void hb_buffer_t::clear_positions () { - if (unlikely (hb_object_is_immutable (this))) - return; - have_output = false; have_positions = true; @@ -332,15 +318,19 @@ hb_buffer_t::swap_buffers () { if (unlikely (!successful)) return; + assert (idx <= len); + if (unlikely (!next_glyphs (len - idx))) return; + assert (have_output); have_output = false; if (out_info != info) { - hb_glyph_info_t *tmp_string; - tmp_string = info; + hb_glyph_info_t *tmp; + tmp = info; info = out_info; - out_info = tmp_string; + out_info = tmp; + pos = (hb_glyph_position_t *) out_info; } @@ -352,31 +342,6 @@ hb_buffer_t::swap_buffers () idx = 0; } - -void -hb_buffer_t::replace_glyphs (unsigned int num_in, - unsigned int num_out, - const uint32_t *glyph_data) -{ - if (unlikely (!make_room_for (num_in, num_out))) return; - - assert (idx + num_in <= len); - - merge_clusters (idx, idx + num_in); - - hb_glyph_info_t orig_info = info[idx]; - hb_glyph_info_t *pinfo = &out_info[out_len]; - for (unsigned int i = 0; i < num_out; i++) - { - *pinfo = orig_info; - pinfo->codepoint = glyph_data[i]; - pinfo++; - } - - idx += num_in; - out_len += num_out; -} - bool hb_buffer_t::move_to (unsigned int i) { @@ -438,13 +403,6 @@ hb_buffer_t::set_masks (hb_mask_t value, if (!mask) return; - if (cluster_start == 0 && cluster_end == (unsigned int)-1) { - unsigned int count = len; - for (unsigned int i = 0; i < count; i++) - info[i].mask = (info[i].mask & not_mask) | value; - return; - } - unsigned int count = len; for (unsigned int i = 0; i < count; i++) if (cluster_start <= info[i].cluster && info[i].cluster < cluster_end) @@ -455,27 +413,13 @@ void hb_buffer_t::reverse_range (unsigned int start, unsigned int end) { - unsigned int i, j; - if (end - start < 2) return; - for (i = start, j = end - 1; i < j; i++, j--) { - hb_glyph_info_t t; - - t = info[i]; - info[i] = info[j]; - info[j] = t; - } + hb_array_t<hb_glyph_info_t> (info, len).reverse (start, end); if (have_positions) { - for (i = start, j = end - 1; i < j; i++, j--) { - hb_glyph_position_t t; - - t = pos[i]; - pos[i] = pos[j]; - pos[j] = t; - } + hb_array_t<hb_glyph_position_t> (pos, len).reverse (start, end); } } @@ -612,7 +556,7 @@ done: void hb_buffer_t::unsafe_to_break_impl (unsigned int start, unsigned int end) { - unsigned int cluster = (unsigned int) -1; + unsigned int cluster = UINT_MAX; cluster = _unsafe_to_break_find_min_cluster (info, start, end, cluster); _unsafe_to_break_set_mask (info, start, end, cluster); } @@ -628,7 +572,7 @@ hb_buffer_t::unsafe_to_break_from_outbuffer (unsigned int start, unsigned int en assert (start <= out_len); assert (idx <= end); - unsigned int cluster = (unsigned int) -1; + unsigned int cluster = UINT_MAX; cluster = _unsafe_to_break_find_min_cluster (out_info, start, out_len, cluster); cluster = _unsafe_to_break_find_min_cluster (info, idx, end, cluster); _unsafe_to_break_set_mask (out_info, start, out_len, cluster); @@ -638,8 +582,7 @@ hb_buffer_t::unsafe_to_break_from_outbuffer (unsigned int start, unsigned int en void hb_buffer_t::guess_segment_properties () { - assert (content_type == HB_BUFFER_CONTENT_TYPE_UNICODE || - (!len && content_type == HB_BUFFER_CONTENT_TYPE_INVALID)); + assert_unicode (); /* If script is set to INVALID, guess from buffer contents */ if (props.script == HB_SCRIPT_INVALID) { @@ -727,21 +670,21 @@ hb_buffer_create () /** * hb_buffer_get_empty: * + * Fetches an empty #hb_buffer_t. * - * - * Return value: (transfer full): + * Return value: (transfer full): The empty buffer * * Since: 0.9.2 **/ hb_buffer_t * hb_buffer_get_empty () { - return const_cast<hb_buffer_t *> (&Null(hb_buffer_t)); + return const_cast<hb_buffer_t *> (&Null (hb_buffer_t)); } /** * hb_buffer_reference: (skip) - * @buffer: an #hb_buffer_t. + * @buffer: An #hb_buffer_t * * Increases the reference count on @buffer by one. This prevents @buffer from * being destroyed until a matching call to hb_buffer_destroy() is made. @@ -759,7 +702,7 @@ hb_buffer_reference (hb_buffer_t *buffer) /** * hb_buffer_destroy: (skip) - * @buffer: an #hb_buffer_t. + * @buffer: An #hb_buffer_t * * Deallocate the @buffer. * Decreases the reference count on @buffer by one. If the result is zero, then @@ -786,15 +729,15 @@ hb_buffer_destroy (hb_buffer_t *buffer) /** * hb_buffer_set_user_data: (skip) - * @buffer: an #hb_buffer_t. - * @key: - * @data: - * @destroy: - * @replace: + * @buffer: An #hb_buffer_t + * @key: The user-data key + * @data: A pointer to the user data + * @destroy: (nullable): A callback to call when @data is not needed anymore + * @replace: Whether to replace an existing data with the same key * + * Attaches a user-data key/data pair to the specified buffer. * - * - * Return value: + * Return value: %true if success, %false otherwise * * Since: 0.9.2 **/ @@ -810,12 +753,13 @@ hb_buffer_set_user_data (hb_buffer_t *buffer, /** * hb_buffer_get_user_data: (skip) - * @buffer: an #hb_buffer_t. - * @key: + * @buffer: An #hb_buffer_t + * @key: The user-data key to query * + * Fetches the user data associated with the specified key, + * attached to the specified buffer. * - * - * Return value: + * Return value: (transfer none): A pointer to the user data * * Since: 0.9.2 **/ @@ -829,11 +773,11 @@ hb_buffer_get_user_data (hb_buffer_t *buffer, /** * hb_buffer_set_content_type: - * @buffer: an #hb_buffer_t. - * @content_type: the type of buffer contents to set + * @buffer: An #hb_buffer_t + * @content_type: The type of buffer contents to set * - * Sets the type of @buffer contents, buffers are either empty, contain - * characters (before shaping) or glyphs (the result of shaping). + * Sets the type of @buffer contents. Buffers are either empty, contain + * characters (before shaping), or contain glyphs (the result of shaping). * * Since: 0.9.5 **/ @@ -846,12 +790,13 @@ hb_buffer_set_content_type (hb_buffer_t *buffer, /** * hb_buffer_get_content_type: - * @buffer: an #hb_buffer_t. + * @buffer: An #hb_buffer_t * - * see hb_buffer_set_content_type(). + * Fetches the type of @buffer contents. Buffers are either empty, contain + * characters (before shaping), or contain glyphs (the result of shaping). * * Return value: - * The type of @buffer contents. + * The type of @buffer contents * * Since: 0.9.5 **/ @@ -864,10 +809,11 @@ hb_buffer_get_content_type (hb_buffer_t *buffer) /** * hb_buffer_set_unicode_funcs: - * @buffer: an #hb_buffer_t. - * @unicode_funcs: - * + * @buffer: An #hb_buffer_t + * @unicode_funcs: The Unicode-functions structure * + * Sets the Unicode-functions structure of a buffer to + * @unicode_funcs. * * Since: 0.9.2 **/ @@ -888,11 +834,11 @@ hb_buffer_set_unicode_funcs (hb_buffer_t *buffer, /** * hb_buffer_get_unicode_funcs: - * @buffer: an #hb_buffer_t. + * @buffer: An #hb_buffer_t * + * Fetches the Unicode-functions structure of a buffer. * - * - * Return value: + * Return value: The Unicode-functions structure * * Since: 0.9.2 **/ @@ -904,7 +850,7 @@ hb_buffer_get_unicode_funcs (hb_buffer_t *buffer) /** * hb_buffer_set_direction: - * @buffer: an #hb_buffer_t. + * @buffer: An #hb_buffer_t * @direction: the #hb_direction_t of the @buffer * * Set the text flow direction of the buffer. No shaping can happen without @@ -930,7 +876,7 @@ hb_buffer_set_direction (hb_buffer_t *buffer, /** * hb_buffer_get_direction: - * @buffer: an #hb_buffer_t. + * @buffer: An #hb_buffer_t * * See hb_buffer_set_direction() * @@ -947,8 +893,8 @@ hb_buffer_get_direction (hb_buffer_t *buffer) /** * hb_buffer_set_script: - * @buffer: an #hb_buffer_t. - * @script: an #hb_script_t to set. + * @buffer: An #hb_buffer_t + * @script: An #hb_script_t to set. * * Sets the script of @buffer to @script. * @@ -958,7 +904,7 @@ hb_buffer_get_direction (hb_buffer_t *buffer) * * You can pass one of the predefined #hb_script_t values, or use * hb_script_from_string() or hb_script_from_iso15924_tag() to get the - * corresponding script from an ISO 15924 script tag. + * corresponding script from an ISO 15924 script tag. * * Since: 0.9.2 **/ @@ -974,12 +920,12 @@ hb_buffer_set_script (hb_buffer_t *buffer, /** * hb_buffer_get_script: - * @buffer: an #hb_buffer_t. + * @buffer: An #hb_buffer_t * - * See hb_buffer_set_script(). + * Fetches the script of @buffer. * * Return value: - * The #hb_script_t of the @buffer. + * The #hb_script_t of the @buffer * * Since: 0.9.2 **/ @@ -991,8 +937,8 @@ hb_buffer_get_script (hb_buffer_t *buffer) /** * hb_buffer_set_language: - * @buffer: an #hb_buffer_t. - * @language: an hb_language_t to set. + * @buffer: An #hb_buffer_t + * @language: An hb_language_t to set * * Sets the language of @buffer to @language. * @@ -1001,7 +947,7 @@ hb_buffer_get_script (hb_buffer_t *buffer) * are orthogonal to the scripts, and though they are related, they are * different concepts and should not be confused with each other. * - * Use hb_language_from_string() to convert from BCP 47 language tags to + * Use hb_language_from_string() to convert from BCP 47 language tags to * #hb_language_t. * * Since: 0.9.2 @@ -1018,7 +964,7 @@ hb_buffer_set_language (hb_buffer_t *buffer, /** * hb_buffer_get_language: - * @buffer: an #hb_buffer_t. + * @buffer: An #hb_buffer_t * * See hb_buffer_set_language(). * @@ -1035,8 +981,8 @@ hb_buffer_get_language (hb_buffer_t *buffer) /** * hb_buffer_set_segment_properties: - * @buffer: an #hb_buffer_t. - * @props: an #hb_segment_properties_t to use. + * @buffer: An #hb_buffer_t + * @props: An #hb_segment_properties_t to use * * Sets the segment properties of the buffer, a shortcut for calling * hb_buffer_set_direction(), hb_buffer_set_script() and @@ -1056,8 +1002,8 @@ hb_buffer_set_segment_properties (hb_buffer_t *buffer, /** * hb_buffer_get_segment_properties: - * @buffer: an #hb_buffer_t. - * @props: (out): the output #hb_segment_properties_t. + * @buffer: An #hb_buffer_t + * @props: (out): The output #hb_segment_properties_t * * Sets @props to the #hb_segment_properties_t of @buffer. * @@ -1073,8 +1019,8 @@ hb_buffer_get_segment_properties (hb_buffer_t *buffer, /** * hb_buffer_set_flags: - * @buffer: an #hb_buffer_t. - * @flags: the buffer flags to set. + * @buffer: An #hb_buffer_t + * @flags: The buffer flags to set * * Sets @buffer flags to @flags. See #hb_buffer_flags_t. * @@ -1092,12 +1038,12 @@ hb_buffer_set_flags (hb_buffer_t *buffer, /** * hb_buffer_get_flags: - * @buffer: an #hb_buffer_t. + * @buffer: An #hb_buffer_t * - * See hb_buffer_set_flags(). + * Fetches the #hb_buffer_flags_t of @buffer. * * Return value: - * The @buffer flags. + * The @buffer flags * * Since: 0.9.7 **/ @@ -1109,16 +1055,18 @@ hb_buffer_get_flags (hb_buffer_t *buffer) /** * hb_buffer_set_cluster_level: - * @buffer: an #hb_buffer_t. - * @cluster_level: - * + * @buffer: An #hb_buffer_t + * @cluster_level: The cluster level to set on the buffer * + * Sets the cluster level of a buffer. The #hb_buffer_cluster_level_t + * dictates one aspect of how HarfBuzz will treat non-base characters + * during shaping. * * Since: 0.9.42 **/ void -hb_buffer_set_cluster_level (hb_buffer_t *buffer, - hb_buffer_cluster_level_t cluster_level) +hb_buffer_set_cluster_level (hb_buffer_t *buffer, + hb_buffer_cluster_level_t cluster_level) { if (unlikely (hb_object_is_immutable (buffer))) return; @@ -1128,11 +1076,13 @@ hb_buffer_set_cluster_level (hb_buffer_t *buffer, /** * hb_buffer_get_cluster_level: - * @buffer: an #hb_buffer_t. - * + * @buffer: An #hb_buffer_t * + * Fetches the cluster level of a buffer. The #hb_buffer_cluster_level_t + * dictates one aspect of how HarfBuzz will treat non-base characters + * during shaping. * - * Return value: + * Return value: The cluster level of @buffer * * Since: 0.9.42 **/ @@ -1145,13 +1095,13 @@ hb_buffer_get_cluster_level (hb_buffer_t *buffer) /** * hb_buffer_set_replacement_codepoint: - * @buffer: an #hb_buffer_t. + * @buffer: An #hb_buffer_t * @replacement: the replacement #hb_codepoint_t * * Sets the #hb_codepoint_t that replaces invalid entries for a given encoding * when adding text to @buffer. * - * Default is %HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT. + * Default is #HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT. * * Since: 0.9.31 **/ @@ -1167,12 +1117,13 @@ hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer, /** * hb_buffer_get_replacement_codepoint: - * @buffer: an #hb_buffer_t. + * @buffer: An #hb_buffer_t * - * See hb_buffer_set_replacement_codepoint(). + * Fetches the #hb_codepoint_t that replaces invalid entries for a given encoding + * when adding text to @buffer. * * Return value: - * The @buffer replacement #hb_codepoint_t. + * The @buffer replacement #hb_codepoint_t * * Since: 0.9.31 **/ @@ -1185,7 +1136,7 @@ hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer) /** * hb_buffer_set_invisible_glyph: - * @buffer: an #hb_buffer_t. + * @buffer: An #hb_buffer_t * @invisible: the invisible #hb_codepoint_t * * Sets the #hb_codepoint_t that replaces invisible characters in @@ -1207,12 +1158,12 @@ hb_buffer_set_invisible_glyph (hb_buffer_t *buffer, /** * hb_buffer_get_invisible_glyph: - * @buffer: an #hb_buffer_t. + * @buffer: An #hb_buffer_t * * See hb_buffer_set_invisible_glyph(). * * Return value: - * The @buffer invisible #hb_codepoint_t. + * The @buffer invisible #hb_codepoint_t * * Since: 2.0.0 **/ @@ -1225,7 +1176,7 @@ hb_buffer_get_invisible_glyph (hb_buffer_t *buffer) /** * hb_buffer_reset: - * @buffer: an #hb_buffer_t. + * @buffer: An #hb_buffer_t * * Resets the buffer to its initial status, as if it was just newly created * with hb_buffer_create(). @@ -1235,12 +1186,15 @@ hb_buffer_get_invisible_glyph (hb_buffer_t *buffer) void hb_buffer_reset (hb_buffer_t *buffer) { + if (unlikely (hb_object_is_immutable (buffer))) + return; + buffer->reset (); } /** * hb_buffer_clear_contents: - * @buffer: an #hb_buffer_t. + * @buffer: An #hb_buffer_t * * Similar to hb_buffer_reset(), but does not clear the Unicode functions and * the replacement code point. @@ -1250,18 +1204,21 @@ hb_buffer_reset (hb_buffer_t *buffer) void hb_buffer_clear_contents (hb_buffer_t *buffer) { + if (unlikely (hb_object_is_immutable (buffer))) + return; + buffer->clear (); } /** * hb_buffer_pre_allocate: - * @buffer: an #hb_buffer_t. - * @size: number of items to pre allocate. + * @buffer: An #hb_buffer_t + * @size: Number of items to pre allocate. * * Pre allocates memory for @buffer to fit at least @size number of items. * * Return value: - * %true if @buffer memory allocation succeeded, %false otherwise. + * %true if @buffer memory allocation succeeded, %false otherwise * * Since: 0.9.2 **/ @@ -1273,7 +1230,7 @@ hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size) /** * hb_buffer_allocation_successful: - * @buffer: an #hb_buffer_t. + * @buffer: An #hb_buffer_t * * Check if allocating memory for the buffer succeeded. * @@ -1290,9 +1247,9 @@ hb_buffer_allocation_successful (hb_buffer_t *buffer) /** * hb_buffer_add: - * @buffer: an #hb_buffer_t. - * @codepoint: a Unicode code point. - * @cluster: the cluster value of @codepoint. + * @buffer: An #hb_buffer_t + * @codepoint: A Unicode code point. + * @cluster: The cluster value of @codepoint. * * Appends a character with the Unicode value of @codepoint to @buffer, and * gives it the initial cluster value of @cluster. Clusters can be any thing @@ -1316,8 +1273,8 @@ hb_buffer_add (hb_buffer_t *buffer, /** * hb_buffer_set_length: - * @buffer: an #hb_buffer_t. - * @length: the new length of @buffer. + * @buffer: An #hb_buffer_t + * @length: The new length of @buffer * * Similar to hb_buffer_pre_allocate(), but clears any new items added at the * end. @@ -1334,7 +1291,7 @@ hb_buffer_set_length (hb_buffer_t *buffer, if (unlikely (hb_object_is_immutable (buffer))) return length == 0; - if (!buffer->ensure (length)) + if (unlikely (!buffer->ensure (length))) return false; /* Wipe the new space */ @@ -1358,7 +1315,7 @@ hb_buffer_set_length (hb_buffer_t *buffer, /** * hb_buffer_get_length: - * @buffer: an #hb_buffer_t. + * @buffer: An #hb_buffer_t * * Returns the number of items in the buffer. * @@ -1376,8 +1333,8 @@ hb_buffer_get_length (hb_buffer_t *buffer) /** * hb_buffer_get_glyph_infos: - * @buffer: an #hb_buffer_t. - * @length: (out): output array length. + * @buffer: An #hb_buffer_t + * @length: (out): The output-array length. * * Returns @buffer glyph information array. Returned pointer * is valid as long as @buffer contents are not modified. @@ -1400,8 +1357,8 @@ hb_buffer_get_glyph_infos (hb_buffer_t *buffer, /** * hb_buffer_get_glyph_positions: - * @buffer: an #hb_buffer_t. - * @length: (out): output length. + * @buffer: An #hb_buffer_t + * @length: (out): The output length * * Returns @buffer glyph position array. Returned pointer * is valid as long as @buffer contents are not modified. @@ -1426,13 +1383,32 @@ hb_buffer_get_glyph_positions (hb_buffer_t *buffer, } /** + * hb_buffer_has_positions: + * @buffer: an #hb_buffer_t. + * + * Returns whether @buffer has glyph position data. + * A buffer gains position data when hb_buffer_get_glyph_positions() is called on it, + * and cleared of position data when hb_buffer_clear_contents() is called. + * + * Return value: + * %true if the @buffer has position array, %false otherwise. + * + * Since: 2.7.3 + **/ +HB_EXTERN hb_bool_t +hb_buffer_has_positions (hb_buffer_t *buffer) +{ + return buffer->have_positions; +} + +/** * hb_glyph_info_get_glyph_flags: - * @info: a #hb_glyph_info_t. + * @info: a #hb_glyph_info_t * * Returns glyph flags encoded within a #hb_glyph_info_t. * * Return value: - * The #hb_glyph_flags_t encoded within @info. + * The #hb_glyph_flags_t encoded within @info * * Since: 1.5.0 **/ @@ -1444,7 +1420,7 @@ hb_glyph_flags_t /** * hb_buffer_reverse: - * @buffer: an #hb_buffer_t. + * @buffer: An #hb_buffer_t * * Reverses buffer contents. * @@ -1458,11 +1434,11 @@ hb_buffer_reverse (hb_buffer_t *buffer) /** * hb_buffer_reverse_range: - * @buffer: an #hb_buffer_t. - * @start: start index. - * @end: end index. + * @buffer: An #hb_buffer_t + * @start: start index + * @end: end index * - * Reverses buffer contents between start to end. + * Reverses buffer contents between @start and @end. * * Since: 0.9.41 **/ @@ -1475,7 +1451,7 @@ hb_buffer_reverse_range (hb_buffer_t *buffer, /** * hb_buffer_reverse_clusters: - * @buffer: an #hb_buffer_t. + * @buffer: An #hb_buffer_t * * Reverses buffer clusters. That is, the buffer contents are * reversed, then each cluster (consecutive items having the @@ -1491,24 +1467,24 @@ hb_buffer_reverse_clusters (hb_buffer_t *buffer) /** * hb_buffer_guess_segment_properties: - * @buffer: an #hb_buffer_t. + * @buffer: An #hb_buffer_t * * Sets unset buffer segment properties based on buffer Unicode * contents. If buffer is not empty, it must have content type - * %HB_BUFFER_CONTENT_TYPE_UNICODE. + * #HB_BUFFER_CONTENT_TYPE_UNICODE. * - * If buffer script is not set (ie. is %HB_SCRIPT_INVALID), it + * If buffer script is not set (ie. is #HB_SCRIPT_INVALID), it * will be set to the Unicode script of the first character in - * the buffer that has a script other than %HB_SCRIPT_COMMON, - * %HB_SCRIPT_INHERITED, and %HB_SCRIPT_UNKNOWN. + * the buffer that has a script other than #HB_SCRIPT_COMMON, + * #HB_SCRIPT_INHERITED, and #HB_SCRIPT_UNKNOWN. * - * Next, if buffer direction is not set (ie. is %HB_DIRECTION_INVALID), + * Next, if buffer direction is not set (ie. is #HB_DIRECTION_INVALID), * it will be set to the natural horizontal direction of the * buffer script as returned by hb_script_get_horizontal_direction(). - * If hb_script_get_horizontal_direction() returns %HB_DIRECTION_INVALID, - * then %HB_DIRECTION_LTR is used. + * If hb_script_get_horizontal_direction() returns #HB_DIRECTION_INVALID, + * then #HB_DIRECTION_LTR is used. * - * Finally, if buffer language is not set (ie. is %HB_LANGUAGE_INVALID), + * Finally, if buffer language is not set (ie. is #HB_LANGUAGE_INVALID), * it will be set to the process's default language as returned by * hb_language_get_default(). This may change in the future by * taking buffer script into consideration when choosing a language. @@ -1534,8 +1510,7 @@ hb_buffer_add_utf (hb_buffer_t *buffer, typedef typename utf_t::codepoint_t T; const hb_codepoint_t replacement = buffer->replacement; - assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE || - (!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID)); + buffer->assert_unicode (); if (unlikely (hb_object_is_immutable (buffer))) return; @@ -1546,7 +1521,10 @@ hb_buffer_add_utf (hb_buffer_t *buffer, if (item_length == -1) item_length = text_length - item_offset; - buffer->ensure (buffer->len + item_length * sizeof (T) / 4); + if (unlikely (item_length < 0 || + item_length > INT_MAX / 8 || + !buffer->ensure (buffer->len + item_length * sizeof (T) / 4))) + return; /* If buffer is empty and pre-context provided, install it. * This check is written this way, to make sure people can @@ -1594,12 +1572,12 @@ hb_buffer_add_utf (hb_buffer_t *buffer, /** * hb_buffer_add_utf8: - * @buffer: an #hb_buffer_t. - * @text: (array length=text_length) (element-type uint8_t): an array of UTF-8 + * @buffer: An #hb_buffer_t + * @text: (array length=text_length) (element-type uint8_t): An array of UTF-8 * characters to append. - * @text_length: the length of the @text, or -1 if it is %NULL terminated. - * @item_offset: the offset of the first character to add to the @buffer. - * @item_length: the number of characters to add to the @buffer, or -1 for the + * @text_length: The length of the @text, or -1 if it is %NULL terminated. + * @item_offset: The offset of the first character to add to the @buffer. + * @item_length: The number of characters to add to the @buffer, or -1 for the * end of @text (assuming it is %NULL terminated). * * See hb_buffer_add_codepoints(). @@ -1621,12 +1599,12 @@ hb_buffer_add_utf8 (hb_buffer_t *buffer, /** * hb_buffer_add_utf16: - * @buffer: an #hb_buffer_t. - * @text: (array length=text_length): an array of UTF-16 characters to append. - * @text_length: the length of the @text, or -1 if it is %NULL terminated. - * @item_offset: the offset of the first character to add to the @buffer. - * @item_length: the number of characters to add to the @buffer, or -1 for the - * end of @text (assuming it is %NULL terminated). + * @buffer: An #hb_buffer_t + * @text: (array length=text_length): An array of UTF-16 characters to append + * @text_length: The length of the @text, or -1 if it is %NULL terminated + * @item_offset: The offset of the first character to add to the @buffer + * @item_length: The number of characters to add to the @buffer, or -1 for the + * end of @text (assuming it is %NULL terminated) * * See hb_buffer_add_codepoints(). * @@ -1647,12 +1625,12 @@ hb_buffer_add_utf16 (hb_buffer_t *buffer, /** * hb_buffer_add_utf32: - * @buffer: an #hb_buffer_t. - * @text: (array length=text_length): an array of UTF-32 characters to append. - * @text_length: the length of the @text, or -1 if it is %NULL terminated. - * @item_offset: the offset of the first character to add to the @buffer. - * @item_length: the number of characters to add to the @buffer, or -1 for the - * end of @text (assuming it is %NULL terminated). + * @buffer: An #hb_buffer_t + * @text: (array length=text_length): An array of UTF-32 characters to append + * @text_length: The length of the @text, or -1 if it is %NULL terminated + * @item_offset: The offset of the first character to add to the @buffer + * @item_length: The number of characters to add to the @buffer, or -1 for the + * end of @text (assuming it is %NULL terminated) * * See hb_buffer_add_codepoints(). * @@ -1673,13 +1651,13 @@ hb_buffer_add_utf32 (hb_buffer_t *buffer, /** * hb_buffer_add_latin1: - * @buffer: an #hb_buffer_t. + * @buffer: An #hb_buffer_t * @text: (array length=text_length) (element-type uint8_t): an array of UTF-8 - * characters to append. - * @text_length: the length of the @text, or -1 if it is %NULL terminated. - * @item_offset: the offset of the first character to add to the @buffer. + * characters to append + * @text_length: the length of the @text, or -1 if it is %NULL terminated + * @item_offset: the offset of the first character to add to the @buffer * @item_length: the number of characters to add to the @buffer, or -1 for the - * end of @text (assuming it is %NULL terminated). + * end of @text (assuming it is %NULL terminated) * * Similar to hb_buffer_add_codepoints(), but allows only access to first 256 * Unicode code points that can fit in 8-bit strings. @@ -1735,10 +1713,10 @@ hb_buffer_add_codepoints (hb_buffer_t *buffer, /** * hb_buffer_append: - * @buffer: an #hb_buffer_t. - * @source: source #hb_buffer_t. + * @buffer: An #hb_buffer_t + * @source: source #hb_buffer_t * @start: start index into source buffer to copy. Use 0 to copy from start of buffer. - * @end: end index into source buffer to copy. Use (unsigned int) -1 to copy to end of buffer. + * @end: end index into source buffer to copy. Use @HB_FEATURE_GLOBAL_END to copy to end of buffer. * * Append (part of) contents of another buffer to this buffer. * @@ -1763,11 +1741,6 @@ hb_buffer_append (hb_buffer_t *buffer, if (start == end) return; - if (!buffer->len) - buffer->content_type = source->content_type; - if (!buffer->have_positions && source->have_positions) - buffer->clear_positions (); - if (buffer->len + (end - start) < buffer->len) /* Overflows. */ { buffer->successful = false; @@ -1779,6 +1752,11 @@ hb_buffer_append (hb_buffer_t *buffer, if (unlikely (!buffer->successful)) return; + if (!orig_len) + buffer->content_type = source->content_type; + if (!buffer->have_positions && source->have_positions) + buffer->clear_positions (); + memcpy (buffer->info + orig_len, source->info + start, (end - start) * sizeof (buffer->info[0])); if (buffer->have_positions) memcpy (buffer->pos + orig_len, source->pos + start, (end - start) * sizeof (buffer->pos[0])); @@ -1842,7 +1820,7 @@ normalize_glyphs_cluster (hb_buffer_t *buffer, /** * hb_buffer_normalize_glyphs: - * @buffer: an #hb_buffer_t. + * @buffer: An #hb_buffer_t * * Reorders a glyph buffer to have canonical in-cluster glyph order / position. * The resulting clusters should behave identical to pre-reordering clusters. @@ -1855,23 +1833,13 @@ void hb_buffer_normalize_glyphs (hb_buffer_t *buffer) { assert (buffer->have_positions); - assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS || - (!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID)); - bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); + buffer->assert_glyphs (); - unsigned int count = buffer->len; - if (unlikely (!count)) return; - hb_glyph_info_t *info = buffer->info; + bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); - unsigned int start = 0; - unsigned int end; - for (end = start + 1; end < count; end++) - if (info[start].cluster != info[end].cluster) { - normalize_glyphs_cluster (buffer, start, end, backward); - start = end; - } - normalize_glyphs_cluster (buffer, start, end, backward); + foreach_cluster (buffer, start, end) + normalize_glyphs_cluster (buffer, start, end, backward); } void @@ -1907,8 +1875,8 @@ hb_buffer_t::sort (unsigned int start, unsigned int end, int(*compar)(const hb_g * @dottedcircle_glyph: glyph id of U+25CC DOTTED CIRCLE, or (hb_codepont_t) -1. * @position_fuzz: allowed absolute difference in position values. * - * If dottedcircle_glyph is (hb_codepoint_t) -1 then %HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT - * and %HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT are never returned. This should be used by most + * If dottedcircle_glyph is (hb_codepoint_t) -1 then #HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT + * and #HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT are never returned. This should be used by most * callers if just comparing two buffers is needed. * * Since: 1.5.0 @@ -1998,12 +1966,12 @@ hb_buffer_diff (hb_buffer_t *buffer, #ifndef HB_NO_BUFFER_MESSAGE /** * hb_buffer_set_message_func: - * @buffer: an #hb_buffer_t. - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * + * @buffer: An #hb_buffer_t + * @func: (closure user_data) (destroy destroy) (scope notified): Callback function + * @user_data: (nullable): Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * + * Sets the implementation function for #hb_buffer_message_func_t. * * Since: 1.1.3 **/ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.h b/src/3rdparty/harfbuzz-ng/src/hb-buffer.h index d5cb746861..865ccb2273 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.h @@ -27,7 +27,7 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_H_IN +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb.h> instead." #endif @@ -59,8 +59,7 @@ HB_BEGIN_DECLS * The #hb_glyph_info_t is the structure that holds information about the * glyphs and their relation to input text. */ -typedef struct hb_glyph_info_t -{ +typedef struct hb_glyph_info_t { hb_codepoint_t codepoint; /*< private >*/ hb_mask_t mask; @@ -91,6 +90,8 @@ typedef struct hb_glyph_info_t * breaking point only. * @HB_GLYPH_FLAG_DEFINED: All the currently defined flags. * + * Flags for #hb_glyph_info_t. + * * Since: 1.5.0 */ typedef enum { /*< flags >*/ @@ -151,6 +152,11 @@ typedef struct hb_segment_properties_t { void *reserved2; } hb_segment_properties_t; +/** + * HB_SEGMENT_PROPERTIES_DEFAULT: + * + * The default #hb_segment_properties_t of of freshly created #hb_buffer_t. + */ #define HB_SEGMENT_PROPERTIES_DEFAULT {HB_DIRECTION_INVALID, \ HB_SCRIPT_INVALID, \ HB_LANGUAGE_INVALID, \ @@ -204,6 +210,8 @@ hb_buffer_get_user_data (hb_buffer_t *buffer, * @HB_BUFFER_CONTENT_TYPE_INVALID: Initial value for new buffer. * @HB_BUFFER_CONTENT_TYPE_UNICODE: The buffer contains input characters (before shaping). * @HB_BUFFER_CONTENT_TYPE_GLYPHS: The buffer contains output glyphs (after shaping). + * + * The type of #hb_buffer_t contents. */ typedef enum { HB_BUFFER_CONTENT_TYPE_INVALID = 0, @@ -289,6 +297,8 @@ hb_buffer_guess_segment_properties (hb_buffer_t *buffer); * not be inserted in the rendering of incorrect * character sequences (such at <0905 093E>). Since: 2.4 * + * Flags for #hb_buffer_t. + * * Since: 0.9.20 */ typedef enum { /*< flags >*/ @@ -315,6 +325,23 @@ hb_buffer_get_flags (hb_buffer_t *buffer); * @HB_BUFFER_CLUSTER_LEVEL_CHARACTERS: Don't group cluster values. * @HB_BUFFER_CLUSTER_LEVEL_DEFAULT: Default cluster level, * equal to @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES. + * + * Data type for holding HarfBuzz's clustering behavior options. The cluster level + * dictates one aspect of how HarfBuzz will treat non-base characters + * during shaping. + * + * In @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES, non-base + * characters are merged into the cluster of the base character that precedes them. + * + * In @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS, non-base characters are initially + * assigned their own cluster values, which are not merged into preceding base + * clusters. This allows HarfBuzz to perform additional operations like reorder + * sequences of adjacent marks. + * + * @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES is the default, because it maintains + * backward compatibility with older versions of HarfBuzz. New client programs that + * do not need to maintain such backward compatibility are recommended to use + * @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS instead of the default. * * Since: 0.9.42 */ @@ -365,7 +392,7 @@ hb_buffer_clear_contents (hb_buffer_t *buffer); HB_EXTERN hb_bool_t hb_buffer_pre_allocate (hb_buffer_t *buffer, - unsigned int size); + unsigned int size); HB_EXTERN hb_bool_t @@ -447,6 +474,9 @@ HB_EXTERN hb_glyph_position_t * hb_buffer_get_glyph_positions (hb_buffer_t *buffer, unsigned int *length); +HB_EXTERN hb_bool_t +hb_buffer_has_positions (hb_buffer_t *buffer); + HB_EXTERN void hb_buffer_normalize_glyphs (hb_buffer_t *buffer); @@ -518,6 +548,27 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer, hb_buffer_serialize_format_t format, hb_buffer_serialize_flags_t flags); +HB_EXTERN unsigned int +hb_buffer_serialize_unicode (hb_buffer_t *buffer, + unsigned int start, + unsigned int end, + char *buf, + unsigned int buf_size, + unsigned int *buf_consumed, + hb_buffer_serialize_format_t format, + hb_buffer_serialize_flags_t flags); + +HB_EXTERN unsigned int +hb_buffer_serialize (hb_buffer_t *buffer, + unsigned int start, + unsigned int end, + char *buf, + unsigned int buf_size, + unsigned int *buf_consumed, + hb_font_t *font, + hb_buffer_serialize_format_t format, + hb_buffer_serialize_flags_t flags); + HB_EXTERN hb_bool_t hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, const char *buf, @@ -526,11 +577,48 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, hb_font_t *font, hb_buffer_serialize_format_t format); +HB_EXTERN hb_bool_t +hb_buffer_deserialize_unicode (hb_buffer_t *buffer, + const char *buf, + int buf_len, + const char **end_ptr, + hb_buffer_serialize_format_t format); + + /* * Compare buffers */ +/** + * hb_buffer_diff_flags_t: + * @HB_BUFFER_DIFF_FLAG_EQUAL: equal buffers. + * @HB_BUFFER_DIFF_FLAG_CONTENT_TYPE_MISMATCH: buffers with different + * #hb_buffer_content_type_t. + * @HB_BUFFER_DIFF_FLAG_LENGTH_MISMATCH: buffers with differing length. + * @HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT: `.notdef` glyph is present in the + * reference buffer. + * @HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT: dotted circle glyph is present + * in the reference buffer. + * @HB_BUFFER_DIFF_FLAG_CODEPOINT_MISMATCH: difference in #hb_glyph_info_t.codepoint + * @HB_BUFFER_DIFF_FLAG_CLUSTER_MISMATCH: difference in #hb_glyph_info_t.cluster + * @HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH: difference in #hb_glyph_flags_t. + * @HB_BUFFER_DIFF_FLAG_POSITION_MISMATCH: difference in #hb_glyph_position_t. + * + * Flags from comparing two #hb_buffer_t's. + * + * Buffer with different #hb_buffer_content_type_t cannot be meaningfully + * compared in any further detail. + * + * For buffers with differing length, the per-glyph comparison is not + * attempted, though we do still scan reference buffer for dotted circle and + * `.notdef` glyphs. + * + * If the buffers have the same length, we compare them glyph-by-glyph and + * report which aspect(s) of the glyph info/position are different. + * + * Since: 1.5.0 + */ typedef enum { /*< flags >*/ HB_BUFFER_DIFF_FLAG_EQUAL = 0x0000, @@ -570,6 +658,23 @@ hb_buffer_diff (hb_buffer_t *buffer, * Debugging. */ +/** + * hb_buffer_message_func_t: + * @buffer: An #hb_buffer_t to work upon + * @font: The #hb_font_t the @buffer is shaped with + * @message: %NULL-terminated message passed to the function + * @user_data: User data pointer passed by the caller + * + * A callback method for #hb_buffer_t. The method gets called with the + * #hb_buffer_t it was set on, the #hb_font_t the buffer is shaped with and a + * message describing what step of the shaping process will be performed. + * Returning %false from this method will skip this shaping step and move to + * the next one. + * + * Return value: %true to perform the shaping step, %false to skip it. + * + * Since: 1.1.3 + */ typedef hb_bool_t (*hb_buffer_message_func_t) (hb_buffer_t *buffer, hb_font_t *font, const char *message, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer.hh index b5596d9457..8b432b5f96 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.hh @@ -35,20 +35,20 @@ #ifndef HB_BUFFER_MAX_LEN_FACTOR -#define HB_BUFFER_MAX_LEN_FACTOR 32 +#define HB_BUFFER_MAX_LEN_FACTOR 64 #endif #ifndef HB_BUFFER_MAX_LEN_MIN -#define HB_BUFFER_MAX_LEN_MIN 8192 +#define HB_BUFFER_MAX_LEN_MIN 16384 #endif #ifndef HB_BUFFER_MAX_LEN_DEFAULT #define HB_BUFFER_MAX_LEN_DEFAULT 0x3FFFFFFF /* Shaping more than a billion chars? Let us know! */ #endif #ifndef HB_BUFFER_MAX_OPS_FACTOR -#define HB_BUFFER_MAX_OPS_FACTOR 64 +#define HB_BUFFER_MAX_OPS_FACTOR 1024 #endif #ifndef HB_BUFFER_MAX_OPS_MIN -#define HB_BUFFER_MAX_OPS_MIN 1024 +#define HB_BUFFER_MAX_OPS_MIN 16384 #endif #ifndef HB_BUFFER_MAX_OPS_DEFAULT #define HB_BUFFER_MAX_OPS_DEFAULT 0x1FFFFFFF /* Shaping more than a billion operations? Let us know! */ @@ -139,7 +139,7 @@ struct hb_buffer_t /* Methods */ - bool in_error () const { return !successful; } + HB_NODISCARD bool in_error () const { return !successful; } void allocate_var (unsigned int start, unsigned int count) { @@ -186,7 +186,7 @@ struct hb_buffer_t hb_glyph_info_t &prev () { return out_info[out_len ? out_len - 1 : 0]; } hb_glyph_info_t prev () const { return out_info[out_len ? out_len - 1 : 0]; } - bool has_separate_output () const { return info != out_info; } + HB_NODISCARD bool has_separate_output () const { return info != out_info; } HB_INTERNAL void reset (); @@ -210,86 +210,89 @@ struct hb_buffer_t HB_INTERNAL void clear_output (); HB_INTERNAL void clear_positions (); - HB_INTERNAL void replace_glyphs (unsigned int num_in, - unsigned int num_out, - const hb_codepoint_t *glyph_data); - - void replace_glyph (hb_codepoint_t glyph_index) + template <typename T> + HB_NODISCARD bool replace_glyphs (unsigned int num_in, + unsigned int num_out, + const T *glyph_data) { - if (unlikely (out_info != info || out_len != idx)) { - if (unlikely (!make_room_for (1, 1))) return; - out_info[out_len] = info[idx]; - } - out_info[out_len].codepoint = glyph_index; + if (unlikely (!make_room_for (num_in, num_out))) return false; - idx++; - out_len++; - } - /* Makes a copy of the glyph at idx to output and replace glyph_index */ - hb_glyph_info_t & output_glyph (hb_codepoint_t glyph_index) - { - if (unlikely (!make_room_for (0, 1))) return Crap(hb_glyph_info_t); + assert (idx + num_in <= len); - if (unlikely (idx == len && !out_len)) - return Crap(hb_glyph_info_t); + merge_clusters (idx, idx + num_in); - out_info[out_len] = idx < len ? info[idx] : out_info[out_len - 1]; - out_info[out_len].codepoint = glyph_index; + hb_glyph_info_t &orig_info = idx < len ? cur() : prev(); - out_len++; + hb_glyph_info_t *pinfo = &out_info[out_len]; + for (unsigned int i = 0; i < num_out; i++) + { + *pinfo = orig_info; + pinfo->codepoint = glyph_data[i]; + pinfo++; + } - return out_info[out_len - 1]; + idx += num_in; + out_len += num_out; + return true; } - void output_info (const hb_glyph_info_t &glyph_info) + + HB_NODISCARD bool replace_glyph (hb_codepoint_t glyph_index) + { return replace_glyphs (1, 1, &glyph_index); } + + /* Makes a copy of the glyph at idx to output and replace glyph_index */ + HB_NODISCARD bool output_glyph (hb_codepoint_t glyph_index) + { return replace_glyphs (0, 1, &glyph_index); } + + HB_NODISCARD bool output_info (const hb_glyph_info_t &glyph_info) { - if (unlikely (!make_room_for (0, 1))) return; + if (unlikely (!make_room_for (0, 1))) return false; out_info[out_len] = glyph_info; out_len++; + return true; } /* Copies glyph at idx to output but doesn't advance idx */ - void copy_glyph () + HB_NODISCARD bool copy_glyph () { - if (unlikely (!make_room_for (0, 1))) return; - - out_info[out_len] = info[idx]; - - out_len++; + /* Extra copy because cur()'s return can be freed within + * output_info() call if buffer reallocates. */ + return output_info (hb_glyph_info_t (cur())); } + /* Copies glyph at idx to output and advance idx. * If there's no output, just advance idx. */ - void - next_glyph () + HB_NODISCARD bool next_glyph () { if (have_output) { if (out_info != info || out_len != idx) { - if (unlikely (!make_room_for (1, 1))) return; + if (unlikely (!make_room_for (1, 1))) return false; out_info[out_len] = info[idx]; } out_len++; } idx++; + return true; } /* Copies n glyphs at idx to output and advance idx. * If there's no output, just advance idx. */ - void - next_glyphs (unsigned int n) + HB_NODISCARD bool next_glyphs (unsigned int n) { if (have_output) { if (out_info != info || out_len != idx) { - if (unlikely (!make_room_for (n, n))) return; + if (unlikely (!make_room_for (n, n))) return false; memmove (out_info + out_len, info + idx, n * sizeof (out_info[0])); } out_len += n; } idx += n; + return true; } /* Advance idx without copying to output. */ void skip_glyph () { idx++; } @@ -318,7 +321,7 @@ struct hb_buffer_t HB_INTERNAL void delete_glyph (); void unsafe_to_break (unsigned int start, - unsigned int end) + unsigned int end) { if (end - start < 2) return; @@ -329,18 +332,51 @@ struct hb_buffer_t /* Internal methods */ - HB_INTERNAL bool move_to (unsigned int i); /* i is output-buffer index. */ + HB_NODISCARD HB_INTERNAL bool move_to (unsigned int i); /* i is output-buffer index. */ - HB_INTERNAL bool enlarge (unsigned int size); + HB_NODISCARD HB_INTERNAL bool enlarge (unsigned int size); - bool ensure (unsigned int size) + HB_NODISCARD bool ensure (unsigned int size) { return likely (!size || size < allocated) ? true : enlarge (size); } - bool ensure_inplace (unsigned int size) + HB_NODISCARD bool ensure_inplace (unsigned int size) { return likely (!size || size < allocated); } - HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out); - HB_INTERNAL bool shift_forward (unsigned int count); + void assert_glyphs () + { + assert ((content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS) || + (!len && (content_type == HB_BUFFER_CONTENT_TYPE_INVALID))); + } + void assert_unicode () + { + assert ((content_type == HB_BUFFER_CONTENT_TYPE_UNICODE) || + (!len && (content_type == HB_BUFFER_CONTENT_TYPE_INVALID))); + } + HB_NODISCARD bool ensure_glyphs () + { + if (unlikely (content_type != HB_BUFFER_CONTENT_TYPE_GLYPHS)) + { + if (content_type != HB_BUFFER_CONTENT_TYPE_INVALID) + return false; + assert (len == 0); + content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS; + } + return true; + } + HB_NODISCARD bool ensure_unicode () + { + if (unlikely (content_type != HB_BUFFER_CONTENT_TYPE_UNICODE)) + { + if (content_type != HB_BUFFER_CONTENT_TYPE_INVALID) + return false; + assert (len == 0); + content_type = HB_BUFFER_CONTENT_TYPE_UNICODE; + } + return true; + } + + HB_NODISCARD HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out); + HB_NODISCARD HB_INTERNAL bool shift_forward (unsigned int count); typedef long scratch_buffer_t; HB_INTERNAL scratch_buffer_t *get_scratch_buffer (unsigned int *size); @@ -386,7 +422,7 @@ struct hb_buffer_t inf.cluster = cluster; } - int + unsigned int _unsafe_to_break_find_min_cluster (const hb_glyph_info_t *infos, unsigned int start, unsigned int end, unsigned int cluster) const diff --git a/src/3rdparty/harfbuzz-ng/src/hb-cff-interp-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-cff-interp-common.hh index 780f61892d..91a9b7d0d1 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-cff-interp-common.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-cff-interp-common.hh @@ -252,30 +252,27 @@ struct number_t struct UnsizedByteStr : UnsizedArrayOf <HBUINT8> { // encode 2-byte int (Dict/CharString) or 4-byte int (Dict) - template <typename INTTYPE, int minVal, int maxVal> - static bool serialize_int (hb_serialize_context_t *c, op_code_t intOp, int value) + template <typename T, typename V> + static bool serialize_int (hb_serialize_context_t *c, op_code_t intOp, V value) { TRACE_SERIALIZE (this); - if (unlikely ((value < minVal || value > maxVal))) - return_trace (false); - HBUINT8 *p = c->allocate_size<HBUINT8> (1); - if (unlikely (p == nullptr)) return_trace (false); + if (unlikely (!p)) return_trace (false); *p = intOp; - INTTYPE *ip = c->allocate_size<INTTYPE> (INTTYPE::static_size); - if (unlikely (ip == nullptr)) return_trace (false); - *ip = (unsigned int) value; - - return_trace (true); + T *ip = c->allocate_size<T> (T::static_size); + if (unlikely (!ip)) return_trace (false); + return_trace (c->check_assign (*ip, value)); } - static bool serialize_int4 (hb_serialize_context_t *c, int value) - { return serialize_int<HBUINT32, 0, 0x7FFFFFFF> (c, OpCode_longintdict, value); } + template <typename V> + static bool serialize_int4 (hb_serialize_context_t *c, V value) + { return serialize_int<HBINT32> (c, OpCode_longintdict, value); } - static bool serialize_int2 (hb_serialize_context_t *c, int value) - { return serialize_int<HBUINT16, 0, 0x7FFF> (c, OpCode_shortint, value); } + template <typename V> + static bool serialize_int2 (hb_serialize_context_t *c, V value) + { return serialize_int<HBINT16> (c, OpCode_shortint, value); } /* Defining null_size allows a Null object may be created. Should be safe because: * A descendent struct Dict uses a Null pointer to indicate a missing table, @@ -408,7 +405,7 @@ struct cff_stack_t else { set_error (); - return Crap(ELEM); + return Crap (ELEM); } } @@ -419,7 +416,7 @@ struct cff_stack_t else { set_error (); - return Crap(ELEM); + return Crap (ELEM); } } void pop (unsigned int n) @@ -435,7 +432,7 @@ struct cff_stack_t if (unlikely (count < 0)) { set_error (); - return Null(ELEM); + return Null (ELEM); } return elements[count - 1]; } @@ -542,7 +539,7 @@ struct op_serializer_t TRACE_SERIALIZE (this); HBUINT8 *d = c->allocate_size<HBUINT8> (opstr.str.length); - if (unlikely (d == nullptr)) return_trace (false); + if (unlikely (!d)) return_trace (false); memcpy (d, &opstr.str[0], opstr.str.length); return_trace (true); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-cff-interp-cs-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-cff-interp-cs-common.hh index d9ad4d0d69..52d778ffe2 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-cff-interp-cs-common.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-cff-interp-cs-common.hh @@ -76,13 +76,13 @@ struct biased_subrs_t void fini () {} - unsigned int get_count () const { return (subrs == nullptr) ? 0 : subrs->count; } + unsigned int get_count () const { return subrs ? subrs->count : 0; } unsigned int get_bias () const { return bias; } byte_str_t operator [] (unsigned int index) const { - if (unlikely ((subrs == nullptr) || index >= subrs->count)) - return Null(byte_str_t); + if (unlikely (!subrs || index >= subrs->count)) + return Null (byte_str_t); else return (*subrs)[index]; } @@ -551,8 +551,13 @@ struct path_procs_t static void rcurveline (ENV &env, PARAM& param) { + unsigned int arg_count = env.argStack.get_count (); + if (unlikely (arg_count < 8)) + return; + unsigned int i = 0; - for (; i + 6 <= env.argStack.get_count (); i += 6) + unsigned int curve_limit = arg_count - 2; + for (; i + 6 <= curve_limit; i += 6) { point_t pt1 = env.get_pt (); pt1.move (env.eval_arg (i), env.eval_arg (i+1)); @@ -562,34 +567,34 @@ struct path_procs_t pt3.move (env.eval_arg (i+4), env.eval_arg (i+5)); PATH::curve (env, param, pt1, pt2, pt3); } - for (; i + 2 <= env.argStack.get_count (); i += 2) - { - point_t pt1 = env.get_pt (); - pt1.move (env.eval_arg (i), env.eval_arg (i+1)); - PATH::line (env, param, pt1); - } + + point_t pt1 = env.get_pt (); + pt1.move (env.eval_arg (i), env.eval_arg (i+1)); + PATH::line (env, param, pt1); } static void rlinecurve (ENV &env, PARAM& param) { + unsigned int arg_count = env.argStack.get_count (); + if (unlikely (arg_count < 8)) + return; + unsigned int i = 0; - unsigned int line_limit = (env.argStack.get_count () % 6); + unsigned int line_limit = arg_count - 6; for (; i + 2 <= line_limit; i += 2) { point_t pt1 = env.get_pt (); pt1.move (env.eval_arg (i), env.eval_arg (i+1)); PATH::line (env, param, pt1); } - for (; i + 6 <= env.argStack.get_count (); i += 6) - { - point_t pt1 = env.get_pt (); - pt1.move (env.eval_arg (i), env.eval_arg (i+1)); - point_t pt2 = pt1; - pt2.move (env.eval_arg (i+2), env.eval_arg (i+3)); - point_t pt3 = pt2; - pt3.move (env.eval_arg (i+4), env.eval_arg (i+5)); - PATH::curve (env, param, pt1, pt2, pt3); - } + + point_t pt1 = env.get_pt (); + pt1.move (env.eval_arg (i), env.eval_arg (i+1)); + point_t pt2 = pt1; + pt2.move (env.eval_arg (i+2), env.eval_arg (i+3)); + point_t pt3 = pt2; + pt3.move (env.eval_arg (i+4), env.eval_arg (i+5)); + PATH::curve (env, param, pt1, pt2, pt3); } static void vvcurveto (ENV &env, PARAM& param) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-cff-interp-dict-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-cff-interp-dict-common.hh index 1f03d82399..a520ca3bce 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-cff-interp-dict-common.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-cff-interp-dict-common.hh @@ -27,8 +27,6 @@ #define HB_CFF_INTERP_DICT_COMMON_HH #include "hb-cff-interp-common.hh" -#include <math.h> -#include <float.h> namespace CFF { @@ -58,19 +56,6 @@ struct top_dict_values_t : dict_values_t<OPSTR> } void fini () { dict_values_t<OPSTR>::fini (); } - unsigned int calculate_serialized_op_size (const OPSTR& opstr) const - { - switch (opstr.op) - { - case OpCode_CharStrings: - case OpCode_FDArray: - return OpCode_Size (OpCode_longintdict) + 4 + OpCode_Size (opstr.op); - - default: - return opstr.str.length; - } - } - unsigned int charStringsOffset; unsigned int FDArrayOffset; }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-cff2-interp-cs.hh b/src/3rdparty/harfbuzz-ng/src/hb-cff2-interp-cs.hh index a72100e1ab..332ece31cd 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-cff2-interp-cs.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-cff2-interp-cs.hh @@ -52,7 +52,7 @@ struct blend_arg_t : number_t void set_real (double v) { reset_blends (); number_t::set_real (v); } void set_blends (unsigned int numValues_, unsigned int valueIndex_, - unsigned int numBlends, hb_array_t<const blend_arg_t> blends_) + unsigned int numBlends, hb_array_t<const blend_arg_t> blends_) { numValues = numValues_; valueIndex = valueIndex_; @@ -80,7 +80,7 @@ struct cff2_cs_interp_env_t : cs_interp_env_t<blend_arg_t, CFF2Subrs> { template <typename ACC> void init (const byte_str_t &str, ACC &acc, unsigned int fd, - const int *coords_=nullptr, unsigned int num_coords_=0) + const int *coords_=nullptr, unsigned int num_coords_=0) { SUPER::init (str, acc.globalSubrs, acc.privateDicts[fd].localSubrs); @@ -90,7 +90,7 @@ struct cff2_cs_interp_env_t : cs_interp_env_t<blend_arg_t, CFF2Subrs> seen_blend = false; seen_vsindex_ = false; scalars.init (); - do_blend = (coords != nullptr) && num_coords && (varStore != &Null(CFF2VariationStore)); + do_blend = num_coords && coords && varStore->size; set_ivs (acc.privateDicts[fd].ivs); } @@ -133,10 +133,11 @@ struct cff2_cs_interp_env_t : cs_interp_env_t<blend_arg_t, CFF2Subrs> region_count = varStore->varStore.get_region_index_count (get_ivs ()); if (do_blend) { - scalars.resize (region_count); - varStore->varStore.get_scalars (get_ivs (), - (int *)coords, num_coords, - &scalars[0], region_count); + if (unlikely (!scalars.resize (region_count))) + set_error (); + else + varStore->varStore.get_scalars (get_ivs (), coords, num_coords, + &scalars[0], region_count); } seen_blend = true; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-common.cc b/src/3rdparty/harfbuzz-ng/src/hb-common.cc index 0ae0c05f48..7bb878b217 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-common.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-common.cc @@ -69,7 +69,6 @@ _hb_options_init () if (0 == strncmp (c, name, p - c) && strlen (name) == static_cast<size_t>(p - c)) do { u.opts.symbol = true; } while (0) OPTION ("uniscribe-bug-compatible", uniscribe_bug_compatible); - OPTION ("aat", aat); #undef OPTION @@ -87,12 +86,15 @@ _hb_options_init () /** * hb_tag_from_string: - * @str: (array length=len) (element-type uint8_t): - * @len: + * @str: (array length=len) (element-type uint8_t): String to convert + * @len: Length of @str, or -1 if it is %NULL-terminated * + * Converts a string into an #hb_tag_t. Valid tags + * are four characters. Shorter input strings will be + * padded with spaces. Longer input strings will be + * truncated. * - * - * Return value: + * Return value: The #hb_tag_t corresponding to @str * * Since: 0.9.2 **/ @@ -117,10 +119,11 @@ hb_tag_from_string (const char *str, int len) /** * hb_tag_to_string: - * @tag: - * @buf: (out caller-allocates) (array fixed-size=4) (element-type uint8_t): - * + * @tag: #hb_tag_t to convert + * @buf: (out caller-allocates) (array fixed-size=4) (element-type uint8_t): Converted string * + * Converts an #hb_tag_t to a string and returns it in @buf. + * Strings will be four characters long. * * Since: 0.9.5 **/ @@ -145,12 +148,17 @@ const char direction_strings[][4] = { /** * hb_direction_from_string: - * @str: (array length=len) (element-type uint8_t): - * @len: + * @str: (array length=len) (element-type uint8_t): String to convert + * @len: Length of @str, or -1 if it is %NULL-terminated * + * Converts a string to an #hb_direction_t. * + * Matching is loose and applies only to the first letter. For + * examples, "LTR" and "left-to-right" will both return #HB_DIRECTION_LTR. * - * Return value: + * Unmatched strings will return #HB_DIRECTION_INVALID. + * + * Return value: The #hb_direction_t matching @str * * Since: 0.9.2 **/ @@ -173,11 +181,11 @@ hb_direction_from_string (const char *str, int len) /** * hb_direction_to_string: - * @direction: - * + * @direction: The #hb_direction_t to convert * + * Converts an #hb_direction_t to a string. * - * Return value: (transfer none): + * Return value: (transfer none): The string corresponding to @direction * * Since: 0.9.2 **/ @@ -333,14 +341,14 @@ retry: /** * hb_language_from_string: * @str: (array length=len) (element-type uint8_t): a string representing - * a BCP 47 language tag + * a BCP 47 language tag * @len: length of the @str, or -1 if it is %NULL-terminated. * - * Converts @str representing a BCP 47 language tag to the corresponding + * Converts @str representing a BCP 47 language tag to the corresponding * #hb_language_t. * * Return value: (transfer none): - * The #hb_language_t corresponding to the BCP 47 language tag. + * The #hb_language_t corresponding to the BCP 47 language tag. * * Since: 0.9.2 **/ @@ -368,9 +376,9 @@ hb_language_from_string (const char *str, int len) /** * hb_language_to_string: - * @language: an #hb_language_t to convert. + * @language: The #hb_language_t to convert * - * See hb_language_from_string(). + * Converts an #hb_language_t to a string. * * Return value: (transfer none): * A %NULL-terminated string representing the @language. Must not be freed by @@ -389,16 +397,17 @@ hb_language_to_string (hb_language_t language) /** * hb_language_get_default: * - * Get default language from current locale. + * Fetch the default language from current locale. * - * Note that the first time this function is called, it calls + * <note>Note that the first time this function is called, it calls * "setlocale (LC_CTYPE, nullptr)" to fetch current locale. The underlying * setlocale function is, in many implementations, NOT threadsafe. To avoid * problems, call this function once before multiple threads can call it. * This function is only used from hb_buffer_guess_segment_properties() by - * HarfBuzz itself. + * HarfBuzz itself.</note> * - * Return value: (transfer none): + * Return value: (transfer none): The default language of the locale as + * an #hb_language_t * * Since: 0.9.2 **/ @@ -422,12 +431,12 @@ hb_language_get_default () /** * hb_script_from_iso15924_tag: - * @tag: an #hb_tag_t representing an ISO 15924 tag. + * @tag: an #hb_tag_t representing an ISO 15924 tag. * - * Converts an ISO 15924 script tag to a corresponding #hb_script_t. + * Converts an ISO 15924 script tag to a corresponding #hb_script_t. * * Return value: - * An #hb_script_t corresponding to the ISO 15924 tag. + * An #hb_script_t corresponding to the ISO 15924 tag. * * Since: 0.9.2 **/ @@ -449,7 +458,12 @@ hb_script_from_iso15924_tag (hb_tag_t tag) case HB_TAG('Q','a','a','c'): return HB_SCRIPT_COPTIC; /* Script variants from https://unicode.org/iso15924/ */ + case HB_TAG('A','r','a','n'): return HB_SCRIPT_ARABIC; case HB_TAG('C','y','r','s'): return HB_SCRIPT_CYRILLIC; + case HB_TAG('G','e','o','k'): return HB_SCRIPT_GEORGIAN; + case HB_TAG('H','a','n','s'): return HB_SCRIPT_HAN; + case HB_TAG('H','a','n','t'): return HB_SCRIPT_HAN; + case HB_TAG('J','a','m','o'): return HB_SCRIPT_HANGUL; case HB_TAG('L','a','t','f'): return HB_SCRIPT_LATIN; case HB_TAG('L','a','t','g'): return HB_SCRIPT_LATIN; case HB_TAG('S','y','r','e'): return HB_SCRIPT_SYRIAC; @@ -468,15 +482,15 @@ hb_script_from_iso15924_tag (hb_tag_t tag) /** * hb_script_from_string: * @str: (array length=len) (element-type uint8_t): a string representing an - * ISO 15924 tag. + * ISO 15924 tag. * @len: length of the @str, or -1 if it is %NULL-terminated. * - * Converts a string @str representing an ISO 15924 script tag to a + * Converts a string @str representing an ISO 15924 script tag to a * corresponding #hb_script_t. Shorthand for hb_tag_from_string() then * hb_script_from_iso15924_tag(). * * Return value: - * An #hb_script_t corresponding to the ISO 15924 tag. + * An #hb_script_t corresponding to the ISO 15924 tag. * * Since: 0.9.2 **/ @@ -490,10 +504,10 @@ hb_script_from_string (const char *str, int len) * hb_script_to_iso15924_tag: * @script: an #hb_script_t to convert. * - * See hb_script_from_iso15924_tag(). + * Converts an #hb_script_t to a corresponding ISO 15924 script tag. * * Return value: - * An #hb_tag_t representing an ISO 15924 script tag. + * An #hb_tag_t representing an ISO 15924 script tag. * * Since: 0.9.2 **/ @@ -505,11 +519,16 @@ hb_script_to_iso15924_tag (hb_script_t script) /** * hb_script_get_horizontal_direction: - * @script: - * + * @script: The #hb_script_t to query * + * Fetches the #hb_direction_t of a script when it is + * set horizontally. All right-to-left scripts will return + * #HB_DIRECTION_RTL. All left-to-right scripts will return + * #HB_DIRECTION_LTR. Scripts that can be written either + * horizontally or vertically will return #HB_DIRECTION_INVALID. + * Unknown scripts will return #HB_DIRECTION_LTR. * - * Return value: + * Return value: The horizontal #hb_direction_t of @script * * Since: 0.9.2 **/ @@ -575,6 +594,13 @@ hb_script_get_horizontal_direction (hb_script_t script) case HB_SCRIPT_OLD_SOGDIAN: case HB_SCRIPT_SOGDIAN: + /* Unicode-12.0 additions */ + case HB_SCRIPT_ELYMAIC: + + /* Unicode-13.0 additions */ + case HB_SCRIPT_CHORASMIAN: + case HB_SCRIPT_YEZIDI: + return HB_DIRECTION_RTL; @@ -590,38 +616,6 @@ hb_script_get_horizontal_direction (hb_script_t script) } -/* hb_user_data_array_t */ - -bool -hb_user_data_array_t::set (hb_user_data_key_t *key, - void * data, - hb_destroy_func_t destroy, - hb_bool_t replace) -{ - if (!key) - return false; - - if (replace) { - if (!data && !destroy) { - items.remove (key, lock); - return true; - } - } - hb_user_data_item_t item = {key, data, destroy}; - bool ret = !!items.replace_or_insert (item, lock, (bool) replace); - - return ret; -} - -void * -hb_user_data_array_t::get (hb_user_data_key_t *key) -{ - hb_user_data_item_t item = {nullptr, nullptr, nullptr}; - - return items.find (key, &item, lock) ? item.data : nullptr; -} - - /* hb_version */ @@ -639,9 +633,9 @@ hb_user_data_array_t::get (hb_user_data_key_t *key) /** * hb_version: - * @major: (out): Library major version component. - * @minor: (out): Library minor version component. - * @micro: (out): Library micro version component. + * @major: (out): Library major version component + * @minor: (out): Library minor version component + * @micro: (out): Library micro version component * * Returns library version as three integer components. * @@ -662,7 +656,7 @@ hb_version (unsigned int *major, * * Returns library version as a string with three components. * - * Return value: library version string. + * Return value: Library version string * * Since: 0.9.2 **/ @@ -674,13 +668,15 @@ hb_version_string () /** * hb_version_atleast: - * @major: - * @minor: - * @micro: - * + * @major: Library major version component + * @minor: Library minor version component + * @micro: Library micro version component * + * Tests the library version against a minimum value, + * as three integer components. * - * Return value: + * Return value: %true if the library is equal to or greater than + * the test value, %false otherwise * * Since: 0.9.30 **/ @@ -909,7 +905,7 @@ parse_one_feature (const char **pp, const char *end, hb_feature_t *feature) * </informaltable> * * Return value: - * %true if @str is successfully parsed, %false otherwise. + * %true if @str is successfully parsed, %false otherwise * * Since: 0.9.5 **/ @@ -960,14 +956,14 @@ hb_feature_to_string (hb_feature_t *feature, len += 4; while (len && s[len - 1] == ' ') len--; - if (feature->start != 0 || feature->end != (unsigned int) -1) + if (feature->start != HB_FEATURE_GLOBAL_START || feature->end != HB_FEATURE_GLOBAL_END) { s[len++] = '['; if (feature->start) len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->start)); if (feature->end != feature->start + 1) { s[len++] = ':'; - if (feature->end != (unsigned int) -1) + if (feature->end != HB_FEATURE_GLOBAL_END) len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->end)); } s[len++] = ']'; @@ -1007,6 +1003,21 @@ parse_one_variation (const char **pp, const char *end, hb_variation_t *variation /** * hb_variation_from_string: + * @str: (array length=len) (element-type uint8_t): a string to parse + * @len: length of @str, or -1 if string is %NULL terminated + * @variation: (out): the #hb_variation_t to initialize with the parsed values + * + * Parses a string into a #hb_variation_t. + * + * The format for specifying variation settings follows. All valid CSS + * font-variation-settings values other than 'normal' and 'inherited' are also + * accepted, though, not documented below. + * + * The format is a tag, optionally followed by an equals sign, followed by a + * number. For example `wght=500`, or `slnt=-7.5`. + * + * Return value: + * %true if @str is successfully parsed, %false otherwise * * Since: 1.4.2 */ @@ -1033,6 +1044,13 @@ hb_variation_from_string (const char *str, int len, /** * hb_variation_to_string: + * @variation: an #hb_variation_t to convert + * @buf: (array length=size) (out): output string + * @size: the allocated size of @buf + * + * Converts an #hb_variation_t into a %NULL-terminated string in the format + * understood by hb_variation_from_string(). The client in responsible for + * allocating big enough size for @buf, 128 bytes is more than enough. * * Since: 1.4.2 */ @@ -1059,9 +1077,11 @@ hb_variation_to_string (hb_variation_t *variation, /** * hb_color_get_alpha: - * color: a #hb_color_t we are interested in its channels. + * @color: an #hb_color_t we are interested in its channels. + * + * Fetches the alpha channel of the given @color. * - * Return value: Alpha channel value of the given color + * Return value: Alpha channel value * * Since: 2.1.0 */ @@ -1073,9 +1093,11 @@ uint8_t /** * hb_color_get_red: - * color: a #hb_color_t we are interested in its channels. + * @color: an #hb_color_t we are interested in its channels. + * + * Fetches the red channel of the given @color. * - * Return value: Red channel value of the given color + * Return value: Red channel value * * Since: 2.1.0 */ @@ -1087,9 +1109,11 @@ uint8_t /** * hb_color_get_green: - * color: a #hb_color_t we are interested in its channels. + * @color: an #hb_color_t we are interested in its channels. * - * Return value: Green channel value of the given color + * Fetches the green channel of the given @color. + * + * Return value: Green channel value * * Since: 2.1.0 */ @@ -1101,9 +1125,11 @@ uint8_t /** * hb_color_get_blue: - * color: a #hb_color_t we are interested in its channels. + * @color: an #hb_color_t we are interested in its channels. + * + * Fetches the blue channel of the given @color. * - * Return value: Blue channel value of the given color + * Return value: Blue channel value * * Since: 2.1.0 */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-common.h b/src/3rdparty/harfbuzz-ng/src/hb-common.h index 037e50880e..532fd428cb 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-common.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-common.h @@ -26,7 +26,7 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_H_IN +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb.h> instead." #endif @@ -88,11 +88,37 @@ typedef unsigned __int64 uint64_t; HB_BEGIN_DECLS - +/** + * hb_bool_t: + * + * Data type for booleans. + * + **/ typedef int hb_bool_t; +/** + * hb_codepoint_t: + * + * Data type for holding Unicode codepoints. Also + * used to hold glyph IDs. + * + **/ typedef uint32_t hb_codepoint_t; +/** + * hb_position_t: + * + * Data type for holding a single coordinate value. + * Contour points and other multi-dimensional data are + * stored as tuples of #hb_position_t's. + * + **/ typedef int32_t hb_position_t; +/** + * hb_mask_t: + * + * Data type for bitmasks. + * + **/ typedef uint32_t hb_mask_t; typedef union _hb_var_int_t { @@ -107,13 +133,63 @@ typedef union _hb_var_int_t { /* hb_tag_t */ +/** + * hb_tag_t: + * + * Data type for tag identifiers. Tags are four + * byte integers, each byte representing a character. + * + * Tags are used to identify tables, design-variation axes, + * scripts, languages, font features, and baselines with + * human-readable names. + * + **/ typedef uint32_t hb_tag_t; +/** + * HB_TAG: + * @c1: 1st character of the tag + * @c2: 2nd character of the tag + * @c3: 3rd character of the tag + * @c4: 4th character of the tag + * + * Constructs an #hb_tag_t from four character literals. + * + **/ #define HB_TAG(c1,c2,c3,c4) ((hb_tag_t)((((uint32_t)(c1)&0xFF)<<24)|(((uint32_t)(c2)&0xFF)<<16)|(((uint32_t)(c3)&0xFF)<<8)|((uint32_t)(c4)&0xFF))) + +/** + * HB_UNTAG: + * @tag: an #hb_tag_t + * + * Extracts four character literals from an #hb_tag_t. + * + * Since: 0.6.0 + * + **/ #define HB_UNTAG(tag) (uint8_t)(((tag)>>24)&0xFF), (uint8_t)(((tag)>>16)&0xFF), (uint8_t)(((tag)>>8)&0xFF), (uint8_t)((tag)&0xFF) +/** + * HB_TAG_NONE: + * + * Unset #hb_tag_t. + */ #define HB_TAG_NONE HB_TAG(0,0,0,0) +/** + * HB_TAG_MAX: + * + * Maximum possible unsigned #hb_tag_t. + * + * Since: 0.9.26 + */ #define HB_TAG_MAX HB_TAG(0xff,0xff,0xff,0xff) +/** + * HB_TAG_MAX_SIGNED: + * + * Maximum possible signed #hb_tag_t. + * + * Since: 0.9.33 + */ #define HB_TAG_MAX_SIGNED HB_TAG(0x7f,0xff,0xff,0xff) /* len=-1 means str is NUL-terminated. */ @@ -132,6 +208,13 @@ hb_tag_to_string (hb_tag_t tag, char *buf); * @HB_DIRECTION_RTL: Text is set horizontally from right to left. * @HB_DIRECTION_TTB: Text is set vertically from top to bottom. * @HB_DIRECTION_BTT: Text is set vertically from bottom to top. + * + * The direction of a text segment or buffer. + * + * A segment can also be tested for horizontal or vertical + * orientation (irrespective of specific direction) with + * HB_DIRECTION_IS_HORIZONTAL() or HB_DIRECTION_IS_VERTICAL(). + * */ typedef enum { HB_DIRECTION_INVALID = 0, @@ -148,17 +231,71 @@ hb_direction_from_string (const char *str, int len); HB_EXTERN const char * hb_direction_to_string (hb_direction_t direction); +/** + * HB_DIRECTION_IS_VALID: + * @dir: #hb_direction_t to test + * + * Tests whether a text direction is valid. + * + **/ #define HB_DIRECTION_IS_VALID(dir) ((((unsigned int) (dir)) & ~3U) == 4) /* Direction must be valid for the following */ +/** + * HB_DIRECTION_IS_HORIZONTAL: + * @dir: #hb_direction_t to test + * + * Tests whether a text direction is horizontal. Requires + * that the direction be valid. + * + **/ #define HB_DIRECTION_IS_HORIZONTAL(dir) ((((unsigned int) (dir)) & ~1U) == 4) +/** + * HB_DIRECTION_IS_VERTICAL: + * @dir: #hb_direction_t to test + * + * Tests whether a text direction is vertical. Requires + * that the direction be valid. + * + **/ #define HB_DIRECTION_IS_VERTICAL(dir) ((((unsigned int) (dir)) & ~1U) == 6) +/** + * HB_DIRECTION_IS_FORWARD: + * @dir: #hb_direction_t to test + * + * Tests whether a text direction moves forward (from left to right, or from + * top to bottom). Requires that the direction be valid. + * + **/ #define HB_DIRECTION_IS_FORWARD(dir) ((((unsigned int) (dir)) & ~2U) == 4) +/** + * HB_DIRECTION_IS_BACKWARD: + * @dir: #hb_direction_t to test + * + * Tests whether a text direction moves backward (from right to left, or from + * bottom to top). Requires that the direction be valid. + * + **/ #define HB_DIRECTION_IS_BACKWARD(dir) ((((unsigned int) (dir)) & ~2U) == 5) +/** + * HB_DIRECTION_REVERSE: + * @dir: #hb_direction_t to reverse + * + * Reverses a text direction. Requires that the direction + * be valid. + * + **/ #define HB_DIRECTION_REVERSE(dir) ((hb_direction_t) (((unsigned int) (dir)) ^ 1)) /* hb_language_t */ +/** + * hb_language_t: + * + * Data type for languages. Each #hb_language_t corresponds to a BCP 47 + * language tag. + * + */ typedef const struct hb_language_impl_t *hb_language_t; HB_EXTERN hb_language_t @@ -167,208 +304,389 @@ hb_language_from_string (const char *str, int len); HB_EXTERN const char * hb_language_to_string (hb_language_t language); +/** + * HB_LANGUAGE_INVALID: + * + * An unset #hb_language_t. + * + * Since: 0.6.0 + */ #define HB_LANGUAGE_INVALID ((hb_language_t) 0) HB_EXTERN hb_language_t hb_language_get_default (void); -/* hb_script_t */ +/** + * hb_script_t: + * @HB_SCRIPT_COMMON: `Zyyy` + * @HB_SCRIPT_INHERITED: `Zinh` + * @HB_SCRIPT_UNKNOWN: `Zzzz` + * @HB_SCRIPT_ARABIC: `Arab` + * @HB_SCRIPT_ARMENIAN: `Armn` + * @HB_SCRIPT_BENGALI: `Beng` + * @HB_SCRIPT_CYRILLIC: `Cyrl` + * @HB_SCRIPT_DEVANAGARI: `Deva` + * @HB_SCRIPT_GEORGIAN: `Geor` + * @HB_SCRIPT_GREEK: `Grek` + * @HB_SCRIPT_GUJARATI: `Gujr` + * @HB_SCRIPT_GURMUKHI: `Guru` + * @HB_SCRIPT_HANGUL: `Hang` + * @HB_SCRIPT_HAN: `Hani` + * @HB_SCRIPT_HEBREW: `Hebr` + * @HB_SCRIPT_HIRAGANA: `Hira` + * @HB_SCRIPT_KANNADA: `Knda` + * @HB_SCRIPT_KATAKANA: `Kana` + * @HB_SCRIPT_LAO: `Laoo` + * @HB_SCRIPT_LATIN: `Latn` + * @HB_SCRIPT_MALAYALAM: `Mlym` + * @HB_SCRIPT_ORIYA: `Orya` + * @HB_SCRIPT_TAMIL: `Taml` + * @HB_SCRIPT_TELUGU: `Telu` + * @HB_SCRIPT_THAI: `Thai` + * @HB_SCRIPT_TIBETAN: `Tibt` + * @HB_SCRIPT_BOPOMOFO: `Bopo` + * @HB_SCRIPT_BRAILLE: `Brai` + * @HB_SCRIPT_CANADIAN_SYLLABICS: `Cans` + * @HB_SCRIPT_CHEROKEE: `Cher` + * @HB_SCRIPT_ETHIOPIC: `Ethi` + * @HB_SCRIPT_KHMER: `Khmr` + * @HB_SCRIPT_MONGOLIAN: `Mong` + * @HB_SCRIPT_MYANMAR: `Mymr` + * @HB_SCRIPT_OGHAM: `Ogam` + * @HB_SCRIPT_RUNIC: `Runr` + * @HB_SCRIPT_SINHALA: `Sinh` + * @HB_SCRIPT_SYRIAC: `Syrc` + * @HB_SCRIPT_THAANA: `Thaa` + * @HB_SCRIPT_YI: `Yiii` + * @HB_SCRIPT_DESERET: `Dsrt` + * @HB_SCRIPT_GOTHIC: `Goth` + * @HB_SCRIPT_OLD_ITALIC: `Ital` + * @HB_SCRIPT_BUHID: `Buhd` + * @HB_SCRIPT_HANUNOO: `Hano` + * @HB_SCRIPT_TAGALOG: `Tglg` + * @HB_SCRIPT_TAGBANWA: `Tagb` + * @HB_SCRIPT_CYPRIOT: `Cprt` + * @HB_SCRIPT_LIMBU: `Limb` + * @HB_SCRIPT_LINEAR_B: `Linb` + * @HB_SCRIPT_OSMANYA: `Osma` + * @HB_SCRIPT_SHAVIAN: `Shaw` + * @HB_SCRIPT_TAI_LE: `Tale` + * @HB_SCRIPT_UGARITIC: `Ugar` + * @HB_SCRIPT_BUGINESE: `Bugi` + * @HB_SCRIPT_COPTIC: `Copt` + * @HB_SCRIPT_GLAGOLITIC: `Glag` + * @HB_SCRIPT_KHAROSHTHI: `Khar` + * @HB_SCRIPT_NEW_TAI_LUE: `Talu` + * @HB_SCRIPT_OLD_PERSIAN: `Xpeo` + * @HB_SCRIPT_SYLOTI_NAGRI: `Sylo` + * @HB_SCRIPT_TIFINAGH: `Tfng` + * @HB_SCRIPT_BALINESE: `Bali` + * @HB_SCRIPT_CUNEIFORM: `Xsux` + * @HB_SCRIPT_NKO: `Nkoo` + * @HB_SCRIPT_PHAGS_PA: `Phag` + * @HB_SCRIPT_PHOENICIAN: `Phnx` + * @HB_SCRIPT_CARIAN: `Cari` + * @HB_SCRIPT_CHAM: `Cham` + * @HB_SCRIPT_KAYAH_LI: `Kali` + * @HB_SCRIPT_LEPCHA: `Lepc` + * @HB_SCRIPT_LYCIAN: `Lyci` + * @HB_SCRIPT_LYDIAN: `Lydi` + * @HB_SCRIPT_OL_CHIKI: `Olck` + * @HB_SCRIPT_REJANG: `Rjng` + * @HB_SCRIPT_SAURASHTRA: `Saur` + * @HB_SCRIPT_SUNDANESE: `Sund` + * @HB_SCRIPT_VAI: `Vaii` + * @HB_SCRIPT_AVESTAN: `Avst` + * @HB_SCRIPT_BAMUM: `Bamu` + * @HB_SCRIPT_EGYPTIAN_HIEROGLYPHS: `Egyp` + * @HB_SCRIPT_IMPERIAL_ARAMAIC: `Armi` + * @HB_SCRIPT_INSCRIPTIONAL_PAHLAVI: `Phli` + * @HB_SCRIPT_INSCRIPTIONAL_PARTHIAN: `Prti` + * @HB_SCRIPT_JAVANESE: `Java` + * @HB_SCRIPT_KAITHI: `Kthi` + * @HB_SCRIPT_LISU: `Lisu` + * @HB_SCRIPT_MEETEI_MAYEK: `Mtei` + * @HB_SCRIPT_OLD_SOUTH_ARABIAN: `Sarb` + * @HB_SCRIPT_OLD_TURKIC: `Orkh` + * @HB_SCRIPT_SAMARITAN: `Samr` + * @HB_SCRIPT_TAI_THAM: `Lana` + * @HB_SCRIPT_TAI_VIET: `Tavt` + * @HB_SCRIPT_BATAK: `Batk` + * @HB_SCRIPT_BRAHMI: `Brah` + * @HB_SCRIPT_MANDAIC: `Mand` + * @HB_SCRIPT_CHAKMA: `Cakm` + * @HB_SCRIPT_MEROITIC_CURSIVE: `Merc` + * @HB_SCRIPT_MEROITIC_HIEROGLYPHS: `Mero` + * @HB_SCRIPT_MIAO: `Plrd` + * @HB_SCRIPT_SHARADA: `Shrd` + * @HB_SCRIPT_SORA_SOMPENG: `Sora` + * @HB_SCRIPT_TAKRI: `Takr` + * @HB_SCRIPT_BASSA_VAH: `Bass`, Since: 0.9.30 + * @HB_SCRIPT_CAUCASIAN_ALBANIAN: `Aghb`, Since: 0.9.30 + * @HB_SCRIPT_DUPLOYAN: `Dupl`, Since: 0.9.30 + * @HB_SCRIPT_ELBASAN: `Elba`, Since: 0.9.30 + * @HB_SCRIPT_GRANTHA: `Gran`, Since: 0.9.30 + * @HB_SCRIPT_KHOJKI: `Khoj`, Since: 0.9.30 + * @HB_SCRIPT_KHUDAWADI: `Sind`, Since: 0.9.30 + * @HB_SCRIPT_LINEAR_A: `Lina`, Since: 0.9.30 + * @HB_SCRIPT_MAHAJANI: `Mahj`, Since: 0.9.30 + * @HB_SCRIPT_MANICHAEAN: `Mani`, Since: 0.9.30 + * @HB_SCRIPT_MENDE_KIKAKUI: `Mend`, Since: 0.9.30 + * @HB_SCRIPT_MODI: `Modi`, Since: 0.9.30 + * @HB_SCRIPT_MRO: `Mroo`, Since: 0.9.30 + * @HB_SCRIPT_NABATAEAN: `Nbat`, Since: 0.9.30 + * @HB_SCRIPT_OLD_NORTH_ARABIAN: `Narb`, Since: 0.9.30 + * @HB_SCRIPT_OLD_PERMIC: `Perm`, Since: 0.9.30 + * @HB_SCRIPT_PAHAWH_HMONG: `Hmng`, Since: 0.9.30 + * @HB_SCRIPT_PALMYRENE: `Palm`, Since: 0.9.30 + * @HB_SCRIPT_PAU_CIN_HAU: `Pauc`, Since: 0.9.30 + * @HB_SCRIPT_PSALTER_PAHLAVI: `Phlp`, Since: 0.9.30 + * @HB_SCRIPT_SIDDHAM: `Sidd`, Since: 0.9.30 + * @HB_SCRIPT_TIRHUTA: `Tirh`, Since: 0.9.30 + * @HB_SCRIPT_WARANG_CITI: `Wara`, Since: 0.9.30 + * @HB_SCRIPT_AHOM: `Ahom`, Since: 0.9.30 + * @HB_SCRIPT_ANATOLIAN_HIEROGLYPHS: `Hluw`, Since: 0.9.30 + * @HB_SCRIPT_HATRAN: `Hatr`, Since: 0.9.30 + * @HB_SCRIPT_MULTANI: `Mult`, Since: 0.9.30 + * @HB_SCRIPT_OLD_HUNGARIAN: `Hung`, Since: 0.9.30 + * @HB_SCRIPT_SIGNWRITING: `Sgnw`, Since: 0.9.30 + * @HB_SCRIPT_ADLAM: `Adlm`, Since: 1.3.0 + * @HB_SCRIPT_BHAIKSUKI: `Bhks`, Since: 1.3.0 + * @HB_SCRIPT_MARCHEN: `Marc`, Since: 1.3.0 + * @HB_SCRIPT_OSAGE: `Osge`, Since: 1.3.0 + * @HB_SCRIPT_TANGUT: `Tang`, Since: 1.3.0 + * @HB_SCRIPT_NEWA: `Newa`, Since: 1.3.0 + * @HB_SCRIPT_MASARAM_GONDI: `Gonm`, Since: 1.6.0 + * @HB_SCRIPT_NUSHU: `Nshu`, Since: 1.6.0 + * @HB_SCRIPT_SOYOMBO: `Soyo`, Since: 1.6.0 + * @HB_SCRIPT_ZANABAZAR_SQUARE: `Zanb`, Since: 1.6.0 + * @HB_SCRIPT_DOGRA: `Dogr`, Since: 1.8.0 + * @HB_SCRIPT_GUNJALA_GONDI: `Gong`, Since: 1.8.0 + * @HB_SCRIPT_HANIFI_ROHINGYA: `Rohg`, Since: 1.8.0 + * @HB_SCRIPT_MAKASAR: `Maka`, Since: 1.8.0 + * @HB_SCRIPT_MEDEFAIDRIN: `Medf`, Since: 1.8.0 + * @HB_SCRIPT_OLD_SOGDIAN: `Sogo`, Since: 1.8.0 + * @HB_SCRIPT_SOGDIAN: `Sogd`, Since: 1.8.0 + * @HB_SCRIPT_ELYMAIC: `Elym`, Since: 2.4.0 + * @HB_SCRIPT_NANDINAGARI: `Nand`, Since: 2.4.0 + * @HB_SCRIPT_NYIAKENG_PUACHUE_HMONG: `Hmnp`, Since: 2.4.0 + * @HB_SCRIPT_WANCHO: `Wcho`, Since: 2.4.0 + * @HB_SCRIPT_CHORASMIAN: `Chrs`, Since: 2.6.7 + * @HB_SCRIPT_DIVES_AKURU: `Diak`, Since: 2.6.7 + * @HB_SCRIPT_KHITAN_SMALL_SCRIPT: `Kits`, Since: 2.6.7 + * @HB_SCRIPT_YEZIDI: `Yezi`, Since: 2.6.7 + * @HB_SCRIPT_INVALID: No script set + * + * Data type for scripts. Each #hb_script_t's value is an #hb_tag_t corresponding + * to the four-letter values defined by [ISO 15924](https://unicode.org/iso15924/). + * + * See also the Script (sc) property of the Unicode Character Database. + * + **/ -/* https://unicode.org/iso15924/ */ /* https://docs.google.com/spreadsheets/d/1Y90M0Ie3MUJ6UVCRDOypOtijlMDLNNyyLk36T6iMu0o */ -/* Unicode Character Database property: Script (sc) */ typedef enum { - /*1.1*/ HB_SCRIPT_COMMON = HB_TAG ('Z','y','y','y'), - /*1.1*/ HB_SCRIPT_INHERITED = HB_TAG ('Z','i','n','h'), - /*5.0*/ HB_SCRIPT_UNKNOWN = HB_TAG ('Z','z','z','z'), - - /*1.1*/ HB_SCRIPT_ARABIC = HB_TAG ('A','r','a','b'), - /*1.1*/ HB_SCRIPT_ARMENIAN = HB_TAG ('A','r','m','n'), - /*1.1*/ HB_SCRIPT_BENGALI = HB_TAG ('B','e','n','g'), - /*1.1*/ HB_SCRIPT_CYRILLIC = HB_TAG ('C','y','r','l'), - /*1.1*/ HB_SCRIPT_DEVANAGARI = HB_TAG ('D','e','v','a'), - /*1.1*/ HB_SCRIPT_GEORGIAN = HB_TAG ('G','e','o','r'), - /*1.1*/ HB_SCRIPT_GREEK = HB_TAG ('G','r','e','k'), - /*1.1*/ HB_SCRIPT_GUJARATI = HB_TAG ('G','u','j','r'), - /*1.1*/ HB_SCRIPT_GURMUKHI = HB_TAG ('G','u','r','u'), - /*1.1*/ HB_SCRIPT_HANGUL = HB_TAG ('H','a','n','g'), - /*1.1*/ HB_SCRIPT_HAN = HB_TAG ('H','a','n','i'), - /*1.1*/ HB_SCRIPT_HEBREW = HB_TAG ('H','e','b','r'), - /*1.1*/ HB_SCRIPT_HIRAGANA = HB_TAG ('H','i','r','a'), - /*1.1*/ HB_SCRIPT_KANNADA = HB_TAG ('K','n','d','a'), - /*1.1*/ HB_SCRIPT_KATAKANA = HB_TAG ('K','a','n','a'), - /*1.1*/ HB_SCRIPT_LAO = HB_TAG ('L','a','o','o'), - /*1.1*/ HB_SCRIPT_LATIN = HB_TAG ('L','a','t','n'), - /*1.1*/ HB_SCRIPT_MALAYALAM = HB_TAG ('M','l','y','m'), - /*1.1*/ HB_SCRIPT_ORIYA = HB_TAG ('O','r','y','a'), - /*1.1*/ HB_SCRIPT_TAMIL = HB_TAG ('T','a','m','l'), - /*1.1*/ HB_SCRIPT_TELUGU = HB_TAG ('T','e','l','u'), - /*1.1*/ HB_SCRIPT_THAI = HB_TAG ('T','h','a','i'), - - /*2.0*/ HB_SCRIPT_TIBETAN = HB_TAG ('T','i','b','t'), - - /*3.0*/ HB_SCRIPT_BOPOMOFO = HB_TAG ('B','o','p','o'), - /*3.0*/ HB_SCRIPT_BRAILLE = HB_TAG ('B','r','a','i'), - /*3.0*/ HB_SCRIPT_CANADIAN_SYLLABICS = HB_TAG ('C','a','n','s'), - /*3.0*/ HB_SCRIPT_CHEROKEE = HB_TAG ('C','h','e','r'), - /*3.0*/ HB_SCRIPT_ETHIOPIC = HB_TAG ('E','t','h','i'), - /*3.0*/ HB_SCRIPT_KHMER = HB_TAG ('K','h','m','r'), - /*3.0*/ HB_SCRIPT_MONGOLIAN = HB_TAG ('M','o','n','g'), - /*3.0*/ HB_SCRIPT_MYANMAR = HB_TAG ('M','y','m','r'), - /*3.0*/ HB_SCRIPT_OGHAM = HB_TAG ('O','g','a','m'), - /*3.0*/ HB_SCRIPT_RUNIC = HB_TAG ('R','u','n','r'), - /*3.0*/ HB_SCRIPT_SINHALA = HB_TAG ('S','i','n','h'), - /*3.0*/ HB_SCRIPT_SYRIAC = HB_TAG ('S','y','r','c'), - /*3.0*/ HB_SCRIPT_THAANA = HB_TAG ('T','h','a','a'), - /*3.0*/ HB_SCRIPT_YI = HB_TAG ('Y','i','i','i'), - - /*3.1*/ HB_SCRIPT_DESERET = HB_TAG ('D','s','r','t'), - /*3.1*/ HB_SCRIPT_GOTHIC = HB_TAG ('G','o','t','h'), - /*3.1*/ HB_SCRIPT_OLD_ITALIC = HB_TAG ('I','t','a','l'), - - /*3.2*/ HB_SCRIPT_BUHID = HB_TAG ('B','u','h','d'), - /*3.2*/ HB_SCRIPT_HANUNOO = HB_TAG ('H','a','n','o'), - /*3.2*/ HB_SCRIPT_TAGALOG = HB_TAG ('T','g','l','g'), - /*3.2*/ HB_SCRIPT_TAGBANWA = HB_TAG ('T','a','g','b'), - - /*4.0*/ HB_SCRIPT_CYPRIOT = HB_TAG ('C','p','r','t'), - /*4.0*/ HB_SCRIPT_LIMBU = HB_TAG ('L','i','m','b'), - /*4.0*/ HB_SCRIPT_LINEAR_B = HB_TAG ('L','i','n','b'), - /*4.0*/ HB_SCRIPT_OSMANYA = HB_TAG ('O','s','m','a'), - /*4.0*/ HB_SCRIPT_SHAVIAN = HB_TAG ('S','h','a','w'), - /*4.0*/ HB_SCRIPT_TAI_LE = HB_TAG ('T','a','l','e'), - /*4.0*/ HB_SCRIPT_UGARITIC = HB_TAG ('U','g','a','r'), - - /*4.1*/ HB_SCRIPT_BUGINESE = HB_TAG ('B','u','g','i'), - /*4.1*/ HB_SCRIPT_COPTIC = HB_TAG ('C','o','p','t'), - /*4.1*/ HB_SCRIPT_GLAGOLITIC = HB_TAG ('G','l','a','g'), - /*4.1*/ HB_SCRIPT_KHAROSHTHI = HB_TAG ('K','h','a','r'), - /*4.1*/ HB_SCRIPT_NEW_TAI_LUE = HB_TAG ('T','a','l','u'), - /*4.1*/ HB_SCRIPT_OLD_PERSIAN = HB_TAG ('X','p','e','o'), - /*4.1*/ HB_SCRIPT_SYLOTI_NAGRI = HB_TAG ('S','y','l','o'), - /*4.1*/ HB_SCRIPT_TIFINAGH = HB_TAG ('T','f','n','g'), - - /*5.0*/ HB_SCRIPT_BALINESE = HB_TAG ('B','a','l','i'), - /*5.0*/ HB_SCRIPT_CUNEIFORM = HB_TAG ('X','s','u','x'), - /*5.0*/ HB_SCRIPT_NKO = HB_TAG ('N','k','o','o'), - /*5.0*/ HB_SCRIPT_PHAGS_PA = HB_TAG ('P','h','a','g'), - /*5.0*/ HB_SCRIPT_PHOENICIAN = HB_TAG ('P','h','n','x'), - - /*5.1*/ HB_SCRIPT_CARIAN = HB_TAG ('C','a','r','i'), - /*5.1*/ HB_SCRIPT_CHAM = HB_TAG ('C','h','a','m'), - /*5.1*/ HB_SCRIPT_KAYAH_LI = HB_TAG ('K','a','l','i'), - /*5.1*/ HB_SCRIPT_LEPCHA = HB_TAG ('L','e','p','c'), - /*5.1*/ HB_SCRIPT_LYCIAN = HB_TAG ('L','y','c','i'), - /*5.1*/ HB_SCRIPT_LYDIAN = HB_TAG ('L','y','d','i'), - /*5.1*/ HB_SCRIPT_OL_CHIKI = HB_TAG ('O','l','c','k'), - /*5.1*/ HB_SCRIPT_REJANG = HB_TAG ('R','j','n','g'), - /*5.1*/ HB_SCRIPT_SAURASHTRA = HB_TAG ('S','a','u','r'), - /*5.1*/ HB_SCRIPT_SUNDANESE = HB_TAG ('S','u','n','d'), - /*5.1*/ HB_SCRIPT_VAI = HB_TAG ('V','a','i','i'), - - /*5.2*/ HB_SCRIPT_AVESTAN = HB_TAG ('A','v','s','t'), - /*5.2*/ HB_SCRIPT_BAMUM = HB_TAG ('B','a','m','u'), - /*5.2*/ HB_SCRIPT_EGYPTIAN_HIEROGLYPHS = HB_TAG ('E','g','y','p'), - /*5.2*/ HB_SCRIPT_IMPERIAL_ARAMAIC = HB_TAG ('A','r','m','i'), - /*5.2*/ HB_SCRIPT_INSCRIPTIONAL_PAHLAVI = HB_TAG ('P','h','l','i'), - /*5.2*/ HB_SCRIPT_INSCRIPTIONAL_PARTHIAN = HB_TAG ('P','r','t','i'), - /*5.2*/ HB_SCRIPT_JAVANESE = HB_TAG ('J','a','v','a'), - /*5.2*/ HB_SCRIPT_KAITHI = HB_TAG ('K','t','h','i'), - /*5.2*/ HB_SCRIPT_LISU = HB_TAG ('L','i','s','u'), - /*5.2*/ HB_SCRIPT_MEETEI_MAYEK = HB_TAG ('M','t','e','i'), - /*5.2*/ HB_SCRIPT_OLD_SOUTH_ARABIAN = HB_TAG ('S','a','r','b'), - /*5.2*/ HB_SCRIPT_OLD_TURKIC = HB_TAG ('O','r','k','h'), - /*5.2*/ HB_SCRIPT_SAMARITAN = HB_TAG ('S','a','m','r'), - /*5.2*/ HB_SCRIPT_TAI_THAM = HB_TAG ('L','a','n','a'), - /*5.2*/ HB_SCRIPT_TAI_VIET = HB_TAG ('T','a','v','t'), - - /*6.0*/ HB_SCRIPT_BATAK = HB_TAG ('B','a','t','k'), - /*6.0*/ HB_SCRIPT_BRAHMI = HB_TAG ('B','r','a','h'), - /*6.0*/ HB_SCRIPT_MANDAIC = HB_TAG ('M','a','n','d'), - - /*6.1*/ HB_SCRIPT_CHAKMA = HB_TAG ('C','a','k','m'), - /*6.1*/ HB_SCRIPT_MEROITIC_CURSIVE = HB_TAG ('M','e','r','c'), - /*6.1*/ HB_SCRIPT_MEROITIC_HIEROGLYPHS = HB_TAG ('M','e','r','o'), - /*6.1*/ HB_SCRIPT_MIAO = HB_TAG ('P','l','r','d'), - /*6.1*/ HB_SCRIPT_SHARADA = HB_TAG ('S','h','r','d'), - /*6.1*/ HB_SCRIPT_SORA_SOMPENG = HB_TAG ('S','o','r','a'), - /*6.1*/ HB_SCRIPT_TAKRI = HB_TAG ('T','a','k','r'), + HB_SCRIPT_COMMON = HB_TAG ('Z','y','y','y'), /*1.1*/ + HB_SCRIPT_INHERITED = HB_TAG ('Z','i','n','h'), /*1.1*/ + HB_SCRIPT_UNKNOWN = HB_TAG ('Z','z','z','z'), /*5.0*/ + + HB_SCRIPT_ARABIC = HB_TAG ('A','r','a','b'), /*1.1*/ + HB_SCRIPT_ARMENIAN = HB_TAG ('A','r','m','n'), /*1.1*/ + HB_SCRIPT_BENGALI = HB_TAG ('B','e','n','g'), /*1.1*/ + HB_SCRIPT_CYRILLIC = HB_TAG ('C','y','r','l'), /*1.1*/ + HB_SCRIPT_DEVANAGARI = HB_TAG ('D','e','v','a'), /*1.1*/ + HB_SCRIPT_GEORGIAN = HB_TAG ('G','e','o','r'), /*1.1*/ + HB_SCRIPT_GREEK = HB_TAG ('G','r','e','k'), /*1.1*/ + HB_SCRIPT_GUJARATI = HB_TAG ('G','u','j','r'), /*1.1*/ + HB_SCRIPT_GURMUKHI = HB_TAG ('G','u','r','u'), /*1.1*/ + HB_SCRIPT_HANGUL = HB_TAG ('H','a','n','g'), /*1.1*/ + HB_SCRIPT_HAN = HB_TAG ('H','a','n','i'), /*1.1*/ + HB_SCRIPT_HEBREW = HB_TAG ('H','e','b','r'), /*1.1*/ + HB_SCRIPT_HIRAGANA = HB_TAG ('H','i','r','a'), /*1.1*/ + HB_SCRIPT_KANNADA = HB_TAG ('K','n','d','a'), /*1.1*/ + HB_SCRIPT_KATAKANA = HB_TAG ('K','a','n','a'), /*1.1*/ + HB_SCRIPT_LAO = HB_TAG ('L','a','o','o'), /*1.1*/ + HB_SCRIPT_LATIN = HB_TAG ('L','a','t','n'), /*1.1*/ + HB_SCRIPT_MALAYALAM = HB_TAG ('M','l','y','m'), /*1.1*/ + HB_SCRIPT_ORIYA = HB_TAG ('O','r','y','a'), /*1.1*/ + HB_SCRIPT_TAMIL = HB_TAG ('T','a','m','l'), /*1.1*/ + HB_SCRIPT_TELUGU = HB_TAG ('T','e','l','u'), /*1.1*/ + HB_SCRIPT_THAI = HB_TAG ('T','h','a','i'), /*1.1*/ + + HB_SCRIPT_TIBETAN = HB_TAG ('T','i','b','t'), /*2.0*/ + + HB_SCRIPT_BOPOMOFO = HB_TAG ('B','o','p','o'), /*3.0*/ + HB_SCRIPT_BRAILLE = HB_TAG ('B','r','a','i'), /*3.0*/ + HB_SCRIPT_CANADIAN_SYLLABICS = HB_TAG ('C','a','n','s'), /*3.0*/ + HB_SCRIPT_CHEROKEE = HB_TAG ('C','h','e','r'), /*3.0*/ + HB_SCRIPT_ETHIOPIC = HB_TAG ('E','t','h','i'), /*3.0*/ + HB_SCRIPT_KHMER = HB_TAG ('K','h','m','r'), /*3.0*/ + HB_SCRIPT_MONGOLIAN = HB_TAG ('M','o','n','g'), /*3.0*/ + HB_SCRIPT_MYANMAR = HB_TAG ('M','y','m','r'), /*3.0*/ + HB_SCRIPT_OGHAM = HB_TAG ('O','g','a','m'), /*3.0*/ + HB_SCRIPT_RUNIC = HB_TAG ('R','u','n','r'), /*3.0*/ + HB_SCRIPT_SINHALA = HB_TAG ('S','i','n','h'), /*3.0*/ + HB_SCRIPT_SYRIAC = HB_TAG ('S','y','r','c'), /*3.0*/ + HB_SCRIPT_THAANA = HB_TAG ('T','h','a','a'), /*3.0*/ + HB_SCRIPT_YI = HB_TAG ('Y','i','i','i'), /*3.0*/ + + HB_SCRIPT_DESERET = HB_TAG ('D','s','r','t'), /*3.1*/ + HB_SCRIPT_GOTHIC = HB_TAG ('G','o','t','h'), /*3.1*/ + HB_SCRIPT_OLD_ITALIC = HB_TAG ('I','t','a','l'), /*3.1*/ + + HB_SCRIPT_BUHID = HB_TAG ('B','u','h','d'), /*3.2*/ + HB_SCRIPT_HANUNOO = HB_TAG ('H','a','n','o'), /*3.2*/ + HB_SCRIPT_TAGALOG = HB_TAG ('T','g','l','g'), /*3.2*/ + HB_SCRIPT_TAGBANWA = HB_TAG ('T','a','g','b'), /*3.2*/ + + HB_SCRIPT_CYPRIOT = HB_TAG ('C','p','r','t'), /*4.0*/ + HB_SCRIPT_LIMBU = HB_TAG ('L','i','m','b'), /*4.0*/ + HB_SCRIPT_LINEAR_B = HB_TAG ('L','i','n','b'), /*4.0*/ + HB_SCRIPT_OSMANYA = HB_TAG ('O','s','m','a'), /*4.0*/ + HB_SCRIPT_SHAVIAN = HB_TAG ('S','h','a','w'), /*4.0*/ + HB_SCRIPT_TAI_LE = HB_TAG ('T','a','l','e'), /*4.0*/ + HB_SCRIPT_UGARITIC = HB_TAG ('U','g','a','r'), /*4.0*/ + + HB_SCRIPT_BUGINESE = HB_TAG ('B','u','g','i'), /*4.1*/ + HB_SCRIPT_COPTIC = HB_TAG ('C','o','p','t'), /*4.1*/ + HB_SCRIPT_GLAGOLITIC = HB_TAG ('G','l','a','g'), /*4.1*/ + HB_SCRIPT_KHAROSHTHI = HB_TAG ('K','h','a','r'), /*4.1*/ + HB_SCRIPT_NEW_TAI_LUE = HB_TAG ('T','a','l','u'), /*4.1*/ + HB_SCRIPT_OLD_PERSIAN = HB_TAG ('X','p','e','o'), /*4.1*/ + HB_SCRIPT_SYLOTI_NAGRI = HB_TAG ('S','y','l','o'), /*4.1*/ + HB_SCRIPT_TIFINAGH = HB_TAG ('T','f','n','g'), /*4.1*/ + + HB_SCRIPT_BALINESE = HB_TAG ('B','a','l','i'), /*5.0*/ + HB_SCRIPT_CUNEIFORM = HB_TAG ('X','s','u','x'), /*5.0*/ + HB_SCRIPT_NKO = HB_TAG ('N','k','o','o'), /*5.0*/ + HB_SCRIPT_PHAGS_PA = HB_TAG ('P','h','a','g'), /*5.0*/ + HB_SCRIPT_PHOENICIAN = HB_TAG ('P','h','n','x'), /*5.0*/ + + HB_SCRIPT_CARIAN = HB_TAG ('C','a','r','i'), /*5.1*/ + HB_SCRIPT_CHAM = HB_TAG ('C','h','a','m'), /*5.1*/ + HB_SCRIPT_KAYAH_LI = HB_TAG ('K','a','l','i'), /*5.1*/ + HB_SCRIPT_LEPCHA = HB_TAG ('L','e','p','c'), /*5.1*/ + HB_SCRIPT_LYCIAN = HB_TAG ('L','y','c','i'), /*5.1*/ + HB_SCRIPT_LYDIAN = HB_TAG ('L','y','d','i'), /*5.1*/ + HB_SCRIPT_OL_CHIKI = HB_TAG ('O','l','c','k'), /*5.1*/ + HB_SCRIPT_REJANG = HB_TAG ('R','j','n','g'), /*5.1*/ + HB_SCRIPT_SAURASHTRA = HB_TAG ('S','a','u','r'), /*5.1*/ + HB_SCRIPT_SUNDANESE = HB_TAG ('S','u','n','d'), /*5.1*/ + HB_SCRIPT_VAI = HB_TAG ('V','a','i','i'), /*5.1*/ + + HB_SCRIPT_AVESTAN = HB_TAG ('A','v','s','t'), /*5.2*/ + HB_SCRIPT_BAMUM = HB_TAG ('B','a','m','u'), /*5.2*/ + HB_SCRIPT_EGYPTIAN_HIEROGLYPHS = HB_TAG ('E','g','y','p'), /*5.2*/ + HB_SCRIPT_IMPERIAL_ARAMAIC = HB_TAG ('A','r','m','i'), /*5.2*/ + HB_SCRIPT_INSCRIPTIONAL_PAHLAVI = HB_TAG ('P','h','l','i'), /*5.2*/ + HB_SCRIPT_INSCRIPTIONAL_PARTHIAN = HB_TAG ('P','r','t','i'), /*5.2*/ + HB_SCRIPT_JAVANESE = HB_TAG ('J','a','v','a'), /*5.2*/ + HB_SCRIPT_KAITHI = HB_TAG ('K','t','h','i'), /*5.2*/ + HB_SCRIPT_LISU = HB_TAG ('L','i','s','u'), /*5.2*/ + HB_SCRIPT_MEETEI_MAYEK = HB_TAG ('M','t','e','i'), /*5.2*/ + HB_SCRIPT_OLD_SOUTH_ARABIAN = HB_TAG ('S','a','r','b'), /*5.2*/ + HB_SCRIPT_OLD_TURKIC = HB_TAG ('O','r','k','h'), /*5.2*/ + HB_SCRIPT_SAMARITAN = HB_TAG ('S','a','m','r'), /*5.2*/ + HB_SCRIPT_TAI_THAM = HB_TAG ('L','a','n','a'), /*5.2*/ + HB_SCRIPT_TAI_VIET = HB_TAG ('T','a','v','t'), /*5.2*/ + + HB_SCRIPT_BATAK = HB_TAG ('B','a','t','k'), /*6.0*/ + HB_SCRIPT_BRAHMI = HB_TAG ('B','r','a','h'), /*6.0*/ + HB_SCRIPT_MANDAIC = HB_TAG ('M','a','n','d'), /*6.0*/ + + HB_SCRIPT_CHAKMA = HB_TAG ('C','a','k','m'), /*6.1*/ + HB_SCRIPT_MEROITIC_CURSIVE = HB_TAG ('M','e','r','c'), /*6.1*/ + HB_SCRIPT_MEROITIC_HIEROGLYPHS = HB_TAG ('M','e','r','o'), /*6.1*/ + HB_SCRIPT_MIAO = HB_TAG ('P','l','r','d'), /*6.1*/ + HB_SCRIPT_SHARADA = HB_TAG ('S','h','r','d'), /*6.1*/ + HB_SCRIPT_SORA_SOMPENG = HB_TAG ('S','o','r','a'), /*6.1*/ + HB_SCRIPT_TAKRI = HB_TAG ('T','a','k','r'), /*6.1*/ /* * Since: 0.9.30 */ - /*7.0*/ HB_SCRIPT_BASSA_VAH = HB_TAG ('B','a','s','s'), - /*7.0*/ HB_SCRIPT_CAUCASIAN_ALBANIAN = HB_TAG ('A','g','h','b'), - /*7.0*/ HB_SCRIPT_DUPLOYAN = HB_TAG ('D','u','p','l'), - /*7.0*/ HB_SCRIPT_ELBASAN = HB_TAG ('E','l','b','a'), - /*7.0*/ HB_SCRIPT_GRANTHA = HB_TAG ('G','r','a','n'), - /*7.0*/ HB_SCRIPT_KHOJKI = HB_TAG ('K','h','o','j'), - /*7.0*/ HB_SCRIPT_KHUDAWADI = HB_TAG ('S','i','n','d'), - /*7.0*/ HB_SCRIPT_LINEAR_A = HB_TAG ('L','i','n','a'), - /*7.0*/ HB_SCRIPT_MAHAJANI = HB_TAG ('M','a','h','j'), - /*7.0*/ HB_SCRIPT_MANICHAEAN = HB_TAG ('M','a','n','i'), - /*7.0*/ HB_SCRIPT_MENDE_KIKAKUI = HB_TAG ('M','e','n','d'), - /*7.0*/ HB_SCRIPT_MODI = HB_TAG ('M','o','d','i'), - /*7.0*/ HB_SCRIPT_MRO = HB_TAG ('M','r','o','o'), - /*7.0*/ HB_SCRIPT_NABATAEAN = HB_TAG ('N','b','a','t'), - /*7.0*/ HB_SCRIPT_OLD_NORTH_ARABIAN = HB_TAG ('N','a','r','b'), - /*7.0*/ HB_SCRIPT_OLD_PERMIC = HB_TAG ('P','e','r','m'), - /*7.0*/ HB_SCRIPT_PAHAWH_HMONG = HB_TAG ('H','m','n','g'), - /*7.0*/ HB_SCRIPT_PALMYRENE = HB_TAG ('P','a','l','m'), - /*7.0*/ HB_SCRIPT_PAU_CIN_HAU = HB_TAG ('P','a','u','c'), - /*7.0*/ HB_SCRIPT_PSALTER_PAHLAVI = HB_TAG ('P','h','l','p'), - /*7.0*/ HB_SCRIPT_SIDDHAM = HB_TAG ('S','i','d','d'), - /*7.0*/ HB_SCRIPT_TIRHUTA = HB_TAG ('T','i','r','h'), - /*7.0*/ HB_SCRIPT_WARANG_CITI = HB_TAG ('W','a','r','a'), - - /*8.0*/ HB_SCRIPT_AHOM = HB_TAG ('A','h','o','m'), - /*8.0*/ HB_SCRIPT_ANATOLIAN_HIEROGLYPHS = HB_TAG ('H','l','u','w'), - /*8.0*/ HB_SCRIPT_HATRAN = HB_TAG ('H','a','t','r'), - /*8.0*/ HB_SCRIPT_MULTANI = HB_TAG ('M','u','l','t'), - /*8.0*/ HB_SCRIPT_OLD_HUNGARIAN = HB_TAG ('H','u','n','g'), - /*8.0*/ HB_SCRIPT_SIGNWRITING = HB_TAG ('S','g','n','w'), + HB_SCRIPT_BASSA_VAH = HB_TAG ('B','a','s','s'), /*7.0*/ + HB_SCRIPT_CAUCASIAN_ALBANIAN = HB_TAG ('A','g','h','b'), /*7.0*/ + HB_SCRIPT_DUPLOYAN = HB_TAG ('D','u','p','l'), /*7.0*/ + HB_SCRIPT_ELBASAN = HB_TAG ('E','l','b','a'), /*7.0*/ + HB_SCRIPT_GRANTHA = HB_TAG ('G','r','a','n'), /*7.0*/ + HB_SCRIPT_KHOJKI = HB_TAG ('K','h','o','j'), /*7.0*/ + HB_SCRIPT_KHUDAWADI = HB_TAG ('S','i','n','d'), /*7.0*/ + HB_SCRIPT_LINEAR_A = HB_TAG ('L','i','n','a'), /*7.0*/ + HB_SCRIPT_MAHAJANI = HB_TAG ('M','a','h','j'), /*7.0*/ + HB_SCRIPT_MANICHAEAN = HB_TAG ('M','a','n','i'), /*7.0*/ + HB_SCRIPT_MENDE_KIKAKUI = HB_TAG ('M','e','n','d'), /*7.0*/ + HB_SCRIPT_MODI = HB_TAG ('M','o','d','i'), /*7.0*/ + HB_SCRIPT_MRO = HB_TAG ('M','r','o','o'), /*7.0*/ + HB_SCRIPT_NABATAEAN = HB_TAG ('N','b','a','t'), /*7.0*/ + HB_SCRIPT_OLD_NORTH_ARABIAN = HB_TAG ('N','a','r','b'), /*7.0*/ + HB_SCRIPT_OLD_PERMIC = HB_TAG ('P','e','r','m'), /*7.0*/ + HB_SCRIPT_PAHAWH_HMONG = HB_TAG ('H','m','n','g'), /*7.0*/ + HB_SCRIPT_PALMYRENE = HB_TAG ('P','a','l','m'), /*7.0*/ + HB_SCRIPT_PAU_CIN_HAU = HB_TAG ('P','a','u','c'), /*7.0*/ + HB_SCRIPT_PSALTER_PAHLAVI = HB_TAG ('P','h','l','p'), /*7.0*/ + HB_SCRIPT_SIDDHAM = HB_TAG ('S','i','d','d'), /*7.0*/ + HB_SCRIPT_TIRHUTA = HB_TAG ('T','i','r','h'), /*7.0*/ + HB_SCRIPT_WARANG_CITI = HB_TAG ('W','a','r','a'), /*7.0*/ + + HB_SCRIPT_AHOM = HB_TAG ('A','h','o','m'), /*8.0*/ + HB_SCRIPT_ANATOLIAN_HIEROGLYPHS = HB_TAG ('H','l','u','w'), /*8.0*/ + HB_SCRIPT_HATRAN = HB_TAG ('H','a','t','r'), /*8.0*/ + HB_SCRIPT_MULTANI = HB_TAG ('M','u','l','t'), /*8.0*/ + HB_SCRIPT_OLD_HUNGARIAN = HB_TAG ('H','u','n','g'), /*8.0*/ + HB_SCRIPT_SIGNWRITING = HB_TAG ('S','g','n','w'), /*8.0*/ /* * Since 1.3.0 */ - /*9.0*/ HB_SCRIPT_ADLAM = HB_TAG ('A','d','l','m'), - /*9.0*/ HB_SCRIPT_BHAIKSUKI = HB_TAG ('B','h','k','s'), - /*9.0*/ HB_SCRIPT_MARCHEN = HB_TAG ('M','a','r','c'), - /*9.0*/ HB_SCRIPT_OSAGE = HB_TAG ('O','s','g','e'), - /*9.0*/ HB_SCRIPT_TANGUT = HB_TAG ('T','a','n','g'), - /*9.0*/ HB_SCRIPT_NEWA = HB_TAG ('N','e','w','a'), + HB_SCRIPT_ADLAM = HB_TAG ('A','d','l','m'), /*9.0*/ + HB_SCRIPT_BHAIKSUKI = HB_TAG ('B','h','k','s'), /*9.0*/ + HB_SCRIPT_MARCHEN = HB_TAG ('M','a','r','c'), /*9.0*/ + HB_SCRIPT_OSAGE = HB_TAG ('O','s','g','e'), /*9.0*/ + HB_SCRIPT_TANGUT = HB_TAG ('T','a','n','g'), /*9.0*/ + HB_SCRIPT_NEWA = HB_TAG ('N','e','w','a'), /*9.0*/ /* * Since 1.6.0 */ - /*10.0*/HB_SCRIPT_MASARAM_GONDI = HB_TAG ('G','o','n','m'), - /*10.0*/HB_SCRIPT_NUSHU = HB_TAG ('N','s','h','u'), - /*10.0*/HB_SCRIPT_SOYOMBO = HB_TAG ('S','o','y','o'), - /*10.0*/HB_SCRIPT_ZANABAZAR_SQUARE = HB_TAG ('Z','a','n','b'), + HB_SCRIPT_MASARAM_GONDI = HB_TAG ('G','o','n','m'), /*10.0*/ + HB_SCRIPT_NUSHU = HB_TAG ('N','s','h','u'), /*10.0*/ + HB_SCRIPT_SOYOMBO = HB_TAG ('S','o','y','o'), /*10.0*/ + HB_SCRIPT_ZANABAZAR_SQUARE = HB_TAG ('Z','a','n','b'), /*10.0*/ /* * Since 1.8.0 */ - /*11.0*/HB_SCRIPT_DOGRA = HB_TAG ('D','o','g','r'), - /*11.0*/HB_SCRIPT_GUNJALA_GONDI = HB_TAG ('G','o','n','g'), - /*11.0*/HB_SCRIPT_HANIFI_ROHINGYA = HB_TAG ('R','o','h','g'), - /*11.0*/HB_SCRIPT_MAKASAR = HB_TAG ('M','a','k','a'), - /*11.0*/HB_SCRIPT_MEDEFAIDRIN = HB_TAG ('M','e','d','f'), - /*11.0*/HB_SCRIPT_OLD_SOGDIAN = HB_TAG ('S','o','g','o'), - /*11.0*/HB_SCRIPT_SOGDIAN = HB_TAG ('S','o','g','d'), + HB_SCRIPT_DOGRA = HB_TAG ('D','o','g','r'), /*11.0*/ + HB_SCRIPT_GUNJALA_GONDI = HB_TAG ('G','o','n','g'), /*11.0*/ + HB_SCRIPT_HANIFI_ROHINGYA = HB_TAG ('R','o','h','g'), /*11.0*/ + HB_SCRIPT_MAKASAR = HB_TAG ('M','a','k','a'), /*11.0*/ + HB_SCRIPT_MEDEFAIDRIN = HB_TAG ('M','e','d','f'), /*11.0*/ + HB_SCRIPT_OLD_SOGDIAN = HB_TAG ('S','o','g','o'), /*11.0*/ + HB_SCRIPT_SOGDIAN = HB_TAG ('S','o','g','d'), /*11.0*/ /* * Since 2.4.0 */ - /*12.0*/HB_SCRIPT_ELYMAIC = HB_TAG ('E','l','y','m'), - /*12.0*/HB_SCRIPT_NANDINAGARI = HB_TAG ('N','a','n','d'), - /*12.0*/HB_SCRIPT_NYIAKENG_PUACHUE_HMONG = HB_TAG ('H','m','n','p'), - /*12.0*/HB_SCRIPT_WANCHO = HB_TAG ('W','c','h','o'), + HB_SCRIPT_ELYMAIC = HB_TAG ('E','l','y','m'), /*12.0*/ + HB_SCRIPT_NANDINAGARI = HB_TAG ('N','a','n','d'), /*12.0*/ + HB_SCRIPT_NYIAKENG_PUACHUE_HMONG = HB_TAG ('H','m','n','p'), /*12.0*/ + HB_SCRIPT_WANCHO = HB_TAG ('W','c','h','o'), /*12.0*/ + + /* + * Since 2.6.7 + */ + HB_SCRIPT_CHORASMIAN = HB_TAG ('C','h','r','s'), /*13.0*/ + HB_SCRIPT_DIVES_AKURU = HB_TAG ('D','i','a','k'), /*13.0*/ + HB_SCRIPT_KHITAN_SMALL_SCRIPT = HB_TAG ('K','i','t','s'), /*13.0*/ + HB_SCRIPT_YEZIDI = HB_TAG ('Y','e','z','i'), /*13.0*/ /* No script set. */ - HB_SCRIPT_INVALID = HB_TAG_NONE, + HB_SCRIPT_INVALID = HB_TAG_NONE, + + /*< private >*/ /* Dummy values to ensure any hb_tag_t value can be passed/stored as hb_script_t * without risking undefined behavior. We have two, for historical reasons. @@ -402,24 +720,44 @@ hb_script_get_horizontal_direction (hb_script_t script); /* User data */ +/** + * hb_user_data_key_t: + * + * Data structure for holding user-data keys. + * + **/ typedef struct hb_user_data_key_t { /*< private >*/ char unused; } hb_user_data_key_t; +/** + * hb_destroy_func_t: + * @user_data: the data to be destroyed + * + * A virtual method for destroy user-data callbacks. + * + */ typedef void (*hb_destroy_func_t) (void *user_data); /* Font features and variations. */ /** - * HB_FEATURE_GLOBAL_START + * HB_FEATURE_GLOBAL_START: + * + * Special setting for #hb_feature_t.start to apply the feature from the start + * of the buffer. * * Since: 2.0.0 */ #define HB_FEATURE_GLOBAL_START 0 + /** - * HB_FEATURE_GLOBAL_END + * HB_FEATURE_GLOBAL_END: + * + * Special setting for #hb_feature_t.end to apply the feature from to the end + * of the buffer. * * Since: 2.0.0 */ @@ -427,17 +765,17 @@ typedef void (*hb_destroy_func_t) (void *user_data); /** * hb_feature_t: - * @tag: a feature tag - * @value: 0 disables the feature, non-zero (usually 1) enables the feature. - * For features implemented as lookup type 3 (like 'salt') the @value is a one - * based index into the alternates. + * @tag: The #hb_tag_t tag of the feature + * @value: The value of the feature. 0 disables the feature, non-zero (usually + * 1) enables the feature. For features implemented as lookup type 3 (like + * 'salt') the @value is a one based index into the alternates. * @start: the cluster to start applying this feature setting (inclusive). * @end: the cluster to end applying this feature setting (exclusive). * * The #hb_feature_t is the structure that holds information about requested * feature application. The feature will be applied with the given value to all * glyphs which are in clusters between @start (inclusive) and @end (exclusive). - * Setting start to @HB_FEATURE_GLOBAL_START and end to @HB_FEATURE_GLOBAL_END + * Setting start to #HB_FEATURE_GLOBAL_START and end to #HB_FEATURE_GLOBAL_END * specifies that the feature always applies to the entire buffer. */ typedef struct hb_feature_t { @@ -457,7 +795,13 @@ hb_feature_to_string (hb_feature_t *feature, /** * hb_variation_t: + * @tag: The #hb_tag_t tag of the variation-axis name + * @value: The value of the variation axis * + * Data type for holding variation data. Registered OpenType + * variation-axis tags are listed in + * [OpenType Axis Tag Registry](https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxisreg). + * * Since: 1.4.2 */ typedef struct hb_variation_t { @@ -476,12 +820,24 @@ hb_variation_to_string (hb_variation_t *variation, /** * hb_color_t: * - * Data type for holding color values. + * Data type for holding color values. Colors are eight bits per + * channel RGB plus alpha transparency. * * Since: 2.1.0 */ typedef uint32_t hb_color_t; +/** + * HB_COLOR: + * @b: blue channel value + * @g: green channel value + * @r: red channel value + * @a: alpha channel value + * + * Constructs an #hb_color_t from four integers. + * + * Since: 2.1.0 + */ #define HB_COLOR(b,g,r,a) ((hb_color_t) HB_TAG ((b),(g),(r),(a))) HB_EXTERN uint8_t diff --git a/src/3rdparty/harfbuzz-ng/src/hb-config.hh b/src/3rdparty/harfbuzz-ng/src/hb-config.hh index 14c5395952..fc8d424bfb 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-config.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-config.hh @@ -58,6 +58,7 @@ #define HB_NO_BITMAP #define HB_NO_CFF #define HB_NO_COLOR +#define HB_NO_DRAW #define HB_NO_ERRNO #define HB_NO_FACE_COLLECT_UNICODES #define HB_NO_GETENV @@ -75,7 +76,7 @@ #define HB_NO_SETLOCALE #define HB_NO_OT_FONT_GLYPH_NAMES #define HB_NO_OT_SHAPE_FRACTIONS -#define HB_NO_STAT +#define HB_NO_STYLE #define HB_NO_SUBSET_LAYOUT #define HB_NO_VAR #endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc index 8885cfe730..461bd20e65 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc @@ -34,7 +34,6 @@ #include "hb-coretext.h" #include "hb-aat-layout.hh" -#include <math.h> /** @@ -190,7 +189,10 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size) * reconfiguring the cascade list causes CoreText crashes. For details, see * crbug.com/549610 */ // 0x00070000 stands for "kCTVersionNumber10_10", see CoreText.h +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" if (&CTGetCoreTextVersion != nullptr && CTGetCoreTextVersion() < 0x00070000) { +#pragma GCC diagnostic pop CFStringRef fontName = CTFontCopyPostScriptName (ct_font); bool isEmojiFont = CFStringCompare (fontName, CFSTR("AppleColorEmoji"), 0) == kCFCompareEqualTo; CFRelease (fontName); @@ -278,13 +280,32 @@ _hb_coretext_shaper_face_data_destroy (hb_coretext_face_data_t *data) CFRelease ((CGFontRef) data); } +/** + * hb_coretext_face_create: + * @cg_font: The CGFontRef to work upon + * + * Creates an #hb_face_t face object from the specified + * CGFontRef. + * + * Return value: the new #hb_face_t face object + * + * Since: 0.9.10 + */ hb_face_t * hb_coretext_face_create (CGFontRef cg_font) { return hb_face_create_for_tables (_hb_cg_reference_table, CGFontRetain (cg_font), _hb_cg_font_release); } -/* +/** + * hb_coretext_face_get_cg_font: + * @face: The #hb_face_t to work upon + * + * Fetches the CGFontRef associated with an #hb_face_t + * face object + * + * Return value: the CGFontRef found + * * Since: 0.9.10 */ CGFontRef @@ -327,7 +348,7 @@ retry: const hb_coretext_font_data_t *data = font->data.coretext; if (unlikely (!data)) return nullptr; - if (fabs (CTFontGetSize ((CTFontRef) data) - (CGFloat) font->ptem) > .5) + if (fabs (CTFontGetSize ((CTFontRef) data) - (CGFloat) font->ptem) > (CGFloat) .5) { /* XXX-MT-bug * Note that evaluating condition above can be dangerous if another thread @@ -351,10 +372,17 @@ retry: return font->data.coretext; } - -/* +/** + * hb_coretext_font_create: + * @ct_font: The CTFontRef to work upon + * + * Creates an #hb_font_t font object from the specified + * CTFontRef. + * + * Return value: the new #hb_font_t font object + * * Since: 1.7.2 - */ + **/ hb_font_t * hb_coretext_font_create (CTFontRef ct_font) { @@ -375,6 +403,17 @@ hb_coretext_font_create (CTFontRef ct_font) return font; } +/** + * hb_coretext_font_get_ct_font: + * @font: #hb_font_t to work upon + * + * Fetches the CTFontRef associated with the specified + * #hb_font_t font object. + * + * Return value: the CTFontRef found + * + * Since: 0.9.10 + */ CTFontRef hb_coretext_font_get_ct_font (hb_font_t *font) { @@ -475,13 +514,19 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, hb_vector_t<feature_event_t> feature_events; for (unsigned int i = 0; i < num_features; i++) { + active_feature_t feature; + +#if MAC_OS_X_VERSION_MIN_REQUIRED < 101000 const hb_aat_feature_mapping_t * mapping = hb_aat_layout_find_feature_mapping (features[i].tag); if (!mapping) continue; - active_feature_t feature; feature.rec.feature = mapping->aatFeatureType; feature.rec.setting = features[i].value ? mapping->selectorToEnable : mapping->selectorToDisable; +#else + feature.rec.feature = features[i].tag; + feature.rec.setting = features[i].value; +#endif feature.order = i; feature_event_t *event; @@ -530,6 +575,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, /* active_features.qsort (); */ for (unsigned int j = 0; j < active_features.length; j++) { +#if MAC_OS_X_VERSION_MIN_REQUIRED < 101000 CFStringRef keys[] = { kCTFontFeatureTypeIdentifierKey, kCTFontFeatureSelectorIdentifierKey @@ -538,6 +584,17 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_features[j].rec.feature), CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_features[j].rec.setting) }; +#else + char tag[5] = {HB_UNTAG (active_features[j].rec.feature)}; + CFTypeRef keys[] = { + kCTFontOpenTypeFeatureTag, + kCTFontOpenTypeFeatureValue + }; + CFTypeRef values[] = { + CFStringCreateWithCString (kCFAllocatorDefault, tag, kCFStringEncodingASCII), + CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_features[j].rec.setting) + }; +#endif static_assert ((ARRAY_LENGTH_CONST (keys) == ARRAY_LENGTH_CONST (values)), ""); CFDictionaryRef dict = CFDictionaryCreate (kCFAllocatorDefault, (const void **) keys, @@ -605,7 +662,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, scratch_size -= _consumed; \ } while (0) - ALLOCATE_ARRAY (UniChar, pchars, buffer->len * 2, /*nothing*/); + ALLOCATE_ARRAY (UniChar, pchars, buffer->len * 2, ((void)nullptr) /*nothing*/); unsigned int chars_len = 0; for (unsigned int i = 0; i < buffer->len; i++) { hb_codepoint_t c = buffer->info[i].codepoint; @@ -619,7 +676,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, } } - ALLOCATE_ARRAY (unsigned int, log_clusters, chars_len, /*nothing*/); + ALLOCATE_ARRAY (unsigned int, log_clusters, chars_len, ((void)nullptr) /*nothing*/); chars_len = 0; for (unsigned int i = 0; i < buffer->len; i++) { @@ -803,7 +860,7 @@ resize_and_retry: buffer->len = 0; uint32_t status_and = ~0, status_or = 0; - double advances_so_far = 0; + CGFloat advances_so_far = 0; /* For right-to-left runs, CoreText returns the glyphs positioned such that * any trailing whitespace is to the left of (0,0). Adjust coordinate system * to fix for that. Test with any RTL string with trailing spaces. @@ -825,10 +882,10 @@ resize_and_retry: status_or |= run_status; status_and &= run_status; DEBUG_MSG (CORETEXT, run, "CTRunStatus: %x", run_status); - double run_advance = CTRunGetTypographicBounds (run, range_all, nullptr, nullptr, nullptr); + CGFloat run_advance = CTRunGetTypographicBounds (run, range_all, nullptr, nullptr, nullptr); if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction)) run_advance = -run_advance; - DEBUG_MSG (CORETEXT, run, "Run advance: %g", run_advance); + DEBUG_MSG (CORETEXT, run, "Run advance: %g", (double) run_advance); /* CoreText does automatic font fallback (AKA "cascading") for characters * not supported by the requested font, and provides no way to turn it off, @@ -1007,7 +1064,7 @@ resize_and_retry: hb_position_t x_offset = (positions[0].x - advances_so_far) * x_mult; for (unsigned int j = 0; j < num_glyphs; j++) { - double advance; + CGFloat advance; if (likely (j + 1 < num_glyphs)) advance = positions[j + 1].x - positions[j].x; else /* last glyph */ @@ -1023,7 +1080,7 @@ resize_and_retry: hb_position_t y_offset = (positions[0].y - advances_so_far) * y_mult; for (unsigned int j = 0; j < num_glyphs; j++) { - double advance; + CGFloat advance; if (likely (j + 1 < num_glyphs)) advance = positions[j + 1].y - positions[j].y; else /* last glyph */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-coretext.h b/src/3rdparty/harfbuzz-ng/src/hb-coretext.h index 4b0a6f01b6..e53dbaf2c7 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-coretext.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-coretext.h @@ -40,8 +40,40 @@ HB_BEGIN_DECLS +/** + * HB_CORETEXT_TAG_MORT: + * + * The #hb_tag_t tag for the `mort` (glyph metamorphosis) table, + * which holds AAT features. + * + * For more information, see + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6mort.html + * + **/ #define HB_CORETEXT_TAG_MORT HB_TAG('m','o','r','t') + +/** + * HB_CORETEXT_TAG_MORX: + * + * The #hb_tag_t tag for the `morx` (extended glyph metamorphosis) + * table, which holds AAT features. + * + * For more information, see + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6morx.html + * + **/ #define HB_CORETEXT_TAG_MORX HB_TAG('m','o','r','x') + +/** + * HB_CORETEXT_TAG_KERX: + * + * The #hb_tag_t tag for the `kerx` (extended kerning) table, which + * holds AAT kerning information. + * + * For more information, see + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6kerx.html + * + **/ #define HB_CORETEXT_TAG_KERX HB_TAG('k','e','r','x') diff --git a/src/3rdparty/harfbuzz-ng/src/hb-debug.hh b/src/3rdparty/harfbuzz-ng/src/hb-debug.hh index a7e52c8cbe..ec3a1ff211 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-debug.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-debug.hh @@ -46,7 +46,6 @@ struct hb_options_t bool unused : 1; /* In-case sign bit is here. */ bool initialized : 1; bool uniscribe_bug_compatible : 1; - bool aat : 1; }; union hb_options_union_t { @@ -230,7 +229,7 @@ _hb_debug_msg<0> (const char *what HB_UNUSED, ...) {} #define DEBUG_MSG_LEVEL(WHAT, OBJ, LEVEL, LEVEL_DIR, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), nullptr, true, (LEVEL), (LEVEL_DIR), __VA_ARGS__) -#define DEBUG_MSG(WHAT, OBJ, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), nullptr, false, 0, 0, __VA_ARGS__) +#define DEBUG_MSG(WHAT, OBJ, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), nullptr, false, 0, 0, __VA_ARGS__) #define DEBUG_MSG_FUNC(WHAT, OBJ, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), HB_FUNC, false, 0, 0, __VA_ARGS__) @@ -374,10 +373,6 @@ struct hb_no_trace_t { #define HB_DEBUG_FT (HB_DEBUG+0) #endif -#ifndef HB_DEBUG_GET_COVERAGE -#define HB_DEBUG_GET_COVERAGE (HB_DEBUG+0) -#endif - #ifndef HB_DEBUG_OBJECT #define HB_DEBUG_OBJECT (HB_DEBUG+0) #endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h b/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h index 43f89a4c4e..5f19125789 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h @@ -24,7 +24,7 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_H_IN +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb.h> instead." #endif @@ -53,11 +53,50 @@ HB_BEGIN_DECLS #ifndef HB_DISABLE_DEPRECATED +/** + * HB_SCRIPT_CANADIAN_ABORIGINAL: + * + * Use #HB_SCRIPT_CANADIAN_SYLLABICS instead: + * + * Deprecated: 0.9.20 + */ #define HB_SCRIPT_CANADIAN_ABORIGINAL HB_SCRIPT_CANADIAN_SYLLABICS +/** + * HB_BUFFER_FLAGS_DEFAULT: + * + * Use #HB_BUFFER_FLAG_DEFAULT instead. + * + * Deprecated: 0.9.20 + */ #define HB_BUFFER_FLAGS_DEFAULT HB_BUFFER_FLAG_DEFAULT +/** + * HB_BUFFER_SERIALIZE_FLAGS_DEFAULT: + * + * Use #HB_BUFFER_SERIALIZE_FLAG_DEFAULT instead. + * + * Deprecated: 0.9.20 + */ #define HB_BUFFER_SERIALIZE_FLAGS_DEFAULT HB_BUFFER_SERIALIZE_FLAG_DEFAULT +/** + * hb_font_get_glyph_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @unicode: The Unicode code point to query + * @variation_selector: The variation-selector code point to query + * @glyph: (out): The glyph ID retrieved + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the glyph ID for a specified Unicode code point + * font, with an optional variation selector. + * + * Return value: %true if data found, %false otherwise + * Deprecated: 1.2.3 + * + **/ typedef hb_bool_t (*hb_font_get_glyph_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t unicode, hb_codepoint_t variation_selector, hb_codepoint_t *glyph, @@ -73,6 +112,11 @@ hb_set_invert (hb_set_t *set); /** * hb_unicode_eastasian_width_func_t: + * @ufuncs: A Unicode-functions structure + * @unicode: The code point to query + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_unicode_funcs_t structure. * * Deprecated: 2.0.0 */ @@ -82,12 +126,12 @@ typedef unsigned int (*hb_unicode_eastasian_width_func_t) (hb_unicode_funcs_t /** * hb_unicode_funcs_set_eastasian_width_func: - * @ufuncs: a Unicode function structure - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: + * @ufuncs: a Unicode-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * - * + * Sets the implementation function for #hb_unicode_eastasian_width_func_t. * * Since: 0.9.2 * Deprecated: 2.0.0 @@ -99,6 +143,10 @@ hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs, /** * hb_unicode_eastasian_width: + * @ufuncs: a Unicode-function structure + * @unicode: The code point to query + * + * Don't use. Not used by HarfBuzz. * * Since: 0.9.2 * Deprecated: 2.0.0 @@ -112,7 +160,7 @@ hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs, * hb_unicode_decompose_compatibility_func_t: * @ufuncs: a Unicode function structure * @u: codepoint to decompose - * @decomposed: address of codepoint array (of length %HB_UNICODE_MAX_DECOMPOSITION_LEN) to write decomposition into + * @decomposed: address of codepoint array (of length #HB_UNICODE_MAX_DECOMPOSITION_LEN) to write decomposition into * @user_data: user data pointer as passed to hb_unicode_funcs_set_decompose_compatibility_func() * * Fully decompose @u to its Unicode compatibility decomposition. The codepoints of the decomposition will be written to @decomposed. @@ -120,7 +168,7 @@ hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs, * * If @u has no compatibility decomposition, zero should be returned. * - * The Unicode standard guarantees that a buffer of length %HB_UNICODE_MAX_DECOMPOSITION_LEN codepoints will always be sufficient for any + * The Unicode standard guarantees that a buffer of length #HB_UNICODE_MAX_DECOMPOSITION_LEN codepoints will always be sufficient for any * compatibility decomposition plus an terminating value of 0. Consequently, @decompose must be allocated by the caller to be at least this length. Implementations * of this function type must ensure that they do not write past the provided array. * @@ -144,10 +192,12 @@ typedef unsigned int (*hb_unicode_decompose_compatibility_func_t) (hb_unicode_ /** * hb_unicode_funcs_set_decompose_compatibility_func: - * @ufuncs: a Unicode function structure - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: + * @ufuncs: A Unicode-functions structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore + * + * Sets the implementation function for #hb_unicode_decompose_compatibility_func_t. * * * @@ -165,16 +215,25 @@ hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs, hb_codepoint_t *decomposed); +/** + * hb_font_get_glyph_v_kerning_func_t: + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the kerning-adjustment value for a glyph-pair in + * the specified font, for vertical text segments. + * + **/ typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_v_kerning_func_t; /** * hb_font_funcs_set_glyph_v_kerning_func: - * @ffuncs: font functions. - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * - * + * Sets the implementation function for #hb_font_get_glyph_v_kerning_func_t. * * Since: 0.9.2 * Deprecated: 2.0.0 diff --git a/src/3rdparty/harfbuzz-ng/src/hb-directwrite.cc b/src/3rdparty/harfbuzz-ng/src/hb-directwrite.cc index efb2029ec0..a07302159c 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-directwrite.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-directwrite.cc @@ -33,6 +33,15 @@ #include "hb-directwrite.h" +/** + * SECTION:hb-directwrite + * @title: hb-directwrite + * @short_description: DirectWrite integration + * @include: hb-directwrite.h + * + * Functions for using HarfBuzz with DirectWrite fonts. + **/ + /* Declare object creator for dynamic support of DWRITE */ typedef HRESULT (* WINAPI t_DWriteCreateFactory)( DWRITE_FACTORY_TYPE factoryType, @@ -635,7 +644,7 @@ _hb_directwrite_shape_full (hb_shape_plan_t *shape_plan, bool isRightToLeft = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); const wchar_t localeName[20] = {0}; - if (buffer->props.language != nullptr) + if (buffer->props.language) mbstowcs ((wchar_t*) localeName, hb_language_to_string (buffer->props.language), 20); @@ -948,6 +957,8 @@ _hb_directwrite_font_release (void *data) * hb_directwrite_face_create: * @font_face: a DirectWrite IDWriteFontFace object. * + * Constructs a new face object from the specified DirectWrite IDWriteFontFace. + * * Return value: #hb_face_t object corresponding to the given input * * Since: 2.4.0 @@ -965,6 +976,8 @@ hb_directwrite_face_create (IDWriteFontFace *font_face) * hb_directwrite_face_get_font_face: * @face: a #hb_face_t object * +* Gets the DirectWrite IDWriteFontFace associated with @face. +* * Return value: DirectWrite IDWriteFontFace object corresponding to the given input * * Since: 2.5.0 diff --git a/src/3rdparty/harfbuzz-ng/src/hb-dispatch.hh b/src/3rdparty/harfbuzz-ng/src/hb-dispatch.hh index 1ce3fac936..4b2b65a8de 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-dispatch.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-dispatch.hh @@ -35,7 +35,7 @@ * Dispatch */ -template <typename Context, typename Return, unsigned int MaxDebugDepth> +template <typename Context, typename Return=hb_empty_t, unsigned int MaxDebugDepth=0> struct hb_dispatch_context_t { private: @@ -43,6 +43,7 @@ struct hb_dispatch_context_t const Context* thiz () const { return static_cast<const Context *> (this); } Context* thiz () { return static_cast< Context *> (this); } public: + const char *get_name () { return "UNKNOWN"; } static constexpr unsigned max_debug_depth = MaxDebugDepth; typedef Return return_t; template <typename T, typename F> @@ -52,6 +53,7 @@ struct hb_dispatch_context_t { return obj.dispatch (thiz (), hb_forward<Ts> (ds)...); } static return_t no_dispatch_return_value () { return Context::default_return_value (); } static bool stop_sublookup_iteration (const return_t r HB_UNUSED) { return false; } + unsigned debug_depth = 0; }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-draw.cc b/src/3rdparty/harfbuzz-ng/src/hb-draw.cc new file mode 100644 index 0000000000..1a5f9c8c6b --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-draw.cc @@ -0,0 +1,261 @@ +/* + * Copyright © 2019-2020 Ebrahim Byagowi + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#include "hb.hh" + +#ifndef HB_NO_DRAW +#ifdef HB_EXPERIMENTAL_API + +#include "hb-draw.hh" +#include "hb-ot.h" +#include "hb-ot-glyf-table.hh" +#include "hb-ot-cff1-table.hh" +#include "hb-ot-cff2-table.hh" + +/** + * hb_draw_funcs_set_move_to_func: + * @funcs: draw functions object + * @move_to: move-to callback + * + * Sets move-to callback to the draw functions object. + * + * Since: EXPERIMENTAL + **/ +void +hb_draw_funcs_set_move_to_func (hb_draw_funcs_t *funcs, + hb_draw_move_to_func_t move_to) +{ + if (unlikely (hb_object_is_immutable (funcs))) return; + funcs->move_to = move_to; +} + +/** + * hb_draw_funcs_set_line_to_func: + * @funcs: draw functions object + * @line_to: line-to callback + * + * Sets line-to callback to the draw functions object. + * + * Since: EXPERIMENTAL + **/ +void +hb_draw_funcs_set_line_to_func (hb_draw_funcs_t *funcs, + hb_draw_line_to_func_t line_to) +{ + if (unlikely (hb_object_is_immutable (funcs))) return; + funcs->line_to = line_to; +} + +/** + * hb_draw_funcs_set_quadratic_to_func: + * @funcs: draw functions object + * @move_to: quadratic-to callback + * + * Sets quadratic-to callback to the draw functions object. + * + * Since: EXPERIMENTAL + **/ +void +hb_draw_funcs_set_quadratic_to_func (hb_draw_funcs_t *funcs, + hb_draw_quadratic_to_func_t quadratic_to) +{ + if (unlikely (hb_object_is_immutable (funcs))) return; + funcs->quadratic_to = quadratic_to; + funcs->is_quadratic_to_set = true; +} + +/** + * hb_draw_funcs_set_cubic_to_func: + * @funcs: draw functions + * @cubic_to: cubic-to callback + * + * Sets cubic-to callback to the draw functions object. + * + * Since: EXPERIMENTAL + **/ +void +hb_draw_funcs_set_cubic_to_func (hb_draw_funcs_t *funcs, + hb_draw_cubic_to_func_t cubic_to) +{ + if (unlikely (hb_object_is_immutable (funcs))) return; + funcs->cubic_to = cubic_to; +} + +/** + * hb_draw_funcs_set_close_path_func: + * @funcs: draw functions object + * @close_path: close-path callback + * + * Sets close-path callback to the draw functions object. + * + * Since: EXPERIMENTAL + **/ +void +hb_draw_funcs_set_close_path_func (hb_draw_funcs_t *funcs, + hb_draw_close_path_func_t close_path) +{ + if (unlikely (hb_object_is_immutable (funcs))) return; + funcs->close_path = close_path; +} + +static void +_move_to_nil (hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED, void *user_data HB_UNUSED) {} + +static void +_line_to_nil (hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED, void *user_data HB_UNUSED) {} + +static void +_quadratic_to_nil (hb_position_t control_x HB_UNUSED, hb_position_t control_y HB_UNUSED, + hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED, + void *user_data HB_UNUSED) {} + +static void +_cubic_to_nil (hb_position_t control1_x HB_UNUSED, hb_position_t control1_y HB_UNUSED, + hb_position_t control2_x HB_UNUSED, hb_position_t control2_y HB_UNUSED, + hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED, + void *user_data HB_UNUSED) {} + +static void +_close_path_nil (void *user_data HB_UNUSED) {} + +/** + * hb_draw_funcs_create: + * + * Creates a new draw callbacks object. + * + * Since: EXPERIMENTAL + **/ +hb_draw_funcs_t * +hb_draw_funcs_create () +{ + hb_draw_funcs_t *funcs; + if (unlikely (!(funcs = hb_object_create<hb_draw_funcs_t> ()))) + return const_cast<hb_draw_funcs_t *> (&Null (hb_draw_funcs_t)); + + funcs->move_to = (hb_draw_move_to_func_t) _move_to_nil; + funcs->line_to = (hb_draw_line_to_func_t) _line_to_nil; + funcs->quadratic_to = (hb_draw_quadratic_to_func_t) _quadratic_to_nil; + funcs->is_quadratic_to_set = false; + funcs->cubic_to = (hb_draw_cubic_to_func_t) _cubic_to_nil; + funcs->close_path = (hb_draw_close_path_func_t) _close_path_nil; + return funcs; +} + +/** + * hb_draw_funcs_reference: + * @funcs: draw functions + * + * Add to callbacks object refcount. + * + * Returns: The same object. + * Since: EXPERIMENTAL + **/ +hb_draw_funcs_t * +hb_draw_funcs_reference (hb_draw_funcs_t *funcs) +{ + return hb_object_reference (funcs); +} + +/** + * hb_draw_funcs_destroy: + * @funcs: draw functions + * + * Decreases refcount of callbacks object and deletes the object if it reaches + * to zero. + * + * Since: EXPERIMENTAL + **/ +void +hb_draw_funcs_destroy (hb_draw_funcs_t *funcs) +{ + if (!hb_object_destroy (funcs)) return; + + free (funcs); +} + +/** + * hb_draw_funcs_make_immutable: + * @funcs: draw functions + * + * Makes funcs object immutable. + * + * Since: EXPERIMENTAL + **/ +void +hb_draw_funcs_make_immutable (hb_draw_funcs_t *funcs) +{ + if (hb_object_is_immutable (funcs)) + return; + + hb_object_make_immutable (funcs); +} + +/** + * hb_draw_funcs_is_immutable: + * @funcs: draw functions + * + * Checks whether funcs is immutable. + * + * Returns: If is immutable. + * Since: EXPERIMENTAL + **/ +hb_bool_t +hb_draw_funcs_is_immutable (hb_draw_funcs_t *funcs) +{ + return hb_object_is_immutable (funcs); +} + +/** + * hb_font_draw_glyph: + * @font: a font object + * @glyph: a glyph id + * @funcs: draw callbacks object + * @user_data: parameter you like be passed to the callbacks when are called + * + * Draw a glyph. + * + * Returns: Whether the font had the glyph and the operation completed successfully. + * Since: EXPERIMENTAL + **/ +hb_bool_t +hb_font_draw_glyph (hb_font_t *font, hb_codepoint_t glyph, + const hb_draw_funcs_t *funcs, + void *user_data) +{ + if (unlikely (funcs == &Null (hb_draw_funcs_t) || + glyph >= font->face->get_num_glyphs ())) + return false; + + draw_helper_t draw_helper (funcs, user_data); + if (font->face->table.glyf->get_path (font, glyph, draw_helper)) return true; +#ifndef HB_NO_CFF + if (font->face->table.cff1->get_path (font, glyph, draw_helper)) return true; + if (font->face->table.cff2->get_path (font, glyph, draw_helper)) return true; +#endif + + return false; +} + +#endif +#endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-draw.h b/src/3rdparty/harfbuzz-ng/src/hb-draw.h new file mode 100644 index 0000000000..bddc876399 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-draw.h @@ -0,0 +1,98 @@ +/* + * Copyright © 2019-2020 Ebrahim Byagowi + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) +#error "Include <hb.h> instead." +#endif + +#ifndef HB_DRAW_H +#define HB_DRAW_H + +#include "hb.h" + +HB_BEGIN_DECLS + +#ifdef HB_EXPERIMENTAL_API +typedef void (*hb_draw_move_to_func_t) (hb_position_t to_x, hb_position_t to_y, void *user_data); +typedef void (*hb_draw_line_to_func_t) (hb_position_t to_x, hb_position_t to_y, void *user_data); +typedef void (*hb_draw_quadratic_to_func_t) (hb_position_t control_x, hb_position_t control_y, + hb_position_t to_x, hb_position_t to_y, + void *user_data); +typedef void (*hb_draw_cubic_to_func_t) (hb_position_t control1_x, hb_position_t control1_y, + hb_position_t control2_x, hb_position_t control2_y, + hb_position_t to_x, hb_position_t to_y, + void *user_data); +typedef void (*hb_draw_close_path_func_t) (void *user_data); + +/** + * hb_draw_funcs_t: + * + * Glyph draw callbacks. + * + * _move_to, _line_to and _cubic_to calls are nessecary to be defined but we + * translate _quadratic_to calls to _cubic_to if the callback isn't defined. + * + * Since: EXPERIMENTAL + **/ +typedef struct hb_draw_funcs_t hb_draw_funcs_t; + +HB_EXTERN void +hb_draw_funcs_set_move_to_func (hb_draw_funcs_t *funcs, + hb_draw_move_to_func_t move_to); + +HB_EXTERN void +hb_draw_funcs_set_line_to_func (hb_draw_funcs_t *funcs, + hb_draw_line_to_func_t line_to); + +HB_EXTERN void +hb_draw_funcs_set_quadratic_to_func (hb_draw_funcs_t *funcs, + hb_draw_quadratic_to_func_t quadratic_to); + +HB_EXTERN void +hb_draw_funcs_set_cubic_to_func (hb_draw_funcs_t *funcs, + hb_draw_cubic_to_func_t cubic_to); + +HB_EXTERN void +hb_draw_funcs_set_close_path_func (hb_draw_funcs_t *funcs, + hb_draw_close_path_func_t close_path); + +HB_EXTERN hb_draw_funcs_t * +hb_draw_funcs_create (void); + +HB_EXTERN hb_draw_funcs_t * +hb_draw_funcs_reference (hb_draw_funcs_t *funcs); + +HB_EXTERN void +hb_draw_funcs_destroy (hb_draw_funcs_t *funcs); + +HB_EXTERN void +hb_draw_funcs_make_immutable (hb_draw_funcs_t *funcs); + +HB_EXTERN hb_bool_t +hb_draw_funcs_is_immutable (hb_draw_funcs_t *funcs); +#endif + +HB_END_DECLS + +#endif /* HB_DRAW_H */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-draw.hh b/src/3rdparty/harfbuzz-ng/src/hb-draw.hh new file mode 100644 index 0000000000..2aa0a5b4db --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-draw.hh @@ -0,0 +1,139 @@ +/* + * Copyright © 2020 Ebrahim Byagowi + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#ifndef HB_DRAW_HH +#define HB_DRAW_HH + +#include "hb.hh" + +#ifdef HB_EXPERIMENTAL_API +struct hb_draw_funcs_t +{ + hb_object_header_t header; + + hb_draw_move_to_func_t move_to; + hb_draw_line_to_func_t line_to; + hb_draw_quadratic_to_func_t quadratic_to; + bool is_quadratic_to_set; + hb_draw_cubic_to_func_t cubic_to; + hb_draw_close_path_func_t close_path; +}; + +struct draw_helper_t +{ + draw_helper_t (const hb_draw_funcs_t *funcs_, void *user_data_) + { + funcs = funcs_; + user_data = user_data_; + path_open = false; + path_start_x = current_x = path_start_y = current_y = 0; + } + ~draw_helper_t () { end_path (); } + + void move_to (hb_position_t x, hb_position_t y) + { + if (path_open) end_path (); + current_x = path_start_x = x; + current_y = path_start_y = y; + } + + void line_to (hb_position_t x, hb_position_t y) + { + if (equal_to_current (x, y)) return; + if (!path_open) start_path (); + funcs->line_to (x, y, user_data); + current_x = x; + current_y = y; + } + + void + quadratic_to (hb_position_t control_x, hb_position_t control_y, + hb_position_t to_x, hb_position_t to_y) + { + if (equal_to_current (control_x, control_y) && equal_to_current (to_x, to_y)) + return; + if (!path_open) start_path (); + if (funcs->is_quadratic_to_set) + funcs->quadratic_to (control_x, control_y, to_x, to_y, user_data); + else + funcs->cubic_to (roundf ((current_x + 2.f * control_x) / 3.f), + roundf ((current_y + 2.f * control_y) / 3.f), + roundf ((to_x + 2.f * control_x) / 3.f), + roundf ((to_y + 2.f * control_y) / 3.f), + to_x, to_y, user_data); + current_x = to_x; + current_y = to_y; + } + + void + cubic_to (hb_position_t control1_x, hb_position_t control1_y, + hb_position_t control2_x, hb_position_t control2_y, + hb_position_t to_x, hb_position_t to_y) + { + if (equal_to_current (control1_x, control1_y) && + equal_to_current (control2_x, control2_y) && + equal_to_current (to_x, to_y)) + return; + if (!path_open) start_path (); + funcs->cubic_to (control1_x, control1_y, control2_x, control2_y, to_x, to_y, user_data); + current_x = to_x; + current_y = to_y; + } + + void end_path () + { + if (path_open) + { + if ((path_start_x != current_x) || (path_start_y != current_y)) + funcs->line_to (path_start_x, path_start_y, user_data); + funcs->close_path (user_data); + } + path_open = false; + path_start_x = current_x = path_start_y = current_y = 0; + } + + protected: + bool equal_to_current (hb_position_t x, hb_position_t y) + { return current_x == x && current_y == y; } + + void start_path () + { + if (path_open) end_path (); + path_open = true; + funcs->move_to (path_start_x, path_start_y, user_data); + } + + hb_position_t path_start_x; + hb_position_t path_start_y; + + hb_position_t current_x; + hb_position_t current_y; + + bool path_open; + const hb_draw_funcs_t *funcs; + void *user_data; +}; +#endif + +#endif /* HB_DRAW_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-face.cc b/src/3rdparty/harfbuzz-ng/src/hb-face.cc index 0c9949fff1..61bd4af7b1 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-face.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-face.cc @@ -41,8 +41,10 @@ * @short_description: Font face objects * @include: hb.h * - * Font face is objects represent a single face in a font family. - * More exactly, a font face represents a single face in a binary font file. + * A font face is an object that represents a single face from within a + * font family. + * + * More precisely, a font face represents a single face in a binary font file. * Font faces are typically built from a binary blob and a face index. * Font faces are used to create fonts. **/ @@ -52,7 +54,7 @@ * hb_face_count: * @blob: a blob. * - * Get number of faces in a blob. + * Fetches the number of faces in a blob. * * Return value: Number of faces in @blob * @@ -87,8 +89,8 @@ DEFINE_NULL_INSTANCE (hb_face_t) = nullptr, /* destroy */ 0, /* index */ - HB_ATOMIC_INT_INIT (1000), /* upem */ - HB_ATOMIC_INT_INIT (0), /* num_glyphs */ + 1000, /* upem */ + 0, /* num_glyphs */ /* Zero for the rest is fine. */ }; @@ -96,13 +98,19 @@ DEFINE_NULL_INSTANCE (hb_face_t) = /** * hb_face_create_for_tables: - * @reference_table_func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * + * @reference_table_func: (closure user_data) (destroy destroy) (scope notified): Table-referencing function + * @user_data: A pointer to the user data + * @destroy: (nullable): A callback to call when @data is not needed anymore * + * Variant of hb_face_create(), built for those cases where it is more + * convenient to provide data for individual tables instead of the whole font + * data. With the caveat that hb_face_get_table_tags() does not currently work + * with faces created this way. + * + * Creates a new face object from the specified @user_data and @reference_table_func, + * with the @destroy callback. * - * Return value: (transfer full) + * Return value: (transfer full): The new face object * * Since: 0.9.2 **/ @@ -182,12 +190,15 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void /** * hb_face_create: (Xconstructor) - * @blob: - * @index: + * @blob: #hb_blob_t to work upon + * @index: The index of the face within @blob * + * Constructs a new face object from the specified blob and + * a face index into that blob. This is used for blobs of + * file formats such as Dfont and TTC that can contain more + * than one face. * - * - * Return value: (transfer full): + * Return value: (transfer full): The new face object * * Since: 0.9.2 **/ @@ -200,10 +211,15 @@ hb_face_create (hb_blob_t *blob, if (unlikely (!blob)) blob = hb_blob_get_empty (); - hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (hb_sanitize_context_t ().sanitize_blob<OT::OpenTypeFontFile> (hb_blob_reference (blob)), index); + blob = hb_sanitize_context_t ().sanitize_blob<OT::OpenTypeFontFile> (hb_blob_reference (blob)); + + hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (blob, index); if (unlikely (!closure)) + { + hb_blob_destroy (blob); return hb_face_get_empty (); + } face = hb_face_create_for_tables (_hb_face_for_data_reference_table, closure, @@ -217,26 +233,26 @@ hb_face_create (hb_blob_t *blob, /** * hb_face_get_empty: * + * Fetches the singleton empty face object. * - * - * Return value: (transfer full) + * Return value: (transfer full): The empty face object * * Since: 0.9.2 **/ hb_face_t * hb_face_get_empty () { - return const_cast<hb_face_t *> (&Null(hb_face_t)); + return const_cast<hb_face_t *> (&Null (hb_face_t)); } /** * hb_face_reference: (skip) - * @face: a face. + * @face: A face object * + * Increases the reference count on a face object. * - * - * Return value: + * Return value: The @face object * * Since: 0.9.2 **/ @@ -248,9 +264,11 @@ hb_face_reference (hb_face_t *face) /** * hb_face_destroy: (skip) - * @face: a face. - * - * + * @face: A face object + * + * Decreases the reference count on a face object. When the + * reference count reaches zero, the face is destroyed, + * freeing all memory. * * Since: 0.9.2 **/ @@ -278,15 +296,15 @@ hb_face_destroy (hb_face_t *face) /** * hb_face_set_user_data: (skip) - * @face: a face. - * @key: - * @data: - * @destroy: - * @replace: + * @face: A face object + * @key: The user-data key to set + * @data: A pointer to the user data + * @destroy: (nullable): A callback to call when @data is not needed anymore + * @replace: Whether to replace an existing data with the same key * + * Attaches a user-data key/data pair to the given face object. * - * - * Return value: + * Return value: %true if success, %false otherwise * * Since: 0.9.2 **/ @@ -302,12 +320,13 @@ hb_face_set_user_data (hb_face_t *face, /** * hb_face_get_user_data: (skip) - * @face: a face. - * @key: - * + * @face: A face object + * @key: The user-data key to query * + * Fetches the user data associated with the specified key, + * attached to the specified face object. * - * Return value: (transfer none): + * Return value: (transfer none): A pointer to the user data * * Since: 0.9.2 **/ @@ -320,9 +339,9 @@ hb_face_get_user_data (const hb_face_t *face, /** * hb_face_make_immutable: - * @face: a face. - * + * @face: A face object * + * Makes the given face object immutable. * * Since: 0.9.2 **/ @@ -337,11 +356,11 @@ hb_face_make_immutable (hb_face_t *face) /** * hb_face_is_immutable: - * @face: a face. + * @face: A face object * + * Tests whether the given face object is immutable. * - * - * Return value: + * Return value: %true is @face is immutable, %false otherwise * * Since: 0.9.2 **/ @@ -354,12 +373,13 @@ hb_face_is_immutable (const hb_face_t *face) /** * hb_face_reference_table: - * @face: a face. - * @tag: - * + * @face: A face object + * @tag: The #hb_tag_t of the table to query * + * Fetches a reference to the specified table within + * the specified face. * - * Return value: (transfer full): + * Return value: (transfer full): A pointer to the @tag table within @face * * Since: 0.9.2 **/ @@ -375,11 +395,13 @@ hb_face_reference_table (const hb_face_t *face, /** * hb_face_reference_blob: - * @face: a face. - * + * @face: A face object * + * Fetches a pointer to the binary blob that contains the + * specified face. Returns an empty blob if referencing face data is not + * possible. * - * Return value: (transfer full): + * Return value: (transfer full): A pointer to the blob for @face * * Since: 0.9.2 **/ @@ -391,10 +413,13 @@ hb_face_reference_blob (hb_face_t *face) /** * hb_face_set_index: - * @face: a face. - * @index: + * @face: A face object + * @index: The index to assign * + * Assigns the specified face-index to @face. Fails if the + * face is immutable. * + * <note>Note: face indices within a collection are zero-based.</note> * * Since: 0.9.2 **/ @@ -410,11 +435,13 @@ hb_face_set_index (hb_face_t *face, /** * hb_face_get_index: - * @face: a face. + * @face: A face object * + * Fetches the face-index corresponding to the given face. * + * <note>Note: face indices within a collection are zero-based.</note> * - * Return value: + * Return value: The index of @face. * * Since: 0.9.2 **/ @@ -426,10 +453,10 @@ hb_face_get_index (const hb_face_t *face) /** * hb_face_set_upem: - * @face: a face. - * @upem: - * + * @face: A face object + * @upem: The units-per-em value to assign * + * Sets the units-per-em (upem) for a face object to the specified value. * * Since: 0.9.2 **/ @@ -445,11 +472,11 @@ hb_face_set_upem (hb_face_t *face, /** * hb_face_get_upem: - * @face: a face. - * + * @face: A face object * + * Fetches the units-per-em (upem) value of the specified face object. * - * Return value: + * Return value: The upem value of @face * * Since: 0.9.2 **/ @@ -461,10 +488,10 @@ hb_face_get_upem (const hb_face_t *face) /** * hb_face_set_glyph_count: - * @face: a face. - * @glyph_count: - * + * @face: A face object + * @glyph_count: The glyph-count value to assign * + * Sets the glyph count for a face object to the specified value. * * Since: 0.9.7 **/ @@ -480,11 +507,11 @@ hb_face_set_glyph_count (hb_face_t *face, /** * hb_face_get_glyph_count: - * @face: a face. + * @face: A face object * + * Fetches the glyph-count value of the specified face object. * - * - * Return value: + * Return value: The glyph-count value of @face * * Since: 0.9.7 **/ @@ -496,14 +523,16 @@ hb_face_get_glyph_count (const hb_face_t *face) /** * hb_face_get_table_tags: - * @face: a face. - * @start_offset: index of first tag to return. - * @table_count: input length of @table_tags array, output number of items written. - * @table_tags: array to write tags into. + * @face: A face object + * @start_offset: The index of first table tag to retrieve + * @table_count: (inout): Input = the maximum number of table tags to return; + * Output = the actual number of table tags returned (may be zero) + * @table_tags: (out) (array length=table_count): The array of table tags found * - * Retrieves table tags for a face, if possible. + * Fetches a list of all table tags for a face, if possible. The list returned will + * begin at the offset provided * - * Return value: total number of tables, or 0 if not possible to list. + * Return value: Total number of tables, or zero if it is not possible to list * * Since: 1.6.0 **/ @@ -537,8 +566,11 @@ hb_face_get_table_tags (const hb_face_t *face, #ifndef HB_NO_FACE_COLLECT_UNICODES /** * hb_face_collect_unicodes: - * @face: font face. - * @out: set to add Unicode characters covered by @face to. + * @face: A face object + * @out: The set to add Unicode characters to + * + * Collects all of the Unicode characters covered by @face and adds + * them to the #hb_set_t set @out. * * Since: 1.9.0 */ @@ -546,14 +578,15 @@ void hb_face_collect_unicodes (hb_face_t *face, hb_set_t *out) { - face->table.cmap->collect_unicodes (out); + face->table.cmap->collect_unicodes (out, face->get_num_glyphs ()); } /** * hb_face_collect_variation_selectors: - * @face: font face. - * @out: set to add Variation Selector characters covered by @face to. - * + * @face: A face object + * @out: The set to add Variation Selector characters to * + * Collects all Unicode "Variation Selector" characters covered by @face and adds + * them to the #hb_set_t set @out. * * Since: 1.9.0 */ @@ -565,10 +598,12 @@ hb_face_collect_variation_selectors (hb_face_t *face, } /** * hb_face_collect_variation_unicodes: - * @face: font face. - * @out: set to add Unicode characters for @variation_selector covered by @face to. - * + * @face: A face object + * @variation_selector: The Variation Selector to query + * @out: The set to add Unicode characters to * + * Collects all Unicode characters for @variation_selector covered by @face and adds + * them to the #hb_set_t set @out. * * Since: 1.9.0 */ @@ -703,6 +738,9 @@ hb_face_builder_create () /** * hb_face_builder_add_table: + * @face: A face object created with hb_face_builder_create() + * @tag: The #hb_tag_t of the table to add + * @blob: The blob containing the table data to add * * Add table for @tag with data provided by @blob to the face. @face must * be created using hb_face_builder_create(). @@ -716,7 +754,10 @@ hb_face_builder_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob) return false; hb_face_builder_data_t *data = (hb_face_builder_data_t *) face->user_data; + hb_face_builder_data_t::table_entry_t *entry = data->tables.push (); + if (unlikely (data->tables.in_error())) + return false; entry->tag = tag; entry->blob = hb_blob_reference (blob); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-face.h b/src/3rdparty/harfbuzz-ng/src/hb-face.h index e8ff090d55..6ef2f8b886 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-face.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-face.h @@ -24,7 +24,7 @@ * Red Hat Author(s): Behdad Esfahbod */ -#ifndef HB_H_IN +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb.h> instead." #endif @@ -46,12 +46,31 @@ hb_face_count (hb_blob_t *blob); * hb_face_t */ +/** + * hb_face_t: + * + * Data type for holding font faces. + * + **/ typedef struct hb_face_t hb_face_t; HB_EXTERN hb_face_t * hb_face_create (hb_blob_t *blob, unsigned int index); +/** + * hb_reference_table_func_t: + * @face: an #hb_face_t to reference table for + * @tag: the tag of the table to reference + * @user_data: User data pointer passed by the caller + * + * Callback function for hb_face_create_for_tables(). + * + * Return value: (transfer full): A pointer to the @tag table within @face + * + * Since: 0.9.2 + */ + typedef hb_blob_t * (*hb_reference_table_func_t) (hb_face_t *face, hb_tag_t tag, void *user_data); /* calls destroy() when not needing user_data anymore */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-face.hh b/src/3rdparty/harfbuzz-ng/src/hb-face.hh index 68834baeb8..765f272858 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-face.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-face.hh @@ -81,7 +81,7 @@ struct hb_face_t return blob; } - HB_PURE_FUNC unsigned int get_upem () const + unsigned int get_upem () const { unsigned int ret = upem.get_relaxed (); if (unlikely (!ret)) @@ -94,7 +94,7 @@ struct hb_face_t unsigned int get_num_glyphs () const { unsigned int ret = num_glyphs.get_relaxed (); - if (unlikely (ret == (unsigned int) -1)) + if (unlikely (ret == UINT_MAX)) return load_num_glyphs (); return ret; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.cc b/src/3rdparty/harfbuzz-ng/src/hb-font.cc index e89ad697ef..37a0e7fe85 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-font.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-font.cc @@ -33,6 +33,9 @@ #include "hb-ot.h" +#include "hb-ot-var-avar-table.hh" +#include "hb-ot-var-fvar-table.hh" + /** * SECTION:hb-font @@ -40,10 +43,20 @@ * @short_description: Font objects * @include: hb.h * - * Font objects represent a font face at a certain size and other - * parameters (pixels per EM, points per EM, variation settings.) - * Fonts are created from font faces, and are used as input to - * hb_shape() among other things. + * Functions for working with font objects. + * + * A font object represents a font face at a specific size and with + * certain other parameters (pixels-per-em, points-per-em, variation + * settings) specified. Font objects are created from font face + * objects, and are used as input to hb_shape(), among other things. + * + * Client programs can optionally pass in their own functions that + * implement the basic, lower-level queries of font objects. This set + * of font functions is defined by the virtual methods in + * #hb_font_funcs_t. + * + * HarfBuzz provides a built-in set of lightweight default + * functions for each method in #hb_font_funcs_t. **/ @@ -52,19 +65,20 @@ */ static hb_bool_t -hb_font_get_font_h_extents_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, +hb_font_get_font_h_extents_nil (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, hb_font_extents_t *extents, - void *user_data HB_UNUSED) + void *user_data HB_UNUSED) { memset (extents, 0, sizeof (*extents)); return false; } + static hb_bool_t -hb_font_get_font_h_extents_default (hb_font_t *font, - void *font_data HB_UNUSED, +hb_font_get_font_h_extents_default (hb_font_t *font, + void *font_data HB_UNUSED, hb_font_extents_t *extents, - void *user_data HB_UNUSED) + void *user_data HB_UNUSED) { hb_bool_t ret = font->parent->get_font_h_extents (extents); if (ret) { @@ -76,19 +90,20 @@ hb_font_get_font_h_extents_default (hb_font_t *font, } static hb_bool_t -hb_font_get_font_v_extents_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, +hb_font_get_font_v_extents_nil (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, hb_font_extents_t *extents, - void *user_data HB_UNUSED) + void *user_data HB_UNUSED) { memset (extents, 0, sizeof (*extents)); return false; } + static hb_bool_t -hb_font_get_font_v_extents_default (hb_font_t *font, - void *font_data HB_UNUSED, +hb_font_get_font_v_extents_default (hb_font_t *font, + void *font_data HB_UNUSED, hb_font_extents_t *extents, - void *user_data HB_UNUSED) + void *user_data HB_UNUSED) { hb_bool_t ret = font->parent->get_font_v_extents (extents); if (ret) { @@ -100,21 +115,22 @@ hb_font_get_font_v_extents_default (hb_font_t *font, } static hb_bool_t -hb_font_get_nominal_glyph_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t unicode HB_UNUSED, +hb_font_get_nominal_glyph_nil (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + hb_codepoint_t unicode HB_UNUSED, hb_codepoint_t *glyph, - void *user_data HB_UNUSED) + void *user_data HB_UNUSED) { *glyph = 0; return false; } + static hb_bool_t -hb_font_get_nominal_glyph_default (hb_font_t *font, - void *font_data HB_UNUSED, - hb_codepoint_t unicode, +hb_font_get_nominal_glyph_default (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t unicode, hb_codepoint_t *glyph, - void *user_data HB_UNUSED) + void *user_data HB_UNUSED) { if (font->has_nominal_glyphs_func_set ()) { @@ -124,15 +140,16 @@ hb_font_get_nominal_glyph_default (hb_font_t *font, } #define hb_font_get_nominal_glyphs_nil hb_font_get_nominal_glyphs_default + static unsigned int -hb_font_get_nominal_glyphs_default (hb_font_t *font, - void *font_data HB_UNUSED, - unsigned int count, +hb_font_get_nominal_glyphs_default (hb_font_t *font, + void *font_data HB_UNUSED, + unsigned int count, const hb_codepoint_t *first_unicode, - unsigned int unicode_stride, - hb_codepoint_t *first_glyph, - unsigned int glyph_stride, - void *user_data HB_UNUSED) + unsigned int unicode_stride, + hb_codepoint_t *first_glyph, + unsigned int glyph_stride, + void *user_data HB_UNUSED) { if (font->has_nominal_glyph_func_set ()) { @@ -153,41 +170,43 @@ hb_font_get_nominal_glyphs_default (hb_font_t *font, } static hb_bool_t -hb_font_get_variation_glyph_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t unicode HB_UNUSED, - hb_codepoint_t variation_selector HB_UNUSED, +hb_font_get_variation_glyph_nil (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + hb_codepoint_t unicode HB_UNUSED, + hb_codepoint_t variation_selector HB_UNUSED, hb_codepoint_t *glyph, - void *user_data HB_UNUSED) + void *user_data HB_UNUSED) { *glyph = 0; return false; } + static hb_bool_t -hb_font_get_variation_glyph_default (hb_font_t *font, - void *font_data HB_UNUSED, - hb_codepoint_t unicode, - hb_codepoint_t variation_selector, +hb_font_get_variation_glyph_default (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t unicode, + hb_codepoint_t variation_selector, hb_codepoint_t *glyph, - void *user_data HB_UNUSED) + void *user_data HB_UNUSED) { return font->parent->get_variation_glyph (unicode, variation_selector, glyph); } static hb_position_t -hb_font_get_glyph_h_advance_nil (hb_font_t *font, - void *font_data HB_UNUSED, - hb_codepoint_t glyph HB_UNUSED, - void *user_data HB_UNUSED) +hb_font_get_glyph_h_advance_nil (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph HB_UNUSED, + void *user_data HB_UNUSED) { return font->x_scale; } + static hb_position_t -hb_font_get_glyph_h_advance_default (hb_font_t *font, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, - void *user_data HB_UNUSED) +hb_font_get_glyph_h_advance_default (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + void *user_data HB_UNUSED) { if (font->has_glyph_h_advances_func_set ()) { @@ -199,19 +218,20 @@ hb_font_get_glyph_h_advance_default (hb_font_t *font, } static hb_position_t -hb_font_get_glyph_v_advance_nil (hb_font_t *font, - void *font_data HB_UNUSED, - hb_codepoint_t glyph HB_UNUSED, - void *user_data HB_UNUSED) +hb_font_get_glyph_v_advance_nil (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph HB_UNUSED, + void *user_data HB_UNUSED) { /* TODO use font_extents.ascender+descender */ return font->y_scale; } + static hb_position_t -hb_font_get_glyph_v_advance_default (hb_font_t *font, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, - void *user_data HB_UNUSED) +hb_font_get_glyph_v_advance_default (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + void *user_data HB_UNUSED) { if (font->has_glyph_v_advances_func_set ()) { @@ -223,15 +243,16 @@ hb_font_get_glyph_v_advance_default (hb_font_t *font, } #define hb_font_get_glyph_h_advances_nil hb_font_get_glyph_h_advances_default + static void -hb_font_get_glyph_h_advances_default (hb_font_t* font, - void* font_data HB_UNUSED, - unsigned int count, +hb_font_get_glyph_h_advances_default (hb_font_t* font, + void* font_data HB_UNUSED, + unsigned int count, const hb_codepoint_t *first_glyph, - unsigned int glyph_stride, - hb_position_t *first_advance, - unsigned int advance_stride, - void *user_data HB_UNUSED) + unsigned int glyph_stride, + hb_position_t *first_advance, + unsigned int advance_stride, + void *user_data HB_UNUSED) { if (font->has_glyph_h_advance_func_set ()) { @@ -256,14 +277,14 @@ hb_font_get_glyph_h_advances_default (hb_font_t* font, #define hb_font_get_glyph_v_advances_nil hb_font_get_glyph_v_advances_default static void -hb_font_get_glyph_v_advances_default (hb_font_t* font, - void* font_data HB_UNUSED, - unsigned int count, +hb_font_get_glyph_v_advances_default (hb_font_t* font, + void* font_data HB_UNUSED, + unsigned int count, const hb_codepoint_t *first_glyph, - unsigned int glyph_stride, - hb_position_t *first_advance, - unsigned int advance_stride, - void *user_data HB_UNUSED) + unsigned int glyph_stride, + hb_position_t *first_advance, + unsigned int advance_stride, + void *user_data HB_UNUSED) { if (font->has_glyph_v_advance_func_set ()) { @@ -287,23 +308,24 @@ hb_font_get_glyph_v_advances_default (hb_font_t* font, } static hb_bool_t -hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t glyph HB_UNUSED, - hb_position_t *x, - hb_position_t *y, - void *user_data HB_UNUSED) +hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + hb_codepoint_t glyph HB_UNUSED, + hb_position_t *x, + hb_position_t *y, + void *user_data HB_UNUSED) { *x = *y = 0; return true; } + static hb_bool_t -hb_font_get_glyph_h_origin_default (hb_font_t *font, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, - hb_position_t *x, - hb_position_t *y, - void *user_data HB_UNUSED) +hb_font_get_glyph_h_origin_default (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + hb_position_t *x, + hb_position_t *y, + void *user_data HB_UNUSED) { hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y); if (ret) @@ -312,23 +334,24 @@ hb_font_get_glyph_h_origin_default (hb_font_t *font, } static hb_bool_t -hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t glyph HB_UNUSED, - hb_position_t *x, - hb_position_t *y, - void *user_data HB_UNUSED) +hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + hb_codepoint_t glyph HB_UNUSED, + hb_position_t *x, + hb_position_t *y, + void *user_data HB_UNUSED) { *x = *y = 0; return false; } + static hb_bool_t -hb_font_get_glyph_v_origin_default (hb_font_t *font, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, - hb_position_t *x, - hb_position_t *y, - void *user_data HB_UNUSED) +hb_font_get_glyph_v_origin_default (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + hb_position_t *x, + hb_position_t *y, + void *user_data HB_UNUSED) { hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y); if (ret) @@ -337,61 +360,64 @@ hb_font_get_glyph_v_origin_default (hb_font_t *font, } static hb_position_t -hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t left_glyph HB_UNUSED, - hb_codepoint_t right_glyph HB_UNUSED, - void *user_data HB_UNUSED) +hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + hb_codepoint_t left_glyph HB_UNUSED, + hb_codepoint_t right_glyph HB_UNUSED, + void *user_data HB_UNUSED) { return 0; } + static hb_position_t -hb_font_get_glyph_h_kerning_default (hb_font_t *font, - void *font_data HB_UNUSED, - hb_codepoint_t left_glyph, - hb_codepoint_t right_glyph, - void *user_data HB_UNUSED) +hb_font_get_glyph_h_kerning_default (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t left_glyph, + hb_codepoint_t right_glyph, + void *user_data HB_UNUSED) { return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph)); } #ifndef HB_DISABLE_DEPRECATED static hb_position_t -hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t top_glyph HB_UNUSED, - hb_codepoint_t bottom_glyph HB_UNUSED, - void *user_data HB_UNUSED) +hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + hb_codepoint_t top_glyph HB_UNUSED, + hb_codepoint_t bottom_glyph HB_UNUSED, + void *user_data HB_UNUSED) { return 0; } + static hb_position_t -hb_font_get_glyph_v_kerning_default (hb_font_t *font, - void *font_data HB_UNUSED, - hb_codepoint_t top_glyph, - hb_codepoint_t bottom_glyph, - void *user_data HB_UNUSED) +hb_font_get_glyph_v_kerning_default (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t top_glyph, + hb_codepoint_t bottom_glyph, + void *user_data HB_UNUSED) { return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph)); } #endif static hb_bool_t -hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t glyph HB_UNUSED, +hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + hb_codepoint_t glyph HB_UNUSED, hb_glyph_extents_t *extents, - void *user_data HB_UNUSED) + void *user_data HB_UNUSED) { memset (extents, 0, sizeof (*extents)); return false; } + static hb_bool_t -hb_font_get_glyph_extents_default (hb_font_t *font, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, +hb_font_get_glyph_extents_default (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, hb_glyph_extents_t *extents, - void *user_data HB_UNUSED) + void *user_data HB_UNUSED) { hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents); if (ret) { @@ -402,25 +428,26 @@ hb_font_get_glyph_extents_default (hb_font_t *font, } static hb_bool_t -hb_font_get_glyph_contour_point_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t glyph HB_UNUSED, - unsigned int point_index HB_UNUSED, - hb_position_t *x, - hb_position_t *y, - void *user_data HB_UNUSED) +hb_font_get_glyph_contour_point_nil (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + hb_codepoint_t glyph HB_UNUSED, + unsigned int point_index HB_UNUSED, + hb_position_t *x, + hb_position_t *y, + void *user_data HB_UNUSED) { *x = *y = 0; return false; } + static hb_bool_t -hb_font_get_glyph_contour_point_default (hb_font_t *font, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, - unsigned int point_index, - hb_position_t *x, - hb_position_t *y, - void *user_data HB_UNUSED) +hb_font_get_glyph_contour_point_default (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + unsigned int point_index, + hb_position_t *x, + hb_position_t *y, + void *user_data HB_UNUSED) { hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y); if (ret) @@ -429,42 +456,47 @@ hb_font_get_glyph_contour_point_default (hb_font_t *font, } static hb_bool_t -hb_font_get_glyph_name_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t glyph HB_UNUSED, - char *name, unsigned int size, - void *user_data HB_UNUSED) +hb_font_get_glyph_name_nil (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + hb_codepoint_t glyph HB_UNUSED, + char *name, + unsigned int size, + void *user_data HB_UNUSED) { if (size) *name = '\0'; return false; } + static hb_bool_t -hb_font_get_glyph_name_default (hb_font_t *font, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, - char *name, unsigned int size, - void *user_data HB_UNUSED) +hb_font_get_glyph_name_default (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + char *name, + unsigned int size, + void *user_data HB_UNUSED) { return font->parent->get_glyph_name (glyph, name, size); } static hb_bool_t -hb_font_get_glyph_from_name_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - const char *name HB_UNUSED, - int len HB_UNUSED, /* -1 means nul-terminated */ +hb_font_get_glyph_from_name_nil (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + const char *name HB_UNUSED, + int len HB_UNUSED, /* -1 means nul-terminated */ hb_codepoint_t *glyph, - void *user_data HB_UNUSED) + void *user_data HB_UNUSED) { *glyph = 0; return false; } + static hb_bool_t -hb_font_get_glyph_from_name_default (hb_font_t *font, - void *font_data HB_UNUSED, - const char *name, int len, /* -1 means nul-terminated */ +hb_font_get_glyph_from_name_default (hb_font_t *font, + void *font_data HB_UNUSED, + const char *name, + int len, /* -1 means nul-terminated */ hb_codepoint_t *glyph, - void *user_data HB_UNUSED) + void *user_data HB_UNUSED) { return font->parent->get_glyph_from_name (name, len, glyph); } @@ -518,9 +550,9 @@ static const hb_font_funcs_t _hb_font_funcs_default = { /** * hb_font_funcs_create: (Xconstructor) * + * Creates a new #hb_font_funcs_t structure of font functions. * - * - * Return value: (transfer full): + * Return value: (transfer full): The font-functions structure * * Since: 0.9.2 **/ @@ -540,9 +572,9 @@ hb_font_funcs_create () /** * hb_font_funcs_get_empty: * + * Fetches an empty font-functions structure. * - * - * Return value: (transfer full): + * Return value: (transfer full): The font-functions structure * * Since: 0.9.2 **/ @@ -554,11 +586,11 @@ hb_font_funcs_get_empty () /** * hb_font_funcs_reference: (skip) - * @ffuncs: font functions. + * @ffuncs: The font-functions structure * + * Increases the reference count on a font-functions structure. * - * - * Return value: + * Return value: The font-functions structure * * Since: 0.9.2 **/ @@ -570,9 +602,11 @@ hb_font_funcs_reference (hb_font_funcs_t *ffuncs) /** * hb_font_funcs_destroy: (skip) - * @ffuncs: font functions. - * + * @ffuncs: The font-functions structure * + * Decreases the reference count on a font-functions structure. When + * the reference count reaches zero, the font-functions structure is + * destroyed, freeing all memory. * * Since: 0.9.2 **/ @@ -591,15 +625,15 @@ hb_font_funcs_destroy (hb_font_funcs_t *ffuncs) /** * hb_font_funcs_set_user_data: (skip) - * @ffuncs: font functions. - * @key: - * @data: - * @destroy: - * @replace: - * + * @ffuncs: The font-functions structure + * @key: The user-data key to set + * @data: A pointer to the user data set + * @destroy: (nullable): A callback to call when @data is not needed anymore + * @replace: Whether to replace an existing data with the same key * + * Attaches a user-data key/data pair to the specified font-functions structure. * - * Return value: + * Return value: %true if success, %false otherwise * * Since: 0.9.2 **/ @@ -607,7 +641,7 @@ hb_bool_t hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs, hb_user_data_key_t *key, void * data, - hb_destroy_func_t destroy, + hb_destroy_func_t destroy /* May be NULL. */, hb_bool_t replace) { return hb_object_set_user_data (ffuncs, key, data, destroy, replace); @@ -615,12 +649,13 @@ hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs, /** * hb_font_funcs_get_user_data: (skip) - * @ffuncs: font functions. - * @key: + * @ffuncs: The font-functions structure + * @key: The user-data key to query * + * Fetches the user data associated with the specified key, + * attached to the specified font-functions structure. * - * - * Return value: (transfer none): + * Return value: (transfer none): A pointer to the user data * * Since: 0.9.2 **/ @@ -634,9 +669,9 @@ hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs, /** * hb_font_funcs_make_immutable: - * @ffuncs: font functions. - * + * @ffuncs: The font-functions structure * + * Makes a font-functions structure immutable. * * Since: 0.9.2 **/ @@ -651,11 +686,11 @@ hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs) /** * hb_font_funcs_is_immutable: - * @ffuncs: font functions. - * + * @ffuncs: The font-functions structure * + * Tests whether a font-functions structure is immutable. * - * Return value: + * Return value: %true if @ffuncs is immutable, %false otherwise * * Since: 0.9.2 **/ @@ -674,7 +709,8 @@ hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \ void *user_data, \ hb_destroy_func_t destroy) \ { \ - if (hb_object_is_immutable (ffuncs)) { \ + if (hb_object_is_immutable (ffuncs)) \ + { \ if (destroy) \ destroy (user_data); \ return; \ @@ -714,17 +750,18 @@ hb_font_t::has_func (unsigned int i) /** * hb_font_get_h_extents: - * @font: a font. - * @extents: (out): - * + * @font: #hb_font_t to work upon + * @extents: (out): The font extents retrieved * + * Fetches the extents for a specified font, for horizontal + * text segments. * - * Return value: + * Return value: %true if data found, %false otherwise * * Since: 1.1.3 **/ hb_bool_t -hb_font_get_h_extents (hb_font_t *font, +hb_font_get_h_extents (hb_font_t *font, hb_font_extents_t *extents) { return font->get_font_h_extents (extents); @@ -732,17 +769,18 @@ hb_font_get_h_extents (hb_font_t *font, /** * hb_font_get_v_extents: - * @font: a font. - * @extents: (out): + * @font: #hb_font_t to work upon + * @extents: (out): The font extents retrieved * + * Fetches the extents for a specified font, for vertical + * text segments. * - * - * Return value: + * Return value: %true if data found, %false otherwise * * Since: 1.1.3 **/ hb_bool_t -hb_font_get_v_extents (hb_font_t *font, +hb_font_get_v_extents (hb_font_t *font, hb_font_extents_t *extents) { return font->get_font_v_extents (extents); @@ -750,20 +788,25 @@ hb_font_get_v_extents (hb_font_t *font, /** * hb_font_get_glyph: - * @font: a font. - * @unicode: - * @variation_selector: - * @glyph: (out): + * @font: #hb_font_t to work upon + * @unicode: The Unicode code point to query + * @variation_selector: A variation-selector code point + * @glyph: (out): The glyph ID retrieved * + * Fetches the glyph ID for a Unicode code point in the specified + * font, with an optional variation selector. * + * If @variation_selector is 0, calls hb_font_get_nominal_glyph(); + * otherwise calls hb_font_get_variation_glyph(). * - * Return value: + * Return value: %true if data found, %false otherwise * * Since: 0.9.2 **/ hb_bool_t -hb_font_get_glyph (hb_font_t *font, - hb_codepoint_t unicode, hb_codepoint_t variation_selector, +hb_font_get_glyph (hb_font_t *font, + hb_codepoint_t unicode, + hb_codepoint_t variation_selector, hb_codepoint_t *glyph) { if (unlikely (variation_selector)) @@ -773,19 +816,24 @@ hb_font_get_glyph (hb_font_t *font, /** * hb_font_get_nominal_glyph: - * @font: a font. - * @unicode: - * @glyph: (out): + * @font: #hb_font_t to work upon + * @unicode: The Unicode code point to query + * @glyph: (out): The glyph ID retrieved * + * Fetches the nominal glyph ID for a Unicode code point in the + * specified font. * + * This version of the function should not be used to fetch glyph IDs + * for code points modified by variation selectors. For variation-selector + * support, user hb_font_get_variation_glyph() or use hb_font_get_glyph(). * - * Return value: + * Return value: %true if data found, %false otherwise * * Since: 1.2.3 **/ hb_bool_t -hb_font_get_nominal_glyph (hb_font_t *font, - hb_codepoint_t unicode, +hb_font_get_nominal_glyph (hb_font_t *font, + hb_codepoint_t unicode, hb_codepoint_t *glyph) { return font->get_nominal_glyph (unicode, glyph); @@ -793,11 +841,17 @@ hb_font_get_nominal_glyph (hb_font_t *font, /** * hb_font_get_nominal_glyphs: - * @font: a font. - * + * @font: #hb_font_t to work upon + * @count: number of code points to query + * @first_unicode: The first Unicode code point to query + * @unicode_stride: The stride between successive code points + * @first_glyph: (out): The first glyph ID retrieved + * @glyph_stride: The stride between successive glyph IDs * + * Fetches the nominal glyph IDs for a sequence of Unicode code points. Glyph + * IDs must be returned in a #hb_codepoint_t output parameter. * - * Return value: + * Return value: the number of code points processed * * Since: 2.6.3 **/ @@ -816,20 +870,23 @@ hb_font_get_nominal_glyphs (hb_font_t *font, /** * hb_font_get_variation_glyph: - * @font: a font. - * @unicode: - * @variation_selector: - * @glyph: (out): - * + * @font: #hb_font_t to work upon + * @unicode: The Unicode code point to query + * @variation_selector: The variation-selector code point to query + * @glyph: (out): The glyph ID retrieved * + * Fetches the glyph ID for a Unicode code point when followed by + * by the specified variation-selector code point, in the specified + * font. * - * Return value: + * Return value: %true if data found, %false otherwise * * Since: 1.2.3 **/ hb_bool_t -hb_font_get_variation_glyph (hb_font_t *font, - hb_codepoint_t unicode, hb_codepoint_t variation_selector, +hb_font_get_variation_glyph (hb_font_t *font, + hb_codepoint_t unicode, + hb_codepoint_t variation_selector, hb_codepoint_t *glyph) { return font->get_variation_glyph (unicode, variation_selector, glyph); @@ -837,134 +894,157 @@ hb_font_get_variation_glyph (hb_font_t *font, /** * hb_font_get_glyph_h_advance: - * @font: a font. - * @glyph: - * + * @font: #hb_font_t to work upon + * @glyph: The glyph ID to query * + * Fetches the advance for a glyph ID in the specified font, + * for horizontal text segments. * - * Return value: + * Return value: The advance of @glyph within @font * * Since: 0.9.2 **/ hb_position_t -hb_font_get_glyph_h_advance (hb_font_t *font, - hb_codepoint_t glyph) +hb_font_get_glyph_h_advance (hb_font_t *font, + hb_codepoint_t glyph) { return font->get_glyph_h_advance (glyph); } /** * hb_font_get_glyph_v_advance: - * @font: a font. - * @glyph: + * @font: #hb_font_t to work upon + * @glyph: The glyph ID to query * + * Fetches the advance for a glyph ID in the specified font, + * for vertical text segments. * - * - * Return value: + * Return value: The advance of @glyph within @font * * Since: 0.9.2 **/ hb_position_t -hb_font_get_glyph_v_advance (hb_font_t *font, - hb_codepoint_t glyph) +hb_font_get_glyph_v_advance (hb_font_t *font, + hb_codepoint_t glyph) { return font->get_glyph_v_advance (glyph); } /** * hb_font_get_glyph_h_advances: - * @font: a font. - * + * @font: #hb_font_t to work upon + * @count: The number of glyph IDs in the sequence queried + * @first_glyph: The first glyph ID to query + * @glyph_stride: The stride between successive glyph IDs + * @first_advance: (out): The first advance retrieved + * @advance_stride: The stride between successive advances * + * Fetches the advances for a sequence of glyph IDs in the specified + * font, for horizontal text segments. * * Since: 1.8.6 **/ void -hb_font_get_glyph_h_advances (hb_font_t* font, - unsigned int count, +hb_font_get_glyph_h_advances (hb_font_t* font, + unsigned int count, const hb_codepoint_t *first_glyph, - unsigned glyph_stride, - hb_position_t *first_advance, - unsigned advance_stride) + unsigned glyph_stride, + hb_position_t *first_advance, + unsigned advance_stride) { font->get_glyph_h_advances (count, first_glyph, glyph_stride, first_advance, advance_stride); } /** * hb_font_get_glyph_v_advances: - * @font: a font. - * + * @font: #hb_font_t to work upon + * @count: The number of glyph IDs in the sequence queried + * @first_glyph: The first glyph ID to query + * @glyph_stride: The stride between successive glyph IDs + * @first_advance: (out): The first advance retrieved + * @advance_stride: (out): The stride between successive advances * + * Fetches the advances for a sequence of glyph IDs in the specified + * font, for vertical text segments. * * Since: 1.8.6 **/ void -hb_font_get_glyph_v_advances (hb_font_t* font, - unsigned int count, +hb_font_get_glyph_v_advances (hb_font_t* font, + unsigned int count, const hb_codepoint_t *first_glyph, - unsigned glyph_stride, - hb_position_t *first_advance, - unsigned advance_stride) + unsigned glyph_stride, + hb_position_t *first_advance, + unsigned advance_stride) { font->get_glyph_v_advances (count, first_glyph, glyph_stride, first_advance, advance_stride); } /** * hb_font_get_glyph_h_origin: - * @font: a font. - * @glyph: - * @x: (out): - * @y: (out): - * + * @font: #hb_font_t to work upon + * @glyph: The glyph ID to query + * @x: (out): The X coordinate of the origin + * @y: (out): The Y coordinate of the origin * + * Fetches the (X,Y) coordinates of the origin for a glyph ID + * in the specified font, for horizontal text segments. * - * Return value: + * Return value: %true if data found, %false otherwise * * Since: 0.9.2 **/ hb_bool_t -hb_font_get_glyph_h_origin (hb_font_t *font, - hb_codepoint_t glyph, - hb_position_t *x, hb_position_t *y) +hb_font_get_glyph_h_origin (hb_font_t *font, + hb_codepoint_t glyph, + hb_position_t *x, + hb_position_t *y) { return font->get_glyph_h_origin (glyph, x, y); } /** * hb_font_get_glyph_v_origin: - * @font: a font. - * @glyph: - * @x: (out): - * @y: (out): + * @font: #hb_font_t to work upon + * @glyph: The glyph ID to query + * @x: (out): The X coordinate of the origin + * @y: (out): The Y coordinate of the origin * + * Fetches the (X,Y) coordinates of the origin for a glyph ID + * in the specified font, for vertical text segments. * - * - * Return value: + * Return value: %true if data found, %false otherwise * * Since: 0.9.2 **/ hb_bool_t -hb_font_get_glyph_v_origin (hb_font_t *font, - hb_codepoint_t glyph, - hb_position_t *x, hb_position_t *y) +hb_font_get_glyph_v_origin (hb_font_t *font, + hb_codepoint_t glyph, + hb_position_t *x, + hb_position_t *y) { return font->get_glyph_v_origin (glyph, x, y); } /** * hb_font_get_glyph_h_kerning: - * @font: a font. - * @left_glyph: - * @right_glyph: + * @font: #hb_font_t to work upon + * @left_glyph: The glyph ID of the left glyph in the glyph pair + * @right_glyph: The glyph ID of the right glyph in the glyph pair * + * Fetches the kerning-adjustment value for a glyph-pair in + * the specified font, for horizontal text segments. * + * <note>It handles legacy kerning only (as returned by the corresponding + * #hb_font_funcs_t function).</note> * - * Return value: + * Return value: The kerning adjustment value * * Since: 0.9.2 **/ hb_position_t -hb_font_get_glyph_h_kerning (hb_font_t *font, - hb_codepoint_t left_glyph, hb_codepoint_t right_glyph) +hb_font_get_glyph_h_kerning (hb_font_t *font, + hb_codepoint_t left_glyph, + hb_codepoint_t right_glyph) { return font->get_glyph_h_kerning (left_glyph, right_glyph); } @@ -972,20 +1052,25 @@ hb_font_get_glyph_h_kerning (hb_font_t *font, #ifndef HB_DISABLE_DEPRECATED /** * hb_font_get_glyph_v_kerning: - * @font: a font. - * @top_glyph: - * @bottom_glyph: + * @font: #hb_font_t to work upon + * @top_glyph: The glyph ID of the top glyph in the glyph pair + * @bottom_glyph: The glyph ID of the bottom glyph in the glyph pair * + * Fetches the kerning-adjustment value for a glyph-pair in + * the specified font, for vertical text segments. * + * <note>It handles legacy kerning only (as returned by the corresponding + * #hb_font_funcs_t function).</note> * - * Return value: + * Return value: The kerning adjustment value * * Since: 0.9.2 * Deprecated: 2.0.0 **/ hb_position_t -hb_font_get_glyph_v_kerning (hb_font_t *font, - hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph) +hb_font_get_glyph_v_kerning (hb_font_t *font, + hb_codepoint_t top_glyph, + hb_codepoint_t bottom_glyph) { return font->get_glyph_v_kerning (top_glyph, bottom_glyph); } @@ -993,19 +1078,20 @@ hb_font_get_glyph_v_kerning (hb_font_t *font, /** * hb_font_get_glyph_extents: - * @font: a font. - * @glyph: - * @extents: (out): - * + * @font: #hb_font_t to work upon + * @glyph: The glyph ID to query + * @extents: (out): The #hb_glyph_extents_t retrieved * + * Fetches the #hb_glyph_extents_t data for a glyph ID + * in the specified font. * - * Return value: + * Return value: %true if data found, %false otherwise * * Since: 0.9.2 **/ hb_bool_t -hb_font_get_glyph_extents (hb_font_t *font, - hb_codepoint_t glyph, +hb_font_get_glyph_extents (hb_font_t *font, + hb_codepoint_t glyph, hb_glyph_extents_t *extents) { return font->get_glyph_extents (glyph, extents); @@ -1013,63 +1099,70 @@ hb_font_get_glyph_extents (hb_font_t *font, /** * hb_font_get_glyph_contour_point: - * @font: a font. - * @glyph: - * @point_index: - * @x: (out): - * @y: (out): - * + * @font: #hb_font_t to work upon + * @glyph: The glyph ID to query + * @point_index: The contour-point index to query + * @x: (out): The X value retrieved for the contour point + * @y: (out): The Y value retrieved for the contour point * + * Fetches the (x,y) coordinates of a specified contour-point index + * in the specified glyph, within the specified font. * - * Return value: + * Return value: %true if data found, %false otherwise * * Since: 0.9.2 **/ hb_bool_t -hb_font_get_glyph_contour_point (hb_font_t *font, - hb_codepoint_t glyph, unsigned int point_index, - hb_position_t *x, hb_position_t *y) +hb_font_get_glyph_contour_point (hb_font_t *font, + hb_codepoint_t glyph, + unsigned int point_index, + hb_position_t *x, + hb_position_t *y) { return font->get_glyph_contour_point (glyph, point_index, x, y); } /** * hb_font_get_glyph_name: - * @font: a font. - * @glyph: - * @name: (array length=size): - * @size: + * @font: #hb_font_t to work upon + * @glyph: The glyph ID to query + * @name: (out) (array length=size): Name string retrieved for the glyph ID + * @size: Length of the glyph-name string retrieved * + * Fetches the glyph-name string for a glyph ID in the specified @font. * - * - * Return value: + * Return value: %true if data found, %false otherwise * * Since: 0.9.2 **/ hb_bool_t -hb_font_get_glyph_name (hb_font_t *font, - hb_codepoint_t glyph, - char *name, unsigned int size) +hb_font_get_glyph_name (hb_font_t *font, + hb_codepoint_t glyph, + char *name, + unsigned int size) { return font->get_glyph_name (glyph, name, size); } /** * hb_font_get_glyph_from_name: - * @font: a font. - * @name: (array length=len): - * @len: - * @glyph: (out): + * @font: #hb_font_t to work upon + * @name: (array length=len): The name string to query + * @len: The length of the name queried + * @glyph: (out): The glyph ID retrieved * + * Fetches the glyph ID that corresponds to a name string in the specified @font. * + * <note>Note: @len == -1 means the name string is null-terminated.</note> * - * Return value: + * Return value: %true if data found, %false otherwise * * Since: 0.9.2 **/ hb_bool_t -hb_font_get_glyph_from_name (hb_font_t *font, - const char *name, int len, /* -1 means nul-terminated */ +hb_font_get_glyph_from_name (hb_font_t *font, + const char *name, + int len, /* -1 means nul-terminated */ hb_codepoint_t *glyph) { return font->get_glyph_from_name (name, len, glyph); @@ -1080,164 +1173,211 @@ hb_font_get_glyph_from_name (hb_font_t *font, /** * hb_font_get_extents_for_direction: - * @font: a font. - * @direction: - * @extents: (out): + * @font: #hb_font_t to work upon + * @direction: The direction of the text segment + * @extents: (out): The #hb_font_extents_t retrieved * + * Fetches the extents for a font in a text segment of the + * specified direction. * + * Calls the appropriate direction-specific variant (horizontal + * or vertical) depending on the value of @direction. * * Since: 1.1.3 **/ void -hb_font_get_extents_for_direction (hb_font_t *font, - hb_direction_t direction, +hb_font_get_extents_for_direction (hb_font_t *font, + hb_direction_t direction, hb_font_extents_t *extents) { return font->get_extents_for_direction (direction, extents); } /** * hb_font_get_glyph_advance_for_direction: - * @font: a font. - * @glyph: - * @direction: - * @x: (out): - * @y: (out): + * @font: #hb_font_t to work upon + * @glyph: The glyph ID to query + * @direction: The direction of the text segment + * @x: (out): The horizontal advance retrieved + * @y: (out): The vertical advance retrieved * + * Fetches the advance for a glyph ID from the specified font, + * in a text segment of the specified direction. * + * Calls the appropriate direction-specific variant (horizontal + * or vertical) depending on the value of @direction. * * Since: 0.9.2 **/ void -hb_font_get_glyph_advance_for_direction (hb_font_t *font, - hb_codepoint_t glyph, - hb_direction_t direction, - hb_position_t *x, hb_position_t *y) +hb_font_get_glyph_advance_for_direction (hb_font_t *font, + hb_codepoint_t glyph, + hb_direction_t direction, + hb_position_t *x, + hb_position_t *y) { return font->get_glyph_advance_for_direction (glyph, direction, x, y); } /** * hb_font_get_glyph_advances_for_direction: - * @font: a font. - * @direction: + * @font: #hb_font_t to work upon + * @direction: The direction of the text segment + * @count: The number of glyph IDs in the sequence queried + * @first_glyph: The first glyph ID to query + * @glyph_stride: The stride between successive glyph IDs + * @first_advance: (out): The first advance retrieved + * @advance_stride: (out): The stride between successive advances * + * Fetches the advances for a sequence of glyph IDs in the specified + * font, in a text segment of the specified direction. * + * Calls the appropriate direction-specific variant (horizontal + * or vertical) depending on the value of @direction. * * Since: 1.8.6 **/ HB_EXTERN void -hb_font_get_glyph_advances_for_direction (hb_font_t* font, - hb_direction_t direction, - unsigned int count, +hb_font_get_glyph_advances_for_direction (hb_font_t* font, + hb_direction_t direction, + unsigned int count, const hb_codepoint_t *first_glyph, - unsigned glyph_stride, - hb_position_t *first_advance, - unsigned advance_stride) + unsigned glyph_stride, + hb_position_t *first_advance, + unsigned advance_stride) { font->get_glyph_advances_for_direction (direction, count, first_glyph, glyph_stride, first_advance, advance_stride); } /** * hb_font_get_glyph_origin_for_direction: - * @font: a font. - * @glyph: - * @direction: - * @x: (out): - * @y: (out): + * @font: #hb_font_t to work upon + * @glyph: The glyph ID to query + * @direction: The direction of the text segment + * @x: (out): The X coordinate retrieved for the origin + * @y: (out): The Y coordinate retrieved for the origin * + * Fetches the (X,Y) coordinates of the origin for a glyph in + * the specified font. * + * Calls the appropriate direction-specific variant (horizontal + * or vertical) depending on the value of @direction. * * Since: 0.9.2 **/ void -hb_font_get_glyph_origin_for_direction (hb_font_t *font, - hb_codepoint_t glyph, - hb_direction_t direction, - hb_position_t *x, hb_position_t *y) +hb_font_get_glyph_origin_for_direction (hb_font_t *font, + hb_codepoint_t glyph, + hb_direction_t direction, + hb_position_t *x, + hb_position_t *y) { return font->get_glyph_origin_for_direction (glyph, direction, x, y); } /** * hb_font_add_glyph_origin_for_direction: - * @font: a font. - * @glyph: - * @direction: - * @x: (out): - * @y: (out): + * @font: #hb_font_t to work upon + * @glyph: The glyph ID to query + * @direction: The direction of the text segment + * @x: (inout): Input = The original X coordinate + * Output = The X coordinate plus the X-coordinate of the origin + * @y: (inout): Input = The original Y coordinate + * Output = The Y coordinate plus the Y-coordinate of the origin * + * Adds the origin coordinates to an (X,Y) point coordinate, in + * the specified glyph ID in the specified font. * + * Calls the appropriate direction-specific variant (horizontal + * or vertical) depending on the value of @direction. * * Since: 0.9.2 **/ void -hb_font_add_glyph_origin_for_direction (hb_font_t *font, - hb_codepoint_t glyph, - hb_direction_t direction, - hb_position_t *x, hb_position_t *y) +hb_font_add_glyph_origin_for_direction (hb_font_t *font, + hb_codepoint_t glyph, + hb_direction_t direction, + hb_position_t *x, + hb_position_t *y) { return font->add_glyph_origin_for_direction (glyph, direction, x, y); } /** * hb_font_subtract_glyph_origin_for_direction: - * @font: a font. - * @glyph: - * @direction: - * @x: (out): - * @y: (out): + * @font: #hb_font_t to work upon + * @glyph: The glyph ID to query + * @direction: The direction of the text segment + * @x: (inout): Input = The original X coordinate + * Output = The X coordinate minus the X-coordinate of the origin + * @y: (inout): Input = The original Y coordinate + * Output = The Y coordinate minus the Y-coordinate of the origin * + * Subtracts the origin coordinates from an (X,Y) point coordinate, + * in the specified glyph ID in the specified font. * + * Calls the appropriate direction-specific variant (horizontal + * or vertical) depending on the value of @direction. * * Since: 0.9.2 **/ void -hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, - hb_codepoint_t glyph, - hb_direction_t direction, - hb_position_t *x, hb_position_t *y) +hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, + hb_codepoint_t glyph, + hb_direction_t direction, + hb_position_t *x, + hb_position_t *y) { return font->subtract_glyph_origin_for_direction (glyph, direction, x, y); } /** * hb_font_get_glyph_kerning_for_direction: - * @font: a font. - * @first_glyph: - * @second_glyph: - * @direction: - * @x: (out): - * @y: (out): + * @font: #hb_font_t to work upon + * @first_glyph: The glyph ID of the first glyph in the glyph pair to query + * @second_glyph: The glyph ID of the second glyph in the glyph pair to query + * @direction: The direction of the text segment + * @x: (out): The horizontal kerning-adjustment value retrieved + * @y: (out): The vertical kerning-adjustment value retrieved * + * Fetches the kerning-adjustment value for a glyph-pair in the specified font. * + * Calls the appropriate direction-specific variant (horizontal + * or vertical) depending on the value of @direction. * * Since: 0.9.2 **/ void -hb_font_get_glyph_kerning_for_direction (hb_font_t *font, - hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, - hb_direction_t direction, - hb_position_t *x, hb_position_t *y) +hb_font_get_glyph_kerning_for_direction (hb_font_t *font, + hb_codepoint_t first_glyph, + hb_codepoint_t second_glyph, + hb_direction_t direction, + hb_position_t *x, + hb_position_t *y) { return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y); } /** * hb_font_get_glyph_extents_for_origin: - * @font: a font. - * @glyph: - * @direction: - * @extents: (out): + * @font: #hb_font_t to work upon + * @glyph: The glyph ID to query + * @direction: The direction of the text segment + * @extents: (out): The #hb_glyph_extents_t retrieved * + * Fetches the #hb_glyph_extents_t data for a glyph ID + * in the specified font, with respect to the origin in + * a text segment in the specified direction. * + * Calls the appropriate direction-specific variant (horizontal + * or vertical) depending on the value of @direction. * - * Return value: + * Return value: %true if data found, %false otherwise * * Since: 0.9.2 **/ hb_bool_t -hb_font_get_glyph_extents_for_origin (hb_font_t *font, - hb_codepoint_t glyph, - hb_direction_t direction, +hb_font_get_glyph_extents_for_origin (hb_font_t *font, + hb_codepoint_t glyph, + hb_direction_t direction, hb_glyph_extents_t *extents) { return font->get_glyph_extents_for_origin (glyph, direction, extents); @@ -1245,65 +1385,79 @@ hb_font_get_glyph_extents_for_origin (hb_font_t *font, /** * hb_font_get_glyph_contour_point_for_origin: - * @font: a font. - * @glyph: - * @point_index: - * @direction: - * @x: (out): - * @y: (out): + * @font: #hb_font_t to work upon + * @glyph: The glyph ID to query + * @point_index: The contour-point index to query + * @direction: The direction of the text segment + * @x: (out): The X value retrieved for the contour point + * @y: (out): The Y value retrieved for the contour point * + * Fetches the (X,Y) coordinates of a specified contour-point index + * in the specified glyph ID in the specified font, with respect + * to the origin in a text segment in the specified direction. * + * Calls the appropriate direction-specific variant (horizontal + * or vertical) depending on the value of @direction. * - * Return value: + * Return value: %true if data found, %false otherwise * * Since: 0.9.2 **/ hb_bool_t -hb_font_get_glyph_contour_point_for_origin (hb_font_t *font, - hb_codepoint_t glyph, unsigned int point_index, - hb_direction_t direction, - hb_position_t *x, hb_position_t *y) +hb_font_get_glyph_contour_point_for_origin (hb_font_t *font, + hb_codepoint_t glyph, + unsigned int point_index, + hb_direction_t direction, + hb_position_t *x, + hb_position_t *y) { return font->get_glyph_contour_point_for_origin (glyph, point_index, direction, x, y); } -/* Generates gidDDD if glyph has no name. */ /** * hb_font_glyph_to_string: - * @font: a font. - * @glyph: - * @s: (array length=size): - * @size: + * @font: #hb_font_t to work upon + * @glyph: The glyph ID to query + * @s: (out) (array length=size): The string containing the glyph name + * @size: Length of string @s * + * Fetches the name of the specified glyph ID in @font and returns + * it in string @s. * + * If the glyph ID has no name in @font, a string of the form `gidDDD` is + * generated, with `DDD` being the glyph ID. * * Since: 0.9.2 **/ void -hb_font_glyph_to_string (hb_font_t *font, - hb_codepoint_t glyph, - char *s, unsigned int size) +hb_font_glyph_to_string (hb_font_t *font, + hb_codepoint_t glyph, + char *s, + unsigned int size) { font->glyph_to_string (glyph, s, size); } -/* Parses gidDDD and uniUUUU strings automatically. */ /** * hb_font_glyph_from_string: - * @font: a font. - * @s: (array length=len) (element-type uint8_t): - * @len: - * @glyph: (out): + * @font: #hb_font_t to work upon + * @s: (array length=len) (element-type uint8_t): string to query + * @len: The length of the string @s + * @glyph: (out): The glyph ID corresponding to the string requested * + * Fetches the glyph ID from @font that matches the specified string. + * Strings of the format `gidDDD` or `uniUUUU` are parsed automatically. * + * <note>Note: @len == -1 means the string is null-terminated.</note> * - * Return value: + * Return value: %true if data found, %false otherwise * * Since: 0.9.2 **/ hb_bool_t -hb_font_glyph_from_string (hb_font_t *font, - const char *s, int len, /* -1 means nul-terminated */ +hb_font_glyph_from_string (hb_font_t *font, + const char *s, + int len, hb_codepoint_t *glyph) { return font->glyph_from_string (s, len, glyph); @@ -1332,6 +1486,7 @@ DEFINE_NULL_INSTANCE (hb_font_t) = 0, /* num_coords */ nullptr, /* coords */ + nullptr, /* design_coords */ const_cast<hb_font_funcs_t *> (&_hb_Null_hb_font_funcs_t), @@ -1364,9 +1519,9 @@ _hb_font_create (hb_face_t *face) * hb_font_create: (Xconstructor) * @face: a face. * + * Constructs a new font object from the specified face. * - * - * Return value: (transfer full): + * Return value: (transfer full): The new font object * * Since: 0.9.2 **/ @@ -1383,13 +1538,28 @@ hb_font_create (hb_face_t *face) return font; } +static void +_hb_font_adopt_var_coords (hb_font_t *font, + int *coords, /* 2.14 normalized */ + float *design_coords, + unsigned int coords_length) +{ + free (font->coords); + free (font->design_coords); + + font->coords = coords; + font->design_coords = design_coords; + font->num_coords = coords_length; +} + /** * hb_font_create_sub_font: - * @parent: parent font. + * @parent: The parent font object * + * Constructs a sub-font font object from the specified @parent font, + * replicating the parent's properties. * - * - * Return value: (transfer full): + * Return value: (transfer full): The new sub-font font object * * Since: 0.9.2 **/ @@ -1413,15 +1583,22 @@ hb_font_create_sub_font (hb_font_t *parent) font->y_ppem = parent->y_ppem; font->ptem = parent->ptem; - font->num_coords = parent->num_coords; - if (font->num_coords) + unsigned int num_coords = parent->num_coords; + if (num_coords) { - unsigned int size = parent->num_coords * sizeof (parent->coords[0]); - font->coords = (int *) malloc (size); - if (unlikely (!font->coords)) - font->num_coords = 0; + int *coords = (int *) calloc (num_coords, sizeof (parent->coords[0])); + float *design_coords = (float *) calloc (num_coords, sizeof (parent->design_coords[0])); + if (likely (coords && design_coords)) + { + memcpy (coords, parent->coords, num_coords * sizeof (parent->coords[0])); + memcpy (design_coords, parent->design_coords, num_coords * sizeof (parent->design_coords[0])); + _hb_font_adopt_var_coords (font, coords, design_coords, num_coords); + } else - memcpy (font->coords, parent->coords, size); + { + free (coords); + free (design_coords); + } } return font; @@ -1430,25 +1607,25 @@ hb_font_create_sub_font (hb_font_t *parent) /** * hb_font_get_empty: * + * Fetches the empty font object. * - * - * Return value: (transfer full) + * Return value: (transfer full): The empty font object * * Since: 0.9.2 **/ hb_font_t * hb_font_get_empty () { - return const_cast<hb_font_t *> (&Null(hb_font_t)); + return const_cast<hb_font_t *> (&Null (hb_font_t)); } /** * hb_font_reference: (skip) - * @font: a font. + * @font: #hb_font_t to work upon * + * Increases the reference count on the given font object. * - * - * Return value: (transfer full): + * Return value: (transfer full): The @font object * * Since: 0.9.2 **/ @@ -1460,9 +1637,11 @@ hb_font_reference (hb_font_t *font) /** * hb_font_destroy: (skip) - * @font: a font. - * + * @font: #hb_font_t to work upon * + * Decreases the reference count on the given font object. When the + * reference count reaches zero, the font is destroyed, + * freeing all memory. * * Since: 0.9.2 **/ @@ -1481,21 +1660,22 @@ hb_font_destroy (hb_font_t *font) hb_font_funcs_destroy (font->klass); free (font->coords); + free (font->design_coords); free (font); } /** * hb_font_set_user_data: (skip) - * @font: a font. - * @key: - * @data: - * @destroy: - * @replace: - * + * @font: #hb_font_t to work upon + * @key: The user-data key + * @data: A pointer to the user data + * @destroy: (nullable): A callback to call when @data is not needed anymore + * @replace: Whether to replace an existing data with the same key * + * Attaches a user-data key/data pair to the specified font object. * - * Return value: + * Return value: %true if success, %false otherwise * * Since: 0.9.2 **/ @@ -1503,7 +1683,7 @@ hb_bool_t hb_font_set_user_data (hb_font_t *font, hb_user_data_key_t *key, void * data, - hb_destroy_func_t destroy, + hb_destroy_func_t destroy /* May be NULL. */, hb_bool_t replace) { return hb_object_set_user_data (font, key, data, destroy, replace); @@ -1511,12 +1691,13 @@ hb_font_set_user_data (hb_font_t *font, /** * hb_font_get_user_data: (skip) - * @font: a font. - * @key: + * @font: #hb_font_t to work upon + * @key: The user-data key to query * + * Fetches the user-data object associated with the specified key, + * attached to the specified font object. * - * - * Return value: (transfer none): + * Return value: (transfer none): Pointer to the user data * * Since: 0.9.2 **/ @@ -1529,9 +1710,9 @@ hb_font_get_user_data (hb_font_t *font, /** * hb_font_make_immutable: - * @font: a font. - * + * @font: #hb_font_t to work upon * + * Makes @font immutable. * * Since: 0.9.2 **/ @@ -1549,11 +1730,11 @@ hb_font_make_immutable (hb_font_t *font) /** * hb_font_is_immutable: - * @font: a font. - * + * @font: #hb_font_t to work upon * + * Tests whether a font object is immutable. * - * Return value: + * Return value: %true if @font is immutable, %false otherwise * * Since: 0.9.2 **/ @@ -1565,10 +1746,10 @@ hb_font_is_immutable (hb_font_t *font) /** * hb_font_set_parent: - * @font: a font. - * @parent: new parent. + * @font: #hb_font_t to work upon + * @parent: The parent font object to assign * - * Sets parent font of @font. + * Sets the parent font of @font. * * Since: 1.0.5 **/ @@ -1591,11 +1772,11 @@ hb_font_set_parent (hb_font_t *font, /** * hb_font_get_parent: - * @font: a font. - * + * @font: #hb_font_t to work upon * + * Fetches the parent font of @font. * - * Return value: (transfer none): + * Return value: (transfer none): The parent font object * * Since: 0.9.2 **/ @@ -1607,10 +1788,10 @@ hb_font_get_parent (hb_font_t *font) /** * hb_font_set_face: - * @font: a font. - * @face: new face. + * @font: #hb_font_t to work upon + * @face: The #hb_face_t to assign * - * Sets font-face of @font. + * Sets @face as the font-face value of @font. * * Since: 1.4.3 **/ @@ -1635,11 +1816,11 @@ hb_font_set_face (hb_font_t *font, /** * hb_font_get_face: - * @font: a font. - * + * @font: #hb_font_t to work upon * + * Fetches the face associated with the specified font object. * - * Return value: (transfer none): + * Return value: (transfer none): The #hb_face_t value * * Since: 0.9.2 **/ @@ -1652,12 +1833,13 @@ hb_font_get_face (hb_font_t *font) /** * hb_font_set_funcs: - * @font: a font. - * @klass: (closure font_data) (destroy destroy) (scope notified): - * @font_data: - * @destroy: - * + * @font: #hb_font_t to work upon + * @klass: (closure font_data) (destroy destroy) (scope notified): The font-functions structure. + * @font_data: Data to attach to @font + * @destroy: (nullable): The function to call when @font_data is not needed anymore * + * Replaces the font-functions structure attached to a font, updating + * the font's user-data with @font-data and the @destroy callback. * * Since: 0.9.2 **/ @@ -1665,7 +1847,7 @@ void hb_font_set_funcs (hb_font_t *font, hb_font_funcs_t *klass, void *font_data, - hb_destroy_func_t destroy) + hb_destroy_func_t destroy /* May be NULL. */) { if (hb_object_is_immutable (font)) { @@ -1689,18 +1871,19 @@ hb_font_set_funcs (hb_font_t *font, /** * hb_font_set_funcs_data: - * @font: a font. - * @font_data: (destroy destroy) (scope notified): - * @destroy: - * + * @font: #hb_font_t to work upon + * @font_data: (destroy destroy) (scope notified): Data to attach to @font + * @destroy: (nullable): The function to call when @font_data is not needed anymore * + * Replaces the user data attached to a font, updating the font's + * @destroy callback. * * Since: 0.9.2 **/ void hb_font_set_funcs_data (hb_font_t *font, - void *font_data, - hb_destroy_func_t destroy) + void *font_data, + hb_destroy_func_t destroy /* May be NULL. */) { /* Destroy user_data? */ if (hb_object_is_immutable (font)) @@ -1720,18 +1903,18 @@ hb_font_set_funcs_data (hb_font_t *font, /** * hb_font_set_scale: - * @font: a font. - * @x_scale: - * @y_scale: - * + * @font: #hb_font_t to work upon + * @x_scale: Horizontal scale value to assign + * @y_scale: Vertical scale value to assign * + * Sets the horizontal and vertical scale of a font. * * Since: 0.9.2 **/ void hb_font_set_scale (hb_font_t *font, - int x_scale, - int y_scale) + int x_scale, + int y_scale) { if (hb_object_is_immutable (font)) return; @@ -1743,18 +1926,18 @@ hb_font_set_scale (hb_font_t *font, /** * hb_font_get_scale: - * @font: a font. - * @x_scale: (out): - * @y_scale: (out): - * + * @font: #hb_font_t to work upon + * @x_scale: (out): Horizontal scale value + * @y_scale: (out): Vertical scale value * + * Fetches the horizontal and vertical scale of a font. * * Since: 0.9.2 **/ void hb_font_get_scale (hb_font_t *font, - int *x_scale, - int *y_scale) + int *x_scale, + int *y_scale) { if (x_scale) *x_scale = font->x_scale; if (y_scale) *y_scale = font->y_scale; @@ -1762,18 +1945,18 @@ hb_font_get_scale (hb_font_t *font, /** * hb_font_set_ppem: - * @font: a font. - * @x_ppem: - * @y_ppem: - * + * @font: #hb_font_t to work upon + * @x_ppem: Horizontal ppem value to assign + * @y_ppem: Vertical ppem value to assign * + * Sets the horizontal and vertical pixels-per-em (ppem) of a font. * * Since: 0.9.2 **/ void -hb_font_set_ppem (hb_font_t *font, - unsigned int x_ppem, - unsigned int y_ppem) +hb_font_set_ppem (hb_font_t *font, + unsigned int x_ppem, + unsigned int y_ppem) { if (hb_object_is_immutable (font)) return; @@ -1784,16 +1967,16 @@ hb_font_set_ppem (hb_font_t *font, /** * hb_font_get_ppem: - * @font: a font. - * @x_ppem: (out): - * @y_ppem: (out): - * + * @font: #hb_font_t to work upon + * @x_ppem: (out): Horizontal ppem value + * @y_ppem: (out): Vertical ppem value * + * Fetches the horizontal and vertical points-per-em (ppem) of a font. * * Since: 0.9.2 **/ void -hb_font_get_ppem (hb_font_t *font, +hb_font_get_ppem (hb_font_t *font, unsigned int *x_ppem, unsigned int *y_ppem) { @@ -1803,17 +1986,19 @@ hb_font_get_ppem (hb_font_t *font, /** * hb_font_set_ptem: - * @font: a font. + * @font: #hb_font_t to work upon * @ptem: font size in points. * - * Sets "point size" of the font. Set to 0 to unset. + * Sets the "point size" of a font. Set to zero to unset. + * Used in CoreText to implement optical sizing. * - * There are 72 points in an inch. + * <note>Note: There are 72 points in an inch.</note> * * Since: 1.6.0 **/ void -hb_font_set_ptem (hb_font_t *font, float ptem) +hb_font_set_ptem (hb_font_t *font, + float ptem) { if (hb_object_is_immutable (font)) return; @@ -1823,11 +2008,12 @@ hb_font_set_ptem (hb_font_t *font, float ptem) /** * hb_font_get_ptem: - * @font: a font. + * @font: #hb_font_t to work upon * - * Gets the "point size" of the font. A value of 0 means unset. + * Fetches the "point size" of a font. Used in CoreText to + * implement optical sizing. * - * Return value: Point size. + * Return value: Point size. A value of zero means "not set." * * Since: 0.9.2 **/ @@ -1842,26 +2028,20 @@ hb_font_get_ptem (hb_font_t *font) * Variations */ -static void -_hb_font_adopt_var_coords_normalized (hb_font_t *font, - int *coords, /* 2.14 normalized */ - unsigned int coords_length) -{ - free (font->coords); - - font->coords = coords; - font->num_coords = coords_length; -} - /** * hb_font_set_variations: + * @font: #hb_font_t to work upon + * @variations: (array length=variations_length): Array of variation settings to apply + * @variations_length: Number of variations to apply + * + * Applies a list of font-variation settings to a font. * * Since: 1.4.2 */ void -hb_font_set_variations (hb_font_t *font, +hb_font_set_variations (hb_font_t *font, const hb_variation_t *variations, - unsigned int variations_length) + unsigned int variations_length) { if (hb_object_is_immutable (font)) return; @@ -1875,34 +2055,66 @@ hb_font_set_variations (hb_font_t *font, unsigned int coords_length = hb_ot_var_get_axis_count (font->face); int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : nullptr; - if (unlikely (coords_length && !normalized)) + float *design_coords = coords_length ? (float *) calloc (coords_length, sizeof (float)) : nullptr; + + if (unlikely (coords_length && !(normalized && design_coords))) + { + free (normalized); + free (design_coords); return; + } + + const OT::fvar &fvar = *font->face->table.fvar; + for (unsigned int i = 0; i < variations_length; i++) + { + hb_ot_var_axis_info_t info; + if (hb_ot_var_find_axis_info (font->face, variations[i].tag, &info) && + info.axis_index < coords_length) + { + float v = variations[i].value; + design_coords[info.axis_index] = v; + normalized[info.axis_index] = fvar.normalize_axis_value (info.axis_index, v); + } + } + font->face->table.avar->map_coords (normalized, coords_length); - hb_ot_var_normalize_variations (font->face, - variations, variations_length, - normalized, coords_length); - _hb_font_adopt_var_coords_normalized (font, normalized, coords_length); + _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length); } /** * hb_font_set_var_coords_design: + * @font: #hb_font_t to work upon + * @coords: (array length=coords_length): Array of variation coordinates to apply + * @coords_length: Number of coordinates to apply + * + * Applies a list of variation coordinates (in design-space units) + * to a font. * * Since: 1.4.2 */ void -hb_font_set_var_coords_design (hb_font_t *font, - const float *coords, - unsigned int coords_length) +hb_font_set_var_coords_design (hb_font_t *font, + const float *coords, + unsigned int coords_length) { if (hb_object_is_immutable (font)) return; int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : nullptr; - if (unlikely (coords_length && !normalized)) + float *design_coords = coords_length ? (float *) calloc (coords_length, sizeof (float)) : nullptr; + + if (unlikely (coords_length && !(normalized && design_coords))) + { + free (normalized); + free (design_coords); return; + } + + if (coords_length) + memcpy (design_coords, coords, coords_length * sizeof (font->design_coords[0])); hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized); - _hb_font_adopt_var_coords_normalized (font, normalized, coords_length); + _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length); } /** @@ -1934,29 +2146,59 @@ hb_font_set_var_named_instance (hb_font_t *font, /** * hb_font_set_var_coords_normalized: + * @font: #hb_font_t to work upon + * @coords: (array length=coords_length): Array of variation coordinates to apply + * @coords_length: Number of coordinates to apply + * + * Applies a list of variation coordinates (in normalized units) + * to a font. + * + * <note>Note: Coordinates should be normalized to 2.14.</note> * * Since: 1.4.2 */ void -hb_font_set_var_coords_normalized (hb_font_t *font, - const int *coords, /* 2.14 normalized */ - unsigned int coords_length) +hb_font_set_var_coords_normalized (hb_font_t *font, + const int *coords, /* 2.14 normalized */ + unsigned int coords_length) { if (hb_object_is_immutable (font)) return; int *copy = coords_length ? (int *) calloc (coords_length, sizeof (coords[0])) : nullptr; - if (unlikely (coords_length && !copy)) + int *unmapped = coords_length ? (int *) calloc (coords_length, sizeof (coords[0])) : nullptr; + float *design_coords = coords_length ? (float *) calloc (coords_length, sizeof (design_coords[0])) : nullptr; + + if (unlikely (coords_length && !(copy && unmapped && design_coords))) + { + free (copy); + free (unmapped); + free (design_coords); return; + } if (coords_length) + { memcpy (copy, coords, coords_length * sizeof (coords[0])); + memcpy (unmapped, coords, coords_length * sizeof (coords[0])); + } - _hb_font_adopt_var_coords_normalized (font, copy, coords_length); + /* Best effort design coords simulation */ + font->face->table.avar->unmap_coords (unmapped, coords_length); + for (unsigned int i = 0; i < coords_length; ++i) + design_coords[i] = font->face->table.fvar->unnormalize_axis_value (i, unmapped[i]); + free (unmapped); + + _hb_font_adopt_var_coords (font, copy, design_coords, coords_length); } /** * hb_font_get_var_coords_normalized: + * @font: #hb_font_t to work upon + * @length: Number of coordinates retrieved + * + * Fetches the list of normalized variation coordinates currently + * set on a font. * * Return value is valid as long as variation coordinates of the font * are not modified. @@ -1964,7 +2206,7 @@ hb_font_set_var_coords_normalized (hb_font_t *font, * Since: 1.4.2 */ const int * -hb_font_get_var_coords_normalized (hb_font_t *font, +hb_font_get_var_coords_normalized (hb_font_t *font, unsigned int *length) { if (length) @@ -1972,6 +2214,30 @@ hb_font_get_var_coords_normalized (hb_font_t *font, return font->coords; } + +#ifdef HB_EXPERIMENTAL_API +/** + * hb_font_get_var_coords_design: + * @font: #hb_font_t to work upon + * @length: (out): number of coordinates + * + * Return value is valid as long as variation coordinates of the font + * are not modified. + * + * Return value: coordinates array + * + * Since: EXPERIMENTAL + */ +const float * +hb_font_get_var_coords_design (hb_font_t *font, + unsigned int *length) +{ + if (length) + *length = font->num_coords; + + return font->design_coords; +} +#endif #endif #ifndef HB_DISABLE_DEPRECATED @@ -2036,23 +2302,23 @@ trampoline_destroy (void *user_data) typedef hb_trampoline_t<hb_font_get_glyph_func_t> hb_font_get_glyph_trampoline_t; static hb_bool_t -hb_font_get_nominal_glyph_trampoline (hb_font_t *font, - void *font_data, - hb_codepoint_t unicode, +hb_font_get_nominal_glyph_trampoline (hb_font_t *font, + void *font_data, + hb_codepoint_t unicode, hb_codepoint_t *glyph, - void *user_data) + void *user_data) { hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data; return trampoline->func (font, font_data, unicode, 0, glyph, trampoline->closure.user_data); } static hb_bool_t -hb_font_get_variation_glyph_trampoline (hb_font_t *font, - void *font_data, - hb_codepoint_t unicode, - hb_codepoint_t variation_selector, +hb_font_get_variation_glyph_trampoline (hb_font_t *font, + void *font_data, + hb_codepoint_t unicode, + hb_codepoint_t variation_selector, hb_codepoint_t *glyph, - void *user_data) + void *user_data) { hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data; return trampoline->func (font, font_data, unicode, variation_selector, glyph, trampoline->closure.user_data); @@ -2060,10 +2326,10 @@ hb_font_get_variation_glyph_trampoline (hb_font_t *font, /** * hb_font_funcs_set_glyph_func: - * @ffuncs: font functions. - * @func: (closure user_data) (destroy destroy) (scope notified): callback function. - * @user_data: data to pass to @func. - * @destroy: function to call when @user_data is not needed anymore. + * @ffuncs: The font-functions structure + * @func: (closure user_data) (destroy destroy) (scope notified): callback function + * @user_data: data to pass to @func + * @destroy: (nullable): function to call when @user_data is not needed anymore * * Deprecated. Use hb_font_funcs_set_nominal_glyph_func() and * hb_font_funcs_set_variation_glyph_func() instead. @@ -2072,10 +2338,18 @@ hb_font_get_variation_glyph_trampoline (hb_font_t *font, * Deprecated: 1.2.3 **/ void -hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, - hb_font_get_glyph_func_t func, - void *user_data, hb_destroy_func_t destroy) +hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, + hb_font_get_glyph_func_t func, + void *user_data, + hb_destroy_func_t destroy /* May be NULL. */) { + if (hb_object_is_immutable (ffuncs)) + { + if (destroy) + destroy (user_data); + return; + } + hb_font_get_glyph_trampoline_t *trampoline; trampoline = trampoline_create (func, user_data, destroy); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.h b/src/3rdparty/harfbuzz-ng/src/hb-font.h index 01ff201aee..15dc126523 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-font.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-font.h @@ -24,7 +24,7 @@ * Red Hat Author(s): Behdad Esfahbod */ -#ifndef HB_H_IN +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb.h> instead." #endif @@ -33,10 +33,16 @@ #include "hb-common.h" #include "hb-face.h" +#include "hb-draw.h" HB_BEGIN_DECLS - +/** + * hb_font_t: + * + * Data type for holding fonts. + * + */ typedef struct hb_font_t hb_font_t; @@ -44,6 +50,19 @@ typedef struct hb_font_t hb_font_t; * hb_font_funcs_t */ +/** + * hb_font_funcs_t: + * + * Data type containing a set of virtual methods used for + * working on #hb_font_t font objects. + * + * HarfBuzz provides a lightweight default function for each of + * the methods in #hb_font_funcs_t. Client programs can implement + * their own replacements for the individual font functions, as + * needed, and replace the default by calling the setter for a + * method. + * + **/ typedef struct hb_font_funcs_t hb_font_funcs_t; HB_EXTERN hb_font_funcs_t * @@ -80,12 +99,21 @@ hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs); /* font and glyph extents */ -/* Note that typically ascender is positive and descender negative in coordinate systems that grow up. */ -typedef struct hb_font_extents_t -{ - hb_position_t ascender; /* typographic ascender. */ - hb_position_t descender; /* typographic descender. */ - hb_position_t line_gap; /* suggested line spacing gap. */ +/** + * hb_font_extents_t: + * @ascender: The height of typographic ascenders. + * @descender: The depth of typographic descenders. + * @line_gap: The suggested line-spacing gap. + * + * Font-wide extent values, measured in font units. + * + * Note that typically @ascender is positive and @descender + * negative, in coordinate systems that grow up. + **/ +typedef struct hb_font_extents_t { + hb_position_t ascender; + hb_position_t descender; + hb_position_t line_gap; /*< private >*/ hb_position_t reserved9; hb_position_t reserved8; @@ -98,33 +126,130 @@ typedef struct hb_font_extents_t hb_position_t reserved1; } hb_font_extents_t; -/* Note that height is negative in coordinate systems that grow up. */ -typedef struct hb_glyph_extents_t -{ - hb_position_t x_bearing; /* left side of glyph from origin. */ - hb_position_t y_bearing; /* top side of glyph from origin. */ - hb_position_t width; /* distance from left to right side. */ - hb_position_t height; /* distance from top to bottom side. */ +/** + * hb_glyph_extents_t: + * @x_bearing: Distance from the x-origin to the left extremum of the glyph. + * @y_bearing: Distance from the top extremum of the glyph to the y-origin. + * @width: Distance from the left extremum of the glyph to the right extremum. + * @height: Distance from the top extremum of the glyph to the bottom extremum. + * + * Glyph extent values, measured in font units. + * + * Note that @height is negative, in coordinate systems that grow up. + **/ +typedef struct hb_glyph_extents_t { + hb_position_t x_bearing; + hb_position_t y_bearing; + hb_position_t width; + hb_position_t height; } hb_glyph_extents_t; /* func types */ +/** + * hb_font_get_font_extents_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @extents: (out): The font extents retrieved + * @user_data: User data pointer passed by the caller + * + * This method should retrieve the extents for a font. + * + **/ typedef hb_bool_t (*hb_font_get_font_extents_func_t) (hb_font_t *font, void *font_data, hb_font_extents_t *extents, void *user_data); + +/** + * hb_font_get_font_h_extents_func_t: + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the extents for a font, for horizontal-direction + * text segments. Extents must be returned in an #hb_glyph_extents output + * parameter. + * + **/ typedef hb_font_get_font_extents_func_t hb_font_get_font_h_extents_func_t; + +/** + * hb_font_get_font_v_extents_func_t: + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the extents for a font, for vertical-direction + * text segments. Extents must be returned in an #hb_glyph_extents output + * parameter. + * + **/ typedef hb_font_get_font_extents_func_t hb_font_get_font_v_extents_func_t; +/** + * hb_font_get_nominal_glyph_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @unicode: The Unicode code point to query + * @glyph: (out): The glyph ID retrieved + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the nominal glyph ID for a specified Unicode code + * point. Glyph IDs must be returned in a #hb_codepoint_t output parameter. + * + * Return value: %true if data found, %false otherwise + * + **/ typedef hb_bool_t (*hb_font_get_nominal_glyph_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t unicode, hb_codepoint_t *glyph, void *user_data); + +/** + * hb_font_get_variation_glyph_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @unicode: The Unicode code point to query + * @variation_selector: The variation-selector code point to query + * @glyph: (out): The glyph ID retrieved + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the glyph ID for a specified Unicode code point + * followed by a specified Variation Selector code point. Glyph IDs must be + * returned in a #hb_codepoint_t output parameter. + * + * Return value: %true if data found, %false otherwise + * + **/ typedef hb_bool_t (*hb_font_get_variation_glyph_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t unicode, hb_codepoint_t variation_selector, hb_codepoint_t *glyph, void *user_data); + +/** + * hb_font_get_nominal_glyphs_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @count: number of code points to query + * @first_unicode: The first Unicode code point to query + * @unicode_stride: The stride between successive code points + * @first_glyph: (out): The first glyph ID retrieved + * @glyph_stride: The stride between successive glyph IDs + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the nominal glyph IDs for a sequence of + * Unicode code points. Glyph IDs must be returned in a #hb_codepoint_t + * output parameter. + * + * Return value: the number of code points processed + * + **/ typedef unsigned int (*hb_font_get_nominal_glyphs_func_t) (hb_font_t *font, void *font_data, unsigned int count, const hb_codepoint_t *first_unicode, @@ -133,13 +258,65 @@ typedef unsigned int (*hb_font_get_nominal_glyphs_func_t) (hb_font_t *font, void unsigned int glyph_stride, void *user_data); - +/** + * hb_font_get_glyph_advance_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @glyph: The glyph ID to query + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the advance for a specified glyph. The + * method must return an #hb_position_t. + * + * Return value: The advance of @glyph within @font + * + **/ typedef hb_position_t (*hb_font_get_glyph_advance_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t glyph, void *user_data); + +/** + * hb_font_get_glyph_h_advance_func_t: + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the advance for a specified glyph, in + * horizontal-direction text segments. Advances must be returned in + * an #hb_position_t output parameter. + * + **/ typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_h_advance_func_t; + +/** + * hb_font_get_glyph_v_advance_func_t: + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the advance for a specified glyph, in + * vertical-direction text segments. Advances must be returned in + * an #hb_position_t output parameter. + * + **/ typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_v_advance_func_t; +/** + * hb_font_get_glyph_advances_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @count: The number of glyph IDs in the sequence queried + * @first_glyph: The first glyph ID to query + * @glyph_stride: The stride between successive glyph IDs + * @first_advance: (out): The first advance retrieved + * @advance_stride: The stride between successive advances + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the advances for a sequence of glyphs. + * + **/ typedef void (*hb_font_get_glyph_advances_func_t) (hb_font_t* font, void* font_data, unsigned int count, const hb_codepoint_t *first_glyph, @@ -147,36 +324,188 @@ typedef void (*hb_font_get_glyph_advances_func_t) (hb_font_t* font, void* font_d hb_position_t *first_advance, unsigned advance_stride, void *user_data); + +/** + * hb_font_get_glyph_h_advances_func_t: + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the advances for a sequence of glyphs, in + * horizontal-direction text segments. + * + **/ typedef hb_font_get_glyph_advances_func_t hb_font_get_glyph_h_advances_func_t; + +/** + * hb_font_get_glyph_v_advances_func_t: + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the advances for a sequence of glyphs, in + * vertical-direction text segments. + * + **/ typedef hb_font_get_glyph_advances_func_t hb_font_get_glyph_v_advances_func_t; +/** + * hb_font_get_glyph_origin_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @glyph: The glyph ID to query + * @x: (out): The X coordinate of the origin + * @y: (out): The Y coordinate of the origin + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the (X,Y) coordinates (in font units) of the + * origin for a glyph. Each coordinate must be returned in an #hb_position_t + * output parameter. + * + * Return value: %true if data found, %false otherwise + * + **/ typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y, void *user_data); + +/** + * hb_font_get_glyph_h_origin_func_t: + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the (X,Y) coordinates (in font units) of the + * origin for a glyph, for horizontal-direction text segments. Each + * coordinate must be returned in an #hb_position_t output parameter. + * + **/ typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_h_origin_func_t; + +/** + * hb_font_get_glyph_v_origin_func_t: + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the (X,Y) coordinates (in font units) of the + * origin for a glyph, for vertical-direction text segments. Each coordinate + * must be returned in an #hb_position_t output parameter. + * + **/ typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_v_origin_func_t; +/** + * hb_font_get_glyph_kerning_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @first_glyph: The glyph ID of the first glyph in the glyph pair + * @second_glyph: The glyph ID of the second glyph in the glyph pair + * @user_data: User data pointer passed by the caller + * + * This method should retrieve the kerning-adjustment value for a glyph-pair in + * the specified font, for horizontal text segments. + * + **/ typedef hb_position_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, void *user_data); +/** + * hb_font_get_glyph_h_kerning_func_t: + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the kerning-adjustment value for a glyph-pair in + * the specified font, for horizontal text segments. + * + **/ typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t; +/** + * hb_font_get_glyph_extents_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @glyph: The glyph ID to query + * @extents: (out): The #hb_glyph_extents_t retrieved + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the extents for a specified glyph. Extents must be + * returned in an #hb_glyph_extents output parameter. + * + * Return value: %true if data found, %false otherwise + * + **/ typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t glyph, hb_glyph_extents_t *extents, void *user_data); + +/** + * hb_font_get_glyph_contour_point_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @glyph: The glyph ID to query + * @point_index: The contour-point index to query + * @x: (out): The X value retrieved for the contour point + * @y: (out): The Y value retrieved for the contour point + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the (X,Y) coordinates (in font units) for a + * specified contour point in a glyph. Each coordinate must be returned as + * an #hb_position_t output parameter. + * + * Return value: %true if data found, %false otherwise + * + **/ typedef hb_bool_t (*hb_font_get_glyph_contour_point_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t glyph, unsigned int point_index, hb_position_t *x, hb_position_t *y, void *user_data); +/** + * hb_font_get_glyph_name_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @glyph: The glyph ID to query + * @name: (out) (array length=size): Name string retrieved for the glyph ID + * @size: Length of the glyph-name string retrieved + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the glyph name that corresponds to a + * glyph ID. The name should be returned in a string output parameter. + * + * Return value: %true if data found, %false otherwise + * + **/ typedef hb_bool_t (*hb_font_get_glyph_name_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t glyph, char *name, unsigned int size, void *user_data); + +/** + * hb_font_get_glyph_from_name_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @name: (array length=len): The name string to query + * @len: The length of the name queried + * @glyph: (out): The glyph ID retrieved + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the glyph ID that corresponds to a glyph-name + * string. + * + * Return value: %true if data found, %false otherwise + * + **/ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void *font_data, const char *name, int len, /* -1 means nul-terminated */ hb_codepoint_t *glyph, @@ -187,12 +516,12 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void * /** * hb_font_funcs_set_font_h_extents_func: - * @ffuncs: font functions. - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * + * Sets the implementation function for #hb_font_get_font_h_extents_func_t. * * Since: 1.1.2 **/ @@ -203,12 +532,12 @@ hb_font_funcs_set_font_h_extents_func (hb_font_funcs_t *ffuncs, /** * hb_font_funcs_set_font_v_extents_func: - * @ffuncs: font functions. - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * + * Sets the implementation function for #hb_font_get_font_v_extents_func_t. * * Since: 1.1.2 **/ @@ -219,12 +548,12 @@ hb_font_funcs_set_font_v_extents_func (hb_font_funcs_t *ffuncs, /** * hb_font_funcs_set_nominal_glyph_func: - * @ffuncs: font functions. - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * + * Sets the implementation function for #hb_font_get_nominal_glyph_func_t. * * Since: 1.2.3 **/ @@ -235,12 +564,12 @@ hb_font_funcs_set_nominal_glyph_func (hb_font_funcs_t *ffuncs, /** * hb_font_funcs_set_nominal_glyphs_func: - * @ffuncs: font functions. - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * + * Sets the implementation function for #hb_font_get_nominal_glyphs_func_t. * * Since: 2.0.0 **/ @@ -251,12 +580,12 @@ hb_font_funcs_set_nominal_glyphs_func (hb_font_funcs_t *ffuncs, /** * hb_font_funcs_set_variation_glyph_func: - * @ffuncs: font functions. - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * + * Sets the implementation function for #hb_font_get_variation_glyph_func_t. * * Since: 1.2.3 **/ @@ -267,12 +596,12 @@ hb_font_funcs_set_variation_glyph_func (hb_font_funcs_t *ffuncs, /** * hb_font_funcs_set_glyph_h_advance_func: - * @ffuncs: font functions. - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * + * Sets the implementation function for #hb_font_get_glyph_h_advance_func_t. * * Since: 0.9.2 **/ @@ -283,12 +612,12 @@ hb_font_funcs_set_glyph_h_advance_func (hb_font_funcs_t *ffuncs, /** * hb_font_funcs_set_glyph_v_advance_func: - * @ffuncs: font functions. - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * + * Sets the implementation function for #hb_font_get_glyph_v_advance_func_t. * * Since: 0.9.2 **/ @@ -299,12 +628,12 @@ hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs, /** * hb_font_funcs_set_glyph_h_advances_func: - * @ffuncs: font functions. - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * + * Sets the implementation function for #hb_font_get_glyph_h_advances_func_t. * * Since: 1.8.6 **/ @@ -315,12 +644,12 @@ hb_font_funcs_set_glyph_h_advances_func (hb_font_funcs_t *ffuncs, /** * hb_font_funcs_set_glyph_v_advances_func: - * @ffuncs: font functions. - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * + * Sets the implementation function for #hb_font_get_glyph_v_advances_func_t. * * Since: 1.8.6 **/ @@ -331,12 +660,12 @@ hb_font_funcs_set_glyph_v_advances_func (hb_font_funcs_t *ffuncs, /** * hb_font_funcs_set_glyph_h_origin_func: - * @ffuncs: font functions. - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * + * Sets the implementation function for #hb_font_get_glyph_h_origin_func_t. * * Since: 0.9.2 **/ @@ -347,12 +676,12 @@ hb_font_funcs_set_glyph_h_origin_func (hb_font_funcs_t *ffuncs, /** * hb_font_funcs_set_glyph_v_origin_func: - * @ffuncs: font functions. - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * + * Sets the implementation function for #hb_font_get_glyph_v_origin_func_t. * * Since: 0.9.2 **/ @@ -363,12 +692,12 @@ hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs, /** * hb_font_funcs_set_glyph_h_kerning_func: - * @ffuncs: font functions. - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * + * Sets the implementation function for #hb_font_get_glyph_h_kerning_func_t. * * Since: 0.9.2 **/ @@ -379,12 +708,12 @@ hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs, /** * hb_font_funcs_set_glyph_extents_func: - * @ffuncs: font functions. - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * + * Sets the implementation function for #hb_font_get_glyph_extents_func_t. * * Since: 0.9.2 **/ @@ -395,12 +724,12 @@ hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs, /** * hb_font_funcs_set_glyph_contour_point_func: - * @ffuncs: font functions. - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * + * Sets the implementation function for #hb_font_get_glyph_contour_point_func_t. * * Since: 0.9.2 **/ @@ -411,12 +740,12 @@ hb_font_funcs_set_glyph_contour_point_func (hb_font_funcs_t *ffuncs, /** * hb_font_funcs_set_glyph_name_func: - * @ffuncs: font functions. - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * + * Sets the implementation function for #hb_font_get_glyph_name_func_t. * * Since: 0.9.2 **/ @@ -427,12 +756,12 @@ hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs, /** * hb_font_funcs_set_glyph_from_name_func: - * @ffuncs: font functions. - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * + * Sets the implementation function for #hb_font_get_glyph_from_name_func_t. * * Since: 0.9.2 **/ @@ -704,6 +1033,12 @@ hb_font_set_var_coords_design (hb_font_t *font, const float *coords, unsigned int coords_length); +#ifdef HB_EXPERIMENTAL_API +HB_EXTERN const float * +hb_font_get_var_coords_design (hb_font_t *font, + unsigned int *length); +#endif + HB_EXTERN void hb_font_set_var_coords_normalized (hb_font_t *font, const int *coords, /* 2.14 normalized */ @@ -717,6 +1052,12 @@ HB_EXTERN void hb_font_set_var_named_instance (hb_font_t *font, unsigned instance_index); +#ifdef HB_EXPERIMENTAL_API +HB_EXTERN hb_bool_t +hb_font_draw_glyph (hb_font_t *font, hb_codepoint_t glyph, + const hb_draw_funcs_t *funcs, void *user_data); +#endif + HB_END_DECLS #endif /* HB_FONT_H */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.hh b/src/3rdparty/harfbuzz-ng/src/hb-font.hh index b1e8e6440c..8fc7f44d44 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-font.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-font.hh @@ -120,6 +120,7 @@ struct hb_font_t /* Font variation coordinates. */ unsigned int num_coords; int *coords; + float *design_coords; hb_font_funcs_t *klass; void *user_data; @@ -286,7 +287,7 @@ struct hb_font_t } hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph, - hb_position_t *x, hb_position_t *y) + hb_position_t *x, hb_position_t *y) { *x = *y = 0; return klass->get.f.glyph_h_origin (this, user_data, @@ -338,7 +339,7 @@ struct hb_font_t } hb_bool_t get_glyph_contour_point (hb_codepoint_t glyph, unsigned int point_index, - hb_position_t *x, hb_position_t *y) + hb_position_t *x, hb_position_t *y) { *x = *y = 0; return klass->get.f.glyph_contour_point (this, user_data, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ft.cc b/src/3rdparty/harfbuzz-ng/src/hb-ft.cc index e526bf40d5..b82c1a67bd 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ft.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ft.cc @@ -48,8 +48,13 @@ * @short_description: FreeType integration * @include: hb-ft.h * - * Functions for using HarfBuzz with the FreeType library to provide face and + * Functions for using HarfBuzz with the FreeType library. + * + * HarfBuzz supports using FreeType to provide face and * font data. + * + * <note>Note that FreeType is not thread-safe, therefore these + * functions are not thread-safe either.</note> **/ @@ -79,7 +84,7 @@ struct hb_ft_font_t bool symbol; /* Whether selected cmap is symbol cmap. */ bool unref; /* Whether to destroy ft_face when done. */ - mutable hb_atomic_int_t cached_x_scale; + mutable int cached_x_scale; mutable hb_advance_cache_t advance_cache; }; @@ -87,9 +92,7 @@ static hb_ft_font_t * _hb_ft_font_create (FT_Face ft_face, bool symbol, bool unref) { hb_ft_font_t *ft_font = (hb_ft_font_t *) calloc (1, sizeof (hb_ft_font_t)); - - if (unlikely (!ft_font)) - return nullptr; + if (unlikely (!ft_font)) return nullptr; ft_font->lock.init (); ft_font->ft_face = ft_face; @@ -98,7 +101,7 @@ _hb_ft_font_create (FT_Face ft_face, bool symbol, bool unref) ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING; - ft_font->cached_x_scale.set_relaxed (0); + ft_font->cached_x_scale = 0; ft_font->advance_cache.init (); return ft_font; @@ -127,10 +130,13 @@ _hb_ft_font_destroy (void *data) /** * hb_ft_font_set_load_flags: - * @font: - * @load_flags: + * @font: #hb_font_t to work upon + * @load_flags: The FreeType load flags to set * + * Sets the FT_Load_Glyph load flags for the specified #hb_font_t. * + * For more information, see + * https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#ft_load_xxx * * Since: 1.0.5 **/ @@ -140,7 +146,7 @@ hb_ft_font_set_load_flags (hb_font_t *font, int load_flags) if (hb_object_is_immutable (font)) return; - if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy) + if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)) return; hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data; @@ -150,17 +156,21 @@ hb_ft_font_set_load_flags (hb_font_t *font, int load_flags) /** * hb_ft_font_get_load_flags: - * @font: + * @font: #hb_font_t to work upon * + * Fetches the FT_Load_Glyph load flags of the specified #hb_font_t. * + * For more information, see + * https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#ft_load_xxx + * + * Return value: FT_Load_Glyph flags found * - * Return value: * Since: 1.0.5 **/ int hb_ft_font_get_load_flags (hb_font_t *font) { - if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy) + if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)) return 0; const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data; @@ -168,10 +178,21 @@ hb_ft_font_get_load_flags (hb_font_t *font) return ft_font->load_flags; } +/** + * hb_ft_font_get_face: + * @font: #hb_font_t to work upon + * + * Fetches the FT_Face associated with the specified #hb_font_t + * font object. + * + * Return value: (nullable): the FT_Face found or %NULL + * + * Since: 0.9.2 + **/ FT_Face hb_ft_font_get_face (hb_font_t *font) { - if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy) + if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)) return nullptr; const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data; @@ -179,6 +200,47 @@ hb_ft_font_get_face (hb_font_t *font) return ft_font->ft_face; } +/** + * hb_ft_font_lock_face: + * @font: #hb_font_t to work upon + * + * Gets the FT_Face associated with @font, This face will be kept around until + * you call hb_ft_font_unlock_face(). + * + * Return value: (nullable): the FT_Face associated with @font or %NULL + * Since: 2.6.5 + **/ +FT_Face +hb_ft_font_lock_face (hb_font_t *font) +{ + if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)) + return nullptr; + + const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data; + + ft_font->lock.lock (); + + return ft_font->ft_face; +} + +/** + * hb_ft_font_unlock_face: + * @font: #hb_font_t to work upon + * + * Releases an FT_Face previously obtained with hb_ft_font_lock_face(). + * + * Since: 2.6.5 + **/ +void +hb_ft_font_unlock_face (hb_font_t *font) +{ + if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)) + return; + + const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data; + + ft_font->lock.unlock (); +} static hb_bool_t @@ -273,10 +335,10 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data, int load_flags = ft_font->load_flags; int mult = font->x_scale < 0 ? -1 : +1; - if (font->x_scale != ft_font->cached_x_scale.get ()) + if (font->x_scale != ft_font->cached_x_scale) { ft_font->advance_cache.clear (); - ft_font->cached_x_scale.set (font->x_scale); + ft_font->cached_x_scale = font->x_scale; } for (unsigned int i = 0; i < count; i++) @@ -556,9 +618,12 @@ _hb_ft_font_set_funcs (hb_font_t *font, FT_Face ft_face, bool unref) { bool symbol = ft_face->charmap && ft_face->charmap->encoding == FT_ENCODING_MS_SYMBOL; + hb_ft_font_t *ft_font = _hb_ft_font_create (ft_face, symbol, unref); + if (unlikely (!ft_font)) return; + hb_font_set_funcs (font, _hb_ft_get_font_funcs (), - _hb_ft_font_create (ft_face, symbol, unref), + ft_font, _hb_ft_font_destroy); } @@ -595,12 +660,22 @@ _hb_ft_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data /** * hb_ft_face_create: - * @ft_face: (destroy destroy) (scope notified): - * @destroy: + * @ft_face: (destroy destroy) (scope notified): FT_Face to work upon + * @destroy: (nullable): A callback to call when the face object is not needed anymore * + * Creates an #hb_face_t face object from the specified FT_Face. * + * 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. + * + * 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 + * after the #hb_face_t face object has been destroyed. + * + * Return value: (transfer full): the new #hb_face_t face object * - * Return value: (transfer full): * Since: 0.9.2 **/ hb_face_t * @@ -630,11 +705,20 @@ hb_ft_face_create (FT_Face ft_face, /** * hb_ft_face_create_referenced: - * @ft_face: + * @ft_face: FT_Face to work upon + * + * Creates an #hb_face_t face object from the specified FT_Face. * + * This is the preferred variant of the hb_ft_face_create* + * function family, because it calls FT_Reference_Face() on @ft_face, + * ensuring that @ft_face remains alive as long as the resulting + * #hb_face_t face object remains alive. Also calls FT_Done_Face() + * when the #hb_face_t face object is destroyed. * + * Use this version unless you know you have good reasons not to. + * + * Return value: (transfer full): the new #hb_face_t face object * - * Return value: (transfer full): * Since: 0.9.38 **/ hb_face_t * @@ -652,11 +736,21 @@ hb_ft_face_finalize (FT_Face ft_face) /** * hb_ft_face_create_cached: - * @ft_face: + * @ft_face: FT_Face to work upon + * + * Creates an #hb_face_t face object from the specified FT_Face. + * + * This variant of the function caches the newly created #hb_face_t + * face object, using the @generic pointer of @ft_face. Subsequent function + * calls that are passed the same @ft_face parameter will have the same + * #hb_face_t returned to them, and that #hb_face_t will be correctly + * reference counted. * + * However, client programs are still responsible for destroying + * @ft_face after the last #hb_face_t face object has been destroyed. * + * Return value: (transfer full): the new #hb_face_t face object * - * Return value: (transfer full): * Since: 0.9.2 **/ hb_face_t * @@ -674,15 +768,34 @@ hb_ft_face_create_cached (FT_Face ft_face) return hb_face_reference ((hb_face_t *) ft_face->generic.data); } - /** * hb_ft_font_create: - * @ft_face: (destroy destroy) (scope notified): - * @destroy: + * @ft_face: (destroy destroy) (scope notified): FT_Face to work upon + * @destroy: (nullable): A callback to call when the font object is not needed anymore + * + * Creates an #hb_font_t font object from the specified FT_Face. + * + * <note>Note: You must set the face size on @ft_face before calling + * hb_ft_font_create() on it. HarfBuzz assumes size is always set and will + * access `size` member of FT_Face unconditionally.</note> + * + * This variant of the function does not provide any life-cycle management. + * + * Most client programs should use hb_ft_font_create_referenced() + * 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 + * after the #hb_font_t font object has been destroyed. * + * 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 + * destroyed only after the #hb_font_t font object has been destroyed. * + * Return value: (transfer full): the new #hb_font_t font object * - * Return value: (transfer full): * Since: 0.9.2 **/ hb_font_t * @@ -700,6 +813,16 @@ hb_ft_font_create (FT_Face ft_face, return font; } +/** + * hb_ft_font_changed: + * @font: #hb_font_t to work upon + * + * Refreshes the state of @font when the underlying FT_Face has changed. + * This function should be called after changing the size or + * variation-axis settings on the FT_Face. + * + * Since: 1.0.5 + **/ void hb_ft_font_changed (hb_font_t *font) { @@ -707,6 +830,7 @@ hb_ft_font_changed (hb_font_t *font) return; hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data; + FT_Face ft_face = ft_font->ft_face; hb_font_set_scale (font, @@ -718,7 +842,7 @@ hb_ft_font_changed (hb_font_t *font) ft_face->size->metrics.y_ppem); #endif -#ifdef HAVE_FT_GET_VAR_BLEND_COORDINATES +#if defined(HAVE_FT_GET_VAR_BLEND_COORDINATES) && !defined(HB_NO_VAR) FT_MM_Var *mm_var = nullptr; if (!FT_Get_MM_Var (ft_face, &mm_var)) { @@ -755,11 +879,23 @@ hb_ft_font_changed (hb_font_t *font) /** * hb_ft_font_create_referenced: - * @ft_face: + * @ft_face: FT_Face to work upon + * + * Creates an #hb_font_t font object from the specified FT_Face. + * + * <note>Note: You must set the face size on @ft_face before calling + * hb_ft_font_create_referenced() on it. HarfBuzz assumes size is always set + * and will access `size` member of FT_Face unconditionally.</note> + * + * This is the preferred variant of the hb_ft_font_create* + * function family, because it calls FT_Reference_Face() on @ft_face, + * ensuring that @ft_face remains alive as long as the resulting + * #hb_font_t font object remains alive. * + * Use this version unless you know you have good reasons not to. * + * Return value: (transfer full): the new #hb_font_t font object * - * Return value: (transfer full): * Since: 0.9.38 **/ hb_font_t * @@ -818,6 +954,28 @@ _release_blob (FT_Face ft_face) hb_blob_destroy ((hb_blob_t *) ft_face->generic.data); } +/** + * hb_ft_font_set_funcs: + * @font: #hb_font_t to work upon + * + * Configures the font-functions structure of the specified + * #hb_font_t font object to use FreeType font functions. + * + * In particular, you can use this function to configure an + * existing #hb_face_t face object for use with FreeType font + * functions even if that #hb_face_t face object was initially + * created with hb_face_create(), and therefore was not + * initially configured to use FreeType font functions. + * + * An #hb_face_t face object created with hb_ft_face_create() + * is preconfigured for FreeType font functions and does not + * require this function to be used. + * + * <note>Note: Internally, this function creates an FT_Face. +* </note> + * + * Since: 1.0.5 + **/ void hb_ft_font_set_funcs (hb_font_t *font) { @@ -857,7 +1015,7 @@ hb_ft_font_set_funcs (hb_font_t *font) FT_Set_Transform (ft_face, &matrix, nullptr); } -#ifdef HAVE_FT_SET_VAR_BLEND_COORDINATES +#if defined(HAVE_FT_GET_VAR_BLEND_COORDINATES) && !defined(HB_NO_VAR) unsigned int num_coords; const int *coords = hb_font_get_var_coords_normalized (font, &num_coords); if (num_coords) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ft.h b/src/3rdparty/harfbuzz-ng/src/hb-ft.h index 94013eeb91..bf07115ab9 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ft.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-ft.h @@ -110,6 +110,12 @@ hb_ft_font_create_referenced (FT_Face ft_face); HB_EXTERN FT_Face hb_ft_font_get_face (hb_font_t *font); +HB_EXTERN FT_Face +hb_ft_font_lock_face (hb_font_t *font); + +HB_EXTERN void +hb_ft_font_unlock_face (hb_font_t *font); + HB_EXTERN void hb_ft_font_set_load_flags (hb_font_t *font, int load_flags); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-gdi.cc b/src/3rdparty/harfbuzz-ng/src/hb-gdi.cc index f6306ef89f..dc4659c7f6 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-gdi.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-gdi.cc @@ -28,6 +28,16 @@ #include "hb-gdi.h" + +/** + * SECTION:hb-gdi + * @title: hb-gdi + * @short_description: GDI integration + * @include: hb-gdi.h + * + * Functions for using HarfBuzz with GDI fonts. + **/ + static hb_blob_t * _hb_gdi_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) { @@ -60,6 +70,8 @@ fail: * hb_gdi_face_create: * @hfont: a HFONT object. * + * Constructs a new face object from the specified GDI HFONT. + * * Return value: #hb_face_t object corresponding to the given input * * Since: 2.6.0 diff --git a/src/3rdparty/harfbuzz-ng/src/hb-glib.cc b/src/3rdparty/harfbuzz-ng/src/hb-glib.cc index db02b6760e..f93bb8853c 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-glib.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-glib.cc @@ -41,166 +41,46 @@ * @short_description: GLib integration * @include: hb-glib.h * - * Functions for using HarfBuzz with the GLib library to provide Unicode data. + * Functions for using HarfBuzz with the GLib library. + * + * HarfBuzz supports using GLib to provide Unicode data, by attaching + * GLib functions to the virtual methods in a #hb_unicode_funcs_t function + * structure. **/ -#if !GLIB_CHECK_VERSION(2,29,14) -static const hb_script_t -glib_script_to_script[] = -{ - HB_SCRIPT_COMMON, - HB_SCRIPT_INHERITED, - HB_SCRIPT_ARABIC, - HB_SCRIPT_ARMENIAN, - HB_SCRIPT_BENGALI, - HB_SCRIPT_BOPOMOFO, - HB_SCRIPT_CHEROKEE, - HB_SCRIPT_COPTIC, - HB_SCRIPT_CYRILLIC, - HB_SCRIPT_DESERET, - HB_SCRIPT_DEVANAGARI, - HB_SCRIPT_ETHIOPIC, - HB_SCRIPT_GEORGIAN, - HB_SCRIPT_GOTHIC, - HB_SCRIPT_GREEK, - HB_SCRIPT_GUJARATI, - HB_SCRIPT_GURMUKHI, - HB_SCRIPT_HAN, - HB_SCRIPT_HANGUL, - HB_SCRIPT_HEBREW, - HB_SCRIPT_HIRAGANA, - HB_SCRIPT_KANNADA, - HB_SCRIPT_KATAKANA, - HB_SCRIPT_KHMER, - HB_SCRIPT_LAO, - HB_SCRIPT_LATIN, - HB_SCRIPT_MALAYALAM, - HB_SCRIPT_MONGOLIAN, - HB_SCRIPT_MYANMAR, - HB_SCRIPT_OGHAM, - HB_SCRIPT_OLD_ITALIC, - HB_SCRIPT_ORIYA, - HB_SCRIPT_RUNIC, - HB_SCRIPT_SINHALA, - HB_SCRIPT_SYRIAC, - HB_SCRIPT_TAMIL, - HB_SCRIPT_TELUGU, - HB_SCRIPT_THAANA, - HB_SCRIPT_THAI, - HB_SCRIPT_TIBETAN, - HB_SCRIPT_CANADIAN_SYLLABICS, - HB_SCRIPT_YI, - HB_SCRIPT_TAGALOG, - HB_SCRIPT_HANUNOO, - HB_SCRIPT_BUHID, - HB_SCRIPT_TAGBANWA, - - /* Unicode-4.0 additions */ - HB_SCRIPT_BRAILLE, - HB_SCRIPT_CYPRIOT, - HB_SCRIPT_LIMBU, - HB_SCRIPT_OSMANYA, - HB_SCRIPT_SHAVIAN, - HB_SCRIPT_LINEAR_B, - HB_SCRIPT_TAI_LE, - HB_SCRIPT_UGARITIC, - - /* Unicode-4.1 additions */ - HB_SCRIPT_NEW_TAI_LUE, - HB_SCRIPT_BUGINESE, - HB_SCRIPT_GLAGOLITIC, - HB_SCRIPT_TIFINAGH, - HB_SCRIPT_SYLOTI_NAGRI, - HB_SCRIPT_OLD_PERSIAN, - HB_SCRIPT_KHAROSHTHI, - - /* Unicode-5.0 additions */ - HB_SCRIPT_UNKNOWN, - HB_SCRIPT_BALINESE, - HB_SCRIPT_CUNEIFORM, - HB_SCRIPT_PHOENICIAN, - HB_SCRIPT_PHAGS_PA, - HB_SCRIPT_NKO, - - /* Unicode-5.1 additions */ - HB_SCRIPT_KAYAH_LI, - HB_SCRIPT_LEPCHA, - HB_SCRIPT_REJANG, - HB_SCRIPT_SUNDANESE, - HB_SCRIPT_SAURASHTRA, - HB_SCRIPT_CHAM, - HB_SCRIPT_OL_CHIKI, - HB_SCRIPT_VAI, - HB_SCRIPT_CARIAN, - HB_SCRIPT_LYCIAN, - HB_SCRIPT_LYDIAN, - - /* Unicode-5.2 additions */ - HB_SCRIPT_AVESTAN, - HB_SCRIPT_BAMUM, - HB_SCRIPT_EGYPTIAN_HIEROGLYPHS, - HB_SCRIPT_IMPERIAL_ARAMAIC, - HB_SCRIPT_INSCRIPTIONAL_PAHLAVI, - HB_SCRIPT_INSCRIPTIONAL_PARTHIAN, - HB_SCRIPT_JAVANESE, - HB_SCRIPT_KAITHI, - HB_SCRIPT_TAI_THAM, - HB_SCRIPT_LISU, - HB_SCRIPT_MEETEI_MAYEK, - HB_SCRIPT_OLD_SOUTH_ARABIAN, - HB_SCRIPT_OLD_TURKIC, - HB_SCRIPT_SAMARITAN, - HB_SCRIPT_TAI_VIET, - - /* Unicode-6.0 additions */ - HB_SCRIPT_BATAK, - HB_SCRIPT_BRAHMI, - HB_SCRIPT_MANDAIC, - - /* Unicode-6.1 additions */ - HB_SCRIPT_CHAKMA, - HB_SCRIPT_MEROITIC_CURSIVE, - HB_SCRIPT_MEROITIC_HIEROGLYPHS, - HB_SCRIPT_MIAO, - HB_SCRIPT_SHARADA, - HB_SCRIPT_SORA_SOMPENG, - HB_SCRIPT_TAKRI -}; -#endif - +/** + * hb_glib_script_to_script: + * @script: The GUnicodeScript identifier to query + * + * Fetches the #hb_script_t script that corresponds to the + * specified GUnicodeScript identifier. + * + * Return value: the #hb_script_t script found + * + * Since: 0.9.38 + **/ hb_script_t hb_glib_script_to_script (GUnicodeScript script) { -#if GLIB_CHECK_VERSION(2,29,14) return (hb_script_t) g_unicode_script_to_iso15924 (script); -#else - if (likely ((unsigned int) script < ARRAY_LENGTH (glib_script_to_script))) - return glib_script_to_script[script]; - - if (unlikely (script == G_UNICODE_SCRIPT_INVALID_CODE)) - return HB_SCRIPT_INVALID; - - return HB_SCRIPT_UNKNOWN; -#endif } +/** + * hb_glib_script_from_script: + * @script: The #hb_script_t to query + * + * Fetches the GUnicodeScript identifier that corresponds to the + * specified #hb_script_t script. + * + * Return value: the GUnicodeScript identifier found + * + * Since: 0.9.38 + **/ GUnicodeScript hb_glib_script_from_script (hb_script_t script) { -#if GLIB_CHECK_VERSION(2,29,14) return g_unicode_script_from_iso15924 (script); -#else - unsigned int count = ARRAY_LENGTH (glib_script_to_script); - for (unsigned int i = 0; i < count; i++) - if (glib_script_to_script[i] == script) - return (GUnicodeScript) i; - - if (unlikely (script == HB_SCRIPT_INVALID)) - return G_UNICODE_SCRIPT_INVALID_CODE; - - return G_UNICODE_SCRIPT_UNKNOWN; -#endif } @@ -373,6 +253,16 @@ void free_static_glib_funcs () } #endif +/** + * hb_glib_get_unicode_funcs: + * + * Fetches a Unicode-functions structure that is populated + * with the appropriate GLib function for each method. + * + * Return value: (transfer none): a pointer to the #hb_unicode_funcs_t Unicode-functions structure + * + * Since: 0.9.38 + **/ hb_unicode_funcs_t * hb_glib_get_unicode_funcs () { @@ -391,6 +281,12 @@ _hb_g_bytes_unref (void *data) /** * hb_glib_blob_create: + * @gbytes: the GBytes structure to work upon + * + * Creates an #hb_blob_t blob from the specified + * GBytes data structure. + * + * Return value: (transfer full): the new #hb_blob_t blob object * * Since: 0.9.38 **/ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-gobject-enums.cc.tmpl b/src/3rdparty/harfbuzz-ng/src/hb-gobject-enums.cc.tmpl deleted file mode 100644 index 17f1adeb1d..0000000000 --- a/src/3rdparty/harfbuzz-ng/src/hb-gobject-enums.cc.tmpl +++ /dev/null @@ -1,80 +0,0 @@ -/*** BEGIN file-header ***/ -/* - * Copyright © 2011 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ - -#include "hb.hh" - -#ifdef HAVE_GOBJECT - -/* g++ didn't like older gtype.h gcc-only code path. */ -#include <glib.h> -#if !GLIB_CHECK_VERSION(2,29,16) -#undef __GNUC__ -#undef __GNUC_MINOR__ -#define __GNUC__ 2 -#define __GNUC_MINOR__ 6 -#endif - -#include "hb-gobject.h" - -/*** END file-header ***/ - -/*** BEGIN file-production ***/ -/* enumerations from "@filename@" */ -/*** END file-production ***/ - -/*** BEGIN file-tail ***/ - -#endif -/*** END file-tail ***/ - -/*** BEGIN value-header ***/ -GType -@enum_name@_get_type () -{ - static gsize type_id = 0; - - if (g_once_init_enter (&type_id)) - { - static const G@Type@Value values[] = { -/*** END value-header ***/ - -/*** BEGIN value-production ***/ - { @VALUENAME@, "@VALUENAME@", "@valuenick@" }, -/*** END value-production ***/ - -/*** BEGIN value-tail ***/ - { 0, NULL, NULL } - }; - GType id = - g_@type@_register_static (g_intern_static_string ("@EnumName@"), values); - g_once_init_leave (&type_id, id); - } - - return type_id; -} - -/*** END value-tail ***/ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-gobject-enums.h.tmpl b/src/3rdparty/harfbuzz-ng/src/hb-gobject-enums.h.tmpl deleted file mode 100644 index 7ef9dfc029..0000000000 --- a/src/3rdparty/harfbuzz-ng/src/hb-gobject-enums.h.tmpl +++ /dev/null @@ -1,56 +0,0 @@ -/*** BEGIN file-header ***/ -/* - * Copyright © 2013 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ - -#ifndef HB_GOBJECT_H_IN -#error "Include <hb-gobject.h> instead." -#endif - -#ifndef HB_GOBJECT_ENUMS_H -#define HB_GOBJECT_ENUMS_H - -#include "hb.h" - -#include <glib-object.h> - -HB_BEGIN_DECLS - - -/*** END file-header ***/ - -/*** BEGIN value-header ***/ -HB_EXTERN GType -@enum_name@_get_type () G_GNUC_CONST; -#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ()) - -/*** END value-header ***/ - -/*** BEGIN file-tail ***/ - -HB_END_DECLS - -#endif /* HB_GOBJECT_ENUMS_H */ -/*** END file-tail ***/ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-gobject-structs.cc b/src/3rdparty/harfbuzz-ng/src/hb-gobject-structs.cc index 7f4922ef19..7c46e26400 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-gobject-structs.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-gobject-structs.cc @@ -32,11 +32,20 @@ /** * SECTION:hb-gobject * @title: hb-gobject - * @short_description: GObject integration + * @short_description: GObject integration support * @include: hb-gobject.h * - * Functions for using HarfBuzz with the GObject library to provide + * Support for using HarfBuzz with the GObject library to provide * type data. + * + * The types and functions listed here are solely a linkage between + * HarfBuzz's public data types and the GTypes used by the GObject framework. + * HarfBuzz uses GObject introspection to generate its Python bindings + * (and potentially other language bindings); client programs should never need + * to access the GObject-integration mechanics. + * + * For client programs using the GNOME and GTK software stack, please see the + * GLib and FreeType integration pages. **/ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-gobject-structs.h b/src/3rdparty/harfbuzz-ng/src/hb-gobject-structs.h index 800beede0f..63467f80df 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-gobject-structs.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-gobject-structs.h @@ -1,5 +1,5 @@ /* - * Copyright © 2011 Google, Inc. + * Copyright (C) 2011 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -24,7 +24,7 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_GOBJECT_H_IN +#if !defined(HB_GOBJECT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb-gobject.h> instead." #endif @@ -40,47 +40,22 @@ HB_BEGIN_DECLS /* Object types */ -/** - * hb_gobject_blob_get_type: - * - * Since: 0.9.2 - **/ HB_EXTERN GType hb_gobject_blob_get_type (void); #define HB_GOBJECT_TYPE_BLOB (hb_gobject_blob_get_type ()) -/** - * hb_gobject_buffer_get_type: - * - * Since: 0.9.2 - **/ HB_EXTERN GType hb_gobject_buffer_get_type (void); #define HB_GOBJECT_TYPE_BUFFER (hb_gobject_buffer_get_type ()) -/** - * hb_gobject_face_get_type: - * - * Since: 0.9.2 - **/ HB_EXTERN GType hb_gobject_face_get_type (void); #define HB_GOBJECT_TYPE_FACE (hb_gobject_face_get_type ()) -/** - * hb_gobject_font_get_type: - * - * Since: 0.9.2 - **/ HB_EXTERN GType hb_gobject_font_get_type (void); #define HB_GOBJECT_TYPE_FONT (hb_gobject_font_get_type ()) -/** - * hb_gobject_font_funcs_get_type: - * - * Since: 0.9.2 - **/ HB_EXTERN GType hb_gobject_font_funcs_get_type (void); #define HB_GOBJECT_TYPE_FONT_FUNCS (hb_gobject_font_funcs_get_type ()) @@ -97,11 +72,6 @@ HB_EXTERN GType hb_gobject_shape_plan_get_type (void); #define HB_GOBJECT_TYPE_SHAPE_PLAN (hb_gobject_shape_plan_get_type ()) -/** - * hb_gobject_unicode_funcs_get_type: - * - * Since: 0.9.2 - **/ HB_EXTERN GType hb_gobject_unicode_funcs_get_type (void); #define HB_GOBJECT_TYPE_UNICODE_FUNCS (hb_gobject_unicode_funcs_get_type ()) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-gobject.h b/src/3rdparty/harfbuzz-ng/src/hb-gobject.h index ea1bd25df8..8891aa0ee7 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-gobject.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-gobject.h @@ -1,5 +1,5 @@ /* - * Copyright © 2011 Google, Inc. + * Copyright (C) 2011 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * diff --git a/src/3rdparty/harfbuzz-ng/src/hb-graphite2.cc b/src/3rdparty/harfbuzz-ng/src/hb-graphite2.cc index f0f2f8c736..9dafe654c8 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-graphite2.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-graphite2.cc @@ -45,7 +45,11 @@ * @short_description: Graphite2 integration * @include: hb-graphite2.h * - * Functions for using HarfBuzz with the Graphite2 fonts. + * Functions for using HarfBuzz with fonts that include Graphite features. + * + * For Graphite features to work, you must be sure that HarfBuzz was compiled + * with the `graphite2` shaping engine enabled. Currently, the default is to + * not enable `graphite2` shaping. **/ @@ -152,7 +156,15 @@ _hb_graphite2_shaper_face_data_destroy (hb_graphite2_face_data_t *data) free (data); } -/* +/** + * hb_graphite2_face_get_gr_face: + * @face: @hb_face_t to query + * + * Fetches the Graphite2 gr_face corresponding to the specified + * #hb_face_t face object. + * + * Return value: the gr_face found + * * Since: 0.9.10 */ gr_face * @@ -183,6 +195,11 @@ _hb_graphite2_shaper_font_data_destroy (hb_graphite2_font_data_t *data HB_UNUSED #ifndef HB_DISABLE_DEPRECATED /** * hb_graphite2_font_get_gr_font: + * @font: An #hb_font_t + * + * Always returns %NULL. Use hb_graphite2_face_get_gr_face() instead. + * + * Return value: (nullable): Graphite2 font associated with @font. * * Since: 0.9.10 * Deprecated: 1.4.2 @@ -272,7 +289,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED, return true; } - buffer->ensure (glyph_count); + (void) buffer->ensure (glyph_count); scratch = buffer->get_scratch_buffer (&scratch_size); while ((DIV_CEIL (sizeof (hb_graphite2_cluster_t) * buffer->len, sizeof (*scratch)) + DIV_CEIL (sizeof (hb_codepoint_t) * glyph_count, sizeof (*scratch))) > scratch_size) @@ -376,7 +393,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED, buffer->len = glyph_count; /* Positioning. */ - unsigned int currclus = (unsigned int) -1; + unsigned int currclus = UINT_MAX; const hb_glyph_info_t *info = buffer->info; hb_glyph_position_t *pPos = hb_buffer_get_glyph_positions (buffer, nullptr); if (!HB_DIRECTION_IS_BACKWARD(buffer->props.direction)) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-graphite2.h b/src/3rdparty/harfbuzz-ng/src/hb-graphite2.h index 1720191b42..f299da9f71 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-graphite2.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-graphite2.h @@ -32,7 +32,15 @@ HB_BEGIN_DECLS - +/** + * HB_GRAPHITE2_TAG_SILF: + * + * The #hb_tag_t tag for the `Silf` table, which holds Graphite + * features. + * + * For more information, see http://graphite.sil.org/ + * + **/ #define HB_GRAPHITE2_TAG_SILF HB_TAG('S','i','l','f') diff --git a/src/3rdparty/harfbuzz-ng/src/hb-icu.cc b/src/3rdparty/harfbuzz-ng/src/hb-icu.cc index 985ff02dcd..008a39e414 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-icu.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-icu.cc @@ -54,7 +54,21 @@ * @short_description: ICU integration * @include: hb-icu.h * - * Functions for using HarfBuzz with the ICU library to provide Unicode data. + * Functions for using HarfBuzz with the International Components for Unicode + * (ICU) library. HarfBuzz supports using ICU to provide Unicode data, by attaching + * ICU functions to the virtual methods in a #hb_unicode_funcs_t function + * structure. + **/ + +/** + * hb_icu_script_to_script: + * @script: The UScriptCode identifier to query + * + * Fetches the #hb_script_t script that corresponds to the + * specified UScriptCode identifier. + * + * Return value: the #hb_script_t script found + * **/ hb_script_t @@ -66,6 +80,16 @@ hb_icu_script_to_script (UScriptCode script) return hb_script_from_string (uscript_getShortName (script), -1); } +/** + * hb_icu_script_from_script: + * @script: The #hb_script_t script to query + * + * Fetches the UScriptCode identifier that corresponds to the + * specified #hb_script_t script. + * + * Return value: the UScriptCode identifier found + * + **/ UScriptCode hb_icu_script_from_script (hb_script_t script) { @@ -168,45 +192,13 @@ hb_icu_unicode_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED, hb_codepoint_t a, hb_codepoint_t b, hb_codepoint_t *ab, - void *user_data HB_UNUSED) + void *user_data) { -#if U_ICU_VERSION_MAJOR_NUM >= 49 - { - const UNormalizer2 *normalizer = (const UNormalizer2 *) user_data; - UChar32 ret = unorm2_composePair (normalizer, a, b); - if (ret < 0) return false; - *ab = ret; - return true; - } -#endif - - /* We don't ifdef-out the fallback code such that compiler always - * sees it and makes sure it's compilable. */ - - UChar utf16[4], normalized[5]; - unsigned int len; - hb_bool_t ret, err; - UErrorCode icu_err; - - len = 0; - err = false; - U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), a, err); - if (err) return false; - U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), b, err); - if (err) return false; - - icu_err = U_ZERO_ERROR; - len = unorm2_normalize (unorm2_getNFCInstance (&icu_err), utf16, len, normalized, ARRAY_LENGTH (normalized), &icu_err); - if (U_FAILURE (icu_err)) - return false; - if (u_countChar32 (normalized, len) == 1) { - U16_GET_UNSAFE (normalized, 0, *ab); - ret = true; - } else { - ret = false; - } - - return ret; + const UNormalizer2 *normalizer = (const UNormalizer2 *) user_data; + UChar32 ret = unorm2_composePair (normalizer, a, b); + if (ret < 0) return false; + *ab = ret; + return true; } static hb_bool_t @@ -214,97 +206,30 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED, hb_codepoint_t ab, hb_codepoint_t *a, hb_codepoint_t *b, - void *user_data HB_UNUSED) + void *user_data) { -#if U_ICU_VERSION_MAJOR_NUM >= 49 + const UNormalizer2 *normalizer = (const UNormalizer2 *) user_data; + UChar decomposed[4]; + int len; + UErrorCode icu_err = U_ZERO_ERROR; + len = unorm2_getRawDecomposition (normalizer, ab, decomposed, + ARRAY_LENGTH (decomposed), &icu_err); + if (U_FAILURE (icu_err) || len < 0) return false; + + len = u_countChar32 (decomposed, len); + if (len == 1) { - const UNormalizer2 *normalizer = (const UNormalizer2 *) user_data; - UChar decomposed[4]; - int len; - UErrorCode icu_err = U_ZERO_ERROR; - len = unorm2_getRawDecomposition (normalizer, ab, decomposed, - ARRAY_LENGTH (decomposed), &icu_err); - if (U_FAILURE (icu_err) || len < 0) return false; - - len = u_countChar32 (decomposed, len); - if (len == 1) { - U16_GET_UNSAFE (decomposed, 0, *a); - *b = 0; - return *a != ab; - } else if (len == 2) { - len = 0; - U16_NEXT_UNSAFE (decomposed, len, *a); - U16_NEXT_UNSAFE (decomposed, len, *b); - } - return true; - } -#endif - - /* We don't ifdef-out the fallback code such that compiler always - * sees it and makes sure it's compilable. */ - - UChar utf16[2], normalized[2 * 19/*HB_UNICODE_MAX_DECOMPOSITION_LEN*/ + 1]; - unsigned int len; - hb_bool_t ret, err; - UErrorCode icu_err; - - /* This function is a monster! Maybe it wasn't a good idea adding a - * pairwise decompose API... */ - /* Watchout for the dragons. Err, watchout for macros changing len. */ - - len = 0; - err = false; - U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), ab, err); - if (err) return false; - - icu_err = U_ZERO_ERROR; - len = unorm2_normalize (unorm2_getNFDInstance (&icu_err), utf16, len, normalized, ARRAY_LENGTH (normalized), &icu_err); - if (U_FAILURE (icu_err)) - return false; - - len = u_countChar32 (normalized, len); - - if (len == 1) { - U16_GET_UNSAFE (normalized, 0, *a); + U16_GET_UNSAFE (decomposed, 0, *a); *b = 0; - ret = *a != ab; - } else if (len == 2) { + return *a != ab; + } + else if (len == 2) + { len = 0; - U16_NEXT_UNSAFE (normalized, len, *a); - U16_NEXT_UNSAFE (normalized, len, *b); - - /* Here's the ugly part: if ab decomposes to a single character and - * that character decomposes again, we have to detect that and undo - * the second part :-(. */ - UChar recomposed[20]; - icu_err = U_ZERO_ERROR; - unorm2_normalize (unorm2_getNFCInstance (&icu_err), normalized, len, recomposed, ARRAY_LENGTH (recomposed), &icu_err); - if (U_FAILURE (icu_err)) - return false; - hb_codepoint_t c; - U16_GET_UNSAFE (recomposed, 0, c); - if (c != *a && c != ab) { - *a = c; - *b = 0; - } - ret = true; - } else { - /* If decomposed to more than two characters, take the last one, - * and recompose the rest to get the first component. */ - U16_PREV_UNSAFE (normalized, len, *b); /* Changes len in-place. */ - UChar recomposed[18 * 2]; - icu_err = U_ZERO_ERROR; - len = unorm2_normalize (unorm2_getNFCInstance (&icu_err), normalized, len, recomposed, ARRAY_LENGTH (recomposed), &icu_err); - if (U_FAILURE (icu_err)) - return false; - /* We expect that recomposed has exactly one character now. */ - if (unlikely (u_countChar32 (recomposed, len) != 1)) - return false; - U16_GET_UNSAFE (recomposed, 0, *a); - ret = true; + U16_NEXT_UNSAFE (decomposed, len, *a); + U16_NEXT_UNSAFE (decomposed, len, *b); } - - return ret; + return true; } @@ -317,11 +242,9 @@ static struct hb_icu_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader_ static hb_unicode_funcs_t *create () { void *user_data = nullptr; -#if U_ICU_VERSION_MAJOR_NUM >= 49 UErrorCode icu_err = U_ZERO_ERROR; user_data = (void *) unorm2_getNFCInstance (&icu_err); assert (user_data); -#endif hb_unicode_funcs_t *funcs = hb_unicode_funcs_create (nullptr); @@ -350,6 +273,16 @@ void free_static_icu_funcs () } #endif +/** + * hb_icu_get_unicode_funcs: + * + * Fetches a Unicode-functions structure that is populated + * with the appropriate ICU function for each method. + * + * Return value: (transfer none): a pointer to the #hb_unicode_funcs_t Unicode-functions structure + * + * Since: 0.9.38 + **/ hb_unicode_funcs_t * hb_icu_get_unicode_funcs () { diff --git a/src/3rdparty/harfbuzz-ng/src/hb-iter.hh b/src/3rdparty/harfbuzz-ng/src/hb-iter.hh index 981c5c218c..f7018150e4 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-iter.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-iter.hh @@ -922,7 +922,7 @@ HB_FUNCOBJ (hb_none); template <typename C, typename V, hb_requires (hb_is_iterable (C))> inline void -hb_fill (C& c, const V &v) +hb_fill (C&& c, const V &v) { for (auto i = hb_iter (c); i; i++) *i = v; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-kern.hh b/src/3rdparty/harfbuzz-ng/src/hb-kern.hh index 99d533c045..3f952fe7fc 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-kern.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-kern.hh @@ -52,8 +52,7 @@ struct hb_kern_machine_t OT::hb_ot_apply_context_t c (1, font, buffer); c.set_lookup_mask (kern_mask); c.set_lookup_props (OT::LookupFlag::IgnoreMarks); - OT::hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c.iter_input; - skippy_iter.init (&c); + auto &skippy_iter = c.iter_input; bool horizontal = HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction); unsigned int count = buffer->len; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-machinery.hh b/src/3rdparty/harfbuzz-ng/src/hb-machinery.hh index 15535d75bd..3bd5a979b0 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-machinery.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-machinery.hh @@ -41,22 +41,6 @@ * Casts */ -/* Cast to struct T, reference to reference */ -template<typename Type, typename TObject> -static inline const Type& CastR(const TObject &X) -{ return reinterpret_cast<const Type&> (X); } -template<typename Type, typename TObject> -static inline Type& CastR(TObject &X) -{ return reinterpret_cast<Type&> (X); } - -/* Cast to struct T, pointer to pointer */ -template<typename Type, typename TObject> -static inline const Type* CastP(const TObject *X) -{ return reinterpret_cast<const Type*> (X); } -template<typename Type, typename TObject> -static inline Type* CastP(TObject *X) -{ return reinterpret_cast<Type*> (X); } - /* StructAtOffset<T>(P,Ofs) returns the struct T& that is placed at memory * location pointed to by P plus Ofs bytes. */ template<typename Type> @@ -70,7 +54,7 @@ static inline const Type& StructAtOffsetUnaligned(const void *P, unsigned int of { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" - return * reinterpret_cast<Type*> ((char *) P + offset); + return * reinterpret_cast<const Type*> ((const char *) P + offset); #pragma GCC diagnostic pop } template<typename Type> @@ -96,6 +80,11 @@ static inline Type& StructAfter(TObject &X) * Size checking */ +/* Size signifying variable-sized array */ +#ifndef HB_VAR_ARRAY +#define HB_VAR_ARRAY 1 +#endif + /* Check _assertion in a method environment */ #define _DEFINE_INSTANCE_ASSERTION1(_line, _assertion) \ void _instance_assertion_on_line_##_line () const \ @@ -135,7 +124,7 @@ static inline Type& StructAfter(TObject &X) #define DEFINE_SIZE_ARRAY(size, array) \ DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size) \ - DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + HB_VAR_ARRAY * sizeof ((array)[0])) \ + DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + (HB_VAR_ARRAY+0) * sizeof ((array)[0])) \ static constexpr unsigned null_size = (size); \ static constexpr unsigned min_size = (size) @@ -250,7 +239,7 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> static Returned* convert (Stored *p) { return p; } /* By default null/init/fini the object. */ - static const Stored* get_null () { return &Null(Stored); } + static const Stored* get_null () { return &Null (Stored); } static Stored *create (Data *data) { Stored *p = (Stored *) calloc (1, sizeof (Stored)); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-map.cc b/src/3rdparty/harfbuzz-ng/src/hb-map.cc index a2c770c586..f115da2bb8 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-map.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-map.cc @@ -42,7 +42,9 @@ /** * hb_map_create: (Xconstructor) * - * Return value: (transfer full): + * Creates a new, initially empty map. + * + * Return value: (transfer full): The new #hb_map_t * * Since: 1.7.7 **/ @@ -62,21 +64,25 @@ hb_map_create () /** * hb_map_get_empty: * - * Return value: (transfer full): + * Fetches the singleton empty #hb_map_t. + * + * Return value: (transfer full): The empty #hb_map_t * * Since: 1.7.7 **/ hb_map_t * hb_map_get_empty () { - return const_cast<hb_map_t *> (&Null(hb_map_t)); + return const_cast<hb_map_t *> (&Null (hb_map_t)); } /** * hb_map_reference: (skip) - * @map: a map. + * @map: A map + * + * Increases the reference count on a map. * - * Return value: (transfer full): + * Return value: (transfer full): The map * * Since: 1.7.7 **/ @@ -88,7 +94,11 @@ hb_map_reference (hb_map_t *map) /** * hb_map_destroy: (skip) - * @map: a map. + * @map: A map + * + * Decreases the reference count on a map. When + * the reference count reaches zero, the map is + * destroyed, freeing all memory. * * Since: 1.7.7 **/ @@ -104,13 +114,15 @@ hb_map_destroy (hb_map_t *map) /** * hb_map_set_user_data: (skip) - * @map: a map. - * @key: - * @data: - * @destroy: - * @replace: + * @map: A map + * @key: The user-data key to set + * @data: A pointer to the user data to set + * @destroy: (nullable): A callback to call when @data is not needed anymore + * @replace: Whether to replace an existing data with the same key + * + * Attaches a user-data key/data pair to the specified map. * - * Return value: + * Return value: %true if success, %false otherwise * * Since: 1.7.7 **/ @@ -126,10 +138,13 @@ hb_map_set_user_data (hb_map_t *map, /** * hb_map_get_user_data: (skip) - * @map: a map. - * @key: + * @map: A map + * @key: The user-data key to query + * + * Fetches the user data associated with the specified key, + * attached to the specified map. * - * Return value: (transfer none): + * Return value: (transfer none): A pointer to the user data * * Since: 1.7.7 **/ @@ -143,11 +158,11 @@ hb_map_get_user_data (hb_map_t *map, /** * hb_map_allocation_successful: - * @map: a map. + * @map: A map * + * Tests whether memory allocation for a set was successful. * - * - * Return value: + * Return value: %true if allocation succeeded, %false otherwise * * Since: 1.7.7 **/ @@ -160,11 +175,11 @@ hb_map_allocation_successful (const hb_map_t *map) /** * hb_map_set: - * @map: a map. - * @key: - * @value: - * + * @map: A map + * @key: The key to store in the map + * @value: The value to store for @key * + * Stores @key:@value in the map. * * Since: 1.7.7 **/ @@ -178,10 +193,10 @@ hb_map_set (hb_map_t *map, /** * hb_map_get: - * @map: a map. - * @key: - * + * @map: A map + * @key: The key to query * + * Fetches the value stored for @key in @map. * * Since: 1.7.7 **/ @@ -194,10 +209,10 @@ hb_map_get (const hb_map_t *map, /** * hb_map_del: - * @map: a map. - * @key: - * + * @map: A map + * @key: The key to delete * + * Removes @key and its stored value from @map. * * Since: 1.7.7 **/ @@ -210,10 +225,12 @@ hb_map_del (hb_map_t *map, /** * hb_map_has: - * @map: a map. - * @key: + * @map: A map + * @key: The key to query * + * Tests whether @key is an element of @map. * + * Return value: %true if @key is found in @map, %false otherwise * * Since: 1.7.7 **/ @@ -227,23 +244,28 @@ hb_map_has (const hb_map_t *map, /** * hb_map_clear: - * @map: a map. - * + * @map: A map * + * Clears out the contents of @map. * * Since: 1.7.7 **/ void hb_map_clear (hb_map_t *map) { + if (unlikely (hb_object_is_immutable (map))) + return; + return map->clear (); } /** * hb_map_is_empty: - * @map: a map. + * @map: A map * + * Tests whether @map is empty (contains no elements). * + * Return value: %true if @map is empty * * Since: 1.7.7 **/ @@ -255,9 +277,11 @@ hb_map_is_empty (const hb_map_t *map) /** * hb_map_get_population: - * @map: a map. + * @map: A map * + * Returns the number of key-value pairs in the map. * + * Return value: The population of @map * * Since: 1.7.7 **/ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-map.h b/src/3rdparty/harfbuzz-ng/src/hb-map.h index b77843c2ba..6a45a7bdd5 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-map.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-map.h @@ -24,7 +24,7 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_H_IN +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb.h> instead." #endif @@ -36,11 +36,21 @@ HB_BEGIN_DECLS -/* +/** + * HB_MAP_VALUE_INVALID: + * + * Unset #hb_map_t value. + * * Since: 1.7.7 */ #define HB_MAP_VALUE_INVALID ((hb_codepoint_t) -1) +/** + * hb_map_t: + * + * Data type for holding integer-to-integer hash maps. + * + **/ typedef struct hb_map_t hb_map_t; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-map.hh b/src/3rdparty/harfbuzz-ng/src/hb-map.hh index 8c8db4d520..84fe1d549b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-map.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-map.hh @@ -54,7 +54,7 @@ struct hb_hashmap_t void clear () { key = kINVALID; value = vINVALID; hash = 0; } - bool operator == (K o) { return hb_deref (key) == hb_deref (o); } + bool operator == (const K &o) { return hb_deref (key) == hb_deref (o); } bool operator == (const item_t &o) { return *this == o.key; } bool is_unused () const { return key == kINVALID; } bool is_tombstone () const { return key != kINVALID && value == vINVALID; } @@ -97,8 +97,6 @@ struct hb_hashmap_t void reset () { - if (unlikely (hb_object_is_immutable (this))) - return; successful = true; clear (); } @@ -117,9 +115,8 @@ struct hb_hashmap_t successful = false; return false; } - + hb_iter (new_items, new_size) - | hb_apply (&item_t::clear) - ; + for (auto &_ : hb_iter (new_items, new_size)) + _.clear (); unsigned int old_size = mask + 1; item_t *old_items = items; @@ -135,8 +132,8 @@ struct hb_hashmap_t for (unsigned int i = 0; i < old_size; i++) if (old_items[i].is_real ()) set_with_hash (old_items[i].key, - old_items[i].hash, - old_items[i].value); + old_items[i].hash, + old_items[i].value); free (old_items); @@ -172,17 +169,15 @@ struct hb_hashmap_t void clear () { - if (unlikely (hb_object_is_immutable (this))) - return; if (items) - + hb_iter (items, mask + 1) - | hb_apply (&item_t::clear) - ; + for (auto &_ : hb_iter (items, mask + 1)) + _.clear (); population = occupancy = 0; } bool is_empty () const { return population == 0; } + explicit operator bool () const { return !is_empty (); } unsigned int get_population () const { return population; } @@ -211,7 +206,7 @@ struct hb_hashmap_t ) /* Sink interface. */ - hb_hashmap_t<K, V, kINVALID, vINVALID>& operator << (const hb_pair_t<K, V>& v) + hb_hashmap_t& operator << (const hb_pair_t<K, V>& v) { set (v.first, v.second); return *this; } protected: diff --git a/src/3rdparty/harfbuzz-ng/src/hb-meta.hh b/src/3rdparty/harfbuzz-ng/src/hb-meta.hh index 2dfaeb7b46..e40d9fd178 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-meta.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-meta.hh @@ -49,6 +49,10 @@ template <bool b> using hb_bool_constant = hb_integral_constant<bool, b>; using hb_true_type = hb_bool_constant<true>; using hb_false_type = hb_bool_constant<false>; +/* Static-assert as expression. */ +template <bool cond> struct static_assert_expr; +template <> struct static_assert_expr<true> : hb_false_type {}; +#define static_assert_expr(C) static_assert_expr<C>::value /* Basic type SFINAE. */ @@ -220,6 +224,8 @@ struct hb_reference_wrapper<T&> }; +/* Type traits */ + template <typename T> using hb_is_integral = hb_bool_constant< hb_is_same (hb_decay<T>, char) || @@ -292,6 +298,15 @@ template <> struct hb_int_max<unsigned long long> : hb_integral_constant<unsigne #define hb_int_max(T) hb_int_max<T>::value +/* Class traits. */ + +#define HB_DELETE_COPY_ASSIGN(TypeName) \ + TypeName(const TypeName&) = delete; \ + void operator=(const TypeName&) = delete +#define HB_DELETE_CREATE_COPY_ASSIGN(TypeName) \ + TypeName() = delete; \ + TypeName(const TypeName&) = delete; \ + void operator=(const TypeName&) = delete template <typename T, typename> struct _hb_is_destructible : hb_false_type {}; @@ -343,7 +358,6 @@ using hb_is_move_assignable = hb_is_assignable<hb_add_lvalue_reference<T>, template <typename T> union hb_trivial { T value; }; -/* Don't know how to do the following. */ template <typename T> using hb_is_trivially_destructible= hb_is_destructible<hb_trivial<T>>; #define hb_is_trivially_destructible(T) hb_is_trivially_destructible<T>::value @@ -396,5 +410,16 @@ using hb_is_trivial= hb_bool_constant< >; #define hb_is_trivial(T) hb_is_trivial<T>::value +/* hb_unwrap_type (T) + * If T has no T::type, returns T. Otherwise calls itself on T::type recursively. + */ + +template <typename T, typename> +struct _hb_unwrap_type : hb_type_identity_t<T> {}; +template <typename T> +struct _hb_unwrap_type<T, hb_void_t<typename T::type>> : _hb_unwrap_type<typename T::type, void> {}; +template <typename T> +using hb_unwrap_type = _hb_unwrap_type<T, void>; +#define hb_unwrap_type(T) typename hb_unwrap_type<T>::type #endif /* HB_META_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-mutex.hh b/src/3rdparty/harfbuzz-ng/src/hb-mutex.hh index e7f8b1c434..2fc8d7ee58 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-mutex.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-mutex.hh @@ -61,10 +61,9 @@ typedef pthread_mutex_t hb_mutex_impl_t; #elif !defined(HB_NO_MT) && defined(_WIN32) -#include <windows.h> typedef CRITICAL_SECTION hb_mutex_impl_t; #define HB_MUTEX_IMPL_INIT {0} -#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) +#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) #define hb_mutex_impl_init(M) InitializeCriticalSectionEx (M, 0, 0) #else #define hb_mutex_impl_init(M) InitializeCriticalSection (M) @@ -74,24 +73,6 @@ typedef CRITICAL_SECTION hb_mutex_impl_t; #define hb_mutex_impl_finish(M) DeleteCriticalSection (M) -#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES) - -#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_YIELD) -# include <sched.h> -# define HB_SCHED_YIELD() sched_yield () -#else -# define HB_SCHED_YIELD() HB_STMT_START {} HB_STMT_END -#endif - -/* This actually is not a totally awful implementation. */ -typedef volatile int hb_mutex_impl_t; -#define HB_MUTEX_IMPL_INIT 0 -#define hb_mutex_impl_init(M) *(M) = 0 -#define hb_mutex_impl_lock(M) HB_STMT_START { while (__sync_lock_test_and_set((M), 1)) HB_SCHED_YIELD (); } HB_STMT_END -#define hb_mutex_impl_unlock(M) __sync_lock_release (M) -#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END - - #elif defined(HB_NO_MT) typedef int hb_mutex_impl_t; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-null.hh b/src/3rdparty/harfbuzz-ng/src/hb-null.hh index d4578205e3..d09f858cde 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-null.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-null.hh @@ -104,7 +104,7 @@ struct NullHelper } \ }; \ namespace Namespace { \ - static_assert (true, "Just so we take semicolon after.") + static_assert (true, "") /* Require semicolon after. */ #define DEFINE_NULL_NAMESPACE_BYTES(Namespace, Type) \ const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::null_size] @@ -117,7 +117,7 @@ struct NullHelper return _hb_Null_##Type; \ } \ }; \ - static_assert (true, "Just so we take semicolon after.") + static_assert (true, "") /* Require semicolon after. */ #define DEFINE_NULL_INSTANCE(Type) \ const Type _hb_Null_##Type @@ -135,7 +135,7 @@ template <typename Type> static inline Type& Crap () { static_assert (hb_null_size (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); Type *obj = reinterpret_cast<Type *> (_hb_CrapPool); - memcpy (obj, &Null(Type), sizeof (*obj)); + memcpy (obj, &Null (Type), sizeof (*obj)); return *obj; } template <typename QType> @@ -148,11 +148,11 @@ struct CrapHelper template <typename Type> struct CrapOrNullHelper { - static Type & get () { return Crap(Type); } + static Type & get () { return Crap (Type); } }; template <typename Type> struct CrapOrNullHelper<const Type> { - static const Type & get () { return Null(Type); } + static const Type & get () { return Null (Type); } }; #define CrapOrNull(Type) CrapOrNullHelper<Type>::get () @@ -174,9 +174,10 @@ struct hb_nonnull_ptr_t /* Only auto-cast to const types. */ template <typename C> operator const C * () const { return get (); } operator const char * () const { return (const char *) get (); } - T * get () const { return v ? v : const_cast<T *> (&Null(T)); } + T * get () const { return v ? v : const_cast<T *> (&Null (T)); } T * get_raw () const { return v; } + private: T *v; }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-number-parser.hh b/src/3rdparty/harfbuzz-ng/src/hb-number-parser.hh index c78c85097e..1a9dbba6dd 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-number-parser.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-number-parser.hh @@ -30,10 +30,8 @@ #include "hb.hh" -#include <float.h> - -#line 37 "hb-number-parser.hh" +#line 35 "hb-number-parser.hh" static const unsigned char _double_parser_trans_keys[] = { 0u, 0u, 43u, 57u, 46u, 57u, 48u, 57u, 43u, 57u, 48u, 57u, 48u, 101u, 48u, 57u, 46u, 101u, 0 @@ -93,12 +91,12 @@ static const int double_parser_error = 0; static const int double_parser_en_main = 1; -#line 70 "hb-number-parser.rl" +#line 68 "hb-number-parser.rl" /* Works only for n < 512 */ static inline double -_pow10 (unsigned int exponent) +_pow10 (unsigned exponent) { static const double _powers_of_10[] = { @@ -112,38 +110,37 @@ _pow10 (unsigned int exponent) 100., 10. }; - unsigned int mask = 1 << (ARRAY_LENGTH (_powers_of_10) - 1); + unsigned mask = 1 << (ARRAY_LENGTH (_powers_of_10) - 1); double result = 1; for (const double *power = _powers_of_10; mask; ++power, mask >>= 1) if (exponent & mask) result *= *power; return result; } +/* a variant of strtod that also gets end of buffer in its second argument */ static inline double -strtod_rl (const char *buf, char **end_ptr) +strtod_rl (const char *p, const char **end_ptr /* IN/OUT */) { - const char *p, *pe; double value = 0; double frac = 0; double frac_count = 0; - unsigned int exp = 0; + unsigned exp = 0; bool neg = false, exp_neg = false, exp_overflow = false; - const unsigned long long MAX_FRACT = 0xFFFFFFFFFFFFFull; /* 1^52-1 */ - const unsigned int MAX_EXP = 0x7FFu; /* 1^11-1 */ - p = buf; - pe = p + strlen (p); + const unsigned long long MAX_FRACT = 0xFFFFFFFFFFFFFull; /* 2^52-1 */ + const unsigned MAX_EXP = 0x7FFu; /* 2^11-1 */ + const char *pe = *end_ptr; while (p < pe && ISSPACE (*p)) p++; int cs; -#line 142 "hb-number-parser.hh" +#line 139 "hb-number-parser.hh" { cs = double_parser_start; } -#line 147 "hb-number-parser.hh" +#line 144 "hb-number-parser.hh" { int _slen; int _trans; @@ -169,21 +166,21 @@ _resume: switch ( _double_parser_trans_actions[_trans] ) { case 1: -#line 39 "hb-number-parser.rl" +#line 37 "hb-number-parser.rl" { neg = true; } break; case 4: -#line 40 "hb-number-parser.rl" +#line 38 "hb-number-parser.rl" { exp_neg = true; } break; case 2: -#line 42 "hb-number-parser.rl" +#line 40 "hb-number-parser.rl" { value = value * 10. + ((*p) - '0'); } break; case 3: -#line 45 "hb-number-parser.rl" +#line 43 "hb-number-parser.rl" { if (likely (frac <= MAX_FRACT / 10)) { @@ -193,7 +190,7 @@ _resume: } break; case 5: -#line 52 "hb-number-parser.rl" +#line 50 "hb-number-parser.rl" { if (likely (exp * 10 + ((*p) - '0') <= MAX_EXP)) exp = exp * 10 + ((*p) - '0'); @@ -201,7 +198,7 @@ _resume: exp_overflow = true; } break; -#line 205 "hb-number-parser.hh" +#line 202 "hb-number-parser.hh" } _again: @@ -213,10 +210,10 @@ _again: _out: {} } -#line 116 "hb-number-parser.rl" +#line 113 "hb-number-parser.rl" - *end_ptr = (char *) p; + *end_ptr = p; if (frac_count) value += frac / _pow10 (frac_count); if (neg) value *= -1.; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-number-parser.rl b/src/3rdparty/harfbuzz-ng/src/hb-number-parser.rl deleted file mode 100644 index 8445fa22a1..0000000000 --- a/src/3rdparty/harfbuzz-ng/src/hb-number-parser.rl +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright © 2019 Ebrahim Byagowi - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - */ - -#ifndef HB_NUMBER_PARSER_HH -#define HB_NUMBER_PARSER_HH - -#include "hb.hh" - -#include <float.h> - -%%{ - -machine double_parser; -alphtype unsigned char; -write data; - -action see_neg { neg = true; } -action see_exp_neg { exp_neg = true; } - -action add_int { - value = value * 10. + (fc - '0'); -} -action add_frac { - if (likely (frac <= MAX_FRACT / 10)) - { - frac = frac * 10. + (fc - '0'); - ++frac_count; - } -} -action add_exp { - if (likely (exp * 10 + (fc - '0') <= MAX_EXP)) - exp = exp * 10 + (fc - '0'); - else - exp_overflow = true; -} - -num = [0-9]+; - -main := ( - ( - (('+'|'-'@see_neg)? num @add_int) ('.' num @add_frac)? - | - (('+'|'-'@see_neg)? '.' num @add_frac) - ) - (('e'|'E') (('+'|'-'@see_exp_neg)? num @add_exp))? -); - -}%% - -/* Works only for n < 512 */ -static inline double -_pow10 (unsigned int exponent) -{ - static const double _powers_of_10[] = - { - 1.0e+256, - 1.0e+128, - 1.0e+64, - 1.0e+32, - 1.0e+16, - 1.0e+8, - 10000., - 100., - 10. - }; - unsigned int mask = 1 << (ARRAY_LENGTH (_powers_of_10) - 1); - double result = 1; - for (const double *power = _powers_of_10; mask; ++power, mask >>= 1) - if (exponent & mask) result *= *power; - return result; -} - -static inline double -strtod_rl (const char *buf, char **end_ptr) -{ - const char *p, *pe; - double value = 0; - double frac = 0; - double frac_count = 0; - unsigned int exp = 0; - bool neg = false, exp_neg = false, exp_overflow = false; - const unsigned long long MAX_FRACT = 0xFFFFFFFFFFFFFull; /* 1^52-1 */ - const unsigned int MAX_EXP = 0x7FFu; /* 1^11-1 */ - p = buf; - pe = p + strlen (p); - - while (p < pe && ISSPACE (*p)) - p++; - - int cs; - %%{ - write init; - write exec; - }%% - - *end_ptr = (char *) p; - - if (frac_count) value += frac / _pow10 (frac_count); - if (neg) value *= -1.; - - if (unlikely (exp_overflow)) - { - if (value == 0) return value; - if (exp_neg) return neg ? -DBL_MIN : DBL_MIN; - else return neg ? -DBL_MAX : DBL_MAX; - } - - if (exp) - { - if (exp_neg) value /= _pow10 (exp); - else value *= _pow10 (exp); - } - - return value; -} - -#endif /* HB_NUMBER_PARSER_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-number.cc b/src/3rdparty/harfbuzz-ng/src/hb-number.cc index 4f84d4ad5c..6e4f3f7ebd 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-number.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-number.cc @@ -25,21 +25,16 @@ #include "hb.hh" #include "hb-machinery.hh" +#include "hb-number.hh" #include "hb-number-parser.hh" -#include <locale.h> -#ifdef HAVE_XLOCALE_H -#include <xlocale.h> -#endif - template<typename T, typename Func> static bool _parse_number (const char **pp, const char *end, T *pv, bool whole_buffer, Func f) { char buf[32]; - unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1, - (unsigned int) (end - *pp)); + unsigned len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned) (end - *pp)); strncpy (buf, *pp, len); buf[len] = '\0'; @@ -50,7 +45,8 @@ _parse_number (const char **pp, const char *end, T *pv, *pv = f (p, &pend); if (unlikely (errno || p == pend || /* Check if consumed whole buffer if is requested */ - (whole_buffer && pend - p != end - *pp))) return false; + (whole_buffer && pend - p != end - *pp))) + return false; *pp += pend - p; return true; @@ -65,83 +61,20 @@ hb_parse_int (const char **pp, const char *end, int *pv, bool whole_buffer) } bool -hb_parse_uint (const char **pp, const char *end, unsigned int *pv, +hb_parse_uint (const char **pp, const char *end, unsigned *pv, bool whole_buffer, int base) { - return _parse_number<unsigned int> (pp, end, pv, whole_buffer, - [base] (const char *p, char **end) - { return strtoul (p, end, base); }); -} - - -#if defined (HAVE_NEWLOCALE) && defined (HAVE_STRTOD_L) -#define USE_XLOCALE 1 -#define HB_LOCALE_T locale_t -#define HB_CREATE_LOCALE(locName) newlocale (LC_ALL_MASK, locName, nullptr) -#define HB_FREE_LOCALE(loc) freelocale (loc) -#elif defined(_MSC_VER) -#define USE_XLOCALE 1 -#define HB_LOCALE_T _locale_t -#define HB_CREATE_LOCALE(locName) _create_locale (LC_ALL, locName) -#define HB_FREE_LOCALE(loc) _free_locale (loc) -#define strtod_l(a, b, c) _strtod_l ((a), (b), (c)) -#endif - -#ifdef USE_XLOCALE - -#if HB_USE_ATEXIT -static void free_static_C_locale (); -#endif - -static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer<HB_LOCALE_T>, - hb_C_locale_lazy_loader_t> -{ - static HB_LOCALE_T create () - { - HB_LOCALE_T C_locale = HB_CREATE_LOCALE ("C"); - -#if HB_USE_ATEXIT - atexit (free_static_C_locale); -#endif - - return C_locale; - } - static void destroy (HB_LOCALE_T p) - { - HB_FREE_LOCALE (p); - } - static HB_LOCALE_T get_null () - { - return nullptr; - } -} static_C_locale; - -#if HB_USE_ATEXIT -static -void free_static_C_locale () -{ - static_C_locale.free_instance (); -} -#endif - -static HB_LOCALE_T -get_C_locale () -{ - return static_C_locale.get_unconst (); + return _parse_number<unsigned> (pp, end, pv, whole_buffer, + [base] (const char *p, char **end) + { return strtoul (p, end, base); }); } -#endif /* USE_XLOCALE */ bool -hb_parse_double (const char **pp, const char *end, double *pv, - bool whole_buffer) +hb_parse_double (const char **pp, const char *end, double *pv, bool whole_buffer) { - return _parse_number<double> (pp, end, pv, whole_buffer, - [] (const char *p, char **end) - { -#ifdef USE_XLOCALE - return strtod_l (p, end, get_C_locale ()); -#else - return strtod_rl (p, end); -#endif - }); + const char *pend = end; + *pv = strtod_rl (*pp, &pend); + if (unlikely (*pp == pend)) return false; + *pp = pend; + return !whole_buffer || end == pend; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-object.hh b/src/3rdparty/harfbuzz-ng/src/hb-object.hh index c470532aac..f3048b1c3e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-object.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-object.hh @@ -140,9 +140,7 @@ struct hb_lockable_set_t * Reference-count. */ -#define HB_REFERENCE_COUNT_INERT_VALUE 0 -#define HB_REFERENCE_COUNT_POISON_VALUE -0x0000DEAD -#define HB_REFERENCE_COUNT_INIT {HB_ATOMIC_INT_INIT (HB_REFERENCE_COUNT_INERT_VALUE)} +#define HB_REFERENCE_COUNT_INIT {0} struct hb_reference_count_t { @@ -152,9 +150,9 @@ struct hb_reference_count_t int get_relaxed () const { return ref_count.get_relaxed (); } int inc () const { return ref_count.inc (); } int dec () const { return ref_count.dec (); } - void fini () { ref_count.set_relaxed (HB_REFERENCE_COUNT_POISON_VALUE); } + void fini () { ref_count.set_relaxed (-0x0000DEAD); } - bool is_inert () const { return ref_count.get_relaxed () == HB_REFERENCE_COUNT_INERT_VALUE; } + bool is_inert () const { return !ref_count.get_relaxed (); } bool is_valid () const { return ref_count.get_relaxed () > 0; } }; @@ -168,8 +166,8 @@ struct hb_user_data_array_t void *data; hb_destroy_func_t destroy; - bool operator == (hb_user_data_key_t *other_key) const { return key == other_key; } - bool operator == (hb_user_data_item_t &other) const { return key == other.key; } + bool operator == (const hb_user_data_key_t *other_key) const { return key == other_key; } + bool operator == (const hb_user_data_item_t &other) const { return key == other.key; } void fini () { if (destroy) destroy (data); } }; @@ -197,15 +195,10 @@ struct hb_user_data_array_t struct hb_object_header_t { hb_reference_count_t ref_count; - mutable hb_atomic_int_t writable; + mutable hb_atomic_int_t writable = 0; hb_atomic_ptr_t<hb_user_data_array_t> user_data; }; -#define HB_OBJECT_HEADER_STATIC \ - { \ - HB_REFERENCE_COUNT_INIT, \ - HB_ATOMIC_INT_INIT (false), \ - HB_ATOMIC_PTR_INIT (nullptr) \ - } +#define HB_OBJECT_HEADER_STATIC {} /* diff --git a/src/3rdparty/harfbuzz-ng/src/hb-open-file.hh b/src/3rdparty/harfbuzz-ng/src/hb-open-file.hh index cb1fdf1c99..54c07ff13c 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-open-file.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-open-file.hh @@ -48,7 +48,7 @@ namespace OT { */ struct OpenTypeFontFile; -struct OffsetTable; +struct OpenTypeOffsetTable; struct TTCHeader; @@ -78,7 +78,7 @@ typedef struct TableRecord DEFINE_SIZE_STATIC (16); } OpenTypeTable; -typedef struct OffsetTable +typedef struct OpenTypeOffsetTable { friend struct OpenTypeFontFile; @@ -91,15 +91,10 @@ typedef struct OffsetTable { if (table_count) { - if (start_offset >= tables.len) - *table_count = 0; - else - *table_count = hb_min (*table_count, tables.len - start_offset); - - const TableRecord *sub_tables = tables.arrayZ + start_offset; - unsigned int count = *table_count; - for (unsigned int i = 0; i < count; i++) - table_tags[i] = sub_tables[i].tag; + + tables.sub_array (start_offset, table_count) + | hb_map (&TableRecord::tag) + | hb_sink (hb_array (table_tags, *table_count)) + ; } return tables.len; } @@ -223,7 +218,7 @@ struct TTCHeaderVersion1 Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */ FixedVersion<>version; /* Version of the TTC Header (1.0), * 0x00010000u */ - LArrayOf<LOffsetTo<OffsetTable>> + LArrayOf<LOffsetTo<OpenTypeOffsetTable>> table; /* Array of offsets to the OffsetTable for each font * from the beginning of the file */ public: @@ -249,7 +244,7 @@ struct TTCHeader switch (u.header.version.major) { case 2: /* version 2 is compatible with version 1 */ case 1: return u.version1.get_face (i); - default:return Null(OpenTypeFontFace); + default:return Null (OpenTypeFontFace); } } @@ -284,7 +279,7 @@ struct TTCHeader struct ResourceRecord { const OpenTypeFontFace & get_face (const void *data_base) const - { return CastR<OpenTypeFontFace> ((data_base+offset).arrayZ); } + { return * reinterpret_cast<const OpenTypeFontFace *> ((data_base+offset).arrayZ); } bool sanitize (hb_sanitize_context_t *c, const void *data_base) const @@ -478,7 +473,7 @@ struct OpenTypeFontFile case TrueTypeTag: return u.fontFace; case TTCTag: return u.ttcHeader.get_face (i); case DFontTag: return u.rfHeader.get_face (i, base_offset); - default: return Null(OpenTypeFontFace); + default: return Null (OpenTypeFontFace); } } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-open-type.hh b/src/3rdparty/harfbuzz-ng/src/hb-open-type.hh index af242ece12..dc0ae1d989 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-open-type.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-open-type.hh @@ -53,14 +53,19 @@ namespace OT { */ /* Integer types in big-endian order and no alignment requirement */ -template <typename Type, unsigned int Size> +template <typename Type, + unsigned int Size = sizeof (Type)> struct IntType { typedef Type type; - typedef hb_conditional<hb_is_signed (Type), signed, unsigned> wide_type; - IntType& operator = (wide_type i) { v = i; return *this; } - operator wide_type () const { return v; } + IntType () = default; + explicit constexpr IntType (Type V) : v {V} {} + IntType& operator = (Type i) { v = i; return *this; } + /* For reason we define cast out operator for signed/unsigned, instead of Type, see: + * https://github.com/harfbuzz/harfbuzz/pull/2875/commits/09836013995cab2b9f07577a179ad7b024130467 */ + operator hb_conditional<hb_is_signed (Type), signed, unsigned> () const { return v; } + bool operator == (const IntType &o) const { return (Type) v == (Type) o.v; } bool operator != (const IntType &o) const { return !(*this == o); } @@ -73,14 +78,28 @@ struct IntType HB_INTERNAL static int cmp (const IntType *a, const IntType *b) { return b->cmp (*a); } - template <typename Type2> + HB_INTERNAL static int cmp (const void *a, const void *b) + { + IntType *pa = (IntType *) a; + IntType *pb = (IntType *) b; + + return pb->cmp (*pa); + } + template <typename Type2, + hb_enable_if (hb_is_integral (Type2) && + sizeof (Type2) < sizeof (int) && + sizeof (Type) < sizeof (int))> int cmp (Type2 a) const { Type b = v; - if (sizeof (Type) < sizeof (int) && sizeof (Type2) < sizeof (int)) - return (int) a - (int) b; - else - return a < b ? -1 : a == b ? 0 : +1; + return (int) a - (int) b; + } + template <typename Type2, + hb_enable_if (hb_is_convertible (Type2, Type))> + int cmp (Type2 a) const + { + Type b = v; + return a < b ? -1 : a == b ? 0 : +1; } bool sanitize (hb_sanitize_context_t *c) const { @@ -93,12 +112,12 @@ struct IntType DEFINE_SIZE_STATIC (Size); }; -typedef IntType<uint8_t, 1> HBUINT8; /* 8-bit unsigned integer. */ -typedef IntType<int8_t, 1> HBINT8; /* 8-bit signed integer. */ -typedef IntType<uint16_t, 2> HBUINT16; /* 16-bit unsigned integer. */ -typedef IntType<int16_t, 2> HBINT16; /* 16-bit signed integer. */ -typedef IntType<uint32_t, 4> HBUINT32; /* 32-bit unsigned integer. */ -typedef IntType<int32_t, 4> HBINT32; /* 32-bit signed integer. */ +typedef IntType<uint8_t> HBUINT8; /* 8-bit unsigned integer. */ +typedef IntType<int8_t> HBINT8; /* 8-bit signed integer. */ +typedef IntType<uint16_t> HBUINT16; /* 16-bit unsigned integer. */ +typedef IntType<int16_t> HBINT16; /* 16-bit signed integer. */ +typedef IntType<uint32_t> HBUINT32; /* 32-bit unsigned integer. */ +typedef IntType<int32_t> HBINT32; /* 32-bit signed integer. */ /* Note: we cannot defined a signed HBINT24 because there's no corresponding C type. * Works for unsigned, but not signed, since we rely on compiler for sign-extension. */ typedef IntType<uint32_t, 3> HBUINT24; /* 24-bit unsigned integer. */ @@ -156,8 +175,8 @@ struct Tag : HBUINT32 { Tag& operator = (hb_tag_t i) { HBUINT32::operator= (i); return *this; } /* What the char* converters return is NOT nul-terminated. Print using "%.4s" */ - operator const char* () const { return reinterpret_cast<const char *> (&this->v); } - operator char* () { return reinterpret_cast<char *> (&this->v); } + operator const char* () const { return reinterpret_cast<const char *> (this); } + operator char* () { return reinterpret_cast<char *> (this); } public: DEFINE_SIZE_STATIC (4); }; @@ -306,11 +325,8 @@ struct OffsetTo : Offset<OffsetType, has_null> } template <typename ...Ts> - bool serialize_subset (hb_subset_context_t *c, - const OffsetTo& src, - const void *src_base, - const void *dst_base, - Ts&&... ds) + bool serialize_subset (hb_subset_context_t *c, const OffsetTo& src, + const void *src_base, Ts&&... ds) { *this = 0; if (src.is_null ()) @@ -323,7 +339,7 @@ struct OffsetTo : Offset<OffsetType, has_null> bool ret = c->dispatch (src_base+src, hb_forward<Ts> (ds)...); if (ret || !has_null) - s->add_link (*this, s->pop_pack (), dst_base); + s->add_link (*this, s->pop_pack ()); else s->pop_discard (); @@ -331,11 +347,13 @@ struct OffsetTo : Offset<OffsetType, has_null> } /* TODO: Somehow merge this with previous function into a serialize_dispatch(). */ + /* Workaround clang bug: https://bugs.llvm.org/show_bug.cgi?id=23029 + * Can't compile: whence = hb_serialize_context_t::Head followed by Ts&&... + */ template <typename ...Ts> - bool serialize_copy (hb_serialize_context_t *c, - const OffsetTo& src, - const void *src_base, - const void *dst_base, + bool serialize_copy (hb_serialize_context_t *c, const OffsetTo& src, + const void *src_base, unsigned dst_bias, + hb_serialize_context_t::whence_t whence, Ts&&... ds) { *this = 0; @@ -346,11 +364,15 @@ struct OffsetTo : Offset<OffsetType, has_null> bool ret = c->copy (src_base+src, hb_forward<Ts> (ds)...); - c->add_link (*this, c->pop_pack (), dst_base); + c->add_link (*this, c->pop_pack (), whence, dst_bias); return ret; } + bool serialize_copy (hb_serialize_context_t *c, const OffsetTo& src, + const void *src_base, unsigned dst_bias = 0) + { return serialize_copy (c, src, src_base, dst_bias, hb_serialize_context_t::Head); } + bool sanitize_shallow (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -423,8 +445,6 @@ struct UnsizedArrayOf { return hb_array (arrayZ, len); } hb_array_t<const Type> as_array (unsigned int len) const { return hb_array (arrayZ, len); } - operator hb_array_t< Type> () { return as_array (); } - operator hb_array_t<const Type> () const { return as_array (); } template <typename T> Type &lsearch (unsigned int len, const T &x, Type ¬_found = Crap (Type)) @@ -432,6 +452,9 @@ struct UnsizedArrayOf template <typename T> const Type &lsearch (unsigned int len, const T &x, const Type ¬_found = Null (Type)) const { return *as_array (len).lsearch (x, ¬_found); } + template <typename T> + bool lfind (unsigned int len, const T &x, unsigned *pos = nullptr) const + { return as_array (len).lfind (x, pos); } void qsort (unsigned int len, unsigned int start = 0, unsigned int end = (unsigned int) -1) { as_array (len).qsort (start, end); } @@ -539,8 +562,8 @@ struct SortedUnsizedArrayOf : UnsizedArrayOf<Type> { return *as_array (len).bsearch (x, ¬_found); } template <typename T> bool bfind (unsigned int len, const T &x, unsigned int *i = nullptr, - hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE, - unsigned int to_store = (unsigned int) -1) const + hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE, + unsigned int to_store = (unsigned int) -1) const { return as_array (len).bfind (x, i, not_found, to_store); } }; @@ -594,7 +617,7 @@ struct ArrayOf hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) { return as_array ().sub_array (start_offset, count); } - bool serialize (hb_serialize_context_t *c, unsigned int items_len) + hb_success_t serialize (hb_serialize_context_t *c, unsigned items_len) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); @@ -604,7 +627,7 @@ struct ArrayOf } template <typename Iterator, hb_requires (hb_is_source_of (Iterator, Type))> - bool serialize (hb_serialize_context_t *c, Iterator items) + hb_success_t serialize (hb_serialize_context_t *c, Iterator items) { TRACE_SERIALIZE (this); unsigned count = items.len (); @@ -657,6 +680,9 @@ struct ArrayOf template <typename T> const Type &lsearch (const T &x, const Type ¬_found = Null (Type)) const { return *as_array ().lsearch (x, ¬_found); } + template <typename T> + bool lfind (const T &x, unsigned *pos = nullptr) const + { return as_array ().lfind (x, pos); } void qsort (unsigned int start = 0, unsigned int end = (unsigned int) -1) { as_array ().qsort (start, end); } @@ -1026,18 +1052,15 @@ struct VarSizedBinSearchArrayOf template <typename T> const Type *bsearch (const T &key) const { - unsigned int size = header.unitSize; - int min = 0, max = (int) get_length () - 1; - while (min <= max) - { - int mid = ((unsigned int) min + (unsigned int) max) / 2; - const Type *p = (const Type *) (((const char *) &bytesZ) + (mid * size)); - int c = p->cmp (key); - if (c < 0) max = mid - 1; - else if (c > 0) min = mid + 1; - else return p; - } - return nullptr; + unsigned pos; + return hb_bsearch_impl (&pos, + key, + (const void *) bytesZ, + get_length (), + header.unitSize, + _hb_cmp_method<T, Type>) + ? (const Type *) (((const char *) &bytesZ) + (pos * header.unitSize)) + : nullptr; } private: diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff-common.hh index 6735c74be4..864a27f458 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff-common.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff-common.hh @@ -38,6 +38,9 @@ using namespace OT; #define CFF_UNDEF_CODE 0xFFFFFFFF +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) @@ -89,11 +92,14 @@ struct CFFIndex unsigned int offset_array_size () const { return calculate_offset_array_size (offSize, count); } - static unsigned int calculate_serialized_size (unsigned int offSize_, unsigned int count, - unsigned int dataSize) + CFFIndex *copy (hb_serialize_context_t *c) const { - if (count == 0) return COUNT::static_size; - return min_size + calculate_offset_array_size (offSize_, count) + dataSize; + TRACE_SERIALIZE (this); + unsigned int size = get_size (); + CFFIndex *out = c->allocate_size<CFFIndex> (size); + if (likely (out)) + memcpy (out, this, size); + return_trace (out); } bool serialize (hb_serialize_context_t *c, const CFFIndex &src) @@ -101,7 +107,7 @@ struct CFFIndex TRACE_SERIALIZE (this); unsigned int size = src.get_size (); CFFIndex *dest = c->allocate_size<CFFIndex> (size); - if (unlikely (dest == nullptr)) return_trace (false); + if (unlikely (!dest)) return_trace (false); memcpy (dest, &src, size); return_trace (true); } @@ -114,7 +120,7 @@ struct CFFIndex if (byteArray.length == 0) { COUNT *dest = c->allocate_min<COUNT> (); - if (unlikely (dest == nullptr)) return_trace (false); + if (unlikely (!dest)) return_trace (false); *dest = 0; } else @@ -139,10 +145,9 @@ struct CFFIndex /* serialize data */ for (unsigned int i = 0; i < byteArray.length; i++) { - const byte_str_t &bs = byteArray[i]; - unsigned char *dest = c->allocate_size<unsigned char> (bs.length); - if (unlikely (dest == nullptr)) - return_trace (false); + const byte_str_t &bs = byteArray[i]; + unsigned char *dest = c->allocate_size<unsigned char> (bs.length); + if (unlikely (!dest)) return_trace (false); memcpy (dest, &bs[0], bs.length); } } @@ -163,6 +168,71 @@ struct CFFIndex return result; } + template <typename Iterator, + hb_requires (hb_is_iterator (Iterator))> + bool serialize (hb_serialize_context_t *c, + Iterator it) + { + TRACE_SERIALIZE (this); + if (it.len () == 0) + { + COUNT *dest = c->allocate_min<COUNT> (); + if (unlikely (!dest)) return_trace (false); + *dest = 0; + } + else + { + serialize_header(c, + it | hb_map ([] (const byte_str_t &_) { return _.length; })); + for (const auto &_ : +it) + _.copy (c); + } + return_trace (true); + } + + bool serialize (hb_serialize_context_t *c, + const byte_str_array_t &byteArray) + { return serialize (c, + hb_iter (byteArray)); } + + bool serialize (hb_serialize_context_t *c, + const str_buff_vec_t &buffArray) + { + auto it = + + hb_iter (buffArray) + | hb_map ([] (const str_buff_t &_) { return byte_str_t (_.arrayZ, _.length); }) + ; + return serialize (c, it); + } + + template <typename Iterator, + hb_requires (hb_is_iterator (Iterator))> + bool serialize_header (hb_serialize_context_t *c, + Iterator it) + { + TRACE_SERIALIZE (this); + + unsigned total = + it | hb_reduce (hb_add, 0); + unsigned off_size = calcOffSize (total); + + /* serialize CFFIndex header */ + if (unlikely (!c->extend_min (*this))) return_trace (false); + this->count = it.len (); + this->offSize = off_size; + if (unlikely (!c->allocate_size<HBUINT8> (off_size * (it.len () + 1)))) + return_trace (false); + + /* serialize indices */ + unsigned int offset = 1; + unsigned int i = 0; + for (unsigned _ : +it) + { + CFFIndex<COUNT>::set_offset_at (i++, offset); + offset += _; + } + CFFIndex<COUNT>::set_offset_at (i, offset); + + return_trace (true); + } + void set_offset_at (unsigned int index, unsigned int offset) { HBUINT8 *p = offsets + offSize * index + offSize; @@ -189,7 +259,7 @@ struct CFFIndex unsigned int length_at (unsigned int index) const { if (unlikely ((offset_at (index + 1) < offset_at (index)) || - (offset_at (index + 1) > offset_at (count)))) + (offset_at (index + 1) > offset_at (count)))) return 0; return offset_at (index + 1) - offset_at (index); } @@ -237,7 +307,8 @@ struct CFFIndex public: COUNT count; /* Number of object data. Note there are (count+1) offsets */ HBUINT8 offSize; /* The byte size of each offset in the offsets array. */ - HBUINT8 offsets[HB_VAR_ARRAY]; /* The array of (count + 1) offsets into objects array (1-base). */ + HBUINT8 offsets[HB_VAR_ARRAY]; + /* The array of (count + 1) offsets into objects array (1-base). */ /* HBUINT8 data[HB_VAR_ARRAY]; Object data */ public: DEFINE_SIZE_ARRAY (COUNT::static_size + HBUINT8::static_size, offsets); @@ -250,7 +321,7 @@ struct CFFIndexOf : CFFIndex<COUNT> { if (likely (index < CFFIndex<COUNT>::count)) return byte_str_t (CFFIndex<COUNT>::data_base () + CFFIndex<COUNT>::offset_at (index) - 1, CFFIndex<COUNT>::length_at (index)); - return Null(byte_str_t); + return Null (byte_str_t); } template <typename DATA, typename PARAM1, typename PARAM2> @@ -284,85 +355,41 @@ struct CFFIndexOf : CFFIndex<COUNT> for (unsigned int i = 0; i < dataArrayLen; i++) { TYPE *dest = c->start_embed<TYPE> (); - if (unlikely (dest == nullptr || - !dest->serialize (c, dataArray[i], param1, param2))) + if (unlikely (!dest || !dest->serialize (c, dataArray[i], param1, param2))) return_trace (false); } return_trace (true); } - - /* in parallel to above */ - template <typename DATA, typename PARAM> - static unsigned int calculate_serialized_size (unsigned int &offSize_ /* OUT */, - const DATA *dataArray, - unsigned int dataArrayLen, - hb_vector_t<unsigned int> &dataSizeArray, /* OUT */ - const PARAM ¶m) - { - /* determine offset size */ - unsigned int totalDataSize = 0; - for (unsigned int i = 0; i < dataArrayLen; i++) - { - unsigned int dataSize = TYPE::calculate_serialized_size (dataArray[i], param); - dataSizeArray[i] = dataSize; - totalDataSize += dataSize; - } - offSize_ = calcOffSize (totalDataSize); - - return CFFIndex<COUNT>::calculate_serialized_size (offSize_, dataArrayLen, totalDataSize); - } }; /* Top Dict, Font Dict, Private Dict */ struct Dict : UnsizedByteStr { - template <typename DICTVAL, typename OP_SERIALIZER, typename PARAM> + template <typename DICTVAL, typename OP_SERIALIZER, typename ...Ts> bool serialize (hb_serialize_context_t *c, const DICTVAL &dictval, OP_SERIALIZER& opszr, - PARAM& param) + Ts&&... ds) { TRACE_SERIALIZE (this); for (unsigned int i = 0; i < dictval.get_count (); i++) - if (unlikely (!opszr.serialize (c, dictval[i], param))) + if (unlikely (!opszr.serialize (c, dictval[i], hb_forward<Ts> (ds)...))) return_trace (false); return_trace (true); } - /* in parallel to above */ - template <typename DICTVAL, typename OP_SERIALIZER, typename PARAM> - static unsigned int calculate_serialized_size (const DICTVAL &dictval, - OP_SERIALIZER& opszr, - PARAM& param) - { - unsigned int size = 0; - for (unsigned int i = 0; i < dictval.get_count (); i++) - size += opszr.calculate_serialized_size (dictval[i], param); - return size; - } - - template <typename DICTVAL, typename OP_SERIALIZER> - static unsigned int calculate_serialized_size (const DICTVAL &dictval, - OP_SERIALIZER& opszr) - { - unsigned int size = 0; - for (unsigned int i = 0; i < dictval.get_count (); i++) - size += opszr.calculate_serialized_size (dictval[i]); - return size; - } - - template <typename INTTYPE, int minVal, int maxVal> - static bool serialize_int_op (hb_serialize_context_t *c, op_code_t op, int value, op_code_t intOp) + template <typename T, typename V> + static bool serialize_int_op (hb_serialize_context_t *c, op_code_t op, V value, op_code_t intOp) { // XXX: not sure why but LLVM fails to compile the following 'unlikely' macro invocation - if (/*unlikely*/ (!serialize_int<INTTYPE, minVal, maxVal> (c, intOp, value))) + if (/*unlikely*/ (!serialize_int<T, V> (c, intOp, value))) return false; TRACE_SERIALIZE (this); /* serialize the opcode */ HBUINT8 *p = c->allocate_size<HBUINT8> (OpCode_Size (op)); - if (unlikely (p == nullptr)) return_trace (false); + if (unlikely (!p)) return_trace (false); if (Is_OpCode_ESC (op)) { *p = OpCode_escape; @@ -373,17 +400,28 @@ struct Dict : UnsizedByteStr return_trace (true); } - static bool serialize_uint4_op (hb_serialize_context_t *c, op_code_t op, int value) - { return serialize_int_op<HBUINT32, 0, 0x7FFFFFFF> (c, op, value, OpCode_longintdict); } + template <typename V> + static bool serialize_int4_op (hb_serialize_context_t *c, op_code_t op, V value) + { return serialize_int_op<HBINT32> (c, op, value, OpCode_longintdict); } + + template <typename V> + static bool serialize_int2_op (hb_serialize_context_t *c, op_code_t op, V value) + { return serialize_int_op<HBINT16> (c, op, value, OpCode_shortint); } - static bool serialize_uint2_op (hb_serialize_context_t *c, op_code_t op, int value) - { return serialize_int_op<HBUINT16, 0, 0x7FFF> (c, op, value, OpCode_shortint); } + template <typename T, int int_op> + static bool serialize_link_op (hb_serialize_context_t *c, op_code_t op, objidx_t link, whence_t whence) + { + T &ofs = *(T *) (c->head + OpCode_Size (int_op)); + if (unlikely (!serialize_int_op<T> (c, op, 0, int_op))) return false; + c->add_link (ofs, link, whence); + return true; + } - static bool serialize_offset4_op (hb_serialize_context_t *c, op_code_t op, int value) - { return serialize_uint4_op (c, op, value); } + static bool serialize_link4_op (hb_serialize_context_t *c, op_code_t op, objidx_t link, whence_t whence = whence_t::Head) + { return serialize_link_op<HBINT32, OpCode_longintdict> (c, op, link, whence); } - static bool serialize_offset2_op (hb_serialize_context_t *c, op_code_t op, int value) - { return serialize_uint2_op (c, op, value); } + static bool serialize_link2_op (hb_serialize_context_t *c, op_code_t op, objidx_t link, whence_t whence = whence_t::Head) + { return serialize_link_op<HBINT16, OpCode_shortint> (c, op, link, whence); } }; struct TopDict : Dict {}; @@ -392,105 +430,39 @@ struct PrivateDict : Dict {}; struct table_info_t { - void init () { offSize = offset = size = 0; } + void init () { offset = size = 0; link = 0; } unsigned int offset; unsigned int size; - unsigned int offSize; + objidx_t link; }; template <typename COUNT> struct FDArray : CFFIndexOf<COUNT, FontDict> { - /* used by CFF1 */ - template <typename DICTVAL, typename OP_SERIALIZER> + template <typename DICTVAL, typename INFO, typename Iterator, typename OP_SERIALIZER> bool serialize (hb_serialize_context_t *c, - unsigned int offSize_, - const hb_vector_t<DICTVAL> &fontDicts, + Iterator it, OP_SERIALIZER& opszr) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return_trace (false); - this->count = fontDicts.length; - this->offSize = offSize_; - if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (fontDicts.length + 1)))) - return_trace (false); - /* serialize font dict offsets */ - unsigned int offset = 1; - unsigned int fid = 0; - for (; fid < fontDicts.length; fid++) - { - CFFIndexOf<COUNT, FontDict>::set_offset_at (fid, offset); - offset += FontDict::calculate_serialized_size (fontDicts[fid], opszr); - } - CFFIndexOf<COUNT, FontDict>::set_offset_at (fid, offset); - - /* serialize font dicts */ - for (unsigned int i = 0; i < fontDicts.length; i++) + /* serialize INDEX data */ + hb_vector_t<unsigned> sizes; + c->push (); + + it + | hb_map ([&] (const hb_pair_t<const DICTVAL&, const INFO&> &_) { FontDict *dict = c->start_embed<FontDict> (); - if (unlikely (!dict->serialize (c, fontDicts[i], opszr, fontDicts[i]))) - return_trace (false); - } - return_trace (true); - } - - /* used by CFF2 */ - template <typename DICTVAL, typename OP_SERIALIZER> - bool serialize (hb_serialize_context_t *c, - unsigned int offSize_, - const hb_vector_t<DICTVAL> &fontDicts, - unsigned int fdCount, - const hb_inc_bimap_t &fdmap, - OP_SERIALIZER& opszr, - const hb_vector_t<table_info_t> &privateInfos) - { - TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return_trace (false); - this->count = fdCount; - this->offSize = offSize_; - if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (fdCount + 1)))) - return_trace (false); - - /* serialize font dict offsets */ - unsigned int offset = 1; - unsigned int fid = 0; - for (unsigned i = 0; i < fontDicts.length; i++) - if (fdmap.has (i)) - { - if (unlikely (fid >= fdCount)) return_trace (false); - CFFIndexOf<COUNT, FontDict>::set_offset_at (fid++, offset); - offset += FontDict::calculate_serialized_size (fontDicts[i], opszr); - } - CFFIndexOf<COUNT, FontDict>::set_offset_at (fid, offset); - - /* serialize font dicts */ - for (unsigned int i = 0; i < fontDicts.length; i++) - if (fdmap.has (i)) - { - FontDict *dict = c->start_embed<FontDict> (); - if (unlikely (!dict->serialize (c, fontDicts[i], opszr, privateInfos[fdmap[i]]))) - return_trace (false); - } - return_trace (true); - } - - /* in parallel to above */ - template <typename OP_SERIALIZER, typename DICTVAL> - static unsigned int calculate_serialized_size (unsigned int &offSize_ /* OUT */, - const hb_vector_t<DICTVAL> &fontDicts, - unsigned int fdCount, - const hb_inc_bimap_t &fdmap, - OP_SERIALIZER& opszr) - { - unsigned int dictsSize = 0; - for (unsigned int i = 0; i < fontDicts.len; i++) - if (fdmap.has (i)) - dictsSize += FontDict::calculate_serialized_size (fontDicts[i], opszr); - - offSize_ = calcOffSize (dictsSize); - return CFFIndex<COUNT>::calculate_serialized_size (offSize_, fdCount, dictsSize); + dict->serialize (c, _.first, opszr, _.second); + return c->head - (const char*)dict; + }) + | hb_sink (sizes) + ; + c->pop_pack (false); + + /* serialize INDEX header */ + return_trace (CFFIndex<COUNT>::serialize_header (c, hb_iter (sizes))); } }; @@ -544,7 +516,7 @@ struct FDSelect3_4 { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this) || !ranges.sanitize (c, nullptr, fdcount) || - (nRanges () == 0) || ranges[0].first != 0)) + (nRanges () == 0) || ranges[0].first != 0)) return_trace (false); for (unsigned int i = 1; i < nRanges (); i++) @@ -588,14 +560,11 @@ struct FDSelect TRACE_SERIALIZE (this); unsigned int size = src.get_size (num_glyphs); FDSelect *dest = c->allocate_size<FDSelect> (size); - if (unlikely (dest == nullptr)) return_trace (false); + if (unlikely (!dest)) return_trace (false); memcpy (dest, &src, size); return_trace (true); } - unsigned int calculate_serialized_size (unsigned int num_glyphs) const - { return get_size (num_glyphs); } - unsigned int get_size (unsigned int num_glyphs) const { switch (format) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-std-str.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-std-str.hh new file mode 100644 index 0000000000..65d56ae18b --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-std-str.hh @@ -0,0 +1,425 @@ +/* + * Copyright © 2019 Adobe, 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. + * + * Adobe Author(s): Michiharu Ariza + */ + +#ifndef HB_OT_CFF1_STD_STR_HH +#if 0 /* Make checks happy. */ +#define HB_OT_CFF1_STD_STR_HH +#include "hb.hh" +#endif + +_S(".notdef") +_S("space") +_S("exclam") +_S("quotedbl") +_S("numbersign") +_S("dollar") +_S("percent") +_S("ampersand") +_S("quoteright") +_S("parenleft") +_S("parenright") +_S("asterisk") +_S("plus") +_S("comma") +_S("hyphen") +_S("period") +_S("slash") +_S("zero") +_S("one") +_S("two") +_S("three") +_S("four") +_S("five") +_S("six") +_S("seven") +_S("eight") +_S("nine") +_S("colon") +_S("semicolon") +_S("less") +_S("equal") +_S("greater") +_S("question") +_S("at") +_S("A") +_S("B") +_S("C") +_S("D") +_S("E") +_S("F") +_S("G") +_S("H") +_S("I") +_S("J") +_S("K") +_S("L") +_S("M") +_S("N") +_S("O") +_S("P") +_S("Q") +_S("R") +_S("S") +_S("T") +_S("U") +_S("V") +_S("W") +_S("X") +_S("Y") +_S("Z") +_S("bracketleft") +_S("backslash") +_S("bracketright") +_S("asciicircum") +_S("underscore") +_S("quoteleft") +_S("a") +_S("b") +_S("c") +_S("d") +_S("e") +_S("f") +_S("g") +_S("h") +_S("i") +_S("j") +_S("k") +_S("l") +_S("m") +_S("n") +_S("o") +_S("p") +_S("q") +_S("r") +_S("s") +_S("t") +_S("u") +_S("v") +_S("w") +_S("x") +_S("y") +_S("z") +_S("braceleft") +_S("bar") +_S("braceright") +_S("asciitilde") +_S("exclamdown") +_S("cent") +_S("sterling") +_S("fraction") +_S("yen") +_S("florin") +_S("section") +_S("currency") +_S("quotesingle") +_S("quotedblleft") +_S("guillemotleft") +_S("guilsinglleft") +_S("guilsinglright") +_S("fi") +_S("fl") +_S("endash") +_S("dagger") +_S("daggerdbl") +_S("periodcentered") +_S("paragraph") +_S("bullet") +_S("quotesinglbase") +_S("quotedblbase") +_S("quotedblright") +_S("guillemotright") +_S("ellipsis") +_S("perthousand") +_S("questiondown") +_S("grave") +_S("acute") +_S("circumflex") +_S("tilde") +_S("macron") +_S("breve") +_S("dotaccent") +_S("dieresis") +_S("ring") +_S("cedilla") +_S("hungarumlaut") +_S("ogonek") +_S("caron") +_S("emdash") +_S("AE") +_S("ordfeminine") +_S("Lslash") +_S("Oslash") +_S("OE") +_S("ordmasculine") +_S("ae") +_S("dotlessi") +_S("lslash") +_S("oslash") +_S("oe") +_S("germandbls") +_S("onesuperior") +_S("logicalnot") +_S("mu") +_S("trademark") +_S("Eth") +_S("onehalf") +_S("plusminus") +_S("Thorn") +_S("onequarter") +_S("divide") +_S("brokenbar") +_S("degree") +_S("thorn") +_S("threequarters") +_S("twosuperior") +_S("registered") +_S("minus") +_S("eth") +_S("multiply") +_S("threesuperior") +_S("copyright") +_S("Aacute") +_S("Acircumflex") +_S("Adieresis") +_S("Agrave") +_S("Aring") +_S("Atilde") +_S("Ccedilla") +_S("Eacute") +_S("Ecircumflex") +_S("Edieresis") +_S("Egrave") +_S("Iacute") +_S("Icircumflex") +_S("Idieresis") +_S("Igrave") +_S("Ntilde") +_S("Oacute") +_S("Ocircumflex") +_S("Odieresis") +_S("Ograve") +_S("Otilde") +_S("Scaron") +_S("Uacute") +_S("Ucircumflex") +_S("Udieresis") +_S("Ugrave") +_S("Yacute") +_S("Ydieresis") +_S("Zcaron") +_S("aacute") +_S("acircumflex") +_S("adieresis") +_S("agrave") +_S("aring") +_S("atilde") +_S("ccedilla") +_S("eacute") +_S("ecircumflex") +_S("edieresis") +_S("egrave") +_S("iacute") +_S("icircumflex") +_S("idieresis") +_S("igrave") +_S("ntilde") +_S("oacute") +_S("ocircumflex") +_S("odieresis") +_S("ograve") +_S("otilde") +_S("scaron") +_S("uacute") +_S("ucircumflex") +_S("udieresis") +_S("ugrave") +_S("yacute") +_S("ydieresis") +_S("zcaron") +_S("exclamsmall") +_S("Hungarumlautsmall") +_S("dollaroldstyle") +_S("dollarsuperior") +_S("ampersandsmall") +_S("Acutesmall") +_S("parenleftsuperior") +_S("parenrightsuperior") +_S("twodotenleader") +_S("onedotenleader") +_S("zerooldstyle") +_S("oneoldstyle") +_S("twooldstyle") +_S("threeoldstyle") +_S("fouroldstyle") +_S("fiveoldstyle") +_S("sixoldstyle") +_S("sevenoldstyle") +_S("eightoldstyle") +_S("nineoldstyle") +_S("commasuperior") +_S("threequartersemdash") +_S("periodsuperior") +_S("questionsmall") +_S("asuperior") +_S("bsuperior") +_S("centsuperior") +_S("dsuperior") +_S("esuperior") +_S("isuperior") +_S("lsuperior") +_S("msuperior") +_S("nsuperior") +_S("osuperior") +_S("rsuperior") +_S("ssuperior") +_S("tsuperior") +_S("ff") +_S("ffi") +_S("ffl") +_S("parenleftinferior") +_S("parenrightinferior") +_S("Circumflexsmall") +_S("hyphensuperior") +_S("Gravesmall") +_S("Asmall") +_S("Bsmall") +_S("Csmall") +_S("Dsmall") +_S("Esmall") +_S("Fsmall") +_S("Gsmall") +_S("Hsmall") +_S("Ismall") +_S("Jsmall") +_S("Ksmall") +_S("Lsmall") +_S("Msmall") +_S("Nsmall") +_S("Osmall") +_S("Psmall") +_S("Qsmall") +_S("Rsmall") +_S("Ssmall") +_S("Tsmall") +_S("Usmall") +_S("Vsmall") +_S("Wsmall") +_S("Xsmall") +_S("Ysmall") +_S("Zsmall") +_S("colonmonetary") +_S("onefitted") +_S("rupiah") +_S("Tildesmall") +_S("exclamdownsmall") +_S("centoldstyle") +_S("Lslashsmall") +_S("Scaronsmall") +_S("Zcaronsmall") +_S("Dieresissmall") +_S("Brevesmall") +_S("Caronsmall") +_S("Dotaccentsmall") +_S("Macronsmall") +_S("figuredash") +_S("hypheninferior") +_S("Ogoneksmall") +_S("Ringsmall") +_S("Cedillasmall") +_S("questiondownsmall") +_S("oneeighth") +_S("threeeighths") +_S("fiveeighths") +_S("seveneighths") +_S("onethird") +_S("twothirds") +_S("zerosuperior") +_S("foursuperior") +_S("fivesuperior") +_S("sixsuperior") +_S("sevensuperior") +_S("eightsuperior") +_S("ninesuperior") +_S("zeroinferior") +_S("oneinferior") +_S("twoinferior") +_S("threeinferior") +_S("fourinferior") +_S("fiveinferior") +_S("sixinferior") +_S("seveninferior") +_S("eightinferior") +_S("nineinferior") +_S("centinferior") +_S("dollarinferior") +_S("periodinferior") +_S("commainferior") +_S("Agravesmall") +_S("Aacutesmall") +_S("Acircumflexsmall") +_S("Atildesmall") +_S("Adieresissmall") +_S("Aringsmall") +_S("AEsmall") +_S("Ccedillasmall") +_S("Egravesmall") +_S("Eacutesmall") +_S("Ecircumflexsmall") +_S("Edieresissmall") +_S("Igravesmall") +_S("Iacutesmall") +_S("Icircumflexsmall") +_S("Idieresissmall") +_S("Ethsmall") +_S("Ntildesmall") +_S("Ogravesmall") +_S("Oacutesmall") +_S("Ocircumflexsmall") +_S("Otildesmall") +_S("Odieresissmall") +_S("OEsmall") +_S("Oslashsmall") +_S("Ugravesmall") +_S("Uacutesmall") +_S("Ucircumflexsmall") +_S("Udieresissmall") +_S("Yacutesmall") +_S("Thornsmall") +_S("Ydieresissmall") +_S("001.000") +_S("001.001") +_S("001.002") +_S("001.003") +_S("Black") +_S("Bold") +_S("Book") +_S("Light") +_S("Medium") +_S("Regular") +_S("Roman") +_S("Semibold") + +#endif /* HB_OT_CFF1_STD_STR_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.cc index 55abd11d61..3298fa35ae 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.cc @@ -28,11 +28,25 @@ #ifndef HB_NO_CFF +#include "hb-draw.hh" +#include "hb-algs.hh" #include "hb-ot-cff1-table.hh" #include "hb-cff1-interp-cs.hh" using namespace CFF; +struct sid_to_gid_t +{ + uint16_t sid; + uint8_t gid; + + int cmp (uint16_t a) const + { + if (a == sid) return 0; + return (a < sid) ? -1 : 1; + } +}; + /* SID to code */ static const uint8_t standard_encoding_to_code [] = { @@ -104,6 +118,80 @@ static const uint16_t expert_subset_charset_to_sid [] = 340, 341, 342, 343, 344, 345, 346 }; +/* SID to glyph ID */ +static const sid_to_gid_t expert_charset_sid_to_gid [] = +{ + { 1, 1 }, { 13, 12 }, { 14, 13 }, { 15, 14 }, + { 27, 26 }, { 28, 27 }, { 99, 15 }, { 109, 46 }, + { 110, 47 }, { 150, 111 }, { 155, 101 }, { 158, 100 }, + { 163, 102 }, { 164, 112 }, { 169, 113 }, { 229, 2 }, + { 230, 3 }, { 231, 4 }, { 232, 5 }, { 233, 6 }, + { 234, 7 }, { 235, 8 }, { 236, 9 }, { 237, 10 }, + { 238, 11 }, { 239, 16 }, { 240, 17 }, { 241, 18 }, + { 242, 19 }, { 243, 20 }, { 244, 21 }, { 245, 22 }, + { 246, 23 }, { 247, 24 }, { 248, 25 }, { 249, 28 }, + { 250, 29 }, { 251, 30 }, { 252, 31 }, { 253, 32 }, + { 254, 33 }, { 255, 34 }, { 256, 35 }, { 257, 36 }, + { 258, 37 }, { 259, 38 }, { 260, 39 }, { 261, 40 }, + { 262, 41 }, { 263, 42 }, { 264, 43 }, { 265, 44 }, + { 266, 45 }, { 267, 48 }, { 268, 49 }, { 269, 50 }, + { 270, 51 }, { 271, 52 }, { 272, 53 }, { 273, 54 }, + { 274, 55 }, { 275, 56 }, { 276, 57 }, { 277, 58 }, + { 278, 59 }, { 279, 60 }, { 280, 61 }, { 281, 62 }, + { 282, 63 }, { 283, 64 }, { 284, 65 }, { 285, 66 }, + { 286, 67 }, { 287, 68 }, { 288, 69 }, { 289, 70 }, + { 290, 71 }, { 291, 72 }, { 292, 73 }, { 293, 74 }, + { 294, 75 }, { 295, 76 }, { 296, 77 }, { 297, 78 }, + { 298, 79 }, { 299, 80 }, { 300, 81 }, { 301, 82 }, + { 302, 83 }, { 303, 84 }, { 304, 85 }, { 305, 86 }, + { 306, 87 }, { 307, 88 }, { 308, 89 }, { 309, 90 }, + { 310, 91 }, { 311, 92 }, { 312, 93 }, { 313, 94 }, + { 314, 95 }, { 315, 96 }, { 316, 97 }, { 317, 98 }, + { 318, 99 }, { 319, 103 }, { 320, 104 }, { 321, 105 }, + { 322, 106 }, { 323, 107 }, { 324, 108 }, { 325, 109 }, + { 326, 110 }, { 327, 114 }, { 328, 115 }, { 329, 116 }, + { 330, 117 }, { 331, 118 }, { 332, 119 }, { 333, 120 }, + { 334, 121 }, { 335, 122 }, { 336, 123 }, { 337, 124 }, + { 338, 125 }, { 339, 126 }, { 340, 127 }, { 341, 128 }, + { 342, 129 }, { 343, 130 }, { 344, 131 }, { 345, 132 }, + { 346, 133 }, { 347, 134 }, { 348, 135 }, { 349, 136 }, + { 350, 137 }, { 351, 138 }, { 352, 139 }, { 353, 140 }, + { 354, 141 }, { 355, 142 }, { 356, 143 }, { 357, 144 }, + { 358, 145 }, { 359, 146 }, { 360, 147 }, { 361, 148 }, + { 362, 149 }, { 363, 150 }, { 364, 151 }, { 365, 152 }, + { 366, 153 }, { 367, 154 }, { 368, 155 }, { 369, 156 }, + { 370, 157 }, { 371, 158 }, { 372, 159 }, { 373, 160 }, + { 374, 161 }, { 375, 162 }, { 376, 163 }, { 377, 164 }, + { 378, 165 } +}; + +/* SID to glyph ID */ +static const sid_to_gid_t expert_subset_charset_sid_to_gid [] = +{ + { 1, 1 }, { 13, 8 }, { 14, 9 }, { 15, 10 }, + { 27, 22 }, { 28, 23 }, { 99, 11 }, { 109, 41 }, + { 110, 42 }, { 150, 64 }, { 155, 55 }, { 158, 54 }, + { 163, 56 }, { 164, 65 }, { 169, 66 }, { 231, 2 }, + { 232, 3 }, { 235, 4 }, { 236, 5 }, { 237, 6 }, + { 238, 7 }, { 239, 12 }, { 240, 13 }, { 241, 14 }, + { 242, 15 }, { 243, 16 }, { 244, 17 }, { 245, 18 }, + { 246, 19 }, { 247, 20 }, { 248, 21 }, { 249, 24 }, + { 250, 25 }, { 251, 26 }, { 253, 27 }, { 254, 28 }, + { 255, 29 }, { 256, 30 }, { 257, 31 }, { 258, 32 }, + { 259, 33 }, { 260, 34 }, { 261, 35 }, { 262, 36 }, + { 263, 37 }, { 264, 38 }, { 265, 39 }, { 266, 40 }, + { 267, 43 }, { 268, 44 }, { 269, 45 }, { 270, 46 }, + { 272, 47 }, { 300, 48 }, { 301, 49 }, { 302, 50 }, + { 305, 51 }, { 314, 52 }, { 315, 53 }, { 320, 57 }, + { 321, 58 }, { 322, 59 }, { 323, 60 }, { 324, 61 }, + { 325, 62 }, { 326, 63 }, { 327, 67 }, { 328, 68 }, + { 329, 69 }, { 330, 70 }, { 331, 71 }, { 332, 72 }, + { 333, 73 }, { 334, 74 }, { 335, 75 }, { 336, 76 }, + { 337, 77 }, { 338, 78 }, { 339, 79 }, { 340, 80 }, + { 341, 81 }, { 342, 82 }, { 343, 83 }, { 344, 84 }, + { 345, 85 }, { 346, 86 } +}; + /* code to SID */ static const uint8_t standard_encoding_to_sid [] = { @@ -157,6 +245,18 @@ hb_codepoint_t OT::cff1::lookup_expert_subset_charset_for_sid (hb_codepoint_t gl return 0; } +hb_codepoint_t OT::cff1::lookup_expert_charset_for_glyph (hb_codepoint_t sid) +{ + const auto *pair = hb_sorted_array (expert_charset_sid_to_gid).bsearch (sid); + return pair ? pair->gid : 0; +} + +hb_codepoint_t OT::cff1::lookup_expert_subset_charset_for_glyph (hb_codepoint_t sid) +{ + const auto *pair = hb_sorted_array (expert_subset_charset_sid_to_gid).bsearch (sid); + return pair ? pair->gid : 0; +} + hb_codepoint_t OT::cff1::lookup_standard_encoding_for_sid (hb_codepoint_t code) { if (code < ARRAY_LENGTH (standard_encoding_to_sid)) @@ -326,7 +426,7 @@ bool OT::cff1::accelerator_t::get_extents (hb_font_t *font, hb_codepoint_t glyph else { extents->x_bearing = font->em_scalef_x (bounds.min.x.to_real ()); - extents->width = font->em_scalef_x (bounds.max.x.to_real () - bounds.min.x.to_real ()); + extents->width = font->em_scalef_x (bounds.max.x.to_real ()) - extents->x_bearing; } if (bounds.min.y >= bounds.max.y) { @@ -336,12 +436,136 @@ bool OT::cff1::accelerator_t::get_extents (hb_font_t *font, hb_codepoint_t glyph else { extents->y_bearing = font->em_scalef_y (bounds.max.y.to_real ()); - extents->height = font->em_scalef_y (bounds.min.y.to_real () - bounds.max.y.to_real ()); + extents->height = font->em_scalef_y (bounds.min.y.to_real ()) - extents->y_bearing; } return true; } +#ifdef HB_EXPERIMENTAL_API +struct cff1_path_param_t +{ + cff1_path_param_t (const OT::cff1::accelerator_t *cff_, hb_font_t *font_, + draw_helper_t &draw_helper_, point_t *delta_) + { + draw_helper = &draw_helper_; + cff = cff_; + font = font_; + delta = delta_; + } + + void move_to (const point_t &p) + { + point_t point = p; + if (delta) point.move (*delta); + draw_helper->move_to (font->em_scalef_x (point.x.to_real ()), font->em_scalef_y (point.y.to_real ())); + } + + void line_to (const point_t &p) + { + point_t point = p; + if (delta) point.move (*delta); + draw_helper->line_to (font->em_scalef_x (point.x.to_real ()), font->em_scalef_y (point.y.to_real ())); + } + + void cubic_to (const point_t &p1, const point_t &p2, const point_t &p3) + { + point_t point1 = p1, point2 = p2, point3 = p3; + if (delta) + { + point1.move (*delta); + point2.move (*delta); + point3.move (*delta); + } + draw_helper->cubic_to (font->em_scalef_x (point1.x.to_real ()), font->em_scalef_y (point1.y.to_real ()), + font->em_scalef_x (point2.x.to_real ()), font->em_scalef_y (point2.y.to_real ()), + font->em_scalef_x (point3.x.to_real ()), font->em_scalef_y (point3.y.to_real ())); + } + + void end_path () { draw_helper->end_path (); } + + hb_font_t *font; + draw_helper_t *draw_helper; + point_t *delta; + + const OT::cff1::accelerator_t *cff; +}; + +struct cff1_path_procs_path_t : path_procs_t<cff1_path_procs_path_t, cff1_cs_interp_env_t, cff1_path_param_t> +{ + static void moveto (cff1_cs_interp_env_t &env, cff1_path_param_t& param, const point_t &pt) + { + param.move_to (pt); + env.moveto (pt); + } + + static void line (cff1_cs_interp_env_t &env, cff1_path_param_t ¶m, const point_t &pt1) + { + param.line_to (pt1); + env.moveto (pt1); + } + + static void curve (cff1_cs_interp_env_t &env, cff1_path_param_t ¶m, const point_t &pt1, const point_t &pt2, const point_t &pt3) + { + param.cubic_to (pt1, pt2, pt3); + env.moveto (pt3); + } +}; + +static bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoint_t glyph, + draw_helper_t &draw_helper, bool in_seac = false, point_t *delta = nullptr); + +struct cff1_cs_opset_path_t : cff1_cs_opset_t<cff1_cs_opset_path_t, cff1_path_param_t, cff1_path_procs_path_t> +{ + static void process_seac (cff1_cs_interp_env_t &env, cff1_path_param_t& param) + { + /* End previous path */ + param.end_path (); + + unsigned int n = env.argStack.get_count (); + point_t delta; + delta.x = env.argStack[n-4]; + delta.y = env.argStack[n-3]; + hb_codepoint_t base = param.cff->std_code_to_glyph (env.argStack[n-2].to_int ()); + hb_codepoint_t accent = param.cff->std_code_to_glyph (env.argStack[n-1].to_int ()); + + if (unlikely (!(!env.in_seac && base && accent + && _get_path (param.cff, param.font, base, *param.draw_helper, true) + && _get_path (param.cff, param.font, accent, *param.draw_helper, true, &delta)))) + env.set_error (); + } +}; + +bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoint_t glyph, + draw_helper_t &draw_helper, bool in_seac, point_t *delta) +{ + if (unlikely (!cff->is_valid () || (glyph >= cff->num_glyphs))) return false; + + unsigned int fd = cff->fdSelect->get_fd (glyph); + cff1_cs_interpreter_t<cff1_cs_opset_path_t, cff1_path_param_t> interp; + const byte_str_t str = (*cff->charStrings)[glyph]; + interp.env.init (str, *cff, fd); + interp.env.set_in_seac (in_seac); + cff1_path_param_t param (cff, font, draw_helper, delta); + if (unlikely (!interp.interpret (param))) return false; + + /* Let's end the path specially since it is called inside seac also */ + param.end_path (); + + return true; +} + +bool OT::cff1::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, draw_helper_t &draw_helper) const +{ +#ifdef HB_NO_OT_FONT_CFF + /* XXX Remove check when this code moves to .hh file. */ + return true; +#endif + + return _get_path (this, font, glyph, draw_helper); +} +#endif + struct get_seac_param_t { void init (const OT::cff1::accelerator_t *_cff) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh index ad206511c1..7228f77727 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh @@ -27,15 +27,21 @@ #ifndef HB_OT_CFF1_TABLE_HH #define HB_OT_CFF1_TABLE_HH -#include "hb-ot-head-table.hh" #include "hb-ot-cff-common.hh" #include "hb-subset-cff1.hh" +#include "hb-draw.hh" + +#define HB_STRING_ARRAY_NAME cff1_std_strings +#define HB_STRING_ARRAY_LIST "hb-ot-cff1-std-str.hh" +#include "hb-string-array.hh" +#undef HB_STRING_ARRAY_LIST +#undef HB_STRING_ARRAY_NAME namespace CFF { /* * CFF -- Compact Font Format (CFF) - * http://www.adobe.com/content/dam/acom/en/devnet/font/pdfs/5176.CFF.pdf + * https://www.adobe.com/content/dam/acom/en/devnet/font/pdfs/5176.CFF.pdf */ #define HB_OT_TAG_cff1 HB_TAG('C','F','F',' ') @@ -49,7 +55,6 @@ template <typename Type> struct CFF1IndexOf : CFFIndexOf<HBUINT16, Type> {}; typedef CFFIndex<HBUINT16> CFF1Index; typedef CFF1Index CFF1CharStrings; -typedef FDArray<HBUINT16> CFF1FDArray; typedef Subrs<HBUINT16> CFF1Subrs; struct CFF1FDSelect : FDSelect {}; @@ -169,7 +174,7 @@ struct Encoding TRACE_SERIALIZE (this); unsigned int size = src.get_size (); Encoding *dest = c->allocate_size<Encoding> (size); - if (unlikely (dest == nullptr)) return_trace (false); + if (unlikely (!dest)) return_trace (false); memcpy (dest, &src, size); return_trace (true); } @@ -183,13 +188,13 @@ struct Encoding { TRACE_SERIALIZE (this); Encoding *dest = c->extend_min (*this); - if (unlikely (dest == nullptr)) return_trace (false); + if (unlikely (!dest)) return_trace (false); dest->format = format | ((supp_codes.length > 0) ? 0x80 : 0); switch (format) { case 0: { Encoding0 *fmt0 = c->allocate_size<Encoding0> (Encoding0::min_size + HBUINT8::static_size * enc_count); - if (unlikely (fmt0 == nullptr)) return_trace (false); + if (unlikely (!fmt0)) return_trace (false); fmt0->nCodes () = enc_count; unsigned int glyph = 0; for (unsigned int i = 0; i < code_ranges.length; i++) @@ -206,7 +211,7 @@ struct Encoding case 1: { Encoding1 *fmt1 = c->allocate_size<Encoding1> (Encoding1::min_size + Encoding1_Range::static_size * code_ranges.length); - if (unlikely (fmt1 == nullptr)) return_trace (false); + if (unlikely (!fmt1)) return_trace (false); fmt1->nRanges () = code_ranges.length; for (unsigned int i = 0; i < code_ranges.length; i++) { @@ -223,7 +228,7 @@ struct Encoding if (supp_codes.length) { CFF1SuppEncData *suppData = c->allocate_size<CFF1SuppEncData> (CFF1SuppEncData::min_size + SuppEncoding::static_size * supp_codes.length); - if (unlikely (suppData == nullptr)) return_trace (false); + if (unlikely (!suppData)) return_trace (false); suppData->nSups () = supp_codes.length; for (unsigned int i = 0; i < supp_codes.length; i++) { @@ -235,23 +240,6 @@ struct Encoding return_trace (true); } - /* parallel to above: calculate the size of a subset Encoding */ - static unsigned int calculate_serialized_size (uint8_t format, - unsigned int enc_count, - unsigned int supp_count) - { - unsigned int size = min_size; - switch (format) - { - case 0: size += Encoding0::min_size + HBUINT8::static_size * enc_count; break; - case 1: size += Encoding1::min_size + Encoding1_Range::static_size * enc_count; break; - default:return 0; - } - if (supp_count > 0) - size += CFF1SuppEncData::min_size + SuppEncoding::static_size * supp_count; - return size; - } - unsigned int get_size () const { unsigned int size = min_size; @@ -414,7 +402,7 @@ struct Charset1_2 { for (unsigned int i = 0;; i++) { if (glyph >= num_glyphs) - return 0; + return 0; if ((ranges[i].first <= sid) && (sid <= ranges[i].first + ranges[i].nLeft)) return glyph + (sid - ranges[i].first); glyph += (ranges[i].nLeft + 1); @@ -457,7 +445,7 @@ struct Charset TRACE_SERIALIZE (this); unsigned int size = src.get_size (num_glyphs); Charset *dest = c->allocate_size<Charset> (size); - if (unlikely (dest == nullptr)) return_trace (false); + if (unlikely (!dest)) return_trace (false); memcpy (dest, &src, size); return_trace (true); } @@ -470,14 +458,14 @@ struct Charset { TRACE_SERIALIZE (this); Charset *dest = c->extend_min (*this); - if (unlikely (dest == nullptr)) return_trace (false); + if (unlikely (!dest)) return_trace (false); dest->format = format; switch (format) { case 0: { Charset0 *fmt0 = c->allocate_size<Charset0> (Charset0::min_size + HBUINT16::static_size * (num_glyphs - 1)); - if (unlikely (fmt0 == nullptr)) return_trace (false); + if (unlikely (!fmt0)) return_trace (false); unsigned int glyph = 0; for (unsigned int i = 0; i < sid_ranges.length; i++) { @@ -491,10 +479,10 @@ struct Charset case 1: { Charset1 *fmt1 = c->allocate_size<Charset1> (Charset1::min_size + Charset1_Range::static_size * sid_ranges.length); - if (unlikely (fmt1 == nullptr)) return_trace (false); + if (unlikely (!fmt1)) return_trace (false); for (unsigned int i = 0; i < sid_ranges.length; i++) { - if (unlikely (!(sid_ranges[i].glyph <= 0xFF))) + if (unlikely (!(sid_ranges[i].glyph <= 0xFF))) return_trace (false); fmt1->ranges[i].first = sid_ranges[i].code; fmt1->ranges[i].nLeft = sid_ranges[i].glyph; @@ -505,10 +493,10 @@ struct Charset case 2: { Charset2 *fmt2 = c->allocate_size<Charset2> (Charset2::min_size + Charset2_Range::static_size * sid_ranges.length); - if (unlikely (fmt2 == nullptr)) return_trace (false); + if (unlikely (!fmt2)) return_trace (false); for (unsigned int i = 0; i < sid_ranges.length; i++) { - if (unlikely (!(sid_ranges[i].glyph <= 0xFFFF))) + if (unlikely (!(sid_ranges[i].glyph <= 0xFFFF))) return_trace (false); fmt2->ranges[i].first = sid_ranges[i].code; fmt2->ranges[i].nLeft = sid_ranges[i].glyph; @@ -520,19 +508,6 @@ struct Charset return_trace (true); } - /* parallel to above: calculate the size of a subset Charset */ - static unsigned int calculate_serialized_size (uint8_t format, - unsigned int count) - { - switch (format) - { - case 0: return min_size + Charset0::min_size + HBUINT16::static_size * (count - 1); - case 1: return min_size + Charset1::min_size + Charset1_Range::static_size * count; - case 2: return min_size + Charset2::min_size + Charset2_Range::static_size * count; - default:return 0; - } - } - unsigned int get_size (unsigned int num_glyphs) const { switch (format) @@ -544,8 +519,9 @@ struct Charset } } - hb_codepoint_t get_sid (hb_codepoint_t glyph) const + hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned int num_glyphs) const { + if (unlikely (glyph >= num_glyphs)) return 0; switch (format) { case 0: return u.format0.get_sid (glyph); @@ -594,7 +570,7 @@ struct Charset struct CFF1StringIndex : CFF1Index { bool serialize (hb_serialize_context_t *c, const CFF1StringIndex &strings, - unsigned int offSize_, const hb_inc_bimap_t &sidmap) + const hb_inc_bimap_t &sidmap) { TRACE_SERIALIZE (this); if (unlikely ((strings.count == 0) || (sidmap.get_population () == 0))) @@ -612,30 +588,14 @@ struct CFF1StringIndex : CFF1Index for (unsigned int i = 0; i < strings.count; i++) { hb_codepoint_t j = sidmap[i]; - if (j != CFF_UNDEF_CODE) + if (j != HB_MAP_VALUE_INVALID) bytesArray[j] = strings[i]; } - bool result = CFF1Index::serialize (c, offSize_, bytesArray); + bool result = CFF1Index::serialize (c, bytesArray); bytesArray.fini (); return_trace (result); } - - /* in parallel to above */ - unsigned int calculate_serialized_size (unsigned int &offSize_ /*OUT*/, const hb_inc_bimap_t &sidmap) const - { - offSize_ = 0; - if ((count == 0) || (sidmap.get_population () == 0)) - return count.static_size; - - unsigned int dataSize = 0; - for (unsigned int i = 0; i < count; i++) - if (sidmap[i] != CFF_UNDEF_CODE) - dataSize += length_at (i); - - offSize_ = calcOffSize(dataSize); - return CFF1Index::calculate_serialized_size (offSize_, sidmap.get_population (), dataSize); - } }; struct cff1_top_dict_interp_env_t : num_interp_env_t @@ -738,7 +698,7 @@ struct cff1_top_dict_values_t : top_dict_values_t<cff1_top_dict_val_t> unsigned int EncodingOffset; unsigned int CharsetOffset; unsigned int FDSelectOffset; - table_info_t privateDictInfo; + table_info_t privateDictInfo; }; struct cff1_top_dict_opset_t : top_dict_opset_t<cff1_top_dict_val_t> @@ -880,21 +840,10 @@ struct cff1_private_dict_values_base_t : dict_values_t<VAL> { dict_values_t<VAL>::init (); subrsOffset = 0; - localSubrs = &Null(CFF1Subrs); + localSubrs = &Null (CFF1Subrs); } void fini () { dict_values_t<VAL>::fini (); } - unsigned int calculate_serialized_size () const - { - unsigned int size = 0; - for (unsigned int i = 0; i < dict_values_t<VAL>::get_count; i++) - if (dict_values_t<VAL>::get_value (i).op == OpCode_Subrs) - size += OpCode_Size (OpCode_shortint) + 2 + OpCode_Size (OpCode_Subrs); - else - size += dict_values_t<VAL>::get_value (i).str.length; - return size; - } - unsigned int subrsOffset; const CFF1Subrs *localSubrs; }; @@ -997,6 +946,37 @@ typedef dict_interpreter_t<cff1_font_dict_opset_t, cff1_font_dict_values_t> cff1 typedef CFF1Index CFF1NameIndex; typedef CFF1IndexOf<TopDict> CFF1TopDictIndex; +struct cff1_font_dict_values_mod_t +{ + cff1_font_dict_values_mod_t() { init (); } + + void init () { init ( &Null (cff1_font_dict_values_t), CFF_UNDEF_SID ); } + + void init (const cff1_font_dict_values_t *base_, + unsigned int fontName_) + { + base = base_; + fontName = fontName_; + privateDictInfo.init (); + } + + unsigned get_count () const { return base->get_count (); } + + const op_str_t &operator [] (unsigned int i) const { return (*base)[i]; } + + const cff1_font_dict_values_t *base; + table_info_t privateDictInfo; + unsigned int fontName; +}; + +struct CFF1FDArray : FDArray<HBUINT16> +{ + /* FDArray::serialize() requires this partial specialization to compile */ + template <typename ITER, typename OP_SERIALIZER> + bool serialize (hb_serialize_context_t *c, ITER it, OP_SERIALIZER& opszr) + { return FDArray<HBUINT16>::serialize<cff1_font_dict_values_mod_t, cff1_font_dict_values_mod_t> (c, it, opszr); } +}; + } /* namespace CFF */ namespace OT { @@ -1031,7 +1011,7 @@ struct cff1 const OT::cff1 *cff = this->blob->template as<OT::cff1> (); - if (cff == &Null(OT::cff1)) + if (cff == &Null (OT::cff1)) { fini (); return; } nameIndex = &cff->nameIndex (cff); @@ -1052,7 +1032,7 @@ struct cff1 } if (is_predef_charset ()) - charset = &Null(Charset); + charset = &Null (Charset); else { charset = &StructAtOffsetOrNull<Charset> (cff, topDict.CharsetOffset); @@ -1064,16 +1044,30 @@ struct cff1 { 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))) + if (unlikely ((fdArray == &Null (CFF1FDArray)) || !fdArray->sanitize (&sc) || + (fdSelect == &Null (CFF1FDSelect)) || !fdSelect->sanitize (&sc, fdArray->count))) { fini (); return; } fdCount = fdArray->count; } else { - fdArray = &Null(CFF1FDArray); - fdSelect = &Null(CFF1FDSelect); + fdArray = &Null (CFF1FDArray); + fdSelect = &Null (CFF1FDSelect); + } + + encoding = &Null (Encoding); + if (is_CID ()) + { + if (unlikely (charset == &Null (Charset))) { fini (); return; } + } + else + { + if (!is_predef_encoding ()) + { + encoding = &StructAtOffsetOrNull<Encoding> (cff, topDict.EncodingOffset); + if (unlikely ((encoding == &Null (Encoding)) || !encoding->sanitize (&sc))) { fini (); return; } + } } stringIndex = &StructAtOffset<CFF1StringIndex> (topDictIndex, topDictIndex->get_size ()); @@ -1086,14 +1080,15 @@ struct cff1 charStrings = &StructAtOffsetOrNull<CFF1CharStrings> (cff, topDict.charStringsOffset); - if ((charStrings == &Null(CFF1CharStrings)) || unlikely (!charStrings->sanitize (&sc))) + if ((charStrings == &Null (CFF1CharStrings)) || unlikely (!charStrings->sanitize (&sc))) { fini (); return; } num_glyphs = charStrings->count; if (num_glyphs != sc.get_num_glyphs ()) { fini (); return; } - privateDicts.resize (fdCount); + if (unlikely (!privateDicts.resize (fdCount))) + { fini (); return; } for (unsigned int i = 0; i < fdCount; i++) privateDicts[i].init (); @@ -1104,14 +1099,14 @@ struct cff1 { byte_str_t fontDictStr = (*fdArray)[i]; if (unlikely (!fontDictStr.sanitize (&sc))) { fini (); return; } - cff1_font_dict_values_t *font; + cff1_font_dict_values_t *font; cff1_font_dict_interpreter_t font_interp; font_interp.env.init (fontDictStr); font = fontDicts.push (); - if (unlikely (font == &Crap(cff1_font_dict_values_t))) { fini (); return; } + if (unlikely (font == &Crap (cff1_font_dict_values_t))) { fini (); return; } font->init (); if (unlikely (!font_interp.interpret (*font))) { fini (); return; } - PRIVDICTVAL *priv = &privateDicts[i]; + PRIVDICTVAL *priv = &privateDicts[i]; const byte_str_t privDictStr (StructAtOffset<UnsizedByteStr> (cff, font->privateDictInfo.offset), font->privateDictInfo.size); if (unlikely (!privDictStr.sanitize (&sc))) { fini (); return; } dict_interpreter_t<PRIVOPSET, PRIVDICTVAL> priv_interp; @@ -1120,15 +1115,15 @@ struct cff1 if (unlikely (!priv_interp.interpret (*priv))) { fini (); return; } priv->localSubrs = &StructAtOffsetOrNull<CFF1Subrs> (&privDictStr, priv->subrsOffset); - if (priv->localSubrs != &Null(CFF1Subrs) && + if (priv->localSubrs != &Null (CFF1Subrs) && unlikely (!priv->localSubrs->sanitize (&sc))) { fini (); return; } } } else /* non-CID */ { - cff1_top_dict_values_t *font = &topDict; - PRIVDICTVAL *priv = &privateDicts[0]; + cff1_top_dict_values_t *font = &topDict; + PRIVDICTVAL *priv = &privateDicts[0]; const byte_str_t privDictStr (StructAtOffset<UnsizedByteStr> (cff, font->privateDictInfo.offset), font->privateDictInfo.size); if (unlikely (!privDictStr.sanitize (&sc))) { fini (); return; } @@ -1138,7 +1133,7 @@ struct cff1 if (unlikely (!priv_interp.interpret (*priv))) { fini (); return; } priv->localSubrs = &StructAtOffsetOrNull<CFF1Subrs> (&privDictStr, priv->subrsOffset); - if (priv->localSubrs != &Null(CFF1Subrs) && + if (priv->localSubrs != &Null (CFF1Subrs) && unlikely (!priv->localSubrs->sanitize (&sc))) { fini (); return; } } @@ -1154,7 +1149,7 @@ struct cff1 blob = nullptr; } - bool is_valid () const { return blob != nullptr; } + bool is_valid () const { return blob; } bool is_CID () const { return topDict.is_CID (); } bool is_predef_charset () const { return topDict.CharsetOffset <= ExpertSubsetCharset; } @@ -1165,69 +1160,18 @@ struct cff1 if (unlikely (sid == CFF_UNDEF_SID)) return 0; - if (charset != &Null(Charset)) + if (charset != &Null (Charset)) return charset->get_glyph (sid, num_glyphs); else if ((topDict.CharsetOffset == ISOAdobeCharset) && (code <= 228 /*zcaron*/)) return sid; return 0; } - protected: - hb_blob_t *blob; - hb_sanitize_context_t sc; - - public: - const Charset *charset; - const CFF1NameIndex *nameIndex; - const CFF1TopDictIndex *topDictIndex; - const CFF1StringIndex *stringIndex; - const CFF1Subrs *globalSubrs; - const CFF1CharStrings *charStrings; - const CFF1FDArray *fdArray; - const CFF1FDSelect *fdSelect; - unsigned int fdCount; - - cff1_top_dict_values_t topDict; - hb_vector_t<cff1_font_dict_values_t> fontDicts; - hb_vector_t<PRIVDICTVAL> privateDicts; - - unsigned int num_glyphs; - }; - - struct accelerator_t : accelerator_templ_t<cff1_private_dict_opset_t, cff1_private_dict_values_t> - { - HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const; - HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const; - }; - - struct accelerator_subset_t : accelerator_templ_t<cff1_private_dict_opset_subset, cff1_private_dict_values_subset_t> - { - void init (hb_face_t *face) - { - SUPER::init (face); - if (blob == nullptr) return; - - const OT::cff1 *cff = this->blob->as<OT::cff1> (); - encoding = &Null(Encoding); - if (is_CID ()) - { - if (unlikely (charset == &Null(Charset))) { fini (); return; } - } - else - { - if (!is_predef_encoding ()) - { - encoding = &StructAtOffsetOrNull<Encoding> (cff, topDict.EncodingOffset); - if (unlikely ((encoding == &Null (Encoding)) || !encoding->sanitize (&sc))) { fini (); return; } - } - } - } - bool is_predef_encoding () const { return topDict.EncodingOffset <= ExpertEncoding; } hb_codepoint_t glyph_to_code (hb_codepoint_t glyph) const { - if (encoding != &Null(Encoding)) + if (encoding != &Null (Encoding)) return encoding->get_code (glyph); else { @@ -1251,20 +1195,20 @@ struct cff1 hb_codepoint_t glyph_to_sid (hb_codepoint_t glyph) const { - if (charset != &Null(Charset)) - return charset->get_sid (glyph); + if (charset != &Null (Charset)) + return charset->get_sid (glyph, num_glyphs); else { hb_codepoint_t sid = 0; switch (topDict.CharsetOffset) { - case ISOAdobeCharset: + case ISOAdobeCharset: if (glyph <= 228 /*zcaron*/) sid = glyph; break; - case ExpertCharset: + case ExpertCharset: sid = lookup_expert_charset_for_sid (glyph); break; - case ExpertSubsetCharset: + case ExpertSubsetCharset: sid = lookup_expert_subset_charset_for_sid (glyph); break; default: @@ -1274,35 +1218,174 @@ struct cff1 } } - const Encoding *encoding; + hb_codepoint_t sid_to_glyph (hb_codepoint_t sid) const + { + if (charset != &Null (Charset)) + return charset->get_glyph (sid, num_glyphs); + else + { + hb_codepoint_t glyph = 0; + switch (topDict.CharsetOffset) + { + case ISOAdobeCharset: + if (sid <= 228 /*zcaron*/) glyph = sid; + break; + case ExpertCharset: + glyph = lookup_expert_charset_for_glyph (sid); + break; + case ExpertSubsetCharset: + glyph = lookup_expert_subset_charset_for_glyph (sid); + break; + default: + break; + } + return glyph; + } + } - private: - typedef accelerator_templ_t<cff1_private_dict_opset_subset, cff1_private_dict_values_subset_t> SUPER; + protected: + hb_blob_t *blob; + hb_sanitize_context_t sc; + + public: + const Encoding *encoding; + const Charset *charset; + const CFF1NameIndex *nameIndex; + const CFF1TopDictIndex *topDictIndex; + const CFF1StringIndex *stringIndex; + const CFF1Subrs *globalSubrs; + const CFF1CharStrings *charStrings; + const CFF1FDArray *fdArray; + const CFF1FDSelect *fdSelect; + unsigned int fdCount; + + cff1_top_dict_values_t topDict; + hb_vector_t<cff1_font_dict_values_t> + fontDicts; + hb_vector_t<PRIVDICTVAL> privateDicts; + + unsigned int num_glyphs; }; - bool subset (hb_subset_plan_t *plan) const + struct accelerator_t : accelerator_templ_t<cff1_private_dict_opset_t, cff1_private_dict_values_t> { - hb_blob_t *cff_prime = nullptr; - - bool success = true; - if (hb_subset_cff1 (plan, &cff_prime)) { - success = success && plan->add_table (HB_OT_TAG_cff1, cff_prime); - hb_blob_t *head_blob = hb_sanitize_context_t().reference_table<head> (plan->source); - success = success && head_blob && plan->add_table (HB_OT_TAG_head, head_blob); - hb_blob_destroy (head_blob); - } else { - success = false; + void init (hb_face_t *face) + { + SUPER::init (face); + + if (!is_valid ()) return; + if (is_CID ()) return; + + /* fill glyph_names */ + for (hb_codepoint_t gid = 0; gid < num_glyphs; gid++) + { + hb_codepoint_t sid = glyph_to_sid (gid); + gname_t gname; + gname.sid = sid; + if (sid < cff1_std_strings_length) + gname.name = cff1_std_strings (sid); + else + { + byte_str_t ustr = (*stringIndex)[sid - cff1_std_strings_length]; + gname.name = hb_bytes_t ((const char*)ustr.arrayZ, ustr.length); + } + if (unlikely (!gname.name.arrayZ)) { fini (); return; } + glyph_names.push (gname); + } + glyph_names.qsort (); } - hb_blob_destroy (cff_prime); - return success; - } + void fini () + { + glyph_names.fini (); + + SUPER::fini (); + } + + bool get_glyph_name (hb_codepoint_t glyph, + char *buf, unsigned int buf_len) const + { + if (!buf) return true; + if (unlikely (!is_valid ())) return false; + if (is_CID()) return false; + hb_codepoint_t sid = glyph_to_sid (glyph); + const char *str; + size_t str_len; + if (sid < cff1_std_strings_length) + { + hb_bytes_t byte_str = cff1_std_strings (sid); + str = byte_str.arrayZ; + str_len = byte_str.length; + } + else + { + byte_str_t ubyte_str = (*stringIndex)[sid - cff1_std_strings_length]; + str = (const char *)ubyte_str.arrayZ; + str_len = ubyte_str.length; + } + if (!str_len) return false; + unsigned int len = hb_min (buf_len - 1, str_len); + strncpy (buf, (const char*)str, len); + buf[len] = '\0'; + return true; + } + + bool get_glyph_from_name (const char *name, int len, + hb_codepoint_t *glyph) const + { + if (len < 0) len = strlen (name); + if (unlikely (!len)) return false; + + gname_t key = { hb_bytes_t (name, len), 0 }; + const gname_t *gname = glyph_names.bsearch (key); + if (!gname) return false; + hb_codepoint_t gid = sid_to_glyph (gname->sid); + if (!gid && gname->sid) return false; + *glyph = gid; + return true; + } + + HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const; + HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const; +#ifdef HB_EXPERIMENTAL_API + HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, draw_helper_t &draw_helper) const; +#endif + + private: + struct gname_t + { + hb_bytes_t name; + uint16_t sid; + + static int cmp (const void *a_, const void *b_) + { + const gname_t *a = (const gname_t *)a_; + const gname_t *b = (const gname_t *)b_; + int minlen = hb_min (a->name.length, b->name.length); + int ret = strncmp (a->name.arrayZ, b->name.arrayZ, minlen); + if (ret) return ret; + return a->name.length - b->name.length; + } + + int cmp (const gname_t &a) const { return cmp (&a, this); } + }; + + hb_sorted_vector_t<gname_t> glyph_names; + + typedef accelerator_templ_t<cff1_private_dict_opset_t, cff1_private_dict_values_t> SUPER; + }; + + struct accelerator_subset_t : accelerator_templ_t<cff1_private_dict_opset_subset, cff1_private_dict_values_subset_t> {}; + + bool subset (hb_subset_context_t *c) const { return hb_subset_cff1 (c); } protected: HB_INTERNAL static hb_codepoint_t lookup_standard_encoding_for_code (hb_codepoint_t sid); HB_INTERNAL static hb_codepoint_t lookup_expert_encoding_for_code (hb_codepoint_t sid); HB_INTERNAL static hb_codepoint_t lookup_expert_charset_for_sid (hb_codepoint_t glyph); HB_INTERNAL static hb_codepoint_t lookup_expert_subset_charset_for_sid (hb_codepoint_t glyph); + HB_INTERNAL static hb_codepoint_t lookup_expert_charset_for_glyph (hb_codepoint_t sid); + HB_INTERNAL static hb_codepoint_t lookup_expert_subset_charset_for_glyph (hb_codepoint_t sid); HB_INTERNAL static hb_codepoint_t lookup_standard_encoding_for_sid (hb_codepoint_t code); public: diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.cc index a2242b76fb..879b7cdb23 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.cc @@ -30,6 +30,7 @@ #include "hb-ot-cff2-table.hh" #include "hb-cff2-interp-cs.hh" +#include "hb-draw.hh" using namespace CFF; @@ -126,7 +127,7 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font, else { extents->x_bearing = font->em_scalef_x (param.min_x.to_real ()); - extents->width = font->em_scalef_x (param.max_x.to_real () - param.min_x.to_real ()); + extents->width = font->em_scalef_x (param.max_x.to_real ()) - extents->x_bearing; } if (param.min_y >= param.max_y) { @@ -136,11 +137,79 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font, else { extents->y_bearing = font->em_scalef_y (param.max_y.to_real ()); - extents->height = font->em_scalef_y (param.min_y.to_real () - param.max_y.to_real ()); + extents->height = font->em_scalef_y (param.min_y.to_real ()) - extents->y_bearing; } return true; } +#ifdef HB_EXPERIMENTAL_API +struct cff2_path_param_t +{ + cff2_path_param_t (hb_font_t *font_, draw_helper_t &draw_helper_) + { + draw_helper = &draw_helper_; + font = font_; + } + + void move_to (const point_t &p) + { draw_helper->move_to (font->em_scalef_x (p.x.to_real ()), font->em_scalef_y (p.y.to_real ())); } + + void line_to (const point_t &p) + { draw_helper->line_to (font->em_scalef_x (p.x.to_real ()), font->em_scalef_y (p.y.to_real ())); } + + void cubic_to (const point_t &p1, const point_t &p2, const point_t &p3) + { + draw_helper->cubic_to (font->em_scalef_x (p1.x.to_real ()), font->em_scalef_y (p1.y.to_real ()), + font->em_scalef_x (p2.x.to_real ()), font->em_scalef_y (p2.y.to_real ()), + font->em_scalef_x (p3.x.to_real ()), font->em_scalef_y (p3.y.to_real ())); + } + + protected: + draw_helper_t *draw_helper; + hb_font_t *font; +}; + +struct cff2_path_procs_path_t : path_procs_t<cff2_path_procs_path_t, cff2_cs_interp_env_t, cff2_path_param_t> +{ + static void moveto (cff2_cs_interp_env_t &env, cff2_path_param_t& param, const point_t &pt) + { + param.move_to (pt); + env.moveto (pt); + } + + static void line (cff2_cs_interp_env_t &env, cff2_path_param_t& param, const point_t &pt1) + { + param.line_to (pt1); + env.moveto (pt1); + } + + static void curve (cff2_cs_interp_env_t &env, cff2_path_param_t& param, const point_t &pt1, const point_t &pt2, const point_t &pt3) + { + param.cubic_to (pt1, pt2, pt3); + env.moveto (pt3); + } +}; + +struct cff2_cs_opset_path_t : cff2_cs_opset_t<cff2_cs_opset_path_t, cff2_path_param_t, cff2_path_procs_path_t> {}; + +bool OT::cff2::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, draw_helper_t &draw_helper) const +{ +#ifdef HB_NO_OT_FONT_CFF + /* XXX Remove check when this code moves to .hh file. */ + return true; +#endif + + if (unlikely (!is_valid () || (glyph >= num_glyphs))) return false; + + unsigned int fd = fdSelect->get_fd (glyph); + cff2_cs_interpreter_t<cff2_cs_opset_path_t, cff2_path_param_t> interp; + const byte_str_t str = (*charStrings)[glyph]; + interp.env.init (str, *this, fd, font->coords, font->num_coords); + cff2_path_param_t param (font, draw_helper); + if (unlikely (!interp.interpret (param))) return false; + return true; +} +#endif #endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh index 8646cde58d..829217feaa 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh @@ -27,9 +27,9 @@ #ifndef HB_OT_CFF2_TABLE_HH #define HB_OT_CFF2_TABLE_HH -#include "hb-ot-head-table.hh" #include "hb-ot-cff-common.hh" #include "hb-subset-cff2.hh" +#include "hb-draw.hh" namespace CFF { @@ -43,7 +43,6 @@ typedef CFFIndex<HBUINT32> CFF2Index; template <typename Type> struct CFF2IndexOf : CFFIndexOf<HBUINT32, Type> {}; typedef CFF2Index CFF2CharStrings; -typedef FDArray<HBUINT32> CFF2FDArray; typedef Subrs<HBUINT32> CFF2Subrs; typedef FDSelect3_4<HBUINT32, HBUINT16> FDSelect4; @@ -56,14 +55,11 @@ struct CFF2FDSelect TRACE_SERIALIZE (this); unsigned int size = src.get_size (num_glyphs); CFF2FDSelect *dest = c->allocate_size<CFF2FDSelect> (size); - if (unlikely (dest == nullptr)) return_trace (false); + if (unlikely (!dest)) return_trace (false); memcpy (dest, &src, size); return_trace (true); } - unsigned int calculate_serialized_size (unsigned int num_glyphs) const - { return get_size (num_glyphs); } - unsigned int get_size (unsigned int num_glyphs) const { switch (format) @@ -127,7 +123,7 @@ struct CFF2VariationStore TRACE_SERIALIZE (this); unsigned int size_ = varStore->get_size (); CFF2VariationStore *dest = c->allocate_size<CFF2VariationStore> (size_); - if (unlikely (dest == nullptr)) return_trace (false); + if (unlikely (!dest)) return_trace (false); memcpy (dest, varStore, size_); return_trace (true); } @@ -150,26 +146,6 @@ struct cff2_top_dict_values_t : top_dict_values_t<> } void fini () { top_dict_values_t<>::fini (); } - unsigned int calculate_serialized_size () const - { - unsigned int size = 0; - for (unsigned int i = 0; i < get_count (); i++) - { - op_code_t op = get_value (i).op; - switch (op) - { - case OpCode_vstore: - case OpCode_FDSelect: - size += OpCode_Size (OpCode_longintdict) + 4 + OpCode_Size (op); - break; - default: - size += top_dict_values_t<>::calculate_serialized_op_size (get_value (i)); - break; - } - } - return size; - } - unsigned int vstoreOffset; unsigned int FDSelectOffset; }; @@ -256,22 +232,11 @@ struct cff2_private_dict_values_base_t : dict_values_t<VAL> { dict_values_t<VAL>::init (); subrsOffset = 0; - localSubrs = &Null(CFF2Subrs); + localSubrs = &Null (CFF2Subrs); ivs = 0; } void fini () { dict_values_t<VAL>::fini (); } - unsigned int calculate_serialized_size () const - { - unsigned int size = 0; - for (unsigned int i = 0; i < dict_values_t<VAL>::get_count; i++) - if (dict_values_t<VAL>::get_value (i).op == OpCode_Subrs) - size += OpCode_Size (OpCode_shortint) + 2 + OpCode_Size (OpCode_Subrs); - else - size += dict_values_t<VAL>::get_value (i).str.length; - return size; - } - unsigned int subrsOffset; const CFF2Subrs *localSubrs; unsigned int ivs; @@ -404,6 +369,14 @@ struct cff2_private_dict_opset_subset_t : dict_opset_t typedef dict_interpreter_t<cff2_top_dict_opset_t, cff2_top_dict_values_t> cff2_top_dict_interpreter_t; typedef dict_interpreter_t<cff2_font_dict_opset_t, cff2_font_dict_values_t> cff2_font_dict_interpreter_t; +struct CFF2FDArray : FDArray<HBUINT32> +{ + /* FDArray::serialize does not compile without this partial specialization */ + template <typename ITER, typename OP_SERIALIZER> + bool serialize (hb_serialize_context_t *c, ITER it, OP_SERIALIZER& opszr) + { return FDArray<HBUINT32>::serialize<cff2_font_dict_values_t, table_info_t> (c, it, opszr); } +}; + } /* namespace CFF */ namespace OT { @@ -438,7 +411,7 @@ struct cff2 const OT::cff2 *cff2 = this->blob->template as<OT::cff2> (); - if (cff2 == &Null(OT::cff2)) + if (cff2 == &Null (OT::cff2)) { fini (); return; } { /* parse top dict */ @@ -456,11 +429,11 @@ struct cff2 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)) || - (((fdSelect != &Null(CFF2FDSelect)) && unlikely (!fdSelect->sanitize (&sc, fdArray->count))))) + 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)) || + (((fdSelect != &Null (CFF2FDSelect)) && unlikely (!fdSelect->sanitize (&sc, fdArray->count))))) { fini (); return; } num_glyphs = charStrings->count; @@ -468,7 +441,8 @@ struct cff2 { fini (); return; } fdCount = fdArray->count; - privateDicts.resize (fdCount); + if (!privateDicts.resize (fdCount)) + { fini (); return; } /* parse font dicts and gather private dicts */ for (unsigned int i = 0; i < fdCount; i++) @@ -479,7 +453,7 @@ struct cff2 cff2_font_dict_interpreter_t font_interp; font_interp.env.init (fontDictStr); font = fontDicts.push (); - if (unlikely (font == &Crap(cff2_font_dict_values_t))) { fini (); return; } + if (unlikely (font == &Crap (cff2_font_dict_values_t))) { fini (); return; } font->init (); if (unlikely (!font_interp.interpret (*font))) { fini (); return; } @@ -491,7 +465,7 @@ struct cff2 if (unlikely (!priv_interp.interpret (privateDicts[i]))) { fini (); return; } privateDicts[i].localSubrs = &StructAtOffsetOrNull<CFF2Subrs> (&privDictStr[0], privateDicts[i].subrsOffset); - if (privateDicts[i].localSubrs != &Null(CFF2Subrs) && + if (privateDicts[i].localSubrs != &Null (CFF2Subrs) && unlikely (!privateDicts[i].localSubrs->sanitize (&sc))) { fini (); return; } } @@ -507,7 +481,7 @@ struct cff2 blob = nullptr; } - bool is_valid () const { return blob != nullptr; } + bool is_valid () const { return blob; } protected: hb_blob_t *blob; @@ -533,27 +507,14 @@ struct cff2 HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const; +#ifdef HB_EXPERIMENTAL_API + HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, draw_helper_t &draw_helper) const; +#endif }; typedef accelerator_templ_t<cff2_private_dict_opset_subset_t, cff2_private_dict_values_subset_t> accelerator_subset_t; - bool subset (hb_subset_plan_t *plan) const - { - hb_blob_t *cff2_prime = nullptr; - - bool success = true; - if (hb_subset_cff2 (plan, &cff2_prime)) { - success = success && plan->add_table (HB_OT_TAG_cff2, cff2_prime); - hb_blob_t *head_blob = hb_sanitize_context_t().reference_table<head> (plan->source); - success = success && head_blob && plan->add_table (HB_OT_TAG_head, head_blob); - hb_blob_destroy (head_blob); - } else { - success = false; - } - hb_blob_destroy (cff2_prime); - - return success; - } + bool subset (hb_subset_context_t *c) const { return hb_subset_cff2 (c); } public: FixedVersion<HBUINT8> version; /* Version of CFF2 table. set to 0x0200u */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh index 9ebd8e417f..878e02ff17 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh @@ -56,6 +56,18 @@ struct CmapSubtableFormat0 out->add (i); } + void collect_mapping (hb_set_t *unicodes, /* OUT */ + hb_map_t *mapping /* OUT */) const + { + for (unsigned i = 0; i < 256; i++) + if (glyphIdArray[i]) + { + hb_codepoint_t glyph = glyphIdArray[i]; + unicodes->add (i); + mapping->set (i, glyph); + } + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -83,18 +95,16 @@ struct CmapSubtableFormat4 HBUINT16 *endCode = c->start_embed<HBUINT16> (); hb_codepoint_t prev_endcp = 0xFFFF; - + it - | hb_apply ([&] (const hb_item_type<Iterator> _) - { - if (prev_endcp != 0xFFFF && prev_endcp + 1u != _.first) - { - HBUINT16 end_code; - end_code = prev_endcp; - c->copy<HBUINT16> (end_code); - } - prev_endcp = _.first; - }) - ; + for (const auto& _ : +it) + { + if (prev_endcp != 0xFFFF && prev_endcp + 1u != _.first) + { + HBUINT16 end_code; + end_code = prev_endcp; + c->copy<HBUINT16> (end_code); + } + prev_endcp = _.first; + } { // last endCode @@ -121,19 +131,17 @@ struct CmapSubtableFormat4 HBUINT16 *startCode = c->start_embed<HBUINT16> (); hb_codepoint_t prev_cp = 0xFFFF; - + it - | hb_apply ([&] (const hb_item_type<Iterator> _) - { - if (prev_cp == 0xFFFF || prev_cp + 1u != _.first) - { - HBUINT16 start_code; - start_code = _.first; - c->copy<HBUINT16> (start_code); - } + for (const auto& _ : +it) + { + if (prev_cp == 0xFFFF || prev_cp + 1u != _.first) + { + HBUINT16 start_code; + start_code = _.first; + c->copy<HBUINT16> (start_code); + } - prev_cp = _.first; - }) - ; + prev_cp = _.first; + } // There must be a final entry with end_code == 0xFFFF. if (it.len () == 0 || prev_cp != 0xFFFF) @@ -149,10 +157,10 @@ struct CmapSubtableFormat4 template<typename Iterator, hb_requires (hb_is_iterator (Iterator))> HBINT16* serialize_idDelta_array (hb_serialize_context_t *c, - Iterator it, - HBUINT16 *endCode, - HBUINT16 *startCode, - unsigned segcount) + Iterator it, + HBUINT16 *endCode, + HBUINT16 *startCode, + unsigned segcount) { unsigned i = 0; hb_codepoint_t last_gid = 0, start_gid = 0, last_cp = 0xFFFF; @@ -162,30 +170,28 @@ struct CmapSubtableFormat4 if ((char *)idDelta - (char *)startCode != (int) segcount * (int) HBINT16::static_size) return nullptr; - + it - | hb_apply ([&] (const hb_item_type<Iterator> _) - { - if (_.first == startCode[i]) - { - use_delta = true; - start_gid = _.second; - } - else if (_.second != last_gid + 1) use_delta = false; + for (const auto& _ : +it) + { + if (_.first == startCode[i]) + { + use_delta = true; + start_gid = _.second; + } + else if (_.second != last_gid + 1) use_delta = false; - if (_.first == endCode[i]) - { - HBINT16 delta; - if (use_delta) delta = (int)start_gid - (int)startCode[i]; - else delta = 0; - c->copy<HBINT16> (delta); + if (_.first == endCode[i]) + { + HBINT16 delta; + if (use_delta) delta = (int)start_gid - (int)startCode[i]; + else delta = 0; + c->copy<HBINT16> (delta); - i++; - } + i++; + } - last_gid = _.second; - last_cp = _.first; - }) - ; + last_gid = _.second; + last_cp = _.first; + } if (it.len () == 0 || last_cp != 0xFFFF) { @@ -238,12 +244,20 @@ struct CmapSubtableFormat4 void serialize (hb_serialize_context_t *c, Iterator it) { + auto format4_iter = + + it + | hb_filter ([&] (const hb_pair_t<hb_codepoint_t, hb_codepoint_t> _) + { return _.first <= 0xFFFF; }) + ; + + if (format4_iter.len () == 0) return; + unsigned table_initpos = c->length (); if (unlikely (!c->extend_min (*this))) return; this->format = 4; //serialize endCode[] - HBUINT16 *endCode = serialize_endcode_array (c, it); + HBUINT16 *endCode = serialize_endcode_array (c, format4_iter); if (unlikely (!endCode)) return; unsigned segcount = (c->length () - min_size) / HBUINT16::static_size; @@ -252,14 +266,14 @@ struct CmapSubtableFormat4 if (unlikely (!c->allocate_size<HBUINT16> (HBUINT16::static_size))) return; // 2 bytes of padding. // serialize startCode[] - HBUINT16 *startCode = serialize_startcode_array (c, it); + HBUINT16 *startCode = serialize_startcode_array (c, format4_iter); if (unlikely (!startCode)) return; //serialize idDelta[] - HBINT16 *idDelta = serialize_idDelta_array (c, it, endCode, startCode, segcount); + HBINT16 *idDelta = serialize_idDelta_array (c, format4_iter, endCode, startCode, segcount); if (unlikely (!idDelta)) return; - HBUINT16 *idRangeOffset = serialize_rangeoffset_glyid (c, it, endCode, startCode, idDelta, segcount); + HBUINT16 *idRangeOffset = serialize_rangeoffset_glyid (c, format4_iter, endCode, startCode, idDelta, segcount); if (unlikely (!c->check_success (idRangeOffset))) return; if (unlikely (!c->check_assign(this->length, c->length () - table_initpos))) return; @@ -291,27 +305,28 @@ struct CmapSubtableFormat4 bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const { - /* Custom two-array bsearch. */ - int min = 0, max = (int) this->segCount - 1; - const HBUINT16 *startCount = this->startCount; - const HBUINT16 *endCount = this->endCount; - unsigned int i; - while (min <= max) + struct CustomRange { - int mid = ((unsigned int) min + (unsigned int) max) / 2; - if (codepoint < startCount[mid]) - max = mid - 1; - else if (codepoint > endCount[mid]) - min = mid + 1; - else + int cmp (hb_codepoint_t k, + unsigned distance) const { - i = mid; - goto found; + if (k > last) return +1; + if (k < (&last)[distance]) return -1; + return 0; } - } - return false; + HBUINT16 last; + }; + + const HBUINT16 *found = hb_bsearch (codepoint, + this->endCount, + this->segCount, + 2, + _hb_cmp_method<hb_codepoint_t, CustomRange, unsigned>, + this->segCount + 1); + if (!found) + return false; + unsigned int i = found - endCount; - found: hb_codepoint_t gid; unsigned int rangeOffset = this->idRangeOffset[i]; if (rangeOffset == 0) @@ -333,8 +348,10 @@ struct CmapSubtableFormat4 *glyph = gid; return true; } + HB_INTERNAL static bool get_glyph_func (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph) { return ((const accelerator_t *) obj)->get_glyph (codepoint, glyph); } + void collect_unicodes (hb_set_t *out) const { unsigned int count = this->segCount; @@ -371,6 +388,45 @@ struct CmapSubtableFormat4 } } + void collect_mapping (hb_set_t *unicodes, /* OUT */ + hb_map_t *mapping /* OUT */) const + { + unsigned count = this->segCount; + if (count && this->startCount[count - 1] == 0xFFFFu) + count--; /* Skip sentinel segment. */ + for (unsigned i = 0; i < count; i++) + { + hb_codepoint_t start = this->startCount[i]; + hb_codepoint_t end = this->endCount[i]; + unsigned rangeOffset = this->idRangeOffset[i]; + if (rangeOffset == 0) + { + for (hb_codepoint_t codepoint = start; codepoint <= end; codepoint++) + { + hb_codepoint_t gid = (codepoint + this->idDelta[i]) & 0xFFFFu; + if (unlikely (!gid)) + continue; + unicodes->add (codepoint); + mapping->set (codepoint, gid); + } + } + else + { + for (hb_codepoint_t codepoint = start; codepoint <= end; codepoint++) + { + unsigned index = rangeOffset / 2 + (codepoint - this->startCount[i]) + i - this->segCount; + if (unlikely (index >= this->glyphIdArrayLength)) + break; + hb_codepoint_t gid = this->glyphIdArray[index]; + if (unlikely (!gid)) + continue; + unicodes->add (codepoint); + mapping->set (codepoint, gid); + } + } + } + } + const HBUINT16 *endCount; const HBUINT16 *startCount; const HBUINT16 *idDelta; @@ -391,6 +447,13 @@ struct CmapSubtableFormat4 accel.collect_unicodes (out); } + void collect_mapping (hb_set_t *unicodes, /* OUT */ + hb_map_t *mapping /* OUT */) const + { + accelerator_t accel (this); + accel.collect_mapping (unicodes, mapping); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -403,8 +466,8 @@ struct CmapSubtableFormat4 * If that is the case, just change the value to truncate * the subtable at the end of the blob. */ uint16_t new_length = (uint16_t) hb_min ((uintptr_t) 65535, - (uintptr_t) (c->end - - (char *) this)); + (uintptr_t) (c->end - + (char *) this)); if (!c->try_set (&length, new_length)) return_trace (false); } @@ -493,6 +556,21 @@ struct CmapSubtableTrimmed out->add (start + i); } + void collect_mapping (hb_set_t *unicodes, /* OUT */ + hb_map_t *mapping /* OUT */) const + { + hb_codepoint_t start_cp = startCharCode; + unsigned count = glyphIdArray.len; + for (unsigned i = 0; i < count; i++) + if (glyphIdArray[i]) + { + hb_codepoint_t unicode = start_cp + i; + hb_codepoint_t glyphid = glyphIdArray[i]; + unicodes->add (unicode); + mapping->set (unicode, glyphid); + } + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -528,19 +606,55 @@ struct CmapSubtableLongSegmented return true; } - void collect_unicodes (hb_set_t *out) const + void collect_unicodes (hb_set_t *out, unsigned int num_glyphs) const { for (unsigned int i = 0; i < this->groups.len; i++) { hb_codepoint_t start = this->groups[i].startCharCode; hb_codepoint_t end = hb_min ((hb_codepoint_t) this->groups[i].endCharCode, (hb_codepoint_t) HB_UNICODE_MAX); - for (hb_codepoint_t codepoint = start; codepoint <= end; codepoint++) + hb_codepoint_t gid = this->groups[i].glyphID; + if (!gid) { - hb_codepoint_t gid = T::group_get_glyph (this->groups[i], codepoint); - if (unlikely (!gid)) - continue; - out->add (codepoint); + /* Intention is: if (hb_is_same (T, CmapSubtableFormat13)) continue; */ + if (! T::group_get_glyph (this->groups[i], end)) continue; + start++; + gid++; + } + if (unlikely ((unsigned int) gid >= num_glyphs)) continue; + if (unlikely ((unsigned int) (gid + end - start) >= num_glyphs)) + end = start + (hb_codepoint_t) num_glyphs - gid; + + out->add_range (start, end); + } + } + + void collect_mapping (hb_set_t *unicodes, /* OUT */ + hb_map_t *mapping, /* OUT */ + unsigned num_glyphs) const + { + for (unsigned i = 0; i < this->groups.len; i++) + { + hb_codepoint_t start = this->groups[i].startCharCode; + hb_codepoint_t end = hb_min ((hb_codepoint_t) this->groups[i].endCharCode, + (hb_codepoint_t) HB_UNICODE_MAX); + hb_codepoint_t gid = this->groups[i].glyphID; + if (!gid) + { + /* Intention is: if (hb_is_same (T, CmapSubtableFormat13)) continue; */ + if (! T::group_get_glyph (this->groups[i], end)) continue; + start++; + gid++; + } + if (unlikely ((unsigned int) gid >= num_glyphs)) continue; + if (unlikely ((unsigned int) (gid + end - start) >= num_glyphs)) + end = start + (hb_codepoint_t) num_glyphs - gid; + + for (unsigned cp = start; cp <= end; cp++) + { + unicodes->add (cp); + mapping->set (cp, gid); + gid++; } } } @@ -582,33 +696,29 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12> hb_codepoint_t startCharCode = 0xFFFF, endCharCode = 0xFFFF; hb_codepoint_t glyphID = 0; - + it - | hb_apply ([&] (const hb_item_type<Iterator> _) - { - if (startCharCode == 0xFFFF) - { - startCharCode = _.first; - endCharCode = _.first; - glyphID = _.second; - } - else if (!_is_gid_consecutive (endCharCode, startCharCode, glyphID, _.first, _.second)) - { - CmapSubtableLongGroup grouprecord; - grouprecord.startCharCode = startCharCode; - grouprecord.endCharCode = endCharCode; - grouprecord.glyphID = glyphID; - c->copy<CmapSubtableLongGroup> (grouprecord); - - startCharCode = _.first; - endCharCode = _.first; - glyphID = _.second; - } - else - { - endCharCode = _.first; - } - }) - ; + for (const auto& _ : +it) + { + if (startCharCode == 0xFFFF) + { + startCharCode = _.first; + endCharCode = _.first; + glyphID = _.second; + } + else if (!_is_gid_consecutive (endCharCode, startCharCode, glyphID, _.first, _.second)) + { + CmapSubtableLongGroup grouprecord; + grouprecord.startCharCode = startCharCode; + grouprecord.endCharCode = endCharCode; + grouprecord.glyphID = glyphID; + c->copy<CmapSubtableLongGroup> (grouprecord); + + startCharCode = _.first; + endCharCode = _.first; + glyphID = _.second; + } + else + endCharCode = _.first; + } CmapSubtableLongGroup record; record.startCharCode = startCharCode; @@ -683,7 +793,7 @@ struct DefaultUVS : SortedArrayOf<UnicodeValueRange, HBUINT32> { hb_codepoint_t first = arrayZ[i].startUnicodeValue; hb_codepoint_t last = hb_min ((hb_codepoint_t) (first + arrayZ[i].additionalCount), - (hb_codepoint_t) HB_UNICODE_MAX); + (hb_codepoint_t) HB_UNICODE_MAX); out->add_range (first, last); } } @@ -772,7 +882,20 @@ struct NonDefaultUVS : SortedArrayOf<UVSMapping, HBUINT32> { unsigned int count = len; for (unsigned int i = 0; i < count; i++) - out->add (arrayZ[i].glyphID); + out->add (arrayZ[i].unicodeValue); + } + + void collect_mapping (hb_set_t *unicodes, /* OUT */ + hb_map_t *mapping /* OUT */) const + { + unsigned count = len; + for (unsigned i = 0; i < count; i++) + { + hb_codepoint_t unicode = arrayZ[i].unicodeValue; + hb_codepoint_t glyphid = arrayZ[i].glyphID; + unicodes->add (unicode); + mapping->set (unicode, glyphid); + } } void closure_glyphs (const hb_set_t *unicodes, @@ -787,7 +910,7 @@ struct NonDefaultUVS : SortedArrayOf<UVSMapping, HBUINT32> NonDefaultUVS* copy (hb_serialize_context_t *c, const hb_set_t *unicodes, - const hb_set_t *glyphs, + const hb_set_t *glyphs_requested, const hb_map_t *glyph_map) const { NonDefaultUVS *out = c->start_embed<NonDefaultUVS> (); @@ -797,7 +920,7 @@ struct NonDefaultUVS : SortedArrayOf<UVSMapping, HBUINT32> + as_array () | hb_filter ([&] (const UVSMapping& _) { - return unicodes->has (_.unicodeValue) || glyphs->has (_.glyphID); + return unicodes->has (_.unicodeValue) || glyphs_requested->has (_.glyphID); }) ; @@ -839,12 +962,34 @@ struct VariationSelectorRecord return GLYPH_VARIANT_NOT_FOUND; } + VariationSelectorRecord(const VariationSelectorRecord& other) + { + *this = other; + } + + void operator= (const VariationSelectorRecord& other) + { + varSelector = other.varSelector; + HBUINT32 offset = other.defaultUVS; + defaultUVS = offset; + offset = other.nonDefaultUVS; + nonDefaultUVS = offset; + } + void collect_unicodes (hb_set_t *out, const void *base) const { (base+defaultUVS).collect_unicodes (out); (base+nonDefaultUVS).collect_unicodes (out); } + void collect_mapping (const void *base, + hb_set_t *unicodes, /* OUT */ + hb_map_t *mapping /* OUT */) const + { + (base+defaultUVS).collect_unicodes (unicodes); + (base+nonDefaultUVS).collect_mapping (unicodes, mapping); + } + int cmp (const hb_codepoint_t &variation_selector) const { return varSelector.cmp (variation_selector); } @@ -856,50 +1001,43 @@ struct VariationSelectorRecord nonDefaultUVS.sanitize (c, base)); } - VariationSelectorRecord* copy (hb_serialize_context_t *c, - const hb_set_t *unicodes, - const hb_set_t *glyphs, - const hb_map_t *glyph_map, - const void *src_base, - const void *dst_base) const + hb_pair_t<unsigned, unsigned> + copy (hb_serialize_context_t *c, + const hb_set_t *unicodes, + const hb_set_t *glyphs_requested, + const hb_map_t *glyph_map, + const void *base) const { auto snap = c->snapshot (); auto *out = c->embed<VariationSelectorRecord> (*this); - if (unlikely (!out)) return nullptr; + if (unlikely (!out)) return hb_pair (0, 0); out->defaultUVS = 0; out->nonDefaultUVS = 0; - bool drop = true; - - if (defaultUVS != 0) + unsigned non_default_uvs_objidx = 0; + if (nonDefaultUVS != 0) { c->push (); - if (c->copy (src_base+defaultUVS, unicodes)) - { - c->add_link (out->defaultUVS, c->pop_pack (), dst_base); - drop = false; - } + if (c->copy (base+nonDefaultUVS, unicodes, glyphs_requested, glyph_map)) + non_default_uvs_objidx = c->pop_pack (); else c->pop_discard (); } - if (nonDefaultUVS != 0) + unsigned default_uvs_objidx = 0; + if (defaultUVS != 0) { c->push (); - if (c->copy (src_base+nonDefaultUVS, unicodes, glyphs, glyph_map)) - { - c->add_link (out->nonDefaultUVS, c->pop_pack (), dst_base); - drop = false; - } + if (c->copy (base+defaultUVS, unicodes)) + default_uvs_objidx = c->pop_pack (); else c->pop_discard (); } - if (drop) - { + + if (!default_uvs_objidx && !non_default_uvs_objidx) c->revert (snap); - return nullptr; - } - else return out; + + return hb_pair (default_uvs_objidx, non_default_uvs_objidx); } HBUINT24 varSelector; /* Variation selector. */ @@ -930,9 +1068,9 @@ struct CmapSubtableFormat14 void serialize (hb_serialize_context_t *c, const hb_set_t *unicodes, - const hb_set_t *glyphs, + const hb_set_t *glyphs_requested, const hb_map_t *glyph_map, - const void *src_base) + const void *base) { auto snap = c->snapshot (); unsigned table_initpos = c->length (); @@ -941,17 +1079,70 @@ struct CmapSubtableFormat14 if (unlikely (!c->extend_min (*this))) return; this->format = 14; - const CmapSubtableFormat14 *src_tbl = reinterpret_cast<const CmapSubtableFormat14*> (src_base); - for (const VariationSelectorRecord& _ : src_tbl->record) - c->copy (_, unicodes, glyphs, glyph_map, src_base, this); + auto src_tbl = reinterpret_cast<const CmapSubtableFormat14*> (base); + + /* + * Some versions of OTS require that offsets are in order. Due to the use + * of push()/pop_pack() serializing the variation records in order results + * in the offsets being in reverse order (first record has the largest + * offset). While this is perfectly valid, it will cause some versions of + * OTS to consider this table bad. + * + * So to prevent this issue we serialize the variation records in reverse + * order, so that the offsets are ordered from small to large. Since + * variation records are supposed to be in increasing order of varSelector + * we then have to reverse the order of the written variation selector + * records after everything is finalized. + */ + hb_vector_t<hb_pair_t<unsigned, unsigned>> obj_indices; + for (int i = src_tbl->record.len - 1; i >= 0; i--) + { + hb_pair_t<unsigned, unsigned> result = src_tbl->record[i].copy (c, unicodes, glyphs_requested, glyph_map, base); + if (result.first || result.second) + obj_indices.push (result); + } if (c->length () - table_initpos == CmapSubtableFormat14::min_size) + { c->revert (snap); - else + return; + } + + if (unlikely (!c->check_success (!obj_indices.in_error ()))) + return; + + int tail_len = init_tail - c->tail; + c->check_assign (this->length, c->length () - table_initpos + tail_len); + c->check_assign (this->record.len, + (c->length () - table_initpos - CmapSubtableFormat14::min_size) / + VariationSelectorRecord::static_size); + + /* Correct the incorrect write order by reversing the order of the variation + records array. */ + _reverse_variation_records (); + + /* Now that records are in the right order, we can set up the offsets. */ + _add_links_to_variation_records (c, obj_indices); + } + + void _reverse_variation_records () + { + record.as_array ().reverse (); + } + + void _add_links_to_variation_records (hb_serialize_context_t *c, + const hb_vector_t<hb_pair_t<unsigned, unsigned>>& obj_indices) + { + for (unsigned i = 0; i < obj_indices.length; i++) { - int tail_len = init_tail - c->tail; - c->check_assign (this->length, c->length () - table_initpos + tail_len); - c->check_assign (this->record.len, (c->length () - table_initpos - CmapSubtableFormat14::min_size) / VariationSelectorRecord::static_size); + /* + * Since the record array has been reversed (see comments in copy()) + * but obj_indices has not been, the indices at obj_indices[i] + * are for the variation record at record[j]. + */ + int j = obj_indices.length - 1 - i; + c->add_link (record[j].defaultUVS, obj_indices[i].first); + c->add_link (record[j].nonDefaultUVS, obj_indices[i].second); } } @@ -966,6 +1157,19 @@ struct CmapSubtableFormat14 ; } + void collect_unicodes (hb_set_t *out) const + { + for (const VariationSelectorRecord& _ : record) + _.collect_unicodes (out, this); + } + + void collect_mapping (hb_set_t *unicodes, /* OUT */ + hb_map_t *mapping /* OUT */) const + { + for (const VariationSelectorRecord& _ : record) + _.collect_mapping (this, unicodes, mapping); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -1001,15 +1205,31 @@ struct CmapSubtable default: return false; } } - void collect_unicodes (hb_set_t *out) const + void collect_unicodes (hb_set_t *out, unsigned int num_glyphs = UINT_MAX) const { switch (u.format) { case 0: u.format0 .collect_unicodes (out); return; case 4: u.format4 .collect_unicodes (out); return; case 6: u.format6 .collect_unicodes (out); return; case 10: u.format10.collect_unicodes (out); return; - case 12: u.format12.collect_unicodes (out); return; - case 13: u.format13.collect_unicodes (out); return; + case 12: u.format12.collect_unicodes (out, num_glyphs); return; + case 13: u.format13.collect_unicodes (out, num_glyphs); return; + case 14: + default: return; + } + } + + void collect_mapping (hb_set_t *unicodes, /* OUT */ + hb_map_t *mapping, /* OUT */ + unsigned num_glyphs = UINT_MAX) const + { + switch (u.format) { + case 0: u.format0 .collect_mapping (unicodes, mapping); return; + case 4: u.format4 .collect_mapping (unicodes, mapping); return; + case 6: u.format6 .collect_mapping (unicodes, mapping); return; + case 10: u.format10.collect_mapping (unicodes, mapping); return; + case 12: u.format12.collect_mapping (unicodes, mapping, num_glyphs); return; + case 13: u.format13.collect_mapping (unicodes, mapping, num_glyphs); return; case 14: default: return; } @@ -1021,12 +1241,12 @@ struct CmapSubtable Iterator it, unsigned format, const hb_subset_plan_t *plan, - const void *src_base) + const void *base) { switch (format) { - case 4: u.format4.serialize (c, it); return; - case 12: u.format12.serialize (c, it); return; - case 14: u.format14.serialize (c, plan->unicodes, plan->_glyphset, plan->glyph_map, src_base); return; + case 4: return u.format4.serialize (c, it); + case 12: return u.format12.serialize (c, it); + case 14: return u.format14.serialize (c, plan->unicodes, plan->glyphs_requested, plan->glyph_map, base); default: return; } } @@ -1087,8 +1307,7 @@ struct EncodingRecord EncodingRecord* copy (hb_serialize_context_t *c, Iterator it, unsigned format, - const void *src_base, - const void *dst_base, + const void *base, const hb_subset_plan_t *plan, /* INOUT */ unsigned *objidx) const { @@ -1102,7 +1321,7 @@ struct EncodingRecord { CmapSubtable *cmapsubtable = c->push<CmapSubtable> (); unsigned origin_length = c->length (); - cmapsubtable->serialize (c, it, format, plan, &(src_base+subtable)); + cmapsubtable->serialize (c, it, format, plan, &(base+subtable)); if (c->length () - origin_length > 0) *objidx = c->pop_pack (); else c->pop_discard (); } @@ -1113,7 +1332,7 @@ struct EncodingRecord return_trace (nullptr); } - c->add_link (out->subtable, *objidx, dst_base); + c->add_link (out->subtable, *objidx); return_trace (out); } @@ -1130,11 +1349,11 @@ struct cmap static constexpr hb_tag_t tableTag = HB_OT_TAG_cmap; template<typename Iterator, typename EncodingRecIter, - hb_requires (hb_is_iterator (Iterator))> + hb_requires (hb_is_iterator (EncodingRecIter))> void serialize (hb_serialize_context_t *c, Iterator it, EncodingRecIter encodingrec_iter, - const void *src_base, + const void *base, const hb_subset_plan_t *plan) { if (unlikely (!c->extend_min ((*this)))) return; @@ -1144,11 +1363,42 @@ struct cmap for (const EncodingRecord& _ : encodingrec_iter) { - unsigned format = (src_base+_.subtable).u.format; + unsigned format = (base+_.subtable).u.format; + if (!plan->glyphs_requested->is_empty ()) + { + hb_set_t unicodes_set; + hb_map_t cp_glyphid_map; + (base+_.subtable).collect_mapping (&unicodes_set, &cp_glyphid_map); + + auto table_iter = + + hb_zip (unicodes_set.iter(), unicodes_set.iter() | hb_map(cp_glyphid_map)) + | hb_filter (plan->_glyphset, hb_second) + | hb_filter ([plan] (const hb_pair_t<hb_codepoint_t, hb_codepoint_t>& p) + { + return plan->unicodes->has (p.first) || + plan->glyphs_requested->has (p.second); + }) + | hb_map ([plan] (const hb_pair_t<hb_codepoint_t, hb_codepoint_t>& p_org) + { + return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (p_org.first, plan->glyph_map->get(p_org.second)); + }) + ; - if (format == 4) c->copy (_, it, 4u, src_base, this, plan, &format4objidx); - else if (format == 12) c->copy (_, it, 12u, src_base, this, plan, &format12objidx); - else if (format == 14) c->copy (_, it, 14u, src_base, this, plan, &format14objidx); + if (format == 4) c->copy (_, table_iter, 4u, base, plan, &format4objidx); + else if (format == 12) c->copy (_, table_iter, 12u, base, plan, &format12objidx); + else if (format == 14) c->copy (_, table_iter, 14u, base, plan, &format14objidx); + } + /* when --gids option is not used, we iterate input unicodes instead of + * all codepoints in each subtable, which is more efficient */ + else + { + hb_set_t unicodes_set; + (base+_.subtable).collect_unicodes (&unicodes_set); + + if (format == 4) c->copy (_, + it | hb_filter (unicodes_set, hb_first), 4u, base, plan, &format4objidx); + else if (format == 12) c->copy (_, + it | hb_filter (unicodes_set, hb_first), 12u, base, plan, &format12objidx); + else if (format == 14) c->copy (_, it, 14u, base, plan, &format14objidx); + } } c->check_assign(this->encodingRecord.len, (c->length () - cmap::min_size)/EncodingRecord::static_size); @@ -1187,7 +1437,6 @@ struct cmap }) ; - if (unlikely (!encodingrec_iter.len ())) return_trace (false); const EncodingRecord *unicode_bmp= nullptr, *unicode_ucs4 = nullptr, *ms_bmp = nullptr, *ms_ucs4 = nullptr; @@ -1205,7 +1454,7 @@ struct cmap else if (_.platformID == 3 && _.encodingID == 10) ms_ucs4 = table; } - if (unlikely (!unicode_bmp && !ms_bmp)) return_trace (false); + if (unlikely (!has_format12 && !unicode_bmp && !ms_bmp)) return_trace (false); if (unlikely (has_format12 && (!unicode_ucs4 && !ms_ucs4))) return_trace (false); auto it = @@ -1219,7 +1468,6 @@ struct cmap | hb_filter ([&] (const hb_pair_t<hb_codepoint_t, hb_codepoint_t> _) { return (_.second != HB_MAP_VALUE_INVALID); }) ; - cmap_prime->serialize (c->serializer, it, encodingrec_iter, this, c->plan); return_trace (true); } @@ -1339,8 +1587,11 @@ struct cmap return get_nominal_glyph (unicode, glyph); } - void collect_unicodes (hb_set_t *out) const - { subtable->collect_unicodes (out); } + void collect_unicodes (hb_set_t *out, unsigned int num_glyphs) const + { subtable->collect_unicodes (out, num_glyphs); } + void collect_mapping (hb_set_t *unicodes, hb_map_t *mapping, + unsigned num_glyphs = UINT_MAX) const + { subtable->collect_mapping (unicodes, mapping, num_glyphs); } void collect_variation_selectors (hb_set_t *out) const { subtable_uvs->collect_variation_selectors (out); } void collect_variation_unicodes (hb_codepoint_t variation_selector, @@ -1413,7 +1664,7 @@ struct cmap } const EncodingRecord *find_encodingrec (unsigned int platform_id, - unsigned int encoding_id) const + unsigned int encoding_id) const { EncodingRecord key; key.platformID = platform_id; @@ -1445,9 +1696,9 @@ struct cmap } protected: - HBUINT16 version; /* Table version number (0). */ + HBUINT16 version; /* Table version number (0). */ SortedArrayOf<EncodingRecord> - encodingRecord; /* Encoding tables. */ + encodingRecord; /* Encoding tables. */ public: DEFINE_SIZE_ARRAY (4, encodingRecord); }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-color-cbdt-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-color-cbdt-table.hh index 3498d3b360..e285acec3d 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-color-cbdt-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-color-cbdt-table.hh @@ -21,7 +21,7 @@ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * - * Google Author(s): Seigo Nonaka + * Google Author(s): Seigo Nonaka, Calder Kitagawa */ #ifndef HB_OT_COLOR_CBDT_TABLE_HH @@ -43,6 +43,35 @@ namespace OT { +struct cblc_bitmap_size_subset_context_t +{ + const char *cbdt; + unsigned int cbdt_length; + hb_vector_t<char> *cbdt_prime; + unsigned int size; /* INOUT + * Input: old size of IndexSubtable + * Output: new size of IndexSubtable + */ + unsigned int num_tables; /* INOUT + * Input: old number of subtables. + * Output: new number of subtables. + */ + hb_codepoint_t start_glyph; /* OUT */ + hb_codepoint_t end_glyph; /* OUT */ +}; + +static inline bool +_copy_data_to_cbdt (hb_vector_t<char> *cbdt_prime, + const void *data, + unsigned length) +{ + unsigned int new_len = cbdt_prime->length + length; + if (unlikely (!cbdt_prime->alloc (new_len))) return false; + memcpy (cbdt_prime->arrayZ + cbdt_prime->length, data, length); + cbdt_prime->length = new_len; + return true; +} + struct SmallGlyphMetrics { bool sanitize (hb_sanitize_context_t *c) const @@ -56,7 +85,7 @@ struct SmallGlyphMetrics extents->x_bearing = font->em_scale_x (bearingX); extents->y_bearing = font->em_scale_y (bearingY); extents->width = font->em_scale_x (width); - extents->height = font->em_scale_y (-height); + extents->height = font->em_scale_y (-static_cast<int>(height)); } HBUINT8 height; @@ -65,7 +94,7 @@ struct SmallGlyphMetrics HBINT8 bearingY; HBUINT8 advance; public: - DEFINE_SIZE_STATIC(5); + DEFINE_SIZE_STATIC (5); }; struct BigGlyphMetrics : SmallGlyphMetrics @@ -74,7 +103,7 @@ struct BigGlyphMetrics : SmallGlyphMetrics HBINT8 vertBearingY; HBUINT8 vertAdvance; public: - DEFINE_SIZE_STATIC(8); + DEFINE_SIZE_STATIC (8); }; struct SBitLineMetrics @@ -98,7 +127,7 @@ struct SBitLineMetrics HBINT8 padding1; HBINT8 padding2; public: - DEFINE_SIZE_STATIC(12); + DEFINE_SIZE_STATIC (12); }; @@ -118,7 +147,7 @@ struct IndexSubtableHeader HBUINT16 imageFormat; HBUINT32 imageDataOffset; public: - DEFINE_SIZE_STATIC(8); + DEFINE_SIZE_STATIC (8); }; template <typename OffsetType> @@ -143,11 +172,23 @@ struct IndexSubtableFormat1Or3 return true; } + bool add_offset (hb_serialize_context_t *c, + unsigned int offset, + unsigned int *size /* OUT (accumulated) */) + { + TRACE_SERIALIZE (this); + Offset<OffsetType> embedded_offset; + embedded_offset = offset; + *size += sizeof (OffsetType); + auto *o = c->embed (embedded_offset); + return_trace ((bool) o); + } + IndexSubtableHeader header; UnsizedArrayOf<Offset<OffsetType>> - offsetArrayZ; + offsetArrayZ; public: - DEFINE_SIZE_ARRAY(8, offsetArrayZ); + DEFINE_SIZE_ARRAY (8, offsetArrayZ); }; struct IndexSubtableFormat1 : IndexSubtableFormat1Or3<HBUINT32> {}; @@ -159,35 +200,153 @@ struct IndexSubtable { TRACE_SANITIZE (this); if (!u.header.sanitize (c)) return_trace (false); - switch (u.header.indexFormat) { + switch (u.header.indexFormat) + { case 1: return_trace (u.format1.sanitize (c, glyph_count)); case 3: return_trace (u.format3.sanitize (c, glyph_count)); default:return_trace (true); } } + bool + finish_subtable (hb_serialize_context_t *c, + unsigned int cbdt_prime_len, + unsigned int num_glyphs, + unsigned int *size /* OUT (accumulated) */) + { + TRACE_SERIALIZE (this); + + unsigned int local_offset = cbdt_prime_len - u.header.imageDataOffset; + switch (u.header.indexFormat) + { + case 1: return_trace (u.format1.add_offset (c, local_offset, size)); + case 3: { + if (!u.format3.add_offset (c, local_offset, size)) + return_trace (false); + if (!(num_glyphs & 0x01)) // Pad to 32-bit alignment if needed. + return_trace (u.format3.add_offset (c, 0, size)); + return_trace (true); + } + // TODO: implement 2, 4, 5. + case 2: case 4: // No-op. + case 5: // Pad to 32-bit aligned. + default: return_trace (false); + } + } + + bool + fill_missing_glyphs (hb_serialize_context_t *c, + unsigned int cbdt_prime_len, + unsigned int num_missing, + unsigned int *size /* OUT (accumulated) */, + unsigned int *num_glyphs /* OUT (accumulated) */) + { + TRACE_SERIALIZE (this); + + unsigned int local_offset = cbdt_prime_len - u.header.imageDataOffset; + switch (u.header.indexFormat) + { + case 1: { + for (unsigned int i = 0; i < num_missing; i++) + { + if (unlikely (!u.format1.add_offset (c, local_offset, size))) + return_trace (false); + *num_glyphs += 1; + } + return_trace (true); + } + case 3: { + for (unsigned int i = 0; i < num_missing; i++) + { + if (unlikely (!u.format3.add_offset (c, local_offset, size))) + return_trace (false); + *num_glyphs += 1; + } + return_trace (true); + } + // TODO: implement 2, 4, 5. + case 2: // Add empty space in cbdt_prime?. + case 4: case 5: // No-op as sparse is supported. + default: return_trace (false); + } + } + + bool + copy_glyph_at_idx (hb_serialize_context_t *c, unsigned int idx, + const char *cbdt, unsigned int cbdt_length, + hb_vector_t<char> *cbdt_prime /* INOUT */, + IndexSubtable *subtable_prime /* INOUT */, + unsigned int *size /* OUT (accumulated) */) const + { + TRACE_SERIALIZE (this); + + unsigned int offset, length, format; + if (unlikely (!get_image_data (idx, &offset, &length, &format))) return_trace (false); + if (unlikely (offset > cbdt_length || cbdt_length - offset < length)) return_trace (false); + + auto *header_prime = subtable_prime->get_header (); + unsigned int new_local_offset = cbdt_prime->length - (unsigned int) header_prime->imageDataOffset; + if (unlikely (!_copy_data_to_cbdt (cbdt_prime, cbdt + offset, length))) return_trace (false); + + return_trace (subtable_prime->add_offset (c, new_local_offset, size)); + } + + bool + add_offset (hb_serialize_context_t *c, unsigned int local_offset, + unsigned int *size /* OUT (accumulated) */) + { + TRACE_SERIALIZE (this); + switch (u.header.indexFormat) + { + case 1: return_trace (u.format1.add_offset (c, local_offset, size)); + case 3: return_trace (u.format3.add_offset (c, local_offset, size)); + // TODO: Implement tables 2, 4, 5 + case 2: // Should be a no-op. + case 4: case 5: // Handle sparse cases. + default: return_trace (false); + } + } + bool get_extents (hb_glyph_extents_t *extents HB_UNUSED) const { - switch (u.header.indexFormat) { + switch (u.header.indexFormat) + { case 2: case 5: /* TODO */ case 1: case 3: case 4: /* Variable-metrics formats do not have metrics here. */ default:return (false); } } - bool get_image_data (unsigned int idx, - unsigned int *offset, - unsigned int *length, - unsigned int *format) const + bool + get_image_data (unsigned int idx, unsigned int *offset, + unsigned int *length, unsigned int *format) const { *format = u.header.imageFormat; - switch (u.header.indexFormat) { + switch (u.header.indexFormat) + { case 1: return u.format1.get_image_data (idx, offset, length); case 3: return u.format3.get_image_data (idx, offset, length); default: return false; } } + const IndexSubtableHeader* get_header () const { return &u.header; } + + void populate_header (unsigned index_format, + unsigned image_format, + unsigned int image_data_offset, + unsigned int *size) + { + u.header.indexFormat = index_format; + u.header.imageFormat = image_format; + u.header.imageDataOffset = image_data_offset; + switch (u.header.indexFormat) + { + case 1: *size += IndexSubtableFormat1::min_size; break; + case 3: *size += IndexSubtableFormat3::min_size; break; + } + } + protected: union { IndexSubtableHeader header; @@ -209,12 +368,135 @@ struct IndexSubtableRecord offsetToSubtable.sanitize (c, base, lastGlyphIndex - firstGlyphIndex + 1)); } - bool get_extents (hb_glyph_extents_t *extents, - const void *base) const + const IndexSubtable* get_subtable (const void *base) const { - return (base+offsetToSubtable).get_extents (extents); + return &(base+offsetToSubtable); } + bool add_new_subtable (hb_subset_context_t* c, + cblc_bitmap_size_subset_context_t *bitmap_size_context, + IndexSubtableRecord *record, + const hb_vector_t<hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*>> *lookup, /* IN */ + const void *base, + unsigned int *start /* INOUT */) const + { + TRACE_SERIALIZE (this); + + auto *subtable = c->serializer->start_embed<IndexSubtable> (); + if (unlikely (!subtable)) return_trace (false); + if (unlikely (!c->serializer->extend_min (subtable))) return_trace (false); + + auto *old_subtable = get_subtable (base); + auto *old_header = old_subtable->get_header (); + + subtable->populate_header (old_header->indexFormat, + old_header->imageFormat, + bitmap_size_context->cbdt_prime->length, + &bitmap_size_context->size); + + unsigned int num_glyphs = 0; + bool early_exit = false; + for (unsigned int i = *start; i < lookup->length; i++) + { + hb_codepoint_t new_gid = (*lookup)[i].first; + const IndexSubtableRecord *next_record = (*lookup)[i].second; + const IndexSubtable *next_subtable = next_record->get_subtable (base); + auto *next_header = next_subtable->get_header (); + if (next_header != old_header) + { + *start = i; + early_exit = true; + break; + } + unsigned int num_missing = record->add_glyph_for_subset (new_gid); + if (unlikely (!subtable->fill_missing_glyphs (c->serializer, + bitmap_size_context->cbdt_prime->length, + num_missing, + &bitmap_size_context->size, + &num_glyphs))) + return_trace (false); + + hb_codepoint_t old_gid = 0; + c->plan->old_gid_for_new_gid (new_gid, &old_gid); + if (old_gid < next_record->firstGlyphIndex) + return_trace (false); + + unsigned int old_idx = (unsigned int) old_gid - next_record->firstGlyphIndex; + if (unlikely (!next_subtable->copy_glyph_at_idx (c->serializer, + old_idx, + bitmap_size_context->cbdt, + bitmap_size_context->cbdt_length, + bitmap_size_context->cbdt_prime, + subtable, + &bitmap_size_context->size))) + return_trace (false); + num_glyphs += 1; + } + if (!early_exit) + *start = lookup->length; + if (unlikely (!subtable->finish_subtable (c->serializer, + bitmap_size_context->cbdt_prime->length, + num_glyphs, + &bitmap_size_context->size))) + return_trace (false); + return_trace (true); + } + + bool add_new_record (hb_subset_context_t *c, + cblc_bitmap_size_subset_context_t *bitmap_size_context, + const hb_vector_t<hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*>> *lookup, /* IN */ + const void *base, + unsigned int *start, /* INOUT */ + hb_vector_t<IndexSubtableRecord>* records /* INOUT */) const + { + TRACE_SERIALIZE (this); + auto snap = c->serializer->snapshot (); + unsigned int old_size = bitmap_size_context->size; + unsigned int old_cbdt_prime_length = bitmap_size_context->cbdt_prime->length; + + // Set to invalid state to indicate filling glyphs is not yet started. + if (unlikely (!c->serializer->check_success (records->resize (records->length + 1)))) + return_trace (false); + + (*records)[records->length - 1].firstGlyphIndex = 1; + (*records)[records->length - 1].lastGlyphIndex = 0; + bitmap_size_context->size += IndexSubtableRecord::min_size; + + c->serializer->push (); + + if (unlikely (!add_new_subtable (c, bitmap_size_context, &((*records)[records->length - 1]), lookup, base, start))) + { + c->serializer->pop_discard (); + c->serializer->revert (snap); + bitmap_size_context->cbdt_prime->shrink (old_cbdt_prime_length); + bitmap_size_context->size = old_size; + records->resize (records->length - 1); + return_trace (false); + } + + bitmap_size_context->num_tables += 1; + return_trace (true); + } + + unsigned int add_glyph_for_subset (hb_codepoint_t gid) + { + if (firstGlyphIndex > lastGlyphIndex) + { + firstGlyphIndex = gid; + lastGlyphIndex = gid; + return 0; + } + // TODO maybe assert? this shouldn't occur. + if (lastGlyphIndex > gid) + return 0; + unsigned int num_missing = (unsigned int) (gid - lastGlyphIndex - 1); + lastGlyphIndex = gid; + return num_missing; + } + + bool get_extents (hb_glyph_extents_t *extents, const void *base) const + { return (base+offsetToSubtable).get_extents (extents); } + bool get_image_data (unsigned int gid, const void *base, unsigned int *offset, @@ -230,7 +512,7 @@ struct IndexSubtableRecord HBGlyphID lastGlyphIndex; LOffsetTo<IndexSubtable> offsetToSubtable; public: - DEFINE_SIZE_STATIC(8); + DEFINE_SIZE_STATIC (8); }; struct IndexSubtableArray @@ -243,6 +525,79 @@ struct IndexSubtableArray return_trace (indexSubtablesZ.sanitize (c, count, this)); } + void + build_lookup (hb_subset_context_t *c, cblc_bitmap_size_subset_context_t *bitmap_size_context, + hb_vector_t<hb_pair_t<hb_codepoint_t, + const IndexSubtableRecord*>> *lookup /* OUT */) const + { + bool start_glyph_is_set = false; + for (hb_codepoint_t new_gid = 0; new_gid < c->plan->num_output_glyphs (); new_gid++) + { + hb_codepoint_t old_gid; + if (unlikely (!c->plan->old_gid_for_new_gid (new_gid, &old_gid))) continue; + + const IndexSubtableRecord* record = find_table (old_gid, bitmap_size_context->num_tables); + if (unlikely (!record)) continue; + + // Don't add gaps to the lookup. The best way to determine if a glyph is a + // gap is that it has no image data. + unsigned int offset, length, format; + if (unlikely (!record->get_image_data (old_gid, this, &offset, &length, &format))) continue; + + lookup->push (hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*> (new_gid, record)); + + if (!start_glyph_is_set) + { + bitmap_size_context->start_glyph = new_gid; + start_glyph_is_set = true; + } + + bitmap_size_context->end_glyph = new_gid; + } + } + + bool + subset (hb_subset_context_t *c, + cblc_bitmap_size_subset_context_t *bitmap_size_context) const + { + TRACE_SUBSET (this); + + auto *dst = c->serializer->start_embed<IndexSubtableArray> (); + if (unlikely (!dst)) return_trace (false); + + hb_vector_t<hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*>> lookup; + build_lookup (c, bitmap_size_context, &lookup); + if (unlikely (!c->serializer->propagate_error (lookup))) + return false; + + bitmap_size_context->size = 0; + bitmap_size_context->num_tables = 0; + hb_vector_t<IndexSubtableRecord> records; + for (unsigned int start = 0; start < lookup.length;) + { + if (unlikely (!lookup[start].second->add_new_record (c, bitmap_size_context, &lookup, this, &start, &records))) + { + // Discard any leftover pushes to the serializer from successful records. + for (unsigned int i = 0; i < records.length; i++) + c->serializer->pop_discard (); + return_trace (false); + } + } + + /* Workaround to ensure offset ordering is from least to greatest when + * resolving links. */ + hb_vector_t<hb_serialize_context_t::objidx_t> objidxs; + for (unsigned int i = 0; i < records.length; i++) + objidxs.push (c->serializer->pop_pack ()); + for (unsigned int i = 0; i < records.length; i++) + { + IndexSubtableRecord* record = c->serializer->embed (records[i]); + if (unlikely (!record)) return_trace (false); + c->serializer->add_link (record->offsetToSubtable, objidxs[records.length - 1 - i]); + } + return_trace (true); + } + public: const IndexSubtableRecord* find_table (hb_codepoint_t glyph, unsigned int numTables) const { @@ -274,14 +629,48 @@ struct BitmapSizeTable vertical.sanitize (c)); } - const IndexSubtableRecord *find_table (hb_codepoint_t glyph, - const void *base, - const void **out_base) const + const IndexSubtableRecord * + find_table (hb_codepoint_t glyph, const void *base, const void **out_base) const { *out_base = &(base+indexSubtableArrayOffset); return (base+indexSubtableArrayOffset).find_table (glyph, numberOfIndexSubtables); } + bool + subset (hb_subset_context_t *c, const void *base, + const char *cbdt, unsigned int cbdt_length, + hb_vector_t<char> *cbdt_prime /* INOUT */) const + { + TRACE_SUBSET (this); + auto *out_table = c->serializer->embed (this); + if (unlikely (!out_table)) return_trace (false); + + cblc_bitmap_size_subset_context_t bitmap_size_context; + bitmap_size_context.cbdt = cbdt; + bitmap_size_context.cbdt_length = cbdt_length; + bitmap_size_context.cbdt_prime = cbdt_prime; + bitmap_size_context.size = indexTablesSize; + bitmap_size_context.num_tables = numberOfIndexSubtables; + bitmap_size_context.start_glyph = 1; + bitmap_size_context.end_glyph = 0; + + if (!out_table->indexSubtableArrayOffset.serialize_subset (c, + indexSubtableArrayOffset, + base, + &bitmap_size_context)) + return_trace (false); + if (!bitmap_size_context.size || + !bitmap_size_context.num_tables || + bitmap_size_context.start_glyph > bitmap_size_context.end_glyph) + return_trace (false); + + out_table->indexTablesSize = bitmap_size_context.size; + out_table->numberOfIndexSubtables = bitmap_size_context.num_tables; + out_table->startGlyphIndex = bitmap_size_context.start_glyph; + out_table->endGlyphIndex = bitmap_size_context.end_glyph; + return_trace (true); + } + protected: LNNOffsetTo<IndexSubtableArray> indexSubtableArrayOffset; @@ -297,7 +686,7 @@ struct BitmapSizeTable HBUINT8 bitDepth; HBINT8 flags; public: - DEFINE_SIZE_STATIC(48); + DEFINE_SIZE_STATIC (48); }; @@ -310,7 +699,7 @@ struct GlyphBitmapDataFormat17 SmallGlyphMetrics glyphMetrics; LArrayOf<HBUINT8> data; public: - DEFINE_SIZE_ARRAY(9, data); + DEFINE_SIZE_ARRAY (9, data); }; struct GlyphBitmapDataFormat18 @@ -318,14 +707,14 @@ struct GlyphBitmapDataFormat18 BigGlyphMetrics glyphMetrics; LArrayOf<HBUINT8> data; public: - DEFINE_SIZE_ARRAY(12, data); + DEFINE_SIZE_ARRAY (12, data); }; struct GlyphBitmapDataFormat19 { LArrayOf<HBUINT8> data; public: - DEFINE_SIZE_ARRAY(4, data); + DEFINE_SIZE_ARRAY (4, data); }; struct CBLC @@ -342,12 +731,50 @@ struct CBLC sizeTables.sanitize (c, this)); } + static bool + sink_cbdt (hb_subset_context_t *c, hb_vector_t<char>* cbdt_prime) + { + hb_blob_t *cbdt_prime_blob = hb_blob_create (cbdt_prime->arrayZ, + cbdt_prime->length, + HB_MEMORY_MODE_WRITABLE, + cbdt_prime->arrayZ, + free); + cbdt_prime->init (); // Leak arrayZ to the blob. + bool ret = c->plan->add_table (HB_OT_TAG_CBDT, cbdt_prime_blob); + hb_blob_destroy (cbdt_prime_blob); + return ret; + } + + bool + subset_size_table (hb_subset_context_t *c, const BitmapSizeTable& table, + const char *cbdt /* IN */, unsigned int cbdt_length, + CBLC *cblc_prime /* INOUT */, hb_vector_t<char> *cbdt_prime /* INOUT */) const + { + TRACE_SUBSET (this); + cblc_prime->sizeTables.len++; + + auto snap = c->serializer->snapshot (); + auto cbdt_prime_len = cbdt_prime->length; + + if (!table.subset (c, this, cbdt, cbdt_length, cbdt_prime)) + { + cblc_prime->sizeTables.len--; + c->serializer->revert (snap); + cbdt_prime->shrink (cbdt_prime_len); + return_trace (false); + } + return_trace (true); + } + + // Implemented in cc file as it depends on definition of CBDT. + HB_INTERNAL bool subset (hb_subset_context_t *c) const; + protected: const BitmapSizeTable &choose_strike (hb_font_t *font) const { unsigned count = sizeTables.len; if (unlikely (!count)) - return Null(BitmapSizeTable); + return Null (BitmapSizeTable); unsigned int requested_ppem = hb_max (font->x_ppem, font->y_ppem); if (!requested_ppem) @@ -373,7 +800,7 @@ struct CBLC FixedVersion<> version; LArrayOf<BitmapSizeTable> sizeTables; public: - DEFINE_SIZE_ARRAY(8, sizeTables); + DEFINE_SIZE_ARRAY (8, sizeTables); }; struct CBDT @@ -384,8 +811,8 @@ struct CBDT { void init (hb_face_t *face) { - cblc = hb_sanitize_context_t().reference_table<CBLC> (face); - cbdt = hb_sanitize_context_t().reference_table<CBDT> (face); + cblc = hb_sanitize_context_t ().reference_table<CBLC> (face); + cbdt = hb_sanitize_context_t ().reference_table<CBDT> (face); upem = hb_face_get_upem (face); } @@ -396,8 +823,8 @@ struct CBDT this->cbdt.destroy (); } - bool get_extents (hb_font_t *font, hb_codepoint_t glyph, - hb_glyph_extents_t *extents) const + bool + get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const { const void *base; const BitmapSizeTable &strike = this->cblc->choose_strike (font); @@ -412,33 +839,27 @@ struct CBDT if (!subtable_record->get_image_data (glyph, base, &image_offset, &image_length, &image_format)) return false; + unsigned int cbdt_len = cbdt.get_length (); + if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length)) + return false; + + switch (image_format) { - unsigned int cbdt_len = cbdt.get_length (); - if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length)) + case 17: { + if (unlikely (image_length < GlyphBitmapDataFormat17::min_size)) return false; - - switch (image_format) - { - case 17: { - if (unlikely (image_length < GlyphBitmapDataFormat17::min_size)) - return false; - const GlyphBitmapDataFormat17& glyphFormat17 = - StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset); - glyphFormat17.glyphMetrics.get_extents (font, extents); - break; - } - case 18: { - if (unlikely (image_length < GlyphBitmapDataFormat18::min_size)) - return false; - const GlyphBitmapDataFormat18& glyphFormat18 = - StructAtOffset<GlyphBitmapDataFormat18> (this->cbdt, image_offset); - glyphFormat18.glyphMetrics.get_extents (font, extents); - break; - } - default: - // TODO: Support other image formats. - return false; - } + auto &glyphFormat17 = StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset); + glyphFormat17.glyphMetrics.get_extents (font, extents); + break; + } + case 18: { + if (unlikely (image_length < GlyphBitmapDataFormat18::min_size)) + return false; + auto &glyphFormat18 = StructAtOffset<GlyphBitmapDataFormat18> (this->cbdt, image_offset); + glyphFormat18.glyphMetrics.get_extents (font, extents); + break; + } + default: return false; /* TODO: Support other image formats. */ } /* Convert to font units. */ @@ -452,8 +873,8 @@ struct CBDT return true; } - hb_blob_t* reference_png (hb_font_t *font, - hb_codepoint_t glyph) const + hb_blob_t* + reference_png (hb_font_t *font, hb_codepoint_t glyph) const { const void *base; const BitmapSizeTable &strike = this->cblc->choose_strike (font); @@ -465,44 +886,41 @@ struct CBDT if (!subtable_record->get_image_data (glyph, base, &image_offset, &image_length, &image_format)) return hb_blob_get_empty (); + unsigned int cbdt_len = cbdt.get_length (); + if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length)) + return hb_blob_get_empty (); + + switch (image_format) + { + case 17: { - unsigned int cbdt_len = cbdt.get_length (); - if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length)) + if (unlikely (image_length < GlyphBitmapDataFormat17::min_size)) return hb_blob_get_empty (); - - switch (image_format) - { - case 17: { - if (unlikely (image_length < GlyphBitmapDataFormat17::min_size)) - return hb_blob_get_empty (); - const GlyphBitmapDataFormat17& glyphFormat17 = - StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset); - return hb_blob_create_sub_blob (cbdt.get_blob (), - image_offset + GlyphBitmapDataFormat17::min_size, - glyphFormat17.data.len); - } - case 18: { - if (unlikely (image_length < GlyphBitmapDataFormat18::min_size)) - return hb_blob_get_empty (); - const GlyphBitmapDataFormat18& glyphFormat18 = - StructAtOffset<GlyphBitmapDataFormat18> (this->cbdt, image_offset); - return hb_blob_create_sub_blob (cbdt.get_blob (), - image_offset + GlyphBitmapDataFormat18::min_size, - glyphFormat18.data.len); - } - case 19: { - if (unlikely (image_length < GlyphBitmapDataFormat19::min_size)) - return hb_blob_get_empty (); - const GlyphBitmapDataFormat19& glyphFormat19 = - StructAtOffset<GlyphBitmapDataFormat19> (this->cbdt, image_offset); - return hb_blob_create_sub_blob (cbdt.get_blob (), - image_offset + GlyphBitmapDataFormat19::min_size, - glyphFormat19.data.len); - } - } + auto &glyphFormat17 = StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset); + return hb_blob_create_sub_blob (cbdt.get_blob (), + image_offset + GlyphBitmapDataFormat17::min_size, + glyphFormat17.data.len); + } + case 18: + { + if (unlikely (image_length < GlyphBitmapDataFormat18::min_size)) + return hb_blob_get_empty (); + auto &glyphFormat18 = StructAtOffset<GlyphBitmapDataFormat18> (this->cbdt, image_offset); + return hb_blob_create_sub_blob (cbdt.get_blob (), + image_offset + GlyphBitmapDataFormat18::min_size, + glyphFormat18.data.len); + } + case 19: + { + if (unlikely (image_length < GlyphBitmapDataFormat19::min_size)) + return hb_blob_get_empty (); + auto &glyphFormat19 = StructAtOffset<GlyphBitmapDataFormat19> (this->cbdt, image_offset); + return hb_blob_create_sub_blob (cbdt.get_blob (), + image_offset + GlyphBitmapDataFormat19::min_size, + glyphFormat19.data.len); + } + default: return hb_blob_get_empty (); /* TODO: Support other image formats. */ } - - return hb_blob_get_empty (); } bool has_data () const { return cbdt.get_length (); } @@ -525,9 +943,41 @@ struct CBDT FixedVersion<> version; UnsizedArrayOf<HBUINT8> dataZ; public: - DEFINE_SIZE_ARRAY(4, dataZ); + DEFINE_SIZE_ARRAY (4, dataZ); }; +inline bool +CBLC::subset (hb_subset_context_t *c) const +{ + TRACE_SUBSET (this); + + auto *cblc_prime = c->serializer->start_embed<CBLC> (); + + // Use a vector as a secondary buffer as the tables need to be built in parallel. + hb_vector_t<char> cbdt_prime; + + if (unlikely (!cblc_prime)) return_trace (false); + if (unlikely (!c->serializer->extend_min (cblc_prime))) return_trace (false); + cblc_prime->version = version; + + hb_blob_t* cbdt_blob = hb_sanitize_context_t ().reference_table<CBDT> (c->plan->source); + unsigned int cbdt_length; + CBDT* cbdt = (CBDT *) hb_blob_get_data (cbdt_blob, &cbdt_length); + if (unlikely (cbdt_length < CBDT::min_size)) + { + hb_blob_destroy (cbdt_blob); + return_trace (false); + } + _copy_data_to_cbdt (&cbdt_prime, cbdt, CBDT::min_size); + + for (const BitmapSizeTable& table : + sizeTables.iter ()) + subset_size_table (c, table, (const char *) cbdt, cbdt_length, cblc_prime, &cbdt_prime); + + hb_blob_destroy (cbdt_blob); + + return_trace (CBLC::sink_cbdt (c, &cbdt_prime)); +} + struct CBDT_accelerator_t : CBDT::accelerator_t {}; } /* namespace OT */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-color-colr-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-color-colr-table.hh index e2ed7c6549..e2a1ff4662 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-color-colr-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-color-colr-table.hh @@ -1,5 +1,6 @@ /* * Copyright © 2018 Ebrahim Byagowi + * Copyright © 2020 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -20,6 +21,8 @@ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Calder Kitagawa */ #ifndef HB_OT_COLOR_COLR_TABLE_HH @@ -47,7 +50,7 @@ struct LayerRecord return_trace (c->check_struct (this)); } - protected: + public: HBGlyphID glyphId; /* Glyph ID of layer glyph */ Index colorIdx; /* Index value to use with a * selected color palette. @@ -112,6 +115,38 @@ struct COLR return glyph_layers.length; } + struct accelerator_t + { + accelerator_t () {} + ~accelerator_t () { fini (); } + + void init (hb_face_t *face) + { colr = hb_sanitize_context_t ().reference_table<COLR> (face); } + + void fini () { this->colr.destroy (); } + + bool is_valid () { return colr.get_blob ()->length; } + + void closure_glyphs (hb_codepoint_t glyph, + hb_set_t *related_ids /* OUT */) const + { colr->closure_glyphs (glyph, related_ids); } + + private: + hb_blob_ptr_t<COLR> colr; + }; + + void closure_glyphs (hb_codepoint_t glyph, + hb_set_t *related_ids /* OUT */) const + { + const BaseGlyphRecord *record = get_base_glyph_record (glyph); + if (!record) return; + + auto glyph_layers = (this+layersZ).as_array (numLayers).sub_array (record->firstLayerIdx, + record->numLayers); + if (!glyph_layers.length) return; + related_ids->add_array (&glyph_layers[0].glyphId, glyph_layers.length, LayerRecord::min_size); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -120,6 +155,111 @@ struct COLR (this+layersZ).sanitize (c, numLayers))); } + template<typename BaseIterator, typename LayerIterator, + hb_requires (hb_is_iterator (BaseIterator)), + hb_requires (hb_is_iterator (LayerIterator))> + bool serialize (hb_serialize_context_t *c, + unsigned version, + BaseIterator base_it, + LayerIterator layer_it) + { + TRACE_SERIALIZE (this); + if (unlikely (base_it.len () != layer_it.len ())) + return_trace (false); + + if (unlikely (!c->extend_min (this))) return_trace (false); + this->version = version; + numLayers = 0; + numBaseGlyphs = base_it.len (); + baseGlyphsZ = COLR::min_size; + layersZ = COLR::min_size + numBaseGlyphs * BaseGlyphRecord::min_size; + + for (const hb_item_type<BaseIterator> _ : + base_it.iter ()) + { + auto* record = c->embed (_); + if (unlikely (!record)) return_trace (false); + record->firstLayerIdx = numLayers; + numLayers += record->numLayers; + } + + for (const hb_item_type<LayerIterator>& _ : + layer_it.iter ()) + _.as_array ().copy (c); + + return_trace (true); + } + + const BaseGlyphRecord* get_base_glyph_record (hb_codepoint_t gid) const + { + if ((unsigned int) gid == 0) // Ignore notdef. + return nullptr; + const BaseGlyphRecord* record = &(this+baseGlyphsZ).bsearch (numBaseGlyphs, (unsigned int) gid); + if ((record && (hb_codepoint_t) record->glyphId != gid)) + record = nullptr; + return record; + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + + const hb_map_t &reverse_glyph_map = *c->plan->reverse_glyph_map; + + auto base_it = + + hb_range (c->plan->num_output_glyphs ()) + | hb_map_retains_sorting ([&](hb_codepoint_t new_gid) + { + hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid); + + const BaseGlyphRecord* old_record = get_base_glyph_record (old_gid); + if (unlikely (!old_record)) + return hb_pair_t<bool, BaseGlyphRecord> (false, Null (BaseGlyphRecord)); + + BaseGlyphRecord new_record = {}; + new_record.glyphId = new_gid; + new_record.numLayers = old_record->numLayers; + return hb_pair_t<bool, BaseGlyphRecord> (true, new_record); + }) + | hb_filter (hb_first) + | hb_map_retains_sorting (hb_second) + ; + + auto layer_it = + + hb_range (c->plan->num_output_glyphs ()) + | hb_map (reverse_glyph_map) + | hb_map_retains_sorting ([&](hb_codepoint_t old_gid) + { + const BaseGlyphRecord* old_record = get_base_glyph_record (old_gid); + hb_vector_t<LayerRecord> out_layers; + + if (unlikely (!old_record || + old_record->firstLayerIdx >= numLayers || + old_record->firstLayerIdx + old_record->numLayers > numLayers)) + return hb_pair_t<bool, hb_vector_t<LayerRecord>> (false, out_layers); + + auto layers = (this+layersZ).as_array (numLayers).sub_array (old_record->firstLayerIdx, + old_record->numLayers); + out_layers.resize (layers.length); + for (unsigned int i = 0; i < layers.length; i++) { + out_layers[i] = layers[i]; + hb_codepoint_t new_gid = 0; + if (unlikely (!c->plan->new_gid_for_old_gid (out_layers[i].glyphId, &new_gid))) + return hb_pair_t<bool, hb_vector_t<LayerRecord>> (false, out_layers); + out_layers[i].glyphId = new_gid; + } + + return hb_pair_t<bool, hb_vector_t<LayerRecord>> (true, out_layers); + }) + | hb_filter (hb_first) + | hb_map_retains_sorting (hb_second) + ; + + if (unlikely (!base_it || !layer_it || base_it.len () != layer_it.len ())) + return_trace (false); + + COLR *colr_prime = c->serializer->start_embed<COLR> (); + return_trace (colr_prime->serialize (c->serializer, version, base_it, layer_it)); + } + protected: HBUINT16 version; /* Table version number (starts at 0). */ HBUINT16 numBaseGlyphs; /* Number of Base Glyph Records. */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-color-cpal-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-color-cpal-table.hh index 1b3c7fc0b8..fa7d3207be 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-color-cpal-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-color-cpal-table.hh @@ -142,12 +142,9 @@ struct CPAL numColors); if (color_count) { - hb_array_t<const BGRAColor> segment_colors = palette_colors.sub_array (start_offset, *color_count); - /* Always return numColors colors per palette even if it has out-of-bounds start index. */ - unsigned int count = hb_min ((unsigned) hb_max ((int) (numColors - start_offset), 0), *color_count); - *color_count = count; - for (unsigned int i = 0; i < count; i++) - colors[i] = segment_colors[i]; /* Bound-checked read. */ + + palette_colors.sub_array (start_offset, color_count) + | hb_sink (hb_array (colors, *color_count)) + ; } return numColors; } @@ -155,7 +152,7 @@ struct CPAL private: const CPALV1Tail& v1 () const { - if (version == 0) return Null(CPALV1Tail); + if (version == 0) return Null (CPALV1Tail); return StructAfter<CPALV1Tail> (*this); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-color-sbix-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-color-sbix-table.hh index 35d3fd5105..09da11597d 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-color-sbix-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-color-sbix-table.hh @@ -1,5 +1,6 @@ /* * Copyright © 2018 Ebrahim Byagowi + * Copyright © 2020 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -20,12 +21,15 @@ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Calder Kitagawa */ #ifndef HB_OT_COLOR_SBIX_TABLE_HH #define HB_OT_COLOR_SBIX_TABLE_HH #include "hb-open-type.hh" +#include "hb-ot-layout-common.hh" /* * sbix -- Standard Bitmap Graphics @@ -40,6 +44,20 @@ namespace OT { struct SBIXGlyph { + SBIXGlyph* copy (hb_serialize_context_t *c, unsigned int data_length) const + { + TRACE_SERIALIZE (this); + SBIXGlyph* new_glyph = c->start_embed<SBIXGlyph> (); + if (unlikely (!new_glyph)) return_trace (nullptr); + if (unlikely (!c->extend_min (new_glyph))) return_trace (nullptr); + + new_glyph->xOffset = xOffset; + new_glyph->yOffset = yOffset; + new_glyph->graphicType = graphicType; + data.copy (c, data_length); + return_trace (new_glyph); + } + HBINT16 xOffset; /* The horizontal (x-axis) offset from the left * edge of the graphic to the glyph’s origin. * That is, the x-coordinate of the point on the @@ -62,6 +80,9 @@ struct SBIXGlyph struct SBIXStrike { + static unsigned int get_size (unsigned num_glyphs) + { return min_size + num_glyphs * HBUINT32::static_size; } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -116,6 +137,49 @@ struct SBIXStrike return hb_blob_create_sub_blob (sbix_blob, glyph_offset, glyph_length); } + bool subset (hb_subset_context_t *c, unsigned int available_len) const + { + TRACE_SUBSET (this); + unsigned int num_output_glyphs = c->plan->num_output_glyphs (); + + auto* out = c->serializer->start_embed<SBIXStrike> (); + if (unlikely (!out)) return_trace (false); + auto snap = c->serializer->snapshot (); + if (unlikely (!c->serializer->extend (*out, num_output_glyphs + 1))) return_trace (false); + out->ppem = ppem; + out->resolution = resolution; + HBUINT32 head; + head = get_size (num_output_glyphs + 1); + + bool has_glyphs = false; + for (unsigned new_gid = 0; new_gid < num_output_glyphs; new_gid++) + { + hb_codepoint_t old_gid; + if (!c->plan->old_gid_for_new_gid (new_gid, &old_gid) || + unlikely (imageOffsetsZ[old_gid].is_null () || + imageOffsetsZ[old_gid + 1].is_null () || + imageOffsetsZ[old_gid + 1] <= imageOffsetsZ[old_gid] || + imageOffsetsZ[old_gid + 1] - imageOffsetsZ[old_gid] <= SBIXGlyph::min_size) || + (unsigned int) imageOffsetsZ[old_gid + 1] > available_len) + { + out->imageOffsetsZ[new_gid] = head; + continue; + } + has_glyphs = true; + unsigned int delta = imageOffsetsZ[old_gid + 1] - imageOffsetsZ[old_gid]; + unsigned int glyph_data_length = delta - SBIXGlyph::min_size; + if (!(this+imageOffsetsZ[old_gid]).copy (c->serializer, glyph_data_length)) + return_trace (false); + out->imageOffsetsZ[new_gid] = head; + head += delta; + } + if (has_glyphs) + out->imageOffsetsZ[num_output_glyphs] = head; + else + c->serializer->revert (snap); + return_trace (has_glyphs); + } + public: HBUINT16 ppem; /* The PPEM size for which this strike was designed. */ HBUINT16 resolution; /* The device pixel density (in PPI) for which this @@ -140,7 +204,7 @@ struct sbix { void init (hb_face_t *face) { - table = hb_sanitize_context_t().reference_table<sbix> (face); + table = hb_sanitize_context_t ().reference_table<sbix> (face); num_glyphs = face->get_num_glyphs (); } void fini () { table.destroy (); } @@ -173,7 +237,7 @@ struct sbix { unsigned count = table->strikes.len; if (unlikely (!count)) - return Null(SBIXStrike); + return Null (SBIXStrike); unsigned int requested_ppem = hb_max (font->x_ppem, font->y_ppem); if (!requested_ppem) @@ -237,7 +301,7 @@ struct sbix extents->x_bearing = x_offset; extents->y_bearing = png.IHDR.height + y_offset; extents->width = png.IHDR.width; - extents->height = -png.IHDR.height; + extents->height = -1 * png.IHDR.height; /* Convert to font units. */ if (strike_ppem) @@ -275,6 +339,63 @@ struct sbix strikes.sanitize (c, this))); } + bool + add_strike (hb_subset_context_t *c, unsigned i) const + { + if (strikes[i].is_null () || c->source_blob->length < (unsigned) strikes[i]) + return false; + + return (this+strikes[i]).subset (c, c->source_blob->length - (unsigned) strikes[i]); + } + + bool serialize_strike_offsets (hb_subset_context_t *c) const + { + TRACE_SERIALIZE (this); + + auto *out = c->serializer->start_embed<LOffsetLArrayOf<SBIXStrike>> (); + if (unlikely (!out)) return_trace (false); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + + hb_vector_t<LOffsetTo<SBIXStrike>*> new_strikes; + hb_vector_t<hb_serialize_context_t::objidx_t> objidxs; + for (int i = strikes.len - 1; i >= 0; --i) + { + auto* o = out->serialize_append (c->serializer); + if (unlikely (!o)) return_trace (false); + *o = 0; + auto snap = c->serializer->snapshot (); + c->serializer->push (); + bool ret = add_strike (c, i); + if (!ret) + { + c->serializer->pop_discard (); + out->pop (); + c->serializer->revert (snap); + } + else + { + objidxs.push (c->serializer->pop_pack ()); + new_strikes.push (o); + } + } + for (unsigned int i = 0; i < new_strikes.length; ++i) + c->serializer->add_link (*new_strikes[i], objidxs[new_strikes.length - 1 - i]); + + return_trace (true); + } + + bool subset (hb_subset_context_t* c) const + { + TRACE_SUBSET (this); + + sbix *sbix_prime = c->serializer->start_embed<sbix> (); + if (unlikely (!sbix_prime)) return_trace (false); + if (unlikely (!c->serializer->embed (this->version))) return_trace (false); + if (unlikely (!c->serializer->embed (this->flags))) return_trace (false); + + return_trace (serialize_strike_offsets (c)); + } + protected: HBUINT16 version; /* Table version number — set to 1 */ HBUINT16 flags; /* Bit 0: Set to 1. Bit 1: Draw outlines. diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-color-svg-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-color-svg-table.hh index 926d61e0fa..1cc40ae53f 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-color-svg-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-color-svg-table.hh @@ -80,7 +80,7 @@ struct SVG struct accelerator_t { void init (hb_face_t *face) - { table = hb_sanitize_context_t().reference_table<SVG> (face); } + { table = hb_sanitize_context_t ().reference_table<SVG> (face); } void fini () { table.destroy (); } hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id) const diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-color.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-color.cc index 0e7203a88b..4170b71317 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-color.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-color.cc @@ -37,9 +37,6 @@ #include "hb-ot-color-sbix-table.hh" #include "hb-ot-color-svg-table.hh" -#include <stdlib.h> -#include <string.h> - /** * SECTION:hb-ot-color @@ -64,7 +61,7 @@ * * Tests whether a face includes a `CPAL` color-palette table. * - * Return value: true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 2.1.0 */ @@ -195,7 +192,7 @@ hb_ot_color_palette_get_colors (hb_face_t *face, * * Tests whether a face includes any `COLR` color layers. * - * Return value: true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 2.1.0 */ @@ -242,7 +239,7 @@ hb_ot_color_glyph_get_layers (hb_face_t *face, * * Tests whether a face includes any `SVG` glyph images. * - * Return value: true if data found, false otherwise. + * Return value: %true if data found, %false otherwise. * * Since: 2.1.0 */ @@ -280,7 +277,7 @@ hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph) * * Tests whether a face has PNG glyph images (either in `CBDT` or `sbix` tables). * - * Return value: true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 2.1.0 */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-color.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-color.h index 63ef20a1a0..c23ce4de44 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-color.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-color.h @@ -26,7 +26,7 @@ * Google Author(s): Sascha Brawer, Behdad Esfahbod */ -#ifndef HB_OT_H_IN +#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb-ot.h> instead." #endif @@ -66,6 +66,8 @@ hb_ot_color_palette_color_get_name_id (hb_face_t *face, * @HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_DARK_BACKGROUND: Flag indicating that the color * palette is appropriate to use when displaying the font on a dark background such as black. * + * Flags that describe the properties of color palette. + * * Since: 2.1.0 */ typedef enum { /*< flags >*/ @@ -95,13 +97,14 @@ hb_ot_color_has_layers (hb_face_t *face); /** * hb_ot_color_layer_t: + * @glyph: the glyph ID of the layer + * @color_index: the palette color index of the layer * * Pairs of glyph and color index. * * Since: 2.1.0 **/ -typedef struct hb_ot_color_layer_t -{ +typedef struct hb_ot_color_layer_t { hb_codepoint_t glyph; unsigned int color_index; } hb_ot_color_layer_t; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-deprecated.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-deprecated.h index bc72f8a701..ce6b6fef11 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-deprecated.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-deprecated.h @@ -24,7 +24,7 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_OT_H_IN +#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb-ot.h> instead." #endif @@ -41,6 +41,13 @@ HB_BEGIN_DECLS /* https://github.com/harfbuzz/harfbuzz/issues/1734 */ +/** + * HB_MATH_GLYPH_PART_FLAG_EXTENDER: + * + * Use #HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER instead. + * + * Deprecated: 2.5.1 + */ #define HB_MATH_GLYPH_PART_FLAG_EXTENDER HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER @@ -71,6 +78,8 @@ hb_ot_tag_from_language (hb_language_t language); /** * HB_OT_VAR_NO_AXIS_INDEX: * + * Do not use. + * * Since: 1.4.2 * Deprecated: 2.2.0 */ @@ -78,12 +87,18 @@ hb_ot_tag_from_language (hb_language_t language); /** * hb_ot_var_axis_t: + * @tag: axis tag + * @name_id: axis name identifier + * @min_value: minimum value of the axis + * @default_value: default value of the axis + * @max_value: maximum value of the axis + * + * Use #hb_ot_var_axis_info_t instead. * * Since: 1.4.2 * Deprecated: 2.2.0 */ -typedef struct hb_ot_var_axis_t -{ +typedef struct hb_ot_var_axis_t { hb_tag_t tag; hb_ot_name_id_t name_id; float min_value; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-face-table-list.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-face-table-list.hh index 6fa9baf135..367e143fdf 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-face-table-list.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-face-table-list.hh @@ -53,13 +53,13 @@ HB_OT_ACCELERATOR (OT, cmap) HB_OT_TABLE (OT, hhea) HB_OT_ACCELERATOR (OT, hmtx) HB_OT_TABLE (OT, OS2) -#if !defined(HB_NO_OT_FONT_GLYPH_NAMES) || !defined(HB_NO_METRICS) +#if !defined(HB_NO_OT_FONT_GLYPH_NAMES) || !defined(HB_NO_METRICS) || !defined(HB_NO_STYLE) HB_OT_ACCELERATOR (OT, post) #endif #ifndef HB_NO_NAME HB_OT_ACCELERATOR (OT, name) #endif -#ifndef HB_NO_STAT +#ifndef HB_NO_STYLE HB_OT_TABLE (OT, STAT) #endif #ifndef HB_NO_META @@ -113,7 +113,6 @@ HB_OT_TABLE (AAT, mort) HB_OT_TABLE (AAT, kerx) HB_OT_TABLE (AAT, ankr) HB_OT_TABLE (AAT, trak) -HB_OT_TABLE (AAT, lcar) HB_OT_TABLE (AAT, ltag) HB_OT_TABLE (AAT, feat) // HB_OT_TABLE (AAT, opbd) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc index 96f94e4a9e..fae7b5b65a 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc @@ -183,22 +183,21 @@ hb_ot_get_glyph_extents (hb_font_t *font, void *user_data HB_UNUSED) { const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; - bool ret = false; #if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR) - if (!ret) ret = ot_face->sbix->get_extents (font, glyph, extents); + if (ot_face->sbix->get_extents (font, glyph, extents)) return true; #endif - if (!ret) ret = ot_face->glyf->get_extents (font, glyph, extents); + if (ot_face->glyf->get_extents (font, glyph, extents)) return true; #ifndef HB_NO_OT_FONT_CFF - if (!ret) ret = ot_face->cff1->get_extents (font, glyph, extents); - if (!ret) ret = ot_face->cff2->get_extents (font, glyph, extents); + if (ot_face->cff1->get_extents (font, glyph, extents)) return true; + if (ot_face->cff2->get_extents (font, glyph, extents)) return true; #endif #if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR) - if (!ret) ret = ot_face->CBDT->get_extents (font, glyph, extents); + if (ot_face->CBDT->get_extents (font, glyph, extents)) return true; #endif // TODO Hook up side-bearings variations. - return ret; + return false; } #ifndef HB_NO_OT_FONT_GLYPH_NAMES @@ -210,7 +209,11 @@ hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED, void *user_data HB_UNUSED) { const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; - return ot_face->post->get_glyph_name (glyph, name, size); + if (ot_face->post->get_glyph_name (glyph, name, size)) return true; +#ifndef HB_NO_OT_FONT_CFF + if (ot_face->cff1->get_glyph_name (glyph, name, size)) return true; +#endif + return false; } static hb_bool_t hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED, @@ -220,7 +223,11 @@ hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED, void *user_data HB_UNUSED) { const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; - return ot_face->post->get_glyph_from_name (name, len, glyph); + if (ot_face->post->get_glyph_from_name (name, len, glyph)) return true; +#ifndef HB_NO_OT_FONT_CFF + if (ot_face->cff1->get_glyph_from_name (name, len, glyph)) return true; +#endif + return false; } #endif @@ -299,6 +306,9 @@ _hb_ot_get_font_funcs () /** * hb_ot_font_set_funcs: + * @font: #hb_font_t to work upon + * + * Sets the font functions to use when working with @font. * * Since: 0.9.28 **/ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.h index 80eaa54b1a..e7959d1ae2 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.h @@ -24,7 +24,7 @@ * Google Author(s): Behdad Esfahbod, Roozbeh Pournader */ -#ifndef HB_OT_H_IN +#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb-ot.h> instead." #endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-gasp-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-gasp-table.hh index 94fff58a15..4f291924af 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-gasp-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-gasp-table.hh @@ -48,8 +48,8 @@ struct GaspRange } public: - HBUINT16 rangeMaxPPEM; /* Upper limit of range, in PPEM */ - HBUINT16 rangeGaspBehavior; + HBUINT16 rangeMaxPPEM; /* Upper limit of range, in PPEM */ + HBUINT16 rangeGaspBehavior; /* Flags describing desired rasterizer behavior. */ public: DEFINE_SIZE_STATIC (4); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh index 571e50ea0c..5352156f02 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh @@ -34,8 +34,7 @@ #include "hb-ot-head-table.hh" #include "hb-ot-hmtx-table.hh" #include "hb-ot-var-gvar-table.hh" - -#include <float.h> +#include "hb-draw.hh" namespace OT { @@ -92,7 +91,10 @@ struct glyf static bool _add_loca_and_head (hb_subset_plan_t * plan, Iterator padded_offsets) { - unsigned max_offset = + padded_offsets | hb_reduce(hb_add, 0); + unsigned max_offset = + + padded_offsets + | hb_reduce (hb_add, 0) + ; unsigned num_offsets = padded_offsets.len () + 1; bool use_short_loca = max_offset < 0x1FFFF; unsigned entry_size = use_short_loca ? 2 : 4; @@ -105,18 +107,18 @@ struct glyf entry_size, num_offsets, max_offset, entry_size * num_offsets); if (use_short_loca) - _write_loca (padded_offsets, 1, hb_array ((HBUINT16*) loca_prime_data, num_offsets)); + _write_loca (padded_offsets, 1, hb_array ((HBUINT16 *) loca_prime_data, num_offsets)); else - _write_loca (padded_offsets, 0, hb_array ((HBUINT32*) loca_prime_data, num_offsets)); + _write_loca (padded_offsets, 0, hb_array ((HBUINT32 *) loca_prime_data, num_offsets)); - hb_blob_t * loca_blob = hb_blob_create (loca_prime_data, - entry_size * num_offsets, - HB_MEMORY_MODE_WRITABLE, - loca_prime_data, - free); + hb_blob_t *loca_blob = hb_blob_create (loca_prime_data, + entry_size * num_offsets, + HB_MEMORY_MODE_WRITABLE, + loca_prime_data, + free); bool result = plan->add_table (HB_OT_TAG_loca, loca_blob) - && _add_head_and_set_loca_version (plan, use_short_loca); + && _add_head_and_set_loca_version (plan, use_short_loca); hb_blob_destroy (loca_blob); return result; @@ -148,7 +150,19 @@ struct glyf const hb_subset_plan_t *plan) { TRACE_SERIALIZE (this); + unsigned init_len = c->length (); for (const auto &_ : it) _.serialize (c, plan); + + /* As a special case when all glyph in the font are empty, add a zero byte + * to the table, so that OTS doesn’t reject it, and to make the table work + * on Windows as well. + * See https://github.com/khaledhosny/ots/issues/52 */ + if (init_len == c->length ()) + { + HBUINT8 empty_byte; + empty_byte = 0; + c->copy (empty_byte); + } return_trace (true); } @@ -172,7 +186,7 @@ struct glyf | hb_map (&SubsetGlyph::padded_size) ; - if (c->serializer->in_error ()) return_trace (false); + if (unlikely (c->serializer->in_error ())) return_trace (false); return_trace (c->serializer->check_success (_add_loca_and_head (c->plan, padded_offsets))); } @@ -227,22 +241,24 @@ struct glyf struct CompositeGlyphChain { + protected: enum composite_glyph_flag_t { - ARG_1_AND_2_ARE_WORDS = 0x0001, - ARGS_ARE_XY_VALUES = 0x0002, - ROUND_XY_TO_GRID = 0x0004, - WE_HAVE_A_SCALE = 0x0008, - MORE_COMPONENTS = 0x0020, - WE_HAVE_AN_X_AND_Y_SCALE = 0x0040, - WE_HAVE_A_TWO_BY_TWO = 0x0080, - WE_HAVE_INSTRUCTIONS = 0x0100, - USE_MY_METRICS = 0x0200, - OVERLAP_COMPOUND = 0x0400, - SCALED_COMPONENT_OFFSET = 0x0800, - UNSCALED_COMPONENT_OFFSET = 0x1000 + ARG_1_AND_2_ARE_WORDS = 0x0001, + ARGS_ARE_XY_VALUES = 0x0002, + ROUND_XY_TO_GRID = 0x0004, + WE_HAVE_A_SCALE = 0x0008, + MORE_COMPONENTS = 0x0020, + WE_HAVE_AN_X_AND_Y_SCALE = 0x0040, + WE_HAVE_A_TWO_BY_TWO = 0x0080, + WE_HAVE_INSTRUCTIONS = 0x0100, + USE_MY_METRICS = 0x0200, + OVERLAP_COMPOUND = 0x0400, + SCALED_COMPONENT_OFFSET = 0x0800, + UNSCALED_COMPONENT_OFFSET = 0x1000 }; + public: unsigned int get_size () const { unsigned int size = min_size; @@ -261,6 +277,13 @@ struct glyf return size; } + void set_glyph_index (hb_codepoint_t new_gid) { glyphIndex = new_gid; } + hb_codepoint_t get_glyph_index () const { return glyphIndex; } + + void drop_instructions_flag () { flags = (uint16_t) flags & ~WE_HAVE_INSTRUCTIONS; } + bool has_instructions () const { return flags & WE_HAVE_INSTRUCTIONS; } + + bool has_more () const { return flags & MORE_COMPONENTS; } bool is_use_my_metrics () const { return flags & USE_MY_METRICS; } bool is_anchored () const { return !(flags & ARGS_ARE_XY_VALUES); } void get_anchor_points (unsigned int &point1, unsigned int &point2) const @@ -349,7 +372,7 @@ struct glyf return tx || ty; } - public: + protected: HBUINT16 flags; HBGlyphID glyphIndex; public: @@ -361,27 +384,27 @@ struct glyf typedef const CompositeGlyphChain *__item_t__; composite_iter_t (hb_bytes_t glyph_, __item_t__ current_) : glyph (glyph_), current (current_) - { if (!in_range (current)) current = nullptr; } + { if (!check_range (current)) current = nullptr; } composite_iter_t () : glyph (hb_bytes_t ()), current (nullptr) {} const CompositeGlyphChain &__item__ () const { return *current; } bool __more__ () const { return current; } void __next__ () { - if (!(current->flags & CompositeGlyphChain::MORE_COMPONENTS)) { current = nullptr; return; } + if (!current->has_more ()) { current = nullptr; return; } const CompositeGlyphChain *possible = &StructAfter<CompositeGlyphChain, CompositeGlyphChain> (*current); - if (!in_range (possible)) { current = nullptr; return; } + if (!check_range (possible)) { current = nullptr; return; } current = possible; } bool operator != (const composite_iter_t& o) const { return glyph != o.glyph || current != o.current; } - bool in_range (const CompositeGlyphChain *composite) const + bool check_range (const CompositeGlyphChain *composite) const { - return glyph.in_range (composite, CompositeGlyphChain::min_size) - && glyph.in_range (composite, composite->get_size ()); + return glyph.check_range (composite, CompositeGlyphChain::min_size) + && glyph.check_range (composite, composite->get_size ()); } private: @@ -389,18 +412,42 @@ struct glyf __item_t__ current; }; + enum phantom_point_index_t + { + PHANTOM_LEFT = 0, + PHANTOM_RIGHT = 1, + PHANTOM_TOP = 2, + PHANTOM_BOTTOM = 3, + PHANTOM_COUNT = 4 + }; + + struct accelerator_t; + struct Glyph { + enum simple_glyph_flag_t + { + FLAG_ON_CURVE = 0x01, + FLAG_X_SHORT = 0x02, + FLAG_Y_SHORT = 0x04, + FLAG_REPEAT = 0x08, + FLAG_X_SAME = 0x10, + FLAG_Y_SAME = 0x20, + FLAG_RESERVED1 = 0x40, + FLAG_RESERVED2 = 0x80 + }; + private: struct GlyphHeader { bool has_data () const { return numberOfContours; } - bool get_extents (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const + bool get_extents (hb_font_t *font, const accelerator_t &glyf_accelerator, + hb_codepoint_t gid, hb_glyph_extents_t *extents) const { /* Undocumented rasterizer behavior: shift glyph to the left by (lsb - xMin), i.e., xMin = lsb */ /* extents->x_bearing = hb_min (glyph_header.xMin, glyph_header.xMax); */ - extents->x_bearing = font->em_scale_x (font->face->table.hmtx->get_side_bearing (gid)); + extents->x_bearing = font->em_scale_x (glyf_accelerator.hmtx->get_side_bearing (gid)); extents->y_bearing = font->em_scale_y (hb_max (yMin, yMax)); extents->width = font->em_scale_x (hb_max (xMin, xMax) - hb_min (xMin, xMax)); extents->height = font->em_scale_y (hb_min (yMin, yMax) - hb_max (yMin, yMax)); @@ -445,18 +492,6 @@ struct glyf return instructionLength; } - enum simple_glyph_flag_t - { - FLAG_ON_CURVE = 0x01, - FLAG_X_SHORT = 0x02, - FLAG_Y_SHORT = 0x04, - FLAG_REPEAT = 0x08, - FLAG_X_SAME = 0x10, - FLAG_Y_SAME = 0x20, - FLAG_RESERVED1 = 0x40, - FLAG_RESERVED2 = 0x80 - }; - const Glyph trim_padding () const { /* based on FontTools _g_l_y_f.py::trim */ @@ -470,7 +505,6 @@ struct glyf unsigned int num_instructions = StructAtOffset<HBUINT16> (glyph, 0); glyph += 2 + num_instructions; - if (unlikely (glyph + 2 >= glyph_end)) return Glyph (); unsigned int coord_bytes = 0; unsigned int coords_with_flags = 0; @@ -519,70 +553,53 @@ struct glyf dest_end = bytes.sub_array (glyph_length, bytes.length - glyph_length); } - struct x_setter_t - { - void set (contour_point_t &point, float v) const { point.x = v; } - bool is_short (uint8_t flag) const { return flag & FLAG_X_SHORT; } - bool is_same (uint8_t flag) const { return flag & FLAG_X_SAME; } - }; - - struct y_setter_t - { - void set (contour_point_t &point, float v) const { point.y = v; } - bool is_short (uint8_t flag) const { return flag & FLAG_Y_SHORT; } - bool is_same (uint8_t flag) const { return flag & FLAG_Y_SAME; } - }; - - template <typename T> static bool read_points (const HBUINT8 *&p /* IN/OUT */, contour_point_vector_t &points_ /* IN/OUT */, - const hb_bytes_t &bytes) + const hb_bytes_t &bytes, + void (* setter) (contour_point_t &_, float v), + const simple_glyph_flag_t short_flag, + const simple_glyph_flag_t same_flag) { - T coord_setter; float v = 0; - for (unsigned int i = 0; i < points_.length - PHANTOM_COUNT; i++) + for (unsigned i = 0; i < points_.length; i++) { uint8_t flag = points_[i].flag; - if (coord_setter.is_short (flag)) + if (flag & short_flag) { - if (unlikely (!bytes.in_range (p))) return false; - if (coord_setter.is_same (flag)) + if (unlikely (!bytes.check_range (p))) return false; + if (flag & same_flag) v += *p++; else v -= *p++; } else { - if (!coord_setter.is_same (flag)) + if (!(flag & same_flag)) { - if (unlikely (!bytes.in_range ((const HBUINT16 *) p))) return false; + if (unlikely (!bytes.check_range ((const HBUINT16 *) p))) return false; v += *(const HBINT16 *) p; p += HBINT16::static_size; } } - coord_setter.set (points_[i], v); + setter (points_[i], v); } return true; } bool get_contour_points (contour_point_vector_t &points_ /* OUT */, - hb_vector_t<unsigned int> &end_points_ /* OUT */, - const bool phantom_only=false) const + bool phantom_only = false) const { const HBUINT16 *endPtsOfContours = &StructAfter<HBUINT16> (header); int num_contours = header.numberOfContours; - if (unlikely (!bytes.in_range (&endPtsOfContours[num_contours + 1]))) return false; + if (unlikely (!bytes.check_range (&endPtsOfContours[num_contours + 1]))) return false; unsigned int num_points = endPtsOfContours[num_contours - 1] + 1; - points_.resize (num_points + PHANTOM_COUNT); + points_.resize (num_points); for (unsigned int i = 0; i < points_.length; i++) points_[i].init (); if (phantom_only) return true; - /* Read simple glyph points if !phantom_only */ - end_points_.resize (num_contours); - for (int i = 0; i < num_contours; i++) - end_points_[i] = endPtsOfContours[i]; + points_[endPtsOfContours[i]].is_end_point = true; /* Skip instructions */ const HBUINT8 *p = &StructAtOffset<HBUINT8> (&endPtsOfContours[num_contours + 1], @@ -591,12 +608,12 @@ struct glyf /* Read flags */ for (unsigned int i = 0; i < num_points; i++) { - if (unlikely (!bytes.in_range (p))) return false; + if (unlikely (!bytes.check_range (p))) return false; uint8_t flag = *p++; points_[i].flag = flag; if (flag & FLAG_REPEAT) { - if (unlikely (!bytes.in_range (p))) return false; + if (unlikely (!bytes.check_range (p))) return false; unsigned int repeat_count = *p++; while ((repeat_count-- > 0) && (++i < num_points)) points_[i].flag = flag; @@ -604,8 +621,10 @@ struct glyf } /* Read x & y coordinates */ - return (read_points<x_setter_t> (p, points_, bytes) && - read_points<y_setter_t> (p, points_, bytes)); + return read_points (p, points_, bytes, [] (contour_point_t &p, float v) { p.x = v; }, + FLAG_X_SHORT, FLAG_X_SAME) + && read_points (p, points_, bytes, [] (contour_point_t &p, float v) { p.y = v; }, + FLAG_Y_SHORT, FLAG_Y_SAME); } }; @@ -628,7 +647,7 @@ struct glyf last = &item; if (unlikely (!last)) return 0; - if ((uint16_t) last->flags & CompositeGlyphChain::WE_HAVE_INSTRUCTIONS) + if (last->has_instructions ()) start = (char *) last - &bytes + last->get_size (); if (unlikely (start > end)) return 0; return end - start; @@ -638,40 +657,19 @@ struct glyf * If removing hints it falls out of that. */ const Glyph trim_padding () const { return Glyph (bytes); } - /* remove WE_HAVE_INSTRUCTIONS flag from composite glyph */ void drop_hints () { for (const auto &_ : get_iterator ()) - *const_cast<OT::HBUINT16 *> (&_.flags) = (uint16_t) _.flags & ~OT::glyf::CompositeGlyphChain::WE_HAVE_INSTRUCTIONS; + const_cast<CompositeGlyphChain &> (_).drop_instructions_flag (); } /* Chop instructions off the end */ void drop_hints_bytes (hb_bytes_t &dest_start) const { dest_start = bytes.sub_array (0, bytes.length - instructions_length (bytes)); } - - bool get_contour_points (contour_point_vector_t &points_ /* OUT */, - hb_vector_t<unsigned int> &end_points_ /* OUT */, - const bool phantom_only=false) const - { - /* add one pseudo point for each component in composite glyph */ - unsigned int num_points = hb_len (get_iterator ()); - points_.resize (num_points + PHANTOM_COUNT); - for (unsigned int i = 0; i < points_.length; i++) points_[i].init (); - return true; - } }; enum glyph_type_t { EMPTY, SIMPLE, COMPOSITE }; - enum phantom_point_index_t - { - PHANTOM_LEFT = 0, - PHANTOM_RIGHT = 1, - PHANTOM_TOP = 2, - PHANTOM_BOTTOM = 3, - PHANTOM_COUNT = 4 - }; - public: composite_iter_t get_composite_iterator () const { @@ -706,39 +704,130 @@ struct glyf } } - /* for a simple glyph, return contour end points, flags, along with coordinate points - * for a composite glyph, return pseudo component points - * in both cases points trailed with four phantom points + /* Note: Recursively calls itself. + * all_points includes phantom points */ - bool get_contour_points (contour_point_vector_t &points_ /* OUT */, - hb_vector_t<unsigned int> &end_points_ /* OUT */, - const bool phantom_only=false) const + bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator, + contour_point_vector_t &all_points /* OUT */, + bool phantom_only = false, + unsigned int depth = 0) const { + if (unlikely (depth > HB_MAX_NESTING_LEVEL)) return false; + contour_point_vector_t points; + switch (type) { - case COMPOSITE: return CompositeGlyph (*header, bytes).get_contour_points (points_, end_points_, phantom_only); - case SIMPLE: return SimpleGlyph (*header, bytes).get_contour_points (points_, end_points_, phantom_only); + case COMPOSITE: + { + /* pseudo component points for each component in composite glyph */ + unsigned num_points = hb_len (CompositeGlyph (*header, bytes).get_iterator ()); + if (unlikely (!points.resize (num_points))) return false; + for (unsigned i = 0; i < points.length; i++) + points[i].init (); + break; + } + case SIMPLE: + if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points, phantom_only))) + return false; + break; + } + + /* Init phantom points */ + if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false; + hb_array_t<contour_point_t> phantoms = points.sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT); + { + for (unsigned i = 0; i < PHANTOM_COUNT; ++i) phantoms[i].init (); + int h_delta = (int) header->xMin - glyf_accelerator.hmtx->get_side_bearing (gid); + int v_orig = (int) header->yMax + glyf_accelerator.vmtx->get_side_bearing (gid); + unsigned h_adv = glyf_accelerator.hmtx->get_advance (gid); + unsigned v_adv = glyf_accelerator.vmtx->get_advance (gid); + phantoms[PHANTOM_LEFT].x = h_delta; + phantoms[PHANTOM_RIGHT].x = h_adv + h_delta; + phantoms[PHANTOM_TOP].y = v_orig; + phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv; + } + +#ifndef HB_NO_VAR + if (unlikely (!glyf_accelerator.gvar->apply_deltas_to_points (gid, font, points.as_array ()))) + return false; +#endif + + switch (type) { + case SIMPLE: + all_points.extend (points.as_array ()); + break; + case COMPOSITE: + { + unsigned int comp_index = 0; + for (auto &item : get_composite_iterator ()) + { + contour_point_vector_t comp_points; + if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_glyph_index ()) + .get_points (font, glyf_accelerator, comp_points, + phantom_only, depth + 1) + || comp_points.length < PHANTOM_COUNT)) + return false; + + /* Copy phantom points from component if USE_MY_METRICS flag set */ + if (item.is_use_my_metrics ()) + for (unsigned int i = 0; i < PHANTOM_COUNT; i++) + phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i]; + + /* Apply component transformation & translation */ + item.transform_points (comp_points); + + /* Apply translation from gvar */ + comp_points.translate (points[comp_index]); + + if (item.is_anchored ()) + { + unsigned int p1, p2; + item.get_anchor_points (p1, p2); + if (likely (p1 < all_points.length && p2 < comp_points.length)) + { + contour_point_t delta; + delta.init (all_points[p1].x - comp_points[p2].x, + all_points[p1].y - comp_points[p2].y); + + comp_points.translate (delta); + } + } + + all_points.extend (comp_points.sub_array (0, comp_points.length - PHANTOM_COUNT)); + + comp_index++; + } + + all_points.extend (phantoms); + } break; default: - /* empty glyph */ - points_.resize (PHANTOM_COUNT); - for (unsigned int i = 0; i < points_.length; i++) points_[i].init (); - return true; + all_points.extend (phantoms); + } + + if (depth == 0) /* Apply at top level */ + { + /* Undocumented rasterizer behavior: + * Shift points horizontally by the updated left side bearing + */ + contour_point_t delta; + delta.init (-phantoms[PHANTOM_LEFT].x, 0.f); + if (delta.x) all_points.translate (delta); } - } - bool is_simple_glyph () const { return type == SIMPLE; } - bool is_composite_glyph () const { return type == COMPOSITE; } + return true; + } - bool get_extents (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const + bool get_extents (hb_font_t *font, const accelerator_t &glyf_accelerator, + hb_glyph_extents_t *extents) const { if (type == EMPTY) return true; /* Empty glyph; zero extents. */ - return header->get_extents (font, gid, extents); + return header->get_extents (font, glyf_accelerator, gid, extents); } - hb_bytes_t get_bytes () const { return bytes; } - const GlyphHeader &get_header () const { return *header; } + hb_bytes_t get_bytes () const { return bytes; } - Glyph (hb_bytes_t bytes_ = hb_bytes_t ()) : - bytes (bytes_), header (bytes.as<GlyphHeader> ()) + Glyph (hb_bytes_t bytes_ = hb_bytes_t (), + hb_codepoint_t gid_ = (hb_codepoint_t) -1) : bytes (bytes_), gid (gid_), + header (bytes.as<GlyphHeader> ()) { int num_contours = header->numberOfContours; if (unlikely (num_contours == 0)) type = EMPTY; @@ -748,6 +837,7 @@ struct glyf protected: hb_bytes_t bytes; + hb_codepoint_t gid; const GlyphHeader *header; unsigned type; }; @@ -760,6 +850,11 @@ struct glyf num_glyphs = 0; loca_table = nullptr; glyf_table = nullptr; +#ifndef HB_NO_VAR + gvar = nullptr; +#endif + hmtx = nullptr; + vmtx = nullptr; face = face_; const OT::head &head = *face->table.head; if (head.indexToLocFormat > 1 || head.glyphDataFormat > 0) @@ -769,8 +864,14 @@ struct glyf loca_table = hb_sanitize_context_t ().reference_table<loca> (face); glyf_table = hb_sanitize_context_t ().reference_table<glyf> (face); +#ifndef HB_NO_VAR + gvar = face->table.gvar; +#endif + hmtx = face->table.hmtx; + vmtx = face->table.vmtx; num_glyphs = hb_max (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1; + num_glyphs = hb_min (num_glyphs, face->get_num_glyphs ()); } void fini () @@ -779,231 +880,150 @@ struct glyf glyf_table.destroy (); } - enum phantom_point_index_t - { - PHANTOM_LEFT = 0, - PHANTOM_RIGHT = 1, - PHANTOM_TOP = 2, - PHANTOM_BOTTOM = 3, - PHANTOM_COUNT = 4 - }; - protected: - - void init_phantom_points (hb_codepoint_t gid, hb_array_t<contour_point_t> &phantoms /* IN/OUT */) const - { - const Glyph &glyph = glyph_for_gid (gid); - int h_delta = (int) glyph.get_header ().xMin - face->table.hmtx->get_side_bearing (gid); - int v_orig = (int) glyph.get_header ().yMax + face->table.vmtx->get_side_bearing (gid); - unsigned int h_adv = face->table.hmtx->get_advance (gid); - unsigned int v_adv = face->table.vmtx->get_advance (gid); - - phantoms[PHANTOM_LEFT].x = h_delta; - phantoms[PHANTOM_RIGHT].x = h_adv + h_delta; - phantoms[PHANTOM_TOP].y = v_orig; - phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv; - } - - struct contour_bounds_t + template<typename T> + bool get_points (hb_font_t *font, hb_codepoint_t gid, T consumer) const { - contour_bounds_t () { min_x = min_y = FLT_MAX; max_x = max_y = -FLT_MAX; } + if (gid >= num_glyphs) return false; - void add (const contour_point_t &p) - { - min_x = hb_min (min_x, p.x); - min_y = hb_min (min_y, p.y); - max_x = hb_max (max_x, p.x); - max_y = hb_max (max_y, p.y); - } + /* Making this alloc free is not that easy + https://github.com/harfbuzz/harfbuzz/issues/2095 + mostly because of gvar handling in VF fonts, + perhaps a separate path for non-VF fonts can be considered */ + contour_point_vector_t all_points; - bool empty () const { return (min_x >= max_x) || (min_y >= max_y); } + bool phantom_only = !consumer.is_consuming_contour_points (); + if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, phantom_only))) + return false; - void get_extents (hb_font_t *font, hb_glyph_extents_t *extents) + if (consumer.is_consuming_contour_points ()) { - if (unlikely (empty ())) - { - extents->width = 0; - extents->x_bearing = 0; - extents->height = 0; - extents->y_bearing = 0; - return; - } - extents->x_bearing = font->em_scalef_x (min_x); - extents->width = font->em_scalef_x (max_x - min_x); - extents->y_bearing = font->em_scalef_y (max_y); - extents->height = font->em_scalef_y (min_y - max_y); + for (unsigned point_index = 0; point_index + 4 < all_points.length; ++point_index) + consumer.consume_point (all_points[point_index]); + consumer.points_end (); } - protected: - float min_x, min_y, max_x, max_y; - }; + /* Where to write phantoms, nullptr if not requested */ + contour_point_t *phantoms = consumer.get_phantoms_sink (); + if (phantoms) + for (unsigned i = 0; i < PHANTOM_COUNT; ++i) + phantoms[i] = all_points[all_points.length - PHANTOM_COUNT + i]; + + return true; + } #ifndef HB_NO_VAR - /* Note: Recursively calls itself. - * all_points includes phantom points - */ - bool get_points_var (hb_codepoint_t gid, - const int *coords, unsigned int coord_count, - contour_point_vector_t &all_points /* OUT */, - unsigned int depth = 0) const + struct points_aggregator_t { - if (unlikely (depth++ > HB_MAX_NESTING_LEVEL)) return false; - contour_point_vector_t points; - hb_vector_t<unsigned int> end_points; - const Glyph &glyph = glyph_for_gid (gid); - if (unlikely (!glyph.get_contour_points (points, end_points))) return false; - hb_array_t<contour_point_t> phantoms = points.sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT); - init_phantom_points (gid, phantoms); - if (unlikely (!face->table.gvar->apply_deltas_to_points (gid, coords, coord_count, points.as_array (), end_points.as_array ()))) return false; + hb_font_t *font; + hb_glyph_extents_t *extents; + contour_point_t *phantoms; - unsigned int comp_index = 0; - if (glyph.is_simple_glyph ()) - all_points.extend (points.as_array ()); - else if (glyph.is_composite_glyph ()) + struct contour_bounds_t { - for (auto &item : glyph.get_composite_iterator ()) - { - contour_point_vector_t comp_points; - if (unlikely (!get_points_var (item.glyphIndex, coords, coord_count, - comp_points, depth)) - || comp_points.length < PHANTOM_COUNT) - return false; - - /* Copy phantom points from component if USE_MY_METRICS flag set */ - if (item.is_use_my_metrics ()) - for (unsigned int i = 0; i < PHANTOM_COUNT; i++) - phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i]; + contour_bounds_t () { min_x = min_y = FLT_MAX; max_x = max_y = -FLT_MAX; } - /* Apply component transformation & translation */ - item.transform_points (comp_points); + void add (const contour_point_t &p) + { + min_x = hb_min (min_x, p.x); + min_y = hb_min (min_y, p.y); + max_x = hb_max (max_x, p.x); + max_y = hb_max (max_y, p.y); + } - /* Apply translatation from gvar */ - comp_points.translate (points[comp_index]); + bool empty () const { return (min_x >= max_x) || (min_y >= max_y); } - if (item.is_anchored ()) + void get_extents (hb_font_t *font, hb_glyph_extents_t *extents) + { + if (unlikely (empty ())) { - unsigned int p1, p2; - item.get_anchor_points (p1, p2); - if (likely (p1 < all_points.length && p2 < comp_points.length)) - { - contour_point_t delta; - delta.init (all_points[p1].x - comp_points[p2].x, - all_points[p1].y - comp_points[p2].y); - - comp_points.translate (delta); - } + extents->width = 0; + extents->x_bearing = 0; + extents->height = 0; + extents->y_bearing = 0; + return; } - - all_points.extend (comp_points.sub_array (0, comp_points.length - PHANTOM_COUNT)); - - comp_index++; + extents->x_bearing = font->em_scalef_x (min_x); + extents->width = font->em_scalef_x (max_x) - extents->x_bearing; + extents->y_bearing = font->em_scalef_y (max_y); + extents->height = font->em_scalef_y (min_y) - extents->y_bearing; } - all_points.extend (phantoms); - } - else return false; - - return true; - } - - bool get_points_bearing_applied (hb_font_t *font, hb_codepoint_t gid, contour_point_vector_t &all_points) const - { - if (unlikely (!get_points_var (gid, font->coords, font->num_coords, all_points) || - all_points.length < PHANTOM_COUNT)) return false; - - /* Undocumented rasterizer behavior: - * Shift points horizontally by the updated left side bearing - */ - contour_point_t delta; - delta.init (-all_points[all_points.length - PHANTOM_COUNT + PHANTOM_LEFT].x, 0.f); - if (delta.x) all_points.translate (delta); - return true; - } + protected: + float min_x, min_y, max_x, max_y; + } bounds; - protected: - - bool get_var_extents_and_phantoms (hb_font_t *font, hb_codepoint_t gid, - hb_glyph_extents_t *extents=nullptr /* OUT */, - contour_point_vector_t *phantoms=nullptr /* OUT */) const - { - contour_point_vector_t all_points; - if (!unlikely (get_points_bearing_applied (font, gid, all_points))) return false; - if (extents) + points_aggregator_t (hb_font_t *font_, hb_glyph_extents_t *extents_, contour_point_t *phantoms_) { - contour_bounds_t bounds; - for (unsigned int i = 0; i + PHANTOM_COUNT < all_points.length; i++) - bounds.add (all_points[i]); - bounds.get_extents (font, extents); + font = font_; + extents = extents_; + phantoms = phantoms_; + if (extents) bounds = contour_bounds_t (); } - if (phantoms) - for (unsigned int i = 0; i < PHANTOM_COUNT; i++) - (*phantoms)[i] = all_points[all_points.length - PHANTOM_COUNT + i]; - return true; - } - bool get_var_metrics (hb_font_t *font, hb_codepoint_t gid, - contour_point_vector_t &phantoms) const - { return get_var_extents_and_phantoms (font, gid, nullptr, &phantoms); } + void consume_point (const contour_point_t &point) { bounds.add (point); } + void points_end () { bounds.get_extents (font, extents); } - bool get_extents_var (hb_font_t *font, hb_codepoint_t gid, - hb_glyph_extents_t *extents) const - { return get_var_extents_and_phantoms (font, gid, extents); } -#endif + bool is_consuming_contour_points () { return extents; } + contour_point_t *get_phantoms_sink () { return phantoms; } + }; public: -#ifndef HB_NO_VAR - unsigned int get_advance_var (hb_font_t *font, hb_codepoint_t gid, - bool is_vertical) const + unsigned + get_advance_var (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const { + if (unlikely (gid >= num_glyphs)) return 0; + bool success = false; - contour_point_vector_t phantoms; - phantoms.resize (PHANTOM_COUNT); - if (likely (font->num_coords == face->table.gvar->get_axis_count ())) - success = get_var_metrics (font, gid, phantoms); + contour_point_t phantoms[PHANTOM_COUNT]; + if (likely (font->num_coords == gvar->get_axis_count ())) + success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms)); if (unlikely (!success)) - return is_vertical ? face->table.vmtx->get_advance (gid) : face->table.hmtx->get_advance (gid); + return is_vertical ? vmtx->get_advance (gid) : hmtx->get_advance (gid); - if (is_vertical) - return roundf (phantoms[PHANTOM_TOP].y - phantoms[PHANTOM_BOTTOM].y); - else - return roundf (phantoms[PHANTOM_RIGHT].x - phantoms[PHANTOM_LEFT].x); + float result = is_vertical + ? phantoms[PHANTOM_TOP].y - phantoms[PHANTOM_BOTTOM].y + : phantoms[PHANTOM_RIGHT].x - phantoms[PHANTOM_LEFT].x; + return hb_clamp (roundf (result), 0.f, (float) UINT_MAX / 2); } int get_side_bearing_var (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const { + if (unlikely (gid >= num_glyphs)) return 0; + hb_glyph_extents_t extents; - contour_point_vector_t phantoms; - phantoms.resize (PHANTOM_COUNT); - if (unlikely (!get_var_extents_and_phantoms (font, gid, &extents, &phantoms))) - return is_vertical ? face->table.vmtx->get_side_bearing (gid) : face->table.hmtx->get_side_bearing (gid); + contour_point_t phantoms[PHANTOM_COUNT]; + if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms)))) + return is_vertical ? vmtx->get_side_bearing (gid) : hmtx->get_side_bearing (gid); - return is_vertical ? ceil (phantoms[PHANTOM_TOP].y) - extents.y_bearing : floor (phantoms[PHANTOM_LEFT].x); + return is_vertical + ? ceilf (phantoms[PHANTOM_TOP].y) - extents.y_bearing + : floorf (phantoms[PHANTOM_LEFT].x); } #endif + public: bool get_extents (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const { -#ifndef HB_NO_VAR - unsigned int coord_count; - const int *coords = hb_font_get_var_coords_normalized (font, &coord_count); - if (coords && coord_count > 0 && coord_count == face->table.gvar->get_axis_count ()) - return get_extents_var (font, gid, extents); -#endif - if (unlikely (gid >= num_glyphs)) return false; - return glyph_for_gid (gid).get_extents (font, gid, extents); +#ifndef HB_NO_VAR + if (font->num_coords && font->num_coords == gvar->get_axis_count ()) + return get_points (font, gid, points_aggregator_t (font, extents, nullptr)); +#endif + return glyph_for_gid (gid).get_extents (font, *this, extents); } const Glyph glyph_for_gid (hb_codepoint_t gid, bool needs_padding_removal = false) const { - unsigned int start_offset, end_offset; if (unlikely (gid >= num_glyphs)) return Glyph (); + unsigned int start_offset, end_offset; + if (short_offset) { const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataZ.arrayZ; @@ -1021,7 +1041,7 @@ struct glyf return Glyph (); Glyph glyph (hb_bytes_t ((const char *) this->glyf_table + start_offset, - end_offset - start_offset)); + end_offset - start_offset), gid); return needs_padding_removal ? glyph.trim_padding () : glyph; } @@ -1036,9 +1056,136 @@ struct glyf gids_to_retain->add (gid); for (auto &item : glyph_for_gid (gid).get_composite_iterator ()) - add_gid_and_children (item.glyphIndex, gids_to_retain, depth); + add_gid_and_children (item.get_glyph_index (), gids_to_retain, depth); } +#ifdef HB_EXPERIMENTAL_API + struct path_builder_t + { + hb_font_t *font; + draw_helper_t *draw_helper; + + struct optional_point_t + { + optional_point_t () { has_data = false; } + optional_point_t (float x_, float y_) { x = x_; y = y_; has_data = true; } + + bool has_data; + float x; + float y; + + optional_point_t lerp (optional_point_t p, float t) + { return optional_point_t (x + t * (p.x - x), y + t * (p.y - y)); } + } first_oncurve, first_offcurve, last_offcurve; + + path_builder_t (hb_font_t *font_, draw_helper_t &draw_helper_) + { + font = font_; + draw_helper = &draw_helper_; + first_oncurve = first_offcurve = last_offcurve = optional_point_t (); + } + + /* based on https://github.com/RazrFalcon/ttf-parser/blob/4f32821/src/glyf.rs#L287 + See also: + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM01/Chap1.html + * https://stackoverflow.com/a/20772557 */ + void consume_point (const contour_point_t &point) + { + /* Skip empty contours */ + if (unlikely (point.is_end_point && !first_oncurve.has_data && !first_offcurve.has_data)) + return; + + bool is_on_curve = point.flag & Glyph::FLAG_ON_CURVE; + optional_point_t p (point.x, point.y); + if (!first_oncurve.has_data) + { + if (is_on_curve) + { + first_oncurve = p; + draw_helper->move_to (font->em_scalef_x (p.x), font->em_scalef_y (p.y)); + } + else + { + if (first_offcurve.has_data) + { + optional_point_t mid = first_offcurve.lerp (p, .5f); + first_oncurve = mid; + last_offcurve = p; + draw_helper->move_to (font->em_scalef_x (mid.x), font->em_scalef_y (mid.y)); + } + else + first_offcurve = p; + } + } + else + { + if (last_offcurve.has_data) + { + if (is_on_curve) + { + draw_helper->quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y), + font->em_scalef_x (p.x), font->em_scalef_y (p.y)); + last_offcurve = optional_point_t (); + } + else + { + optional_point_t mid = last_offcurve.lerp (p, .5f); + draw_helper->quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y), + font->em_scalef_x (mid.x), font->em_scalef_y (mid.y)); + last_offcurve = p; + } + } + else + { + if (is_on_curve) + draw_helper->line_to (font->em_scalef_x (p.x), font->em_scalef_y (p.y)); + else + last_offcurve = p; + } + } + + if (point.is_end_point) + { + if (first_offcurve.has_data && last_offcurve.has_data) + { + optional_point_t mid = last_offcurve.lerp (first_offcurve, .5f); + draw_helper->quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y), + font->em_scalef_x (mid.x), font->em_scalef_y (mid.y)); + last_offcurve = optional_point_t (); + /* now check the rest */ + } + + if (first_offcurve.has_data && first_oncurve.has_data) + draw_helper->quadratic_to (font->em_scalef_x (first_offcurve.x), font->em_scalef_y (first_offcurve.y), + font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y)); + else if (last_offcurve.has_data && first_oncurve.has_data) + draw_helper->quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y), + font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y)); + else if (first_oncurve.has_data) + draw_helper->line_to (font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y)); + + /* Getting ready for the next contour */ + first_oncurve = first_offcurve = last_offcurve = optional_point_t (); + draw_helper->end_path (); + } + } + void points_end () {} + + bool is_consuming_contour_points () { return true; } + contour_point_t *get_phantoms_sink () { return nullptr; } + }; + + bool + get_path (hb_font_t *font, hb_codepoint_t gid, draw_helper_t &draw_helper) const + { return get_points (font, gid, path_builder_t (font, draw_helper)); } +#endif + +#ifndef HB_NO_VAR + const gvar_accelerator_t *gvar; +#endif + const hmtx_accelerator_t *hmtx; + const vmtx_accelerator_t *vmtx; + private: bool short_offset; unsigned int num_glyphs; @@ -1063,7 +1210,7 @@ struct glyf hb_bytes_t dest_glyph = dest_start.copy (c); dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + dest_end.copy (c).length); unsigned int pad_length = padding (); - DEBUG_MSG (SUBSET, nullptr, "serialize %d byte glyph, width %d pad %d", dest_glyph.length, dest_glyph.length + pad_length, pad_length); + DEBUG_MSG (SUBSET, nullptr, "serialize %d byte glyph, width %d pad %d", dest_glyph.length, dest_glyph.length + pad_length, pad_length); HBUINT8 pad; pad = 0; @@ -1073,14 +1220,14 @@ struct glyf pad_length--; } - if (!unlikely (dest_glyph.length)) return_trace (true); + if (unlikely (!dest_glyph.length)) return_trace (true); /* update components gids */ for (auto &_ : Glyph (dest_glyph).get_composite_iterator ()) { hb_codepoint_t new_gid; - if (plan->new_gid_for_old_gid (_.glyphIndex, &new_gid)) - ((OT::glyf::CompositeGlyphChain *) &_)->glyphIndex = new_gid; + if (plan->new_gid_for_old_gid (_.get_glyph_index (), &new_gid)) + const_cast<CompositeGlyphChain &> (_).set_glyph_index (new_gid); } if (plan->drop_hints) Glyph (dest_glyph).drop_hints (); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-hdmx-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-hdmx-table.hh index 96c1d1f634..c9c391bad5 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hdmx-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hdmx-table.hh @@ -107,11 +107,8 @@ struct hdmx this->numRecords = it.len (); this->sizeDeviceRecord = DeviceRecord::get_size (it ? (*it).second.len () : 0); - + it - | hb_apply ([c] (const hb_item_type<Iterator>& _) { - c->start_embed<DeviceRecord> ()->serialize (c, _.first, _.second); - }) - ; + for (const hb_item_type<Iterator>& _ : +it) + c->start_embed<DeviceRecord> ()->serialize (c, _.first, _.second); return_trace (c->successful); } @@ -134,10 +131,10 @@ struct hdmx auto row = + hb_range (c->plan->num_output_glyphs ()) | hb_map (c->plan->reverse_glyph_map) - | hb_map ([=] (hb_codepoint_t _) + | hb_map ([this, c, device_record] (hb_codepoint_t _) { if (c->plan->is_empty_glyph (_)) - return Null(HBUINT8); + return Null (HBUINT8); return device_record->widthsZ.as_array (get_num_glyphs ()) [_]; }) ; @@ -164,10 +161,12 @@ struct hdmx } protected: - HBUINT16 version; /* Table version number (0) */ - HBUINT16 numRecords; /* Number of device records. */ - HBUINT32 sizeDeviceRecord; /* Size of a device record, 32-bit aligned. */ - DeviceRecord firstDeviceRecord; /* Array of device records. */ + HBUINT16 version; /* Table version number (0) */ + HBUINT16 numRecords; /* Number of device records. */ + HBUINT32 sizeDeviceRecord; + /* Size of a device record, 32-bit aligned. */ + DeviceRecord firstDeviceRecord; + /* Array of device records. */ public: DEFINE_SIZE_MIN (8); }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh index 3c0bb3d6dd..ac588e3af6 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh @@ -43,7 +43,7 @@ namespace OT { struct head { - friend struct OffsetTable; + friend struct OpenTypeOffsetTable; static constexpr hb_tag_t tableTag = HB_OT_TAG_head; @@ -54,6 +54,18 @@ struct head return 16 <= upem && upem <= 16384 ? upem : 1000; } + bool serialize (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); + return_trace ((bool) c->embed (this)); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + return_trace (serialize (c->serializer)); + } + enum mac_style_flag_t { BOLD = 1u<<0, ITALIC = 1u<<1, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh index 778b6c5132..d9c9bd3537 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh @@ -54,35 +54,38 @@ struct _hea } public: - FixedVersion<>version; /* 0x00010000u for version 1.0. */ - FWORD ascender; /* Typographic ascent. */ - FWORD descender; /* Typographic descent. */ - FWORD lineGap; /* Typographic line gap. */ - UFWORD advanceMax; /* Maximum advance width/height value in - * metrics table. */ - FWORD minLeadingBearing; /* Minimum left/top sidebearing value in - * metrics table. */ - FWORD minTrailingBearing; /* Minimum right/bottom sidebearing value; - * calculated as Min(aw - lsb - - * (xMax - xMin)) for horizontal. */ - FWORD maxExtent; /* horizontal: Max(lsb + (xMax - xMin)), - * vertical: minLeadingBearing+(yMax-yMin). */ - HBINT16 caretSlopeRise; /* Used to calculate the slope of the - * cursor (rise/run); 1 for vertical caret, - * 0 for horizontal.*/ - HBINT16 caretSlopeRun; /* 0 for vertical caret, 1 for horizontal. */ - HBINT16 caretOffset; /* The amount by which a slanted - * highlight on a glyph needs - * to be shifted to produce the - * best appearance. Set to 0 for - * non-slanted fonts. */ - HBINT16 reserved1; /* Set to 0. */ - HBINT16 reserved2; /* Set to 0. */ - HBINT16 reserved3; /* Set to 0. */ - HBINT16 reserved4; /* Set to 0. */ - HBINT16 metricDataFormat; /* 0 for current format. */ - HBUINT16 numberOfLongMetrics; /* Number of LongMetric entries in metric - * table. */ + FixedVersion<>version; /* 0x00010000u for version 1.0. */ + FWORD ascender; /* Typographic ascent. */ + FWORD descender; /* Typographic descent. */ + FWORD lineGap; /* Typographic line gap. */ + UFWORD advanceMax; /* Maximum advance width/height value in + * metrics table. */ + FWORD minLeadingBearing; + /* Minimum left/top sidebearing value in + * metrics table. */ + FWORD minTrailingBearing; + /* Minimum right/bottom sidebearing value; + * calculated as Min(aw - lsb - + * (xMax - xMin)) for horizontal. */ + FWORD maxExtent; /* horizontal: Max(lsb + (xMax - xMin)), + * vertical: minLeadingBearing+(yMax-yMin). */ + HBINT16 caretSlopeRise; /* Used to calculate the slope of the + * cursor (rise/run); 1 for vertical caret, + * 0 for horizontal.*/ + HBINT16 caretSlopeRun; /* 0 for vertical caret, 1 for horizontal. */ + HBINT16 caretOffset; /* The amount by which a slanted + * highlight on a glyph needs + * to be shifted to produce the + * best appearance. Set to 0 for + * non-slanted fonts. */ + HBINT16 reserved1; /* Set to 0. */ + HBINT16 reserved2; /* Set to 0. */ + HBINT16 reserved3; /* Set to 0. */ + HBINT16 reserved4; /* Set to 0. */ + HBINT16 metricDataFormat;/* 0 for current format. */ + HBUINT16 numberOfLongMetrics; + /* Number of LongMetric entries in metric + * table. */ public: DEFINE_SIZE_STATIC (36); }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh index e20b372622..d06c0fa4a4 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh @@ -101,25 +101,23 @@ struct hmtxvmtx unsigned num_advances) { unsigned idx = 0; - + it - | hb_apply ([c, &idx, num_advances] (const hb_item_type<Iterator>& _) - { - if (idx < num_advances) - { - LongMetric lm; - lm.advance = _.first; - lm.sb = _.second; - if (unlikely (!c->embed<LongMetric> (&lm))) return; - } - else - { - FWORD *sb = c->allocate_size<FWORD> (FWORD::static_size); - if (unlikely (!sb)) return; - *sb = _.second; - } - idx++; - }) - ; + for (auto _ : it) + { + if (idx < num_advances) + { + LongMetric lm; + lm.advance = _.first; + lm.sb = _.second; + if (unlikely (!c->embed<LongMetric> (&lm))) return; + } + else + { + FWORD *sb = c->allocate_size<FWORD> (FWORD::static_size); + if (unlikely (!sb)) return; + *sb = _.second; + } + idx++; + } } bool subset (hb_subset_context_t *c) const @@ -169,7 +167,7 @@ struct hmtxvmtx num_advances = T::is_horizontal ? face->table.hhea->numberOfLongMetrics : face->table.vhea->numberOfLongMetrics; - table = hb_sanitize_context_t().reference_table<hmtxvmtx> (face, T::tableTag); + table = hb_sanitize_context_t ().reference_table<hmtxvmtx> (face, T::tableTag); /* Cap num_metrics() and num_advances() based on table length. */ unsigned int len = table.get_length (); @@ -186,7 +184,7 @@ struct hmtxvmtx table = hb_blob_get_empty (); } - var_table = hb_sanitize_context_t().reference_table<HVARVVAR> (face, T::variationsTag); + var_table = hb_sanitize_context_t ().reference_table<HVARVVAR> (face, T::variationsTag); } void fini () @@ -216,7 +214,7 @@ struct hmtxvmtx return side_bearing; if (var_table.get_length ()) - return side_bearing + var_table->get_side_bearing_var (glyph, font->coords, font->num_coords); // TODO Optimize?! + return side_bearing + var_table->get_side_bearing_var (glyph, font->coords, font->num_coords); // TODO Optimize?! return _glyf_get_side_bearing_var (font, glyph, T::tableTag == HB_OT_TAG_vmtx); #else @@ -250,7 +248,7 @@ struct hmtxvmtx return advance; if (var_table.get_length ()) - return advance + roundf (var_table->get_advance_var (font, glyph)); // TODO Optimize?! + return advance + roundf (var_table->get_advance_var (glyph, font)); // TODO Optimize?! return _glyf_get_advance_var (font, glyph, T::tableTag == HB_OT_TAG_vmtx); #else @@ -295,27 +293,29 @@ struct hmtxvmtx }; protected: - UnsizedArrayOf<LongMetric>longMetricZ;/* Paired advance width and leading - * bearing values for each glyph. The - * value numOfHMetrics comes from - * the 'hhea' table. If the font is - * monospaced, only one entry need - * be in the array, but that entry is - * required. The last entry applies to - * all subsequent glyphs. */ -/*UnsizedArrayOf<FWORD> leadingBearingX;*//* Here the advance is assumed - * to be the same as the advance - * for the last entry above. The - * number of entries in this array is - * derived from numGlyphs (from 'maxp' - * table) minus numberOfLongMetrics. - * This generally is used with a run - * of monospaced glyphs (e.g., Kanji - * fonts or Courier fonts). Only one - * run is allowed and it must be at - * the end. This allows a monospaced - * font to vary the side bearing - * values for each glyph. */ + UnsizedArrayOf<LongMetric> + longMetricZ; /* Paired advance width and leading + * bearing values for each glyph. The + * value numOfHMetrics comes from + * the 'hhea' table. If the font is + * monospaced, only one entry need + * be in the array, but that entry is + * required. The last entry applies to + * all subsequent glyphs. */ +/*UnsizedArrayOf<FWORD> leadingBearingX;*/ + /* Here the advance is assumed + * to be the same as the advance + * for the last entry above. The + * number of entries in this array is + * derived from numGlyphs (from 'maxp' + * table) minus numberOfLongMetrics. + * This generally is used with a run + * of monospaced glyphs (e.g., Kanji + * fonts or Courier fonts). Only one + * run is allowed and it must be at + * the end. This allows a monospaced + * font to vary the side bearing + * values for each glyph. */ public: DEFINE_SIZE_ARRAY (0, longMetricZ); }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-kern-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-kern-table.hh index 36e5a358e6..3563cab8bd 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-kern-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-kern-table.hh @@ -86,21 +86,26 @@ struct KernSubTableFormat3 } protected: - KernSubTableHeader header; - HBUINT16 glyphCount; /* The number of glyphs in this font. */ - HBUINT8 kernValueCount; /* The number of kerning values. */ - HBUINT8 leftClassCount; /* The number of left-hand classes. */ - HBUINT8 rightClassCount;/* The number of right-hand classes. */ - HBUINT8 flags; /* Set to zero (reserved for future use). */ - UnsizedArrayOf<FWORD> kernValueZ; /* The kerning values. - * Length kernValueCount. */ + KernSubTableHeader + header; + HBUINT16 glyphCount; /* The number of glyphs in this font. */ + HBUINT8 kernValueCount; /* The number of kerning values. */ + HBUINT8 leftClassCount; /* The number of left-hand classes. */ + HBUINT8 rightClassCount;/* The number of right-hand classes. */ + HBUINT8 flags; /* Set to zero (reserved for future use). */ + UnsizedArrayOf<FWORD> + kernValueZ; /* The kerning values. + * Length kernValueCount. */ #if 0 - UnsizedArrayOf<HBUINT8>leftClass; /* The left-hand classes. - * Length glyphCount. */ - UnsizedArrayOf<HBUINT8>rightClass; /* The right-hand classes. - * Length glyphCount. */ - UnsizedArrayOf<HBUINT8>kernIndex; /* The indices into the kernValue array. - * Length leftClassCount * rightClassCount */ + UnsizedArrayOf<HBUINT8> + leftClass; /* The left-hand classes. + * Length glyphCount. */ + UnsizedArrayOf<HBUINT8> + rightClass; /* The right-hand classes. + * Length glyphCount. */ + UnsizedArrayOf<HBUINT8>kernIndex; + /* The indices into the kernValue array. + * Length leftClassCount * rightClassCount */ #endif public: DEFINE_SIZE_ARRAY (KernSubTableHeader::static_size + 6, kernValueZ); @@ -246,8 +251,8 @@ struct KernAATSubTableHeader HBUINT8 coverage; /* Coverage bits. */ HBUINT8 format; /* Subtable format. */ HBUINT16 tupleIndex; /* The tuple index (used for variations fonts). - * This value specifies which tuple this subtable covers. - * Note: We don't implement. */ + * This value specifies which tuple this subtable covers. + * Note: We don't implement. */ public: DEFINE_SIZE_STATIC (8); }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-base-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-base-table.hh index 02fe14fa06..4df0d942ce 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-base-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-base-table.hh @@ -379,12 +379,20 @@ struct Axis const BaseCoord **coord) const { const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag); - if (!base_script.has_data ()) return false; + if (!base_script.has_data ()) + { + *coord = nullptr; + return false; + } if (likely (coord)) { unsigned int tag_index = 0; - (this+baseTagList).bfind (baseline_tag, &tag_index); + if (!(this+baseTagList).bfind (baseline_tag, &tag_index)) + { + *coord = nullptr; + return false; + } *coord = &base_script.get_base_coord (tag_index); } @@ -398,7 +406,11 @@ struct Axis const BaseCoord **max_coord) const { const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag); - if (!base_script.has_data ()) return false; + if (!base_script.has_data ()) + { + *min_coord = *max_coord = nullptr; + return false; + } base_script.get_min_max (language_tag).get_min_max (feature_tag, min_coord, max_coord); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh index fa08140f56..0ba7e3c061 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh @@ -60,6 +60,18 @@ #define HB_MAX_LANGSYS 2000 #endif +#ifndef HB_MAX_FEATURES +#define HB_MAX_FEATURES 750 +#endif + +#ifndef HB_MAX_FEATURE_INDICES +#define HB_MAX_FEATURE_INDICES 1500 +#endif + +#ifndef HB_MAX_LOOKUP_INDICES +#define HB_MAX_LOOKUP_INDICES 20000 +#endif + namespace OT { @@ -73,48 +85,147 @@ static inline void Coverage_serialize (hb_serialize_context_t *c, template<typename Iterator> static inline void ClassDef_serialize (hb_serialize_context_t *c, - Iterator it); + Iterator it); static void ClassDef_remap_and_serialize (hb_serialize_context_t *c, - const hb_set_t &glyphset, - const hb_map_t &gid_klass_map, - hb_sorted_vector_t<HBGlyphID> glyphs, - hb_sorted_vector_t<unsigned> klasses, - hb_map_t *klass_map /*INOUT*/); + const hb_set_t &glyphset, + const hb_map_t &gid_klass_map, + hb_sorted_vector_t<HBGlyphID> &glyphs, + const hb_set_t &klasses, + hb_map_t *klass_map /*INOUT*/); + +struct hb_subset_layout_context_t : + hb_dispatch_context_t<hb_subset_layout_context_t, hb_empty_t, HB_DEBUG_SUBSET> +{ + const char *get_name () { return "SUBSET_LAYOUT"; } + static return_t default_return_value () { return hb_empty_t (); } + + bool visitScript () + { + return script_count++ < HB_MAX_SCRIPTS; + } + + bool visitLangSys () + { + return langsys_count++ < HB_MAX_LANGSYS; + } + + bool visitFeatureIndex (int count) + { + feature_index_count += count; + return feature_index_count < HB_MAX_FEATURE_INDICES; + } + + bool visitLookupIndex() + { + lookup_index_count++; + return lookup_index_count < HB_MAX_LOOKUP_INDICES; + } + + hb_subset_context_t *subset_context; + const hb_tag_t table_tag; + const hb_map_t *lookup_index_map; + const hb_map_t *feature_index_map; + hb_subset_layout_context_t (hb_subset_context_t *c_, + hb_tag_t tag_, + hb_map_t *lookup_map_, + hb_map_t *feature_map_) : + subset_context (c_), + table_tag (tag_), + lookup_index_map (lookup_map_), + feature_index_map (feature_map_), + script_count (0), + langsys_count (0), + feature_index_count (0), + lookup_index_count (0) + {} + + private: + unsigned script_count; + unsigned langsys_count; + unsigned feature_index_count; + unsigned lookup_index_count; +}; + +struct hb_collect_variation_indices_context_t : + hb_dispatch_context_t<hb_collect_variation_indices_context_t> +{ + template <typename T> + return_t dispatch (const T &obj) { obj.collect_variation_indices (this); return hb_empty_t (); } + static return_t default_return_value () { return hb_empty_t (); } + + hb_set_t *layout_variation_indices; + const hb_set_t *glyph_set; + const hb_map_t *gpos_lookups; + + hb_collect_variation_indices_context_t (hb_set_t *layout_variation_indices_, + const hb_set_t *glyph_set_, + const hb_map_t *gpos_lookups_) : + layout_variation_indices (layout_variation_indices_), + glyph_set (glyph_set_), + gpos_lookups (gpos_lookups_) {} +}; template<typename OutputArray> struct subset_offset_array_t { - subset_offset_array_t - (hb_subset_context_t *subset_context, - OutputArray& out, - const void *src_base, - const void *dest_base) - : _subset_context(subset_context), _out (out), _src_base (src_base), _dest_base (dest_base) {} + subset_offset_array_t (hb_subset_context_t *subset_context_, + OutputArray& out_, + const void *base_) : subset_context (subset_context_), + out (out_), base (base_) {} template <typename T> - bool - operator () - (T&& offset) + bool operator () (T&& offset) { - auto *o = _out.serialize_append (_subset_context->serializer); + auto *o = out.serialize_append (subset_context->serializer); if (unlikely (!o)) return false; - auto snap = _subset_context->serializer->snapshot (); - bool ret = o->serialize_subset (_subset_context, offset, _src_base, _dest_base); + auto snap = subset_context->serializer->snapshot (); + bool ret = o->serialize_subset (subset_context, offset, base); if (!ret) { - _out.pop (); - _subset_context->serializer->revert (snap); + out.pop (); + subset_context->serializer->revert (snap); } return ret; } private: - hb_subset_context_t *_subset_context; - OutputArray &_out; - const void *_src_base; - const void *_dest_base; + hb_subset_context_t *subset_context; + OutputArray &out; + const void *base; +}; + + +template<typename OutputArray, typename Arg> +struct subset_offset_array_arg_t +{ + subset_offset_array_arg_t (hb_subset_context_t *subset_context_, + OutputArray& out_, + const void *base_, + Arg &&arg_) : subset_context (subset_context_), out (out_), + base (base_), arg (arg_) {} + + template <typename T> + bool operator () (T&& offset) + { + auto *o = out.serialize_append (subset_context->serializer); + if (unlikely (!o)) return false; + auto snap = subset_context->serializer->snapshot (); + bool ret = o->serialize_subset (subset_context, offset, base, arg); + if (!ret) + { + out.pop (); + subset_context->serializer->revert (snap); + } + return ret; + } + + private: + hb_subset_context_t *subset_context; + OutputArray &out; + const void *base; + Arg &&arg; }; /* @@ -126,16 +237,55 @@ struct { template<typename OutputArray> subset_offset_array_t<OutputArray> - operator () - (hb_subset_context_t *subset_context, - OutputArray& out, - const void *src_base, - const void *dest_base) const + operator () (hb_subset_context_t *subset_context, OutputArray& out, + const void *base) const + { return subset_offset_array_t<OutputArray> (subset_context, out, base); } + + /* Variant with one extra argument passed to serialize_subset */ + template<typename OutputArray, typename Arg> + subset_offset_array_arg_t<OutputArray, Arg> + operator () (hb_subset_context_t *subset_context, OutputArray& out, + const void *base, Arg &&arg) const + { return subset_offset_array_arg_t<OutputArray, Arg> (subset_context, out, base, arg); } +} +HB_FUNCOBJ (subset_offset_array); + +template<typename OutputArray> +struct subset_record_array_t +{ + subset_record_array_t (hb_subset_layout_context_t *c_, OutputArray* out_, + const void *base_) : subset_layout_context (c_), + out (out_), base (base_) {} + + template <typename T> + void + operator () (T&& record) { - return subset_offset_array_t<OutputArray> (subset_context, out, src_base, dest_base); + auto snap = subset_layout_context->subset_context->serializer->snapshot (); + bool ret = record.subset (subset_layout_context, base); + if (!ret) subset_layout_context->subset_context->serializer->revert (snap); + else out->len++; } + + private: + hb_subset_layout_context_t *subset_layout_context; + OutputArray *out; + const void *base; +}; + +/* + * Helper to subset a RecordList/record array. Subsets each Record in the array and + * discards the record if the subset operation returns false. + */ +struct +{ + template<typename OutputArray> + subset_record_array_t<OutputArray> + operator () (hb_subset_layout_context_t *c, OutputArray* out, + const void *base) const + { return subset_record_array_t<OutputArray> (c, out, base); } } -HB_FUNCOBJ (subset_offset_array); +HB_FUNCOBJ (subset_record_array); /* * @@ -153,31 +303,20 @@ struct Record_sanitize_closure_t { const void *list_base; }; -struct RecordList_subset_context_t { - - RecordList_subset_context_t() : script_count (0), langsys_count (0) - {} - - bool visitScript () - { - return script_count++ < HB_MAX_SCRIPTS; - } - - bool visitLangSys () - { - return langsys_count++ < HB_MAX_LANGSYS; - } - - private: - unsigned int script_count; - unsigned int langsys_count; -}; - template <typename Type> struct Record { int cmp (hb_tag_t a) const { return tag.cmp (a); } + bool subset (hb_subset_layout_context_t *c, const void *base) const + { + TRACE_SUBSET (this); + auto *out = c->subset_context->serializer->embed (this); + if (unlikely (!out)) return_trace (false); + bool ret = out->offset.serialize_subset (c->subset_context, offset, base, c, &tag); + return_trace (ret); + } + bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -206,11 +345,12 @@ struct RecordArrayOf : SortedArrayOf<Record<Type>> unsigned int *record_count /* IN/OUT */, hb_tag_t *record_tags /* OUT */) const { - if (record_count) { - const Record<Type> *arr = this->sub_array (start_offset, record_count); - unsigned int count = *record_count; - for (unsigned int i = 0; i < count; i++) - record_tags[i] = arr[i].tag; + if (record_count) + { + + this->sub_array (start_offset, record_count) + | hb_map (&Record<Type>::tag) + | hb_sink (hb_array (record_tags, *record_count)) + ; } return this->len; } @@ -226,29 +366,16 @@ struct RecordListOf : RecordArrayOf<Type> const Type& operator [] (unsigned int i) const { return this+this->get_offset (i); } - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, + hb_subset_layout_context_t *l) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (*this); if (unlikely (!c->serializer->extend_min (out))) return_trace (false); - RecordList_subset_context_t record_list_context; - - unsigned int count = this->len; - for (unsigned int i = 0; i < count; i++) - { - auto *record = out->serialize_append (c->serializer); - if (unlikely (!record)) return false; - auto snap = c->serializer->snapshot (); - if (record->offset.serialize_subset (c, this->get_offset (i), this, out, &record_list_context)) - { - record->tag = this->get_tag(i); - continue; - } - out->pop (); - c->serializer->revert (snap); - } - + + this->iter () + | hb_apply (subset_record_array (l, out, this)) + ; return_trace (true); } @@ -259,11 +386,31 @@ struct RecordListOf : RecordArrayOf<Type> } }; +struct Feature; + +struct RecordListOfFeature : RecordListOf<Feature> +{ + bool subset (hb_subset_context_t *c, + hb_subset_layout_context_t *l) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + unsigned count = this->len; + + hb_zip (*this, hb_range (count)) + | hb_filter (l->feature_index_map, hb_second) + | hb_map (hb_first) + | hb_apply (subset_record_array (l, out, this)) + ; + return_trace (true); + } +}; struct RangeRecord { int cmp (hb_codepoint_t g) const - { return g < start ? -1 : g <= end ? 0 : +1; } + { return g < first ? -1 : g <= last ? 0 : +1; } bool sanitize (hb_sanitize_context_t *c) const { @@ -272,14 +419,14 @@ struct RangeRecord } bool intersects (const hb_set_t *glyphs) const - { return glyphs->intersects (start, end); } + { return glyphs->intersects (first, last); } template <typename set_t> - bool add_coverage (set_t *glyphs) const - { return glyphs->add_range (start, end); } + bool collect_coverage (set_t *glyphs) const + { return glyphs->add_range (first, last); } - HBGlyphID start; /* First GlyphID in the range */ - HBGlyphID end; /* Last GlyphID in the range */ + HBGlyphID first; /* First GlyphID in the range */ + HBGlyphID last; /* Last GlyphID in the range */ HBUINT16 value; /* Value */ public: DEFINE_SIZE_STATIC (6); @@ -289,15 +436,38 @@ DECLARE_NULL_NAMESPACE_BYTES (OT, RangeRecord); struct IndexArray : ArrayOf<Index> { + bool intersects (const hb_map_t *indexes) const + { return hb_any (*this, indexes); } + + template <typename Iterator, + hb_requires (hb_is_iterator (Iterator))> + void serialize (hb_serialize_context_t *c, + hb_subset_layout_context_t *l, + Iterator it) + { + if (!it) return; + if (unlikely (!c->extend_min ((*this)))) return; + + for (const auto _ : it) + { + if (!l->visitLookupIndex()) break; + + Index i; + i = _; + c->copy (i); + this->len++; + } + } + unsigned int get_indexes (unsigned int start_offset, unsigned int *_count /* IN/OUT */, unsigned int *_indexes /* OUT */) const { - if (_count) { - const HBUINT16 *arr = this->sub_array (start_offset, _count); - unsigned int count = *_count; - for (unsigned int i = 0; i < count; i++) - _indexes[i] = arr[i]; + if (_count) + { + + this->sub_array (start_offset, _count) + | hb_sink (hb_array (_indexes, *_count)) + ; } return this->len; } @@ -309,10 +479,6 @@ struct IndexArray : ArrayOf<Index> }; -struct Script; -struct LangSys; -struct Feature; - struct LangSys { unsigned int get_feature_count () const @@ -340,6 +506,42 @@ struct LangSys return_trace (c->embed (*this)); } + bool operator == (const LangSys& o) const + { + if (featureIndex.len != o.featureIndex.len || + reqFeatureIndex != o.reqFeatureIndex) + return false; + + for (const auto _ : + hb_zip (featureIndex, o.featureIndex)) + if (_.first != _.second) return false; + + return true; + } + + bool subset (hb_subset_context_t *c, + hb_subset_layout_context_t *l, + const Tag *tag = nullptr) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + out->reqFeatureIndex = l->feature_index_map->has (reqFeatureIndex) ? l->feature_index_map->get (reqFeatureIndex) : 0xFFFFu; + + if (!l->visitFeatureIndex (featureIndex.len)) + return_trace (false); + + auto it = + + hb_iter (featureIndex) + | hb_filter (l->feature_index_map) + | hb_map (l->feature_index_map) + ; + + bool ret = bool (it); + out->featureIndex.serialize (c->serializer, l, it); + return_trace (ret); + } + bool sanitize (hb_sanitize_context_t *c, const Record_sanitize_closure_t * = nullptr) const { @@ -379,34 +581,46 @@ struct Script bool has_default_lang_sys () const { return defaultLangSys != 0; } const LangSys& get_default_lang_sys () const { return this+defaultLangSys; } - bool subset (hb_subset_context_t *c, RecordList_subset_context_t *record_list_context) const + bool subset (hb_subset_context_t *c, + hb_subset_layout_context_t *l, + const Tag *tag) const { TRACE_SUBSET (this); - if (!record_list_context->visitScript ()) return_trace (false); + if (!l->visitScript ()) return_trace (false); auto *out = c->serializer->start_embed (*this); - if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); - out->defaultLangSys.serialize_copy (c->serializer, defaultLangSys, this, out); - - for (const auto &src: langSys) + bool defaultLang = false; + if (has_default_lang_sys ()) { - if (!record_list_context->visitLangSys ()) { - continue; + c->serializer->push (); + const LangSys& ls = this+defaultLangSys; + bool ret = ls.subset (c, l); + if (!ret && tag && *tag != HB_TAG ('D', 'F', 'L', 'T')) + { + c->serializer->pop_discard (); + out->defaultLangSys = 0; } - - auto snap = c->serializer->snapshot (); - auto *lang_sys = c->serializer->embed (src); - - if (likely(lang_sys) - && lang_sys->offset.serialize_copy (c->serializer, src.offset, this, out)) + else { - out->langSys.len++; - continue; + c->serializer->add_link (out->defaultLangSys, c->serializer->pop_pack ()); + defaultLang = true; } - c->serializer->revert (snap); } - return_trace (true); + + + langSys.iter () + | hb_filter ([=] (const Record<LangSys>& record) {return l->visitLangSys (); }) + | hb_filter ([&] (const Record<LangSys>& record) + { + const LangSys& d = this+defaultLangSys; + const LangSys& l = this+record.offset; + return !(l == d); + }) + | hb_apply (subset_record_array (l, &(out->langSys), this)) + ; + + return_trace (bool (out->langSys.len) || defaultLang || l->table_tag == HB_OT_TAG_GSUB); } bool sanitize (hb_sanitize_context_t *c, @@ -503,6 +717,12 @@ struct FeatureParamsSize return_trace (true); } + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + return_trace ((bool) c->serializer->embed (*this)); + } + HBUINT16 designSize; /* Represents the design size in 720/inch * units (decipoints). The design size entry * must be non-zero. When there is a design @@ -553,6 +773,12 @@ struct FeatureParamsStylisticSet return_trace (c->check_struct (this)); } + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + return_trace ((bool) c->serializer->embed (*this)); + } + HBUINT16 version; /* (set to 0): This corresponds to a “minor” * version number. Additional data may be * added to the end of this Feature Parameters @@ -579,6 +805,27 @@ struct FeatureParamsStylisticSet /* https://docs.microsoft.com/en-us/typography/opentype/spec/features_ae#cv01-cv99 */ struct FeatureParamsCharacterVariants { + unsigned + get_characters (unsigned start_offset, unsigned *char_count, hb_codepoint_t *chars) const + { + if (char_count) + { + + characters.sub_array (start_offset, char_count) + | hb_sink (hb_array (chars, *char_count)) + ; + } + return characters.len; + } + + unsigned get_size () const + { return min_size + characters.len * HBUINT24::static_size; } + + 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); @@ -635,6 +882,19 @@ struct FeatureParams return_trace (true); } + bool subset (hb_subset_context_t *c, const Tag* tag) const + { + TRACE_SUBSET (this); + if (!tag) return_trace (false); + if (*tag == HB_TAG ('s','i','z','e')) + return_trace (u.size.subset (c)); + if ((*tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */ + return_trace (u.stylisticSet.subset (c)); + if ((*tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */ + return_trace (u.characterVariants.subset (c)); + return_trace (false); + } + #ifndef HB_NO_LAYOUT_FEATURE_PARAMS const FeatureParamsSize& get_size_params (hb_tag_t tag) const { @@ -682,13 +942,28 @@ struct Feature const FeatureParams &get_feature_params () const { return this+featureParams; } - bool subset (hb_subset_context_t *c, RecordList_subset_context_t *r) const + bool intersects_lookup_indexes (const hb_map_t *lookup_indexes) const + { return lookupIndex.intersects (lookup_indexes); } + + bool subset (hb_subset_context_t *c, + hb_subset_layout_context_t *l, + const Tag *tag = nullptr) const { TRACE_SUBSET (this); - auto *out = c->serializer->embed (*this); - if (unlikely (!out)) return_trace (false); - out->featureParams = 0; /* TODO(subset) FeatureParams. */ - return_trace (true); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + bool subset_featureParams = out->featureParams.serialize_subset (c, featureParams, this, tag); + + auto it = + + hb_iter (lookupIndex) + | hb_filter (l->lookup_index_map) + | hb_map (l->lookup_index_map) + ; + + out->lookupIndex.serialize (c->serializer, l, it); + return_trace (bool (it) || subset_featureParams + || (tag && *tag == HB_TAG ('p', 'r', 'e', 'f'))); } bool sanitize (hb_sanitize_context_t *c, @@ -775,10 +1050,10 @@ struct Lookup template <typename TSubTable> const OffsetArrayOf<TSubTable>& get_subtables () const - { return CastR<OffsetArrayOf<TSubTable>> (subTable); } + { return reinterpret_cast<const OffsetArrayOf<TSubTable> &> (subTable); } template <typename TSubTable> OffsetArrayOf<TSubTable>& get_subtables () - { return CastR<OffsetArrayOf<TSubTable>> (subTable); } + { return reinterpret_cast<OffsetArrayOf<TSubTable> &> (subTable); } template <typename TSubTable> const TSubTable& get_subtable (unsigned int i) const @@ -848,17 +1123,17 @@ struct Lookup bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - auto *out = c->serializer->embed (*this); - if (unlikely (!out)) return_trace (false); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + out->lookupType = lookupType; + out->lookupFlag = lookupFlag; - /* Subset the actual subtables. */ - /* TODO Drop empty ones, either by calling intersects() beforehand, - * or just dropping null offsets after. */ - const OffsetArrayOf<TSubTable>& subtables = get_subtables<TSubTable> (); - OffsetArrayOf<TSubTable>& out_subtables = out->get_subtables<TSubTable> (); - unsigned int count = subTable.len; - for (unsigned int i = 0; i < count; i++) - out_subtables[i].serialize_subset (c, subtables[i], this, out, get_type ()); + const hb_set_t *glyphset = c->plan->glyphset_gsub (); + unsigned int lookup_type = get_type (); + + hb_iter (get_subtables <TSubTable> ()) + | hb_filter ([this, glyphset, lookup_type] (const OffsetTo<TSubTable> &_) { return (this+_).intersects (glyphset, lookup_type); }) + | hb_apply (subset_offset_array (c, out->get_subtables<TSubTable> (), this, lookup_type)) + ; return_trace (true); } @@ -868,6 +1143,10 @@ struct Lookup { TRACE_SANITIZE (this); if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false); + + unsigned subtables = get_subtable_count (); + if (unlikely (!c->visit_subtables (subtables))) return_trace (false); + if (lookupFlag & LookupFlag::UseMarkFilteringSet) { const HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable); @@ -890,8 +1169,7 @@ struct Lookup * https://bugs.chromium.org/p/chromium/issues/detail?id=960331 */ unsigned int type = get_subtable<TSubTable> (0).u.extension.get_type (); - unsigned int count = get_subtable_count (); - for (unsigned int i = 1; i < count; i++) + for (unsigned int i = 1; i < subtables; i++) if (get_subtable<TSubTable> (i).u.extension.get_type () != type) return_trace (false); } @@ -912,6 +1190,32 @@ struct Lookup typedef OffsetListOf<Lookup> LookupList; +template <typename TLookup> +struct LookupOffsetList : OffsetListOf<TLookup> +{ + bool subset (hb_subset_context_t *c, + hb_subset_layout_context_t *l) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + unsigned count = this->len; + + hb_zip (*this, hb_range (count)) + | hb_filter (l->lookup_index_map, hb_second) + | hb_map (hb_first) + | hb_apply (subset_offset_array (c, *out, this)) + ; + return_trace (true); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (OffsetListOf<TLookup>::sanitize (c, this)); + } +}; + /* * Coverage Table @@ -947,8 +1251,9 @@ struct CoverageFormat1 { /* TODO Speed up, using hb_set_next() and bsearch()? */ unsigned int count = glyphArray.len; + const HBGlyphID *arr = glyphArray.arrayZ; for (unsigned int i = 0; i < count; i++) - if (glyphs->has (glyphArray[i])) + if (glyphs->has (arr[i])) return true; return false; } @@ -956,7 +1261,7 @@ struct CoverageFormat1 { return glyphs->has (glyphArray[index]); } template <typename set_t> - bool add_coverage (set_t *glyphs) const + bool collect_coverage (set_t *glyphs) const { return glyphs->add_sorted_array (glyphArray.arrayZ, glyphArray.len); } public: @@ -993,9 +1298,9 @@ struct CoverageFormat2 unsigned int get_coverage (hb_codepoint_t glyph_id) const { const RangeRecord &range = rangeRecord.bsearch (glyph_id); - return likely (range.start <= range.end) ? - (unsigned int) range.value + (glyph_id - range.start) : - NOT_COVERED; + return likely (range.first <= range.last) + ? (unsigned int) range.value + (glyph_id - range.first) + : NOT_COVERED; } template <typename Iterator, @@ -1032,10 +1337,10 @@ struct CoverageFormat2 if (last + 1 != g) { range++; - rangeRecord[range].start = g; + rangeRecord[range].first = g; rangeRecord[range].value = count; } - rangeRecord[range].end = g; + rangeRecord[range].last = g; last = g; count++; } @@ -1052,20 +1357,23 @@ struct CoverageFormat2 bool intersects (const hb_set_t *glyphs) const { /* TODO Speed up, using hb_set_next() and bsearch()? */ - unsigned int count = rangeRecord.len; - for (unsigned int i = 0; i < count; i++) - if (rangeRecord[i].intersects (glyphs)) + /* TODO(iter) Rewrite as dagger. */ + unsigned count = rangeRecord.len; + const RangeRecord *arr = rangeRecord.arrayZ; + for (unsigned i = 0; i < count; i++) + if (arr[i].intersects (glyphs)) return true; return false; } bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { - unsigned int i; - unsigned int count = rangeRecord.len; - for (i = 0; i < count; i++) { - const RangeRecord &range = rangeRecord[i]; + /* TODO(iter) Rewrite as dagger. */ + unsigned count = rangeRecord.len; + const RangeRecord *arr = rangeRecord.arrayZ; + for (unsigned i = 0; i < count; i++) { + const RangeRecord &range = arr[i]; if (range.value <= index && - index < (unsigned int) range.value + (range.end - range.start) && + index < (unsigned int) range.value + (range.last - range.first) && range.intersects (glyphs)) return true; else if (index < range.value) @@ -1075,11 +1383,11 @@ struct CoverageFormat2 } template <typename set_t> - bool add_coverage (set_t *glyphs) const + bool collect_coverage (set_t *glyphs) const { unsigned int count = rangeRecord.len; for (unsigned int i = 0; i < count; i++) - if (unlikely (!rangeRecord[i].add_coverage (glyphs))) + if (unlikely (!rangeRecord[i].collect_coverage (glyphs))) return false; return true; } @@ -1093,8 +1401,8 @@ struct CoverageFormat2 c = &c_; coverage = 0; i = 0; - j = c->rangeRecord.len ? c->rangeRecord[0].start : 0; - if (unlikely (c->rangeRecord[0].start > c->rangeRecord[0].end)) + j = c->rangeRecord.len ? c->rangeRecord[0].first : 0; + if (unlikely (c->rangeRecord[0].first > c->rangeRecord[0].last)) { /* Broken table. Skip. */ i = c->rangeRecord.len; @@ -1104,13 +1412,13 @@ struct CoverageFormat2 bool more () const { return i < c->rangeRecord.len; } void next () { - if (j >= c->rangeRecord[i].end) + if (j >= c->rangeRecord[i].last) { i++; if (more ()) { unsigned int old = coverage; - j = c->rangeRecord[i].start; + j = c->rangeRecord[i].first; coverage = c->rangeRecord[i].value; if (unlikely (coverage != old + 1)) { @@ -1198,7 +1506,7 @@ struct Coverage bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->glyphset (); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; auto it = @@ -1246,12 +1554,12 @@ struct Coverage /* Might return false if array looks unsorted. * Used for faster rejection of corrupt data. */ template <typename set_t> - bool add_coverage (set_t *glyphs) const + bool collect_coverage (set_t *glyphs) const { switch (u.format) { - case 1: return u.format1.add_coverage (glyphs); - case 2: return u.format2.add_coverage (glyphs); + case 1: return u.format1.collect_coverage (glyphs); + case 2: return u.format2.collect_coverage (glyphs); default:return false; } } @@ -1259,7 +1567,7 @@ struct Coverage struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t> { static constexpr bool is_sorted_iterator = true; - iter_t (const Coverage &c_ = Null(Coverage)) + iter_t (const Coverage &c_ = Null (Coverage)) { memset (this, 0, sizeof (*this)); format = c_.u.format; @@ -1333,22 +1641,28 @@ struct Coverage template<typename Iterator> static inline void Coverage_serialize (hb_serialize_context_t *c, - Iterator it) + Iterator it) { c->start_embed<Coverage> ()->serialize (c, it); } static void ClassDef_remap_and_serialize (hb_serialize_context_t *c, - const hb_set_t &glyphset, - const hb_map_t &gid_klass_map, - hb_sorted_vector_t<HBGlyphID> glyphs, - hb_sorted_vector_t<unsigned> klasses, - hb_map_t *klass_map /*INOUT*/) + const hb_set_t &glyphset, + const hb_map_t &gid_klass_map, + hb_sorted_vector_t<HBGlyphID> &glyphs, + const hb_set_t &klasses, + hb_map_t *klass_map /*INOUT*/) { - bool has_no_match = glyphset.get_population () > gid_klass_map.get_population (); - - hb_map_t m; - if (!klass_map) klass_map = &m; + if (!klass_map) + { + ClassDef_serialize (c, hb_zip (glyphs.iter (), + glyphs.iter () + | hb_map (gid_klass_map))); + return; + } + + /* any glyph not assigned a class value falls into Class zero (0), + * if any glyph assigned to class 0, remapping must start with 0->0*/ + if (glyphset.get_population () > gid_klass_map.get_population ()) + klass_map->set (0, 0); - if (has_no_match) klass_map->set (0, 0); unsigned idx = klass_map->has (0) ? 1 : 0; for (const unsigned k: klasses.iter ()) { @@ -1356,17 +1670,16 @@ static void ClassDef_remap_and_serialize (hb_serialize_context_t *c, klass_map->set (k, idx); idx++; } - + auto it = + glyphs.iter () - | hb_map_retains_sorting ([&] (const HBGlyphID& gid) -> hb_pair_t<hb_codepoint_t, HBUINT16> - { - HBUINT16 new_klass; - new_klass = klass_map->get (gid_klass_map[gid]); - return hb_pair ((hb_codepoint_t)gid, new_klass); - }) + | hb_map_retains_sorting ([&] (const HBGlyphID& gid) -> hb_pair_t<hb_codepoint_t, unsigned> + { + unsigned new_klass = klass_map->get (gid_klass_map[gid]); + return hb_pair ((hb_codepoint_t)gid, new_klass); + }) ; - + c->propagate_error (glyphs, klasses); ClassDef_serialize (c, it); } @@ -1388,7 +1701,7 @@ struct ClassDefFormat1 template<typename Iterator, hb_requires (hb_is_iterator (Iterator))> bool serialize (hb_serialize_context_t *c, - Iterator it) + Iterator it) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); @@ -1400,21 +1713,31 @@ struct ClassDefFormat1 return_trace (true); } - startGlyph = (*it).first; - classValue.serialize (c, + it - | hb_map (hb_second)); + hb_codepoint_t glyph_min = (*it).first; + hb_codepoint_t glyph_max = + it + | hb_map (hb_first) + | hb_reduce (hb_max, 0u); + unsigned glyph_count = glyph_max - glyph_min + 1; + + startGlyph = glyph_min; + if (unlikely (!classValue.serialize (c, glyph_count))) return_trace (false); + for (const hb_pair_t<hb_codepoint_t, unsigned> gid_klass_pair : + it) + { + unsigned idx = gid_klass_pair.first - glyph_min; + classValue[idx] = gid_klass_pair.second; + } return_trace (true); } bool subset (hb_subset_context_t *c, - hb_map_t *klass_map = nullptr /*OUT*/) const + hb_map_t *klass_map = nullptr /*OUT*/) const { TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->glyphset (); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; - + hb_sorted_vector_t<HBGlyphID> glyphs; - hb_sorted_vector_t<unsigned> orig_klasses; + hb_set_t orig_klasses; hb_map_t gid_org_klass_map; hb_codepoint_t start = startGlyph; @@ -1427,11 +1750,11 @@ struct ClassDefFormat1 glyphs.push (glyph_map[gid]); gid_org_klass_map.set (glyph_map[gid], klass); - orig_klasses.push (klass); + orig_klasses.add (klass); } ClassDef_remap_and_serialize (c->serializer, glyphset, gid_org_klass_map, - glyphs, orig_klasses, klass_map); + glyphs, orig_klasses, klass_map); return_trace ((bool) glyphs); } @@ -1442,7 +1765,7 @@ struct ClassDefFormat1 } template <typename set_t> - bool add_coverage (set_t *glyphs) const + bool collect_coverage (set_t *glyphs) const { unsigned int start = 0; unsigned int count = classValue.len; @@ -1465,7 +1788,7 @@ struct ClassDefFormat1 } template <typename set_t> - bool add_class (set_t *glyphs, unsigned int klass) const + bool collect_class (set_t *glyphs, unsigned klass) const { unsigned int count = classValue.len; for (unsigned int i = 0; i < count; i++) @@ -1483,7 +1806,7 @@ struct ClassDefFormat1 if (classValue[iter - start]) return true; return false; } - bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const + bool intersects_class (const hb_set_t *glyphs, uint16_t klass) const { unsigned int count = classValue.len; if (klass == 0) @@ -1496,8 +1819,12 @@ struct ClassDefFormat1 if (hb_set_next (glyphs, &g)) return true; /* Fall through. */ } + /* TODO Speed up, using set overlap first? */ + /* TODO(iter) Rewrite as dagger. */ + HBUINT16 k {klass}; + const HBUINT16 *arr = classValue.arrayZ; for (unsigned int i = 0; i < count; i++) - if (classValue[i] == klass && glyphs->has (startGlyph + i)) + if (arr[i] == k && glyphs->has (startGlyph + i)) return true; return false; } @@ -1524,7 +1851,7 @@ struct ClassDefFormat2 template<typename Iterator, hb_requires (hb_is_iterator (Iterator))> bool serialize (hb_serialize_context_t *c, - Iterator it) + Iterator it) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); @@ -1540,8 +1867,8 @@ struct ClassDefFormat2 unsigned prev_klass = (*it).second; RangeRecord range_rec; - range_rec.start = prev_gid; - range_rec.end = prev_gid; + range_rec.first = prev_gid; + range_rec.last = prev_gid; range_rec.value = prev_klass; RangeRecord *record = c->copy (range_rec); @@ -1553,37 +1880,37 @@ struct ClassDefFormat2 unsigned cur_klass = gid_klass_pair.second; if (cur_gid != prev_gid + 1 || - cur_klass != prev_klass) + cur_klass != prev_klass) { - if (unlikely (!record)) break; - record->end = prev_gid; - num_ranges++; + if (unlikely (!record)) break; + record->last = prev_gid; + num_ranges++; - range_rec.start = cur_gid; - range_rec.end = cur_gid; - range_rec.value = cur_klass; + range_rec.first = cur_gid; + range_rec.last = cur_gid; + range_rec.value = cur_klass; - record = c->copy (range_rec); + record = c->copy (range_rec); } prev_klass = cur_klass; prev_gid = cur_gid; } - if (likely (record)) record->end = prev_gid; + if (likely (record)) record->last = prev_gid; rangeRecord.len = num_ranges; return_trace (true); } bool subset (hb_subset_context_t *c, - hb_map_t *klass_map = nullptr /*OUT*/) const + hb_map_t *klass_map = nullptr /*OUT*/) const { TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->glyphset (); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; hb_sorted_vector_t<HBGlyphID> glyphs; - hb_sorted_vector_t<unsigned> orig_klasses; + hb_set_t orig_klasses; hb_map_t gid_org_klass_map; unsigned count = rangeRecord.len; @@ -1591,19 +1918,19 @@ struct ClassDefFormat2 { unsigned klass = rangeRecord[i].value; if (!klass) continue; - hb_codepoint_t start = rangeRecord[i].start; - hb_codepoint_t end = rangeRecord[i].end + 1; + hb_codepoint_t start = rangeRecord[i].first; + hb_codepoint_t end = rangeRecord[i].last + 1; for (hb_codepoint_t g = start; g < end; g++) { if (!glyphset.has (g)) continue; glyphs.push (glyph_map[g]); - gid_org_klass_map.set (glyph_map[g], klass); - orig_klasses.push (klass); + gid_org_klass_map.set (glyph_map[g], klass); + orig_klasses.add (klass); } } ClassDef_remap_and_serialize (c->serializer, glyphset, gid_org_klass_map, - glyphs, orig_klasses, klass_map); + glyphs, orig_klasses, klass_map); return_trace ((bool) glyphs); } @@ -1614,24 +1941,24 @@ struct ClassDefFormat2 } template <typename set_t> - bool add_coverage (set_t *glyphs) const + bool collect_coverage (set_t *glyphs) const { unsigned int count = rangeRecord.len; for (unsigned int i = 0; i < count; i++) if (rangeRecord[i].value) - if (unlikely (!rangeRecord[i].add_coverage (glyphs))) + if (unlikely (!rangeRecord[i].collect_coverage (glyphs))) return false; return true; } template <typename set_t> - bool add_class (set_t *glyphs, unsigned int klass) const + bool collect_class (set_t *glyphs, unsigned int klass) const { unsigned int count = rangeRecord.len; for (unsigned int i = 0; i < count; i++) { if (rangeRecord[i].value == klass) - if (unlikely (!rangeRecord[i].add_coverage (glyphs))) + if (unlikely (!rangeRecord[i].collect_coverage (glyphs))) return false; } return true; @@ -1642,11 +1969,14 @@ struct ClassDefFormat2 /* TODO Speed up, using hb_set_next() and bsearch()? */ unsigned int count = rangeRecord.len; for (unsigned int i = 0; i < count; i++) - if (rangeRecord[i].intersects (glyphs)) + { + const auto& range = rangeRecord[i]; + if (range.intersects (glyphs) && range.value) return true; + } return false; } - bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const + bool intersects_class (const hb_set_t *glyphs, uint16_t klass) const { unsigned int count = rangeRecord.len; if (klass == 0) @@ -1657,16 +1987,20 @@ struct ClassDefFormat2 { if (!hb_set_next (glyphs, &g)) break; - if (g < rangeRecord[i].start) + if (g < rangeRecord[i].first) return true; - g = rangeRecord[i].end; + g = rangeRecord[i].last; } if (g != HB_SET_VALUE_INVALID && hb_set_next (glyphs, &g)) return true; /* Fall through. */ } + /* TODO Speed up, using set overlap first? */ + /* TODO(iter) Rewrite as dagger. */ + HBUINT16 k {klass}; + const RangeRecord *arr = rangeRecord.arrayZ; for (unsigned int i = 0; i < count; i++) - if (rangeRecord[i].value == klass && rangeRecord[i].intersects (glyphs)) + if (arr[i].value == k && arr[i].intersects (glyphs)) return true; return false; } @@ -1713,7 +2047,7 @@ struct ClassDef hb_codepoint_t glyph_min = (*it).first; hb_codepoint_t glyph_max = + it | hb_map (hb_first) - | hb_reduce (hb_max, 0u); + | hb_reduce (hb_max, 0u); unsigned num_ranges = 1; hb_codepoint_t prev_gid = glyph_min; @@ -1721,17 +2055,18 @@ struct ClassDef for (const auto gid_klass_pair : it) { - hb_codepoint_t cur_gid = gid_klass_pair.first; - unsigned cur_klass = gid_klass_pair.second; - if (cur_gid != prev_gid + 1 || - cur_klass != prev_klass) - num_ranges++; - - prev_gid = cur_gid; - prev_klass = cur_klass; + hb_codepoint_t cur_gid = gid_klass_pair.first; + unsigned cur_klass = gid_klass_pair.second; + if (cur_gid == glyph_min || !cur_klass) continue; + if (cur_gid != prev_gid + 1 || + cur_klass != prev_klass) + num_ranges++; + + prev_gid = cur_gid; + prev_klass = cur_klass; } - if (1 + (glyph_max - glyph_min + 1) < num_ranges * 3) + if (1 + (glyph_max - glyph_min + 1) <= num_ranges * 3) format = 1; } u.format = format; @@ -1745,7 +2080,7 @@ struct ClassDef } bool subset (hb_subset_context_t *c, - hb_map_t *klass_map = nullptr /*OUT*/) const + hb_map_t *klass_map = nullptr /*OUT*/) const { TRACE_SUBSET (this); switch (u.format) { @@ -1769,11 +2104,11 @@ struct ClassDef /* Might return false if array looks unsorted. * Used for faster rejection of corrupt data. */ template <typename set_t> - bool add_coverage (set_t *glyphs) const + bool collect_coverage (set_t *glyphs) const { switch (u.format) { - case 1: return u.format1.add_coverage (glyphs); - case 2: return u.format2.add_coverage (glyphs); + case 1: return u.format1.collect_coverage (glyphs); + case 2: return u.format2.collect_coverage (glyphs); default:return false; } } @@ -1781,11 +2116,11 @@ struct ClassDef /* Might return false if array looks unsorted. * Used for faster rejection of corrupt data. */ template <typename set_t> - bool add_class (set_t *glyphs, unsigned int klass) const + bool collect_class (set_t *glyphs, unsigned int klass) const { switch (u.format) { - case 1: return u.format1.add_class (glyphs, klass); - case 2: return u.format2.add_class (glyphs, klass); + case 1: return u.format1.collect_class (glyphs, klass); + case 2: return u.format2.collect_class (glyphs, klass); default:return false; } } @@ -1819,7 +2154,7 @@ struct ClassDef template<typename Iterator> static inline void ClassDef_serialize (hb_serialize_context_t *c, - Iterator it) + Iterator it) { c->start_embed<ClassDef> ()->serialize (c, it); } @@ -1871,7 +2206,7 @@ struct VarRegionAxis struct VarRegionList { float evaluate (unsigned int region_index, - const int *coords, unsigned int coord_len) const + const int *coords, unsigned int coord_len) const { if (unlikely (region_index >= regionCount)) return 0.; @@ -1906,8 +2241,13 @@ struct VarRegionList axisCount = src->axisCount; regionCount = region_map.get_population (); if (unlikely (!c->allocate_size<VarRegionList> (get_size () - min_size))) return_trace (false); + unsigned int region_count = src->get_region_count (); for (unsigned int r = 0; r < regionCount; r++) - memcpy (&axesZ[axisCount * r], &src->axesZ[axisCount * region_map.backward (r)], VarRegionAxis::static_size * axisCount); + { + unsigned int backward = region_map.backward (r); + if (backward >= region_count) return_trace (false); + memcpy (&axesZ[axisCount * r], &src->axesZ[axisCount * backward], VarRegionAxis::static_size * axisCount); + } return_trace (true); } @@ -1936,8 +2276,8 @@ struct VarData { return itemCount * get_row_size (); } float get_delta (unsigned int inner, - const int *coords, unsigned int coord_count, - const VarRegionList ®ions) const + const int *coords, unsigned int coord_count, + const VarRegionList ®ions) const { if (unlikely (inner >= itemCount)) return 0.; @@ -1967,7 +2307,7 @@ struct VarData return delta; } - void get_scalars (int *coords, unsigned int coord_count, + void get_scalars (const int *coords, unsigned int coord_count, const VarRegionList ®ions, float *scalars /*OUT */, unsigned int num_scalars) const @@ -2031,8 +2371,8 @@ struct VarData for (r = 0; r < ri_count; r++) if (delta_sz[r]) { - ri_map[r] = (delta_sz[r] == kShort)? short_index++ : byte_index++; - new_ri_count++; + ri_map[r] = (delta_sz[r] == kShort)? short_index++ : byte_index++; + new_ri_count++; } shortCount = new_short_count; @@ -2145,7 +2485,7 @@ struct VariationStore bool serialize (hb_serialize_context_t *c, const VariationStore *src, - const hb_array_t <hb_inc_bimap_t> &inner_maps) + const hb_array_t <hb_inc_bimap_t> &inner_maps) { TRACE_SERIALIZE (this); unsigned int set_count = 0; @@ -2180,11 +2520,49 @@ struct VariationStore return_trace (true); } + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + + VariationStore *varstore_prime = c->serializer->start_embed<VariationStore> (); + if (unlikely (!varstore_prime)) return_trace (false); + + const hb_set_t *variation_indices = c->plan->layout_variation_indices; + if (variation_indices->is_empty ()) return_trace (false); + + hb_vector_t<hb_inc_bimap_t> inner_maps; + inner_maps.resize ((unsigned) dataSets.len); + for (unsigned i = 0; i < inner_maps.length; i++) + inner_maps[i].init (); + + for (unsigned idx : c->plan->layout_variation_indices->iter ()) + { + uint16_t major = idx >> 16; + uint16_t minor = idx & 0xFFFF; + + if (major >= inner_maps.length) + { + for (unsigned i = 0; i < inner_maps.length; i++) + inner_maps[i].fini (); + return_trace (false); + } + inner_maps[major].add (minor); + } + varstore_prime->serialize (c->serializer, this, inner_maps.as_array ()); + + for (unsigned i = 0; i < inner_maps.length; i++) + inner_maps[i].fini (); + + return_trace ( + !c->serializer->in_error() + && varstore_prime->dataSets); + } + unsigned int get_region_index_count (unsigned int ivs) const { return (this+dataSets[ivs]).get_region_index_count (); } void get_scalars (unsigned int ivs, - int *coords, unsigned int coord_count, + const int *coords, unsigned int coord_count, float *scalars /*OUT*/, unsigned int num_scalars) const { @@ -2216,6 +2594,14 @@ struct ConditionFormat1 { friend struct Condition; + 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 (true); + } + private: bool evaluate (const int *coords, unsigned int coord_len) const { @@ -2248,6 +2634,17 @@ struct Condition } } + template <typename context_t, typename ...Ts> + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { + TRACE_DISPATCH (this, u.format); + if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); + switch (u.format) { + case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...)); + default:return_trace (c->default_return_value ()); + } + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -2278,6 +2675,18 @@ struct ConditionSet return true; } + 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); + + + conditions.iter () + | hb_apply (subset_offset_array (c, out->conditions, this)) + ; + return_trace (true); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -2294,6 +2703,30 @@ struct FeatureTableSubstitutionRecord { friend struct FeatureTableSubstitution; + void collect_lookups (const void *base, hb_set_t *lookup_indexes /* OUT */) const + { + return (base+feature).add_lookup_indexes_to (lookup_indexes); + } + + void closure_features (const void *base, + const hb_map_t *lookup_indexes, + hb_set_t *feature_indexes /* OUT */) const + { + if ((base+feature).intersects_lookup_indexes (lookup_indexes)) + feature_indexes->add (featureIndex); + } + + bool subset (hb_subset_layout_context_t *c, const void *base) const + { + TRACE_SUBSET (this); + auto *out = c->subset_context->serializer->embed (this); + if (unlikely (!out)) return_trace (false); + + out->featureIndex = c->feature_index_map->get (featureIndex); + bool ret = out->feature.serialize_subset (c->subset_context, feature, base, c); + return_trace (ret); + } + bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -2321,6 +2754,39 @@ struct FeatureTableSubstitution return nullptr; } + void collect_lookups (const hb_set_t *feature_indexes, + hb_set_t *lookup_indexes /* OUT */) const + { + + hb_iter (substitutions) + | hb_filter (feature_indexes, &FeatureTableSubstitutionRecord::featureIndex) + | hb_apply ([this, lookup_indexes] (const FeatureTableSubstitutionRecord& r) + { r.collect_lookups (this, lookup_indexes); }) + ; + } + + void closure_features (const hb_map_t *lookup_indexes, + hb_set_t *feature_indexes /* OUT */) const + { + for (const FeatureTableSubstitutionRecord& record : substitutions) + record.closure_features (this, lookup_indexes, feature_indexes); + } + + bool subset (hb_subset_context_t *c, + hb_subset_layout_context_t *l) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + out->version.major = version.major; + out->version.minor = version.minor; + + + substitutions.iter () + | hb_apply (subset_record_array (l, &(out->substitutions), this)) + ; + return_trace (true); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -2341,6 +2807,32 @@ struct FeatureVariationRecord { friend struct FeatureVariations; + void collect_lookups (const void *base, + const hb_set_t *feature_indexes, + hb_set_t *lookup_indexes /* OUT */) const + { + return (base+substitutions).collect_lookups (feature_indexes, lookup_indexes); + } + + void closure_features (const void *base, + const hb_map_t *lookup_indexes, + hb_set_t *feature_indexes /* OUT */) const + { + (base+substitutions).closure_features (lookup_indexes, feature_indexes); + } + + bool subset (hb_subset_layout_context_t *c, const void *base) const + { + TRACE_SUBSET (this); + auto *out = c->subset_context->serializer->embed (this); + if (unlikely (!out)) return_trace (false); + + out->conditions.serialize_subset (c->subset_context, conditions, base); + out->substitutions.serialize_subset (c->subset_context, substitutions, base, c); + + return_trace (true); + } + bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -2362,7 +2854,7 @@ struct FeatureVariations static constexpr unsigned NOT_FOUND_INDEX = 0xFFFFFFFFu; bool find_index (const int *coords, unsigned int coord_len, - unsigned int *index) const + unsigned int *index) const { unsigned int count = varRecords.len; for (unsigned int i = 0; i < count; i++) @@ -2391,6 +2883,36 @@ struct FeatureVariations return_trace (c->embed (*this)); } + void collect_lookups (const hb_set_t *feature_indexes, + hb_set_t *lookup_indexes /* OUT */) const + { + for (const FeatureVariationRecord& r : varRecords) + r.collect_lookups (this, feature_indexes, lookup_indexes); + } + + void closure_features (const hb_map_t *lookup_indexes, + hb_set_t *feature_indexes /* OUT */) const + { + for (const FeatureVariationRecord& record : varRecords) + record.closure_features (this, lookup_indexes, feature_indexes); + } + + bool subset (hb_subset_context_t *c, + hb_subset_layout_context_t *l) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + out->version.major = version.major; + out->version.minor = version.minor; + + + varRecords.iter () + | hb_apply (subset_record_array (l, &(out->varRecords), this)) + ; + return_trace (bool (out->varRecords)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -2506,10 +3028,30 @@ struct VariationDevice hb_position_t get_y_delta (hb_font_t *font, const VariationStore &store) const { return font->em_scalef_y (get_delta (font, store)); } - VariationDevice* copy (hb_serialize_context_t *c) const + VariationDevice* copy (hb_serialize_context_t *c, const hb_map_t *layout_variation_idx_map) const { TRACE_SERIALIZE (this); - return_trace (c->embed<VariationDevice> (this)); + auto snap = c->snapshot (); + auto *out = c->embed (this); + if (unlikely (!out)) return_trace (nullptr); + if (!layout_variation_idx_map || layout_variation_idx_map->is_empty ()) return_trace (out); + + unsigned org_idx = (outerIndex << 16) + innerIndex; + if (!layout_variation_idx_map->has (org_idx)) + { + c->revert (snap); + return_trace (nullptr); + } + unsigned new_idx = layout_variation_idx_map->get (org_idx); + out->outerIndex = new_idx >> 16; + out->innerIndex = new_idx & 0xFFFF; + return_trace (out); + } + + void record_variation_index (hb_set_t *layout_variation_indices) const + { + unsigned var_idx = (outerIndex << 16) + innerIndex; + layout_variation_indices->add (var_idx); } bool sanitize (hb_sanitize_context_t *c) const @@ -2597,7 +3139,7 @@ struct Device } } - Device* copy (hb_serialize_context_t *c) const + Device* copy (hb_serialize_context_t *c, const hb_map_t *layout_variation_idx_map=nullptr) const { TRACE_SERIALIZE (this); switch (u.b.format) { @@ -2609,13 +3151,32 @@ struct Device #endif #ifndef HB_NO_VAR case 0x8000: - return_trace (reinterpret_cast<Device *> (u.variation.copy (c))); + return_trace (reinterpret_cast<Device *> (u.variation.copy (c, layout_variation_idx_map))); #endif default: return_trace (nullptr); } } + void collect_variation_indices (hb_set_t *layout_variation_indices) const + { + switch (u.b.format) { +#ifndef HB_NO_HINTING + case 1: + case 2: + case 3: + return; +#endif +#ifndef HB_NO_VAR + case 0x8000: + u.variation.record_variation_index (layout_variation_indices); + return; +#endif + default: + return; + } + } + protected: union { DeviceHeader b; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh index dc751d88ea..437e760f64 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh @@ -41,8 +41,18 @@ namespace OT { * Attachment List Table */ -typedef ArrayOf<HBUINT16> AttachPoint; /* Array of contour point indices--in - * increasing numerical order */ +/* Array of contour point indices--in increasing numerical order */ +struct AttachPoint : ArrayOf<HBUINT16> +{ + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out)) return_trace (false); + + return_trace (out->serialize (c->serializer, + iter ())); + } +}; struct AttachList { @@ -63,15 +73,36 @@ struct AttachList if (point_count) { - hb_array_t<const HBUINT16> array = points.sub_array (start_offset, point_count); - unsigned int count = array.length; - for (unsigned int i = 0; i < count; i++) - point_array[i] = array[i]; + + points.sub_array (start_offset, point_count) + | hb_sink (hb_array (point_array, *point_count)) + ; } return points.len; } + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + const hb_set_t &glyphset = *c->plan->glyphset (); + const hb_map_t &glyph_map = *c->plan->glyph_map; + + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + + hb_sorted_vector_t<hb_codepoint_t> new_coverage; + + hb_zip (this+coverage, attachPoint) + | hb_filter (glyphset, hb_first) + | hb_filter (subset_offset_array (c, out->attachPoint, this), hb_second) + | hb_map (hb_first) + | hb_map (glyph_map) + | hb_sink (new_coverage) + ; + out->coverage.serialize (c->serializer, out) + .serialize (c->serializer, new_coverage.iter ()); + return_trace (bool (new_coverage)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -96,6 +127,13 @@ struct AttachList struct CaretValueFormat1 { friend struct CaretValue; + 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 (true); + } private: hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction) const @@ -119,6 +157,13 @@ struct CaretValueFormat1 struct CaretValueFormat2 { friend struct CaretValue; + 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 (true); + } private: hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const @@ -153,6 +198,19 @@ struct CaretValueFormat3 font->em_scale_y (coordinate) + (this+deviceTable).get_y_delta (font, var_store); } + 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, c->serializer->to_bias (out), + hb_serialize_context_t::Head, c->plan->layout_variation_idx_map)); + } + + void collect_variation_indices (hb_set_t *layout_variation_indices) const + { (this+deviceTable).collect_variation_indices (layout_variation_indices); } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -173,9 +231,9 @@ struct CaretValueFormat3 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 + hb_direction_t direction, + hb_codepoint_t glyph_id, + const VariationStore &var_store) const { switch (u.format) { case 1: return u.format1.get_caret_value (font, direction); @@ -185,6 +243,32 @@ struct CaretValue } } + template <typename context_t, typename ...Ts> + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { + TRACE_DISPATCH (this, u.format); + if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); + switch (u.format) { + case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...)); + case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...)); + case 3: return_trace (c->dispatch (u.format3, hb_forward<Ts> (ds)...)); + default:return_trace (c->default_return_value ()); + } + } + + void collect_variation_indices (hb_set_t *layout_variation_indices) const + { + switch (u.format) { + case 1: + case 2: + return; + case 3: + u.format3.collect_variation_indices (layout_variation_indices); + return; + default: return; + } + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -210,25 +294,45 @@ struct CaretValue struct LigGlyph { - unsigned int get_lig_carets (hb_font_t *font, - hb_direction_t direction, - hb_codepoint_t glyph_id, - const VariationStore &var_store, - unsigned int start_offset, - unsigned int *caret_count /* IN/OUT */, - hb_position_t *caret_array /* OUT */) const + unsigned get_lig_carets (hb_font_t *font, + hb_direction_t direction, + hb_codepoint_t glyph_id, + const VariationStore &var_store, + unsigned start_offset, + unsigned *caret_count /* IN/OUT */, + hb_position_t *caret_array /* OUT */) const { if (caret_count) { - hb_array_t <const OffsetTo<CaretValue>> array = carets.sub_array (start_offset, caret_count); - unsigned int count = array.length; - for (unsigned int i = 0; i < count; i++) - caret_array[i] = (this+array[i]).get_caret_value (font, direction, glyph_id, var_store); + + carets.sub_array (start_offset, caret_count) + | hb_map (hb_add (this)) + | hb_map ([&] (const CaretValue &value) { return value.get_caret_value (font, direction, glyph_id, var_store); }) + | hb_sink (hb_array (caret_array, *caret_count)) + ; } return carets.len; } + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + + + hb_iter (carets) + | hb_apply (subset_offset_array (c, out->carets, this)) + ; + + return_trace (bool (out->carets)); + } + + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const + { + for (const OffsetTo<CaretValue>& offset : carets.iter ()) + (this+offset).collect_variation_indices (c->layout_variation_indices); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -265,6 +369,38 @@ struct LigCaretList return lig_glyph.get_lig_carets (font, direction, glyph_id, var_store, start_offset, caret_count, caret_array); } + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + const hb_set_t &glyphset = *c->plan->glyphset (); + const hb_map_t &glyph_map = *c->plan->glyph_map; + + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + + hb_sorted_vector_t<hb_codepoint_t> new_coverage; + + hb_zip (this+coverage, ligGlyph) + | hb_filter (glyphset, hb_first) + | hb_filter (subset_offset_array (c, out->ligGlyph, this), hb_second) + | hb_map (hb_first) + | hb_map (glyph_map) + | hb_sink (new_coverage) + ; + out->coverage.serialize (c->serializer, out) + .serialize (c->serializer, new_coverage.iter ()); + return_trace (bool (new_coverage)); + } + + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const + { + + hb_zip (this+coverage, ligGlyph) + | hb_filter (c->glyph_set, hb_first) + | hb_map (hb_second) + | hb_map (hb_add (this)) + | hb_apply ([c] (const LigGlyph& _) { _.collect_variation_indices (c); }) + ; + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -288,6 +424,34 @@ struct MarkGlyphSetsFormat1 bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const { return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; } + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + out->format = format; + + bool ret = true; + for (const LOffsetTo<Coverage>& offset : coverage.iter ()) + { + auto *o = out->coverage.serialize_append (c->serializer); + if (unlikely (!o)) + { + ret = false; + break; + } + + //not using o->serialize_subset (c, offset, this, out) here because + //OTS doesn't allow null offset. + //See issue: https://github.com/khaledhosny/ots/issues/172 + c->serializer->push (); + c->dispatch (this+offset); + c->serializer->add_link (*o, c->serializer->pop_pack ()); + } + + return_trace (ret && out->coverage.len); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -313,6 +477,15 @@ struct MarkGlyphSets } } + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + switch (u.format) { + case 1: return_trace (u.format1.subset (c)); + default:return_trace (false); + } + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -356,7 +529,7 @@ struct GDEF unsigned int get_glyph_class (hb_codepoint_t glyph) const { return (this+glyphClassDef).get_class (glyph); } void get_glyphs_in_class (unsigned int klass, hb_set_t *glyphs) const - { (this+glyphClassDef).add_class (glyphs, klass); } + { (this+glyphClassDef).collect_class (glyphs, klass); } bool has_mark_attachment_types () const { return markAttachClassDef != 0; } unsigned int get_mark_attachment_type (hb_codepoint_t glyph) const @@ -386,7 +559,7 @@ struct GDEF bool has_var_store () const { return version.to_int () >= 0x00010003u && varStore != 0; } const VariationStore &get_var_store () const - { return version.to_int () >= 0x00010003u ? this+varStore : Null(VariationStore); } + { return version.to_int () >= 0x00010003u ? this+varStore : Null (VariationStore); } /* glyph_props is a 16-bit integer where the lower 8-bit have bits representing * glyph class and other bits, and high 8-bit the mark attachment type (if any). @@ -409,15 +582,15 @@ struct GDEF } } - HB_INTERNAL bool is_blacklisted (hb_blob_t *blob, + HB_INTERNAL bool is_blocklisted (hb_blob_t *blob, hb_face_t *face) const; struct accelerator_t { void init (hb_face_t *face) { - this->table = hb_sanitize_context_t().reference_table<GDEF> (face); - if (unlikely (this->table->is_blacklisted (this->table.get_blob (), face))) + this->table = hb_sanitize_context_t ().reference_table<GDEF> (face); + if (unlikely (this->table->is_blocklisted (this->table.get_blob (), face))) { hb_blob_destroy (this->table.get_blob ()); this->table = hb_blob_get_empty (); @@ -436,24 +609,66 @@ struct GDEF (version.to_int () >= 0x00010003u ? varStore.static_size : 0); } + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const + { (this+ligCaretList).collect_variation_indices (c); } + + void remap_layout_variation_indices (const hb_set_t *layout_variation_indices, + hb_map_t *layout_variation_idx_map /* OUT */) const + { + if (version.to_int () < 0x00010003u || !varStore) return; + if (layout_variation_indices->is_empty ()) return; + + unsigned new_major = 0, new_minor = 0; + unsigned last_major = (layout_variation_indices->get_min ()) >> 16; + for (unsigned idx : layout_variation_indices->iter ()) + { + uint16_t major = idx >> 16; + if (major >= (this+varStore).get_sub_table_count ()) break; + if (major != last_major) + { + new_minor = 0; + ++new_major; + } + + unsigned new_idx = (new_major << 16) + new_minor; + layout_variation_idx_map->set (idx, new_idx); + ++new_minor; + last_major = major; + } + } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (*this); if (unlikely (!out)) return_trace (false); - out->glyphClassDef.serialize_subset (c, glyphClassDef, this, out); - out->attachList = 0;//TODO(subset) serialize_subset (c, attachList, this, out); - out->ligCaretList = 0;//TODO(subset) serialize_subset (c, ligCaretList, this, out); - out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this, out); + bool subset_glyphclassdef = out->glyphClassDef.serialize_subset (c, glyphClassDef, this); + bool subset_attachlist = out->attachList.serialize_subset (c, attachList, this); + bool subset_ligcaretlist = out->ligCaretList.serialize_subset (c, ligCaretList, this); + bool subset_markattachclassdef = out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this); + bool subset_markglyphsetsdef = true; if (version.to_int () >= 0x00010002u) - out->markGlyphSetsDef = 0;// TODO(subset) serialize_subset (c, markGlyphSetsDef, this, out); + { + subset_markglyphsetsdef = out->markGlyphSetsDef.serialize_subset (c, markGlyphSetsDef, this); + if (!subset_markglyphsetsdef && + version.to_int () == 0x00010002u) + out->version.minor = 0; + } + bool subset_varstore = true; if (version.to_int () >= 0x00010003u) - out->varStore = 0;// TODO(subset) serialize_subset (c, varStore, this, out); + { + subset_varstore = out->varStore.serialize_subset (c, varStore, this); + if (!subset_varstore && version.to_int () == 0x00010003u) + out->version.minor = 2; + } - return_trace (true); + return_trace (subset_glyphclassdef || subset_attachlist || + subset_ligcaretlist || subset_markattachclassdef || + (out->version.to_int () >= 0x00010002u && subset_markglyphsetsdef) || + (out->version.to_int () >= 0x00010003u && subset_varstore)); } bool sanitize (hb_sanitize_context_t *c) const diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh index 024312d610..f523e35c00 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh @@ -34,6 +34,11 @@ namespace OT { +struct MarkArray; +static void Markclass_closure_and_remap_indexes (const Coverage &mark_coverage, + const MarkArray &mark_array, + const hb_set_t &glyphset, + hb_map_t* klass_mapping /* INOUT */); /* buffer **position** var allocations */ #define attach_chain() var.i16[0] /* glyph to which this attaches to, relative to current glyphs; negative for going back, positive for forward. */ @@ -74,14 +79,14 @@ struct ValueFormat : HBUINT16 /* All fields are options. Only those available advance the value pointer. */ #if 0 - HBINT16 xPlacement; /* Horizontal adjustment for + HBINT16 xPlacement; /* Horizontal adjustment for * placement--in design units */ - HBINT16 yPlacement; /* Vertical adjustment for + HBINT16 yPlacement; /* Vertical adjustment for * placement--in design units */ - HBINT16 xAdvance; /* Horizontal adjustment for + HBINT16 xAdvance; /* Horizontal adjustment for * advance--in design units (only used * for horizontal writing) */ - HBINT16 yAdvance; /* Vertical adjustment for advance--in + HBINT16 yAdvance; /* Vertical adjustment for advance--in * design units (only used for vertical * writing) */ OffsetTo<Device> xPlaDevice; /* Offset to Device table for @@ -155,6 +160,60 @@ struct ValueFormat : HBUINT16 return ret; } + void serialize_copy (hb_serialize_context_t *c, const void *base, + const Value *values, const hb_map_t *layout_variation_idx_map) const + { + unsigned int format = *this; + if (!format) return; + + if (format & xPlacement) c->copy (*values++); + if (format & yPlacement) c->copy (*values++); + if (format & xAdvance) c->copy (*values++); + if (format & yAdvance) c->copy (*values++); + + if (format & xPlaDevice) copy_device (c, base, values++, layout_variation_idx_map); + if (format & yPlaDevice) copy_device (c, base, values++, layout_variation_idx_map); + if (format & xAdvDevice) copy_device (c, base, values++, layout_variation_idx_map); + if (format & yAdvDevice) copy_device (c, base, values++, layout_variation_idx_map); + } + + void collect_variation_indices (hb_collect_variation_indices_context_t *c, + const void *base, + const hb_array_t<const Value>& values) const + { + unsigned format = *this; + unsigned i = 0; + if (format & xPlacement) i++; + if (format & yPlacement) i++; + if (format & xAdvance) i++; + if (format & yAdvance) i++; + if (format & xPlaDevice) + { + (base + get_device (&(values[i]))).collect_variation_indices (c->layout_variation_indices); + i++; + } + + if (format & ValueFormat::yPlaDevice) + { + (base + get_device (&(values[i]))).collect_variation_indices (c->layout_variation_indices); + i++; + } + + if (format & ValueFormat::xAdvDevice) + { + + (base + get_device (&(values[i]))).collect_variation_indices (c->layout_variation_indices); + i++; + } + + if (format & ValueFormat::yAdvDevice) + { + + (base + get_device (&(values[i]))).collect_variation_indices (c->layout_variation_indices); + i++; + } + } + private: bool sanitize_value_devices (hb_sanitize_context_t *c, const void *base, const Value *values) const { @@ -173,18 +232,42 @@ struct ValueFormat : HBUINT16 return true; } - HB_INTERNAL static OffsetTo<Device>& get_device (Value* value) - { return *CastP<OffsetTo<Device>> (value); } - HB_INTERNAL static const OffsetTo<Device>& get_device (const Value* value, bool *worked=nullptr) + static inline OffsetTo<Device>& get_device (Value* value) + { + return *static_cast<OffsetTo<Device> *> (value); + } + static inline const OffsetTo<Device>& get_device (const Value* value, bool *worked=nullptr) { if (worked) *worked |= bool (*value); - return *CastP<OffsetTo<Device>> (value); + return *static_cast<const OffsetTo<Device> *> (value); + } + + bool copy_device (hb_serialize_context_t *c, const void *base, + const Value *src_value, const hb_map_t *layout_variation_idx_map) const + { + Value *dst_value = c->copy (*src_value); + + if (!dst_value) return false; + if (*dst_value == 0) return true; + + *dst_value = 0; + c->push (); + if ((base + get_device (src_value)).copy (c, layout_variation_idx_map)) + { + c->add_link (*dst_value, c->pop_pack ()); + return true; + } + else + { + c->pop_discard (); + return false; + } } - HB_INTERNAL static const HBINT16& get_short (const Value* value, bool *worked=nullptr) + static inline const HBINT16& get_short (const Value* value, bool *worked=nullptr) { if (worked) *worked |= bool (*value); - return *CastP<HBINT16> (value); + return *reinterpret_cast<const HBINT16 *> (value); } public: @@ -237,9 +320,11 @@ struct ValueFormat : HBUINT16 }; template<typename Iterator> -static inline void SinglePos_serialize (hb_serialize_context_t *c, - Iterator it, - ValueFormat valFormat); +static void SinglePos_serialize (hb_serialize_context_t *c, + const void *src, + Iterator it, + ValueFormat valFormat, + const hb_map_t *layout_variation_idx_map); struct AnchorFormat1 @@ -338,17 +423,26 @@ struct AnchorFormat3 return_trace (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this)); } - AnchorFormat3* copy (hb_serialize_context_t *c) const + AnchorFormat3* copy (hb_serialize_context_t *c, + const hb_map_t *layout_variation_idx_map) const { TRACE_SERIALIZE (this); + if (!layout_variation_idx_map) return_trace (nullptr); + auto *out = c->embed<AnchorFormat3> (this); if (unlikely (!out)) return_trace (nullptr); - out->xDeviceTable.serialize_copy (c, xDeviceTable, this, out); - out->yDeviceTable.serialize_copy (c, yDeviceTable, this, out); + out->xDeviceTable.serialize_copy (c, xDeviceTable, this, 0, hb_serialize_context_t::Head, layout_variation_idx_map); + out->yDeviceTable.serialize_copy (c, yDeviceTable, this, 0, hb_serialize_context_t::Head, layout_variation_idx_map); return_trace (out); } + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const + { + (this+xDeviceTable).collect_variation_indices (c->layout_variation_indices); + (this+yDeviceTable).collect_variation_indices (c->layout_variation_indices); + } + protected: HBUINT16 format; /* Format identifier--format = 3 */ FWORD xCoordinate; /* Horizontal value--in design units */ @@ -391,17 +485,29 @@ struct Anchor } } - Anchor* copy (hb_serialize_context_t *c) const + Anchor* copy (hb_serialize_context_t *c, const hb_map_t *layout_variation_idx_map) const { TRACE_SERIALIZE (this); switch (u.format) { case 1: return_trace (reinterpret_cast<Anchor *> (u.format1.copy (c))); case 2: return_trace (reinterpret_cast<Anchor *> (u.format2.copy (c))); - case 3: return_trace (reinterpret_cast<Anchor *> (u.format3.copy (c))); + case 3: return_trace (reinterpret_cast<Anchor *> (u.format3.copy (c, layout_variation_idx_map))); default:return_trace (nullptr); } } + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const + { + switch (u.format) { + case 1: case 2: + return; + case 3: + u.format3.collect_variation_indices (c); + return; + default: return; + } + } + protected: union { HBUINT16 format; /* Format identifier */ @@ -420,11 +526,66 @@ struct AnchorMatrix unsigned int cols, bool *found) const { *found = false; - if (unlikely (row >= rows || col >= cols)) return Null(Anchor); + if (unlikely (row >= rows || col >= cols)) return Null (Anchor); *found = !matrixZ[row * cols + col].is_null (); return this+matrixZ[row * cols + col]; } + template <typename Iterator, + hb_requires (hb_is_iterator (Iterator))> + void collect_variation_indices (hb_collect_variation_indices_context_t *c, + Iterator index_iter) const + { + for (unsigned i : index_iter) + (this+matrixZ[i]).collect_variation_indices (c); + } + + template <typename Iterator, + hb_requires (hb_is_iterator (Iterator))> + bool serialize (hb_serialize_context_t *c, + unsigned num_rows, + AnchorMatrix const *offset_matrix, + const hb_map_t *layout_variation_idx_map, + Iterator index_iter) + { + TRACE_SERIALIZE (this); + if (!index_iter) return_trace (false); + if (unlikely (!c->extend_min ((*this)))) return_trace (false); + + this->rows = num_rows; + for (const unsigned i : index_iter) + { + auto *offset = c->embed (offset_matrix->matrixZ[i]); + if (!offset) return_trace (false); + offset->serialize_copy (c, offset_matrix->matrixZ[i], + offset_matrix, c->to_bias (this), + hb_serialize_context_t::Head, + layout_variation_idx_map); + } + + return_trace (true); + } + + bool subset (hb_subset_context_t *c, + unsigned cols, + const hb_map_t *klass_mapping) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + + auto indexes = + + hb_range (rows * cols) + | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % cols); }) + ; + + out->serialize (c->serializer, + (unsigned) rows, + this, + c->plan->layout_variation_idx_map, + indexes); + return_trace (true); + } + bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const { TRACE_SANITIZE (this); @@ -438,7 +599,6 @@ struct AnchorMatrix } HBUINT16 rows; /* Number of rows */ - protected: UnsizedArrayOf<OffsetTo<Anchor>> matrixZ; /* Matrix of offsets to Anchor tables-- * from beginning of AnchorMatrix table */ @@ -451,12 +611,34 @@ struct MarkRecord { friend struct MarkArray; + unsigned get_class () const { return (unsigned) klass; } bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && markAnchor.sanitize (c, base)); } + MarkRecord *copy (hb_serialize_context_t *c, + const void *src_base, + unsigned dst_bias, + const hb_map_t *klass_mapping, + const hb_map_t *layout_variation_idx_map) const + { + TRACE_SERIALIZE (this); + auto *out = c->embed (this); + if (unlikely (!out)) return_trace (nullptr); + + out->klass = klass_mapping->get (klass); + out->markAnchor.serialize_copy (c, markAnchor, src_base, dst_bias, hb_serialize_context_t::Head, layout_variation_idx_map); + return_trace (out); + } + + void collect_variation_indices (hb_collect_variation_indices_context_t *c, + const void *src_base) const + { + (src_base+markAnchor).collect_variation_indices (c); + } + protected: HBUINT16 klass; /* Class defined for this mark */ OffsetTo<Anchor> @@ -502,6 +684,21 @@ struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage orde return_trace (true); } + template<typename Iterator, + hb_requires (hb_is_source_of (Iterator, MarkRecord))> + bool serialize (hb_serialize_context_t *c, + const hb_map_t *klass_mapping, + const hb_map_t *layout_variation_idx_map, + const void *base, + Iterator it) + { + TRACE_SERIALIZE (this); + if (unlikely (!c->extend_min (*this))) return_trace (false); + if (unlikely (!c->check_assign (len, it.len ()))) return_trace (false); + c->copy_all (it, base, c->to_bias (this), klass_mapping, layout_variation_idx_map); + return_trace (true); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -517,8 +714,22 @@ struct SinglePosFormat1 bool intersects (const hb_set_t *glyphs) const { return (this+coverage).intersects (glyphs); } + void closure_lookups (hb_closure_lookups_context_t *c) const {} + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const + { + if (!valueFormat.has_device ()) return; + + auto it = + + hb_iter (this+coverage) + | hb_filter (c->glyph_set) + ; + + if (!it) return; + valueFormat.collect_variation_indices (c, this, values.as_array (valueFormat.get_len ())); + } + void collect_glyphs (hb_collect_glyphs_context_t *c) const - { if (unlikely (!(this+coverage).add_coverage (c->input))) return; } + { if (unlikely (!(this+coverage).collect_coverage (c->input))) return; } const Coverage &get_coverage () const { return this+coverage; } @@ -538,14 +749,20 @@ struct SinglePosFormat1 template<typename Iterator, hb_requires (hb_is_iterator (Iterator))> void serialize (hb_serialize_context_t *c, + const void *src, Iterator it, - ValueFormat valFormat) + ValueFormat valFormat, + const hb_map_t *layout_variation_idx_map) { - if (unlikely (!c->extend_min (*this))) return; + auto out = c->extend_min (*this); + if (unlikely (!out)) return; if (unlikely (!c->check_assign (valueFormat, valFormat))) return; - for (const auto &_ : hb_second (*it)) - c->copy (_); + + it + | hb_map (hb_second) + | hb_apply ([&] (hb_array_t<const Value> _) + { valFormat.serialize_copy (c, src, &_, layout_variation_idx_map); }) + ; auto glyphs = + it @@ -558,7 +775,7 @@ struct SinglePosFormat1 bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->glyphset (); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; auto it = @@ -569,7 +786,7 @@ struct SinglePosFormat1 ; bool ret = bool (it); - SinglePos_serialize (c->serializer, it, valueFormat); + SinglePos_serialize (c->serializer, this, it, valueFormat, c->plan->layout_variation_idx_map); return_trace (ret); } @@ -600,8 +817,29 @@ struct SinglePosFormat2 bool intersects (const hb_set_t *glyphs) const { return (this+coverage).intersects (glyphs); } + void closure_lookups (hb_closure_lookups_context_t *c) const {} + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const + { + if (!valueFormat.has_device ()) return; + + auto it = + + hb_zip (this+coverage, hb_range ((unsigned) valueCount)) + | hb_filter (c->glyph_set, hb_first) + ; + + if (!it) return; + + unsigned sub_length = valueFormat.get_len (); + const hb_array_t<const Value> values_array = values.as_array (valueCount * sub_length); + + for (unsigned i : + it + | hb_map (hb_second)) + valueFormat.collect_variation_indices (c, this, values_array.sub_array (i * sub_length, sub_length)); + + } + void collect_glyphs (hb_collect_glyphs_context_t *c) const - { if (unlikely (!(this+coverage).add_coverage (c->input))) return; } + { if (unlikely (!(this+coverage).collect_coverage (c->input))) return; } const Coverage &get_coverage () const { return this+coverage; } @@ -625,16 +863,21 @@ struct SinglePosFormat2 template<typename Iterator, hb_requires (hb_is_iterator (Iterator))> void serialize (hb_serialize_context_t *c, + const void *src, Iterator it, - ValueFormat valFormat) + ValueFormat valFormat, + const hb_map_t *layout_variation_idx_map) { - if (unlikely (!c->extend_min (*this))) return; + auto out = c->extend_min (*this); + if (unlikely (!out)) return; if (unlikely (!c->check_assign (valueFormat, valFormat))) return; if (unlikely (!c->check_assign (valueCount, it.len ()))) return; - for (const auto iter : it) - for (const auto &_ : iter.second) - c->copy (_); + + it + | hb_map (hb_second) + | hb_apply ([&] (hb_array_t<const Value> _) + { valFormat.serialize_copy (c, src, &_, layout_variation_idx_map); }) + ; auto glyphs = + it @@ -647,7 +890,7 @@ struct SinglePosFormat2 bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->glyphset (); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; unsigned sub_length = valueFormat.get_len (); @@ -665,7 +908,7 @@ struct SinglePosFormat2 ; bool ret = bool (it); - SinglePos_serialize (c->serializer, it, valueFormat); + SinglePos_serialize (c->serializer, this, it, valueFormat, c->plan->layout_variation_idx_map); return_trace (ret); } @@ -711,8 +954,10 @@ struct SinglePos template<typename Iterator, hb_requires (hb_is_iterator (Iterator))> void serialize (hb_serialize_context_t *c, + const void *src, Iterator glyph_val_iter_pairs, - ValueFormat valFormat) + ValueFormat valFormat, + const hb_map_t *layout_variation_idx_map) { if (unlikely (!c->extend_min (u.format))) return; unsigned format = 2; @@ -721,9 +966,9 @@ struct SinglePos u.format = format; switch (u.format) { - case 1: u.format1.serialize (c, glyph_val_iter_pairs, valFormat); + case 1: u.format1.serialize (c, src, glyph_val_iter_pairs, valFormat, layout_variation_idx_map); return; - case 2: u.format2.serialize (c, glyph_val_iter_pairs, valFormat); + case 2: u.format2.serialize (c, src, glyph_val_iter_pairs, valFormat, layout_variation_idx_map); return; default:return; } @@ -750,27 +995,59 @@ struct SinglePos }; template<typename Iterator> -static inline void +static void SinglePos_serialize (hb_serialize_context_t *c, + const void *src, Iterator it, - ValueFormat valFormat) -{ c->start_embed<SinglePos> ()->serialize (c, it, valFormat); } + ValueFormat valFormat, + const hb_map_t *layout_variation_idx_map) +{ c->start_embed<SinglePos> ()->serialize (c, src, it, valFormat, layout_variation_idx_map); } struct PairValueRecord { friend struct PairSet; + int cmp (hb_codepoint_t k) const + { return secondGlyph.cmp (k); } + + struct serialize_closure_t + { + const void *base; + const ValueFormat *valueFormats; + unsigned len1; /* valueFormats[0].get_len() */ + const hb_map_t *glyph_map; + const hb_map_t *layout_variation_idx_map; + }; + bool serialize (hb_serialize_context_t *c, - unsigned length, - const hb_map_t &glyph_map) const + serialize_closure_t *closure) const { TRACE_SERIALIZE (this); auto *out = c->start_embed (*this); if (unlikely (!c->extend_min (out))) return_trace (false); - - out->secondGlyph = glyph_map[secondGlyph]; - return_trace (c->copy (values, length)); + + out->secondGlyph = (*closure->glyph_map)[secondGlyph]; + + closure->valueFormats[0].serialize_copy (c, closure->base, &values[0], closure->layout_variation_idx_map); + closure->valueFormats[1].serialize_copy (c, closure->base, &values[closure->len1], closure->layout_variation_idx_map); + + return_trace (true); + } + + void collect_variation_indices (hb_collect_variation_indices_context_t *c, + const ValueFormat *valueFormats, + const void *base) const + { + unsigned record1_len = valueFormats[0].get_len (); + unsigned record2_len = valueFormats[1].get_len (); + const hb_array_t<const Value> values_array = values.as_array (record1_len + record2_len); + + if (valueFormats[0].has_device ()) + valueFormats[0].collect_variation_indices (c, base, values_array.sub_array (0, record1_len)); + + if (valueFormats[1].has_device ()) + valueFormats[1].collect_variation_indices (c, base, values_array.sub_array (record1_len, record2_len)); } protected: @@ -806,7 +1083,7 @@ struct PairSet } void collect_glyphs (hb_collect_glyphs_context_t *c, - const ValueFormat *valueFormats) const + const ValueFormat *valueFormats) const { unsigned int len1 = valueFormats[0].get_len (); unsigned int len2 = valueFormats[1].get_len (); @@ -816,9 +1093,27 @@ struct PairSet c->input->add_array (&record->secondGlyph, len, record_size); } + void collect_variation_indices (hb_collect_variation_indices_context_t *c, + const ValueFormat *valueFormats) const + { + unsigned len1 = valueFormats[0].get_len (); + unsigned len2 = valueFormats[1].get_len (); + unsigned record_size = HBUINT16::static_size * (1 + len1 + len2); + + const PairValueRecord *record = &firstPairValueRecord; + unsigned count = len; + for (unsigned i = 0; i < count; i++) + { + if (c->glyph_set->has (record->secondGlyph)) + { record->collect_variation_indices (c, valueFormats, this); } + + record = &StructAtOffset<const PairValueRecord> (record, record_size); + } + } + bool apply (hb_ot_apply_context_t *c, - const ValueFormat *valueFormats, - unsigned int pos) const + const ValueFormat *valueFormats, + unsigned int pos) const { TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; @@ -826,40 +1121,26 @@ struct PairSet unsigned int len2 = valueFormats[1].get_len (); unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2); - unsigned int count = len; - - /* Hand-coded bsearch. */ - if (unlikely (!count)) - return_trace (false); - hb_codepoint_t x = buffer->info[pos].codepoint; - int min = 0, max = (int) count - 1; - while (min <= max) + const PairValueRecord *record = hb_bsearch (buffer->info[pos].codepoint, + &firstPairValueRecord, + len, + record_size); + if (record) { - int mid = ((unsigned int) min + (unsigned int) max) / 2; - const PairValueRecord *record = &StructAtOffset<PairValueRecord> (&firstPairValueRecord, record_size * mid); - hb_codepoint_t mid_x = record->secondGlyph; - if (x < mid_x) - max = mid - 1; - else if (x > mid_x) - min = mid + 1; - else - { - /* Note the intentional use of "|" instead of short-circuit "||". */ - if (valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos()) | - valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos])) - buffer->unsafe_to_break (buffer->idx, pos + 1); - if (len2) - pos++; - buffer->idx = pos; - return_trace (true); - } + /* Note the intentional use of "|" instead of short-circuit "||". */ + if (valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos()) | + valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos])) + buffer->unsafe_to_break (buffer->idx, pos + 1); + if (len2) + pos++; + buffer->idx = pos; + return_trace (true); } - return_trace (false); } bool subset (hb_subset_context_t *c, - const ValueFormat valueFormats[2]) const + const ValueFormat valueFormats[2]) const { TRACE_SUBSET (this); auto snap = c->serializer->snapshot (); @@ -868,19 +1149,28 @@ struct PairSet if (unlikely (!c->serializer->extend_min (out))) return_trace (false); out->len = 0; - const hb_set_t &glyphset = *c->plan->glyphset (); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; unsigned len1 = valueFormats[0].get_len (); unsigned len2 = valueFormats[1].get_len (); unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2); + PairValueRecord::serialize_closure_t closure = + { + this, + valueFormats, + len1, + &glyph_map, + c->plan->layout_variation_idx_map + }; + const PairValueRecord *record = &firstPairValueRecord; unsigned count = len, num = 0; for (unsigned i = 0; i < count; i++) { - if (!glyphset.has (record->secondGlyph)) continue; - if (record->serialize (c->serializer, len1 + len2, glyph_map)) num++; + if (glyphset.has (record->secondGlyph) + && record->serialize (c->serializer, &closure)) num++; record = &StructAtOffset<const PairValueRecord> (record, record_size); } @@ -891,7 +1181,6 @@ struct PairSet struct sanitize_closure_t { - const void *base; const ValueFormat *valueFormats; unsigned int len1; /* valueFormats[0].get_len() */ unsigned int stride; /* 1 + len1 + len2 */ @@ -908,8 +1197,8 @@ struct PairSet unsigned int count = len; const PairValueRecord *record = &firstPairValueRecord; - return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, closure->base, &record->values[0], count, closure->stride) && - closure->valueFormats[1].sanitize_values_stride_unsafe (c, closure->base, &record->values[closure->len1], count, closure->stride)); + return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, this, &record->values[0], count, closure->stride) && + closure->valueFormats[1].sanitize_values_stride_unsafe (c, this, &record->values[closure->len1], count, closure->stride)); } protected: @@ -935,9 +1224,27 @@ struct PairPosFormat1 ; } + void closure_lookups (hb_closure_lookups_context_t *c) const {} + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const + { + if ((!valueFormat[0].has_device ()) && (!valueFormat[1].has_device ())) return; + + auto it = + + hb_zip (this+coverage, pairSet) + | hb_filter (c->glyph_set, hb_first) + | hb_map (hb_second) + ; + + if (!it) return; + + it + | hb_map (hb_add (this)) + | hb_apply ([&] (const PairSet& _) { _.collect_variation_indices (c, valueFormat); }) + ; + } + void collect_glyphs (hb_collect_glyphs_context_t *c) const { - if (unlikely (!(this+coverage).add_coverage (c->input))) return; + if (unlikely (!(this+coverage).collect_coverage (c->input))) return; unsigned int count = pairSet.len; for (unsigned int i = 0; i < count; i++) (this+pairSet[i]).collect_glyphs (c, valueFormat); @@ -963,7 +1270,7 @@ struct PairPosFormat1 { TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->glyphset (); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; auto *out = c->serializer->start_embed (*this); @@ -981,7 +1288,7 @@ struct PairPosFormat1 auto *o = out->pairSet.serialize_append (c->serializer); if (unlikely (!o)) return false; auto snap = c->serializer->snapshot (); - bool ret = o->serialize_subset (c, _, this, out, valueFormat); + bool ret = o->serialize_subset (c, _, this, valueFormat); if (!ret) { out->pairSet.pop (); @@ -1011,7 +1318,6 @@ struct PairPosFormat1 unsigned int len2 = valueFormat[1].get_len (); PairSet::sanitize_closure_t closure = { - this, valueFormat, len1, 1 + len1 + len2 @@ -1046,10 +1352,43 @@ struct PairPosFormat2 (this+classDef2).intersects (glyphs); } + void closure_lookups (hb_closure_lookups_context_t *c) const {} + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const + { + if ((!valueFormat1.has_device ()) && (!valueFormat2.has_device ())) return; + + hb_set_t class1_set, class2_set; + for (const unsigned cp : c->glyph_set->iter ()) + { + unsigned klass1 = (this+classDef1).get (cp); + unsigned klass2 = (this+classDef2).get (cp); + class1_set.add (klass1); + class2_set.add (klass2); + } + + if (class1_set.is_empty () || class2_set.is_empty ()) return; + + unsigned len1 = valueFormat1.get_len (); + unsigned len2 = valueFormat2.get_len (); + const hb_array_t<const Value> values_array = values.as_array ((unsigned)class1Count * (unsigned) class2Count * (len1 + len2)); + for (const unsigned class1_idx : class1_set.iter ()) + { + for (const unsigned class2_idx : class2_set.iter ()) + { + unsigned start_offset = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2); + if (valueFormat1.has_device ()) + valueFormat1.collect_variation_indices (c, this, values_array.sub_array (start_offset, len1)); + + if (valueFormat2.has_device ()) + valueFormat2.collect_variation_indices (c, this, values_array.sub_array (start_offset+len1, len2)); + } + } + } + void collect_glyphs (hb_collect_glyphs_context_t *c) const { - if (unlikely (!(this+coverage).add_coverage (c->input))) return; - if (unlikely (!(this+classDef2).add_coverage (c->input))) return; + if (unlikely (!(this+coverage).collect_coverage (c->input))) return; + if (unlikely (!(this+classDef2).collect_coverage (c->input))) return; } const Coverage &get_coverage () const { return this+coverage; } @@ -1096,32 +1435,33 @@ struct PairPosFormat2 out->valueFormat2 = valueFormat2; hb_map_t klass1_map; - out->classDef1.serialize_subset (c, classDef1, this, out, &klass1_map); + out->classDef1.serialize_subset (c, classDef1, this, &klass1_map); out->class1Count = klass1_map.get_population (); hb_map_t klass2_map; - out->classDef2.serialize_subset (c, classDef2, this, out, &klass2_map); + out->classDef2.serialize_subset (c, classDef2, this, &klass2_map); out->class2Count = klass2_map.get_population (); - unsigned record_len = valueFormat1.get_len () + valueFormat2.get_len (); + unsigned len1 = valueFormat1.get_len (); + unsigned len2 = valueFormat2.get_len (); + hb_range ((unsigned) class1Count) | hb_filter (klass1_map) | hb_apply ([&] (const unsigned class1_idx) - { - + hb_range ((unsigned) class2Count) - | hb_filter (klass2_map) - | hb_apply ([&] (const unsigned class2_idx) - { - unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * record_len; - for (unsigned i = 0; i < record_len; i++) - c->serializer->copy (values[idx+i]); - }) - ; - }) + { + + hb_range ((unsigned) class2Count) + | hb_filter (klass2_map) + | hb_apply ([&] (const unsigned class2_idx) + { + unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2); + valueFormat1.serialize_copy (c->serializer, this, &values[idx], c->plan->layout_variation_idx_map); + valueFormat2.serialize_copy (c->serializer, this, &values[idx + len1], c->plan->layout_variation_idx_map); + }) + ; + }) ; - const hb_set_t &glyphset = *c->plan->glyphset (); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; auto it = @@ -1217,16 +1557,24 @@ struct EntryExitRecord return_trace (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base)); } + void collect_variation_indices (hb_collect_variation_indices_context_t *c, + const void *src_base) const + { + (src_base+entryAnchor).collect_variation_indices (c); + (src_base+exitAnchor).collect_variation_indices (c); + } + EntryExitRecord* copy (hb_serialize_context_t *c, const void *src_base, - const void *dst_base) const + const void *dst_base, + const hb_map_t *layout_variation_idx_map) const { TRACE_SERIALIZE (this); auto *out = c->embed (this); if (unlikely (!out)) return_trace (nullptr); - out->entryAnchor.serialize_copy (c, entryAnchor, src_base, dst_base); - out->exitAnchor.serialize_copy (c, exitAnchor, src_base, dst_base); + out->entryAnchor.serialize_copy (c, entryAnchor, src_base, c->to_bias (dst_base), hb_serialize_context_t::Head, layout_variation_idx_map); + out->exitAnchor.serialize_copy (c, exitAnchor, src_base, c->to_bias (dst_base), hb_serialize_context_t::Head, layout_variation_idx_map); return_trace (out); } @@ -1251,8 +1599,19 @@ struct CursivePosFormat1 bool intersects (const hb_set_t *glyphs) const { return (this+coverage).intersects (glyphs); } + void closure_lookups (hb_closure_lookups_context_t *c) const {} + + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const + { + + hb_zip (this+coverage, entryExitRecord) + | hb_filter (c->glyph_set, hb_first) + | hb_map (hb_second) + | hb_apply ([&] (const EntryExitRecord& record) { record.collect_variation_indices (c, this); }) + ; + } + void collect_glyphs (hb_collect_glyphs_context_t *c) const - { if (unlikely (!(this+coverage).add_coverage (c->input))) return; } + { if (unlikely (!(this+coverage).collect_coverage (c->input))) return; } const Coverage &get_coverage () const { return this+coverage; } @@ -1353,6 +1712,12 @@ struct CursivePosFormat1 else pos[child].x_offset = x_offset; + /* If parent was attached to child, break them free. + * https://github.com/harfbuzz/harfbuzz/issues/2469 + */ + if (unlikely (pos[parent].attach_chain() == -pos[child].attach_chain())) + pos[parent].attach_chain() = 0; + buffer->idx++; return_trace (true); } @@ -1361,7 +1726,8 @@ struct CursivePosFormat1 hb_requires (hb_is_iterator (Iterator))> void serialize (hb_serialize_context_t *c, Iterator it, - const void *src_base) + const void *src_base, + const hb_map_t *layout_variation_idx_map) { if (unlikely (!c->extend_min ((*this)))) return; this->format = 1; @@ -1369,7 +1735,7 @@ struct CursivePosFormat1 for (const EntryExitRecord& entry_record : + it | hb_map (hb_second)) - c->copy (entry_record, src_base, this); + c->copy (entry_record, src_base, this, layout_variation_idx_map); auto glyphs = + it @@ -1382,7 +1748,7 @@ struct CursivePosFormat1 bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->glyphset (); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; auto *out = c->serializer->start_embed (*this); @@ -1396,7 +1762,7 @@ struct CursivePosFormat1 ; bool ret = bool (it); - out->serialize (c->serializer, it, this); + out->serialize (c->serializer, it, this, c->plan->layout_variation_idx_map); return_trace (ret); } @@ -1444,16 +1810,73 @@ typedef AnchorMatrix BaseArray; /* base-major-- * mark-minor-- * ordered by class--zero-based. */ +static void Markclass_closure_and_remap_indexes (const Coverage &mark_coverage, + const MarkArray &mark_array, + const hb_set_t &glyphset, + hb_map_t* klass_mapping /* INOUT */) +{ + hb_set_t orig_classes; + + + hb_zip (mark_coverage, mark_array) + | hb_filter (glyphset, hb_first) + | hb_map (hb_second) + | hb_map (&MarkRecord::get_class) + | hb_sink (orig_classes) + ; + + unsigned idx = 0; + for (auto klass : orig_classes.iter ()) + { + if (klass_mapping->has (klass)) continue; + klass_mapping->set (klass, idx); + idx++; + } +} + struct MarkBasePosFormat1 { bool intersects (const hb_set_t *glyphs) const - { return (this+markCoverage).intersects (glyphs) && - (this+baseCoverage).intersects (glyphs); } + { + return (this+markCoverage).intersects (glyphs) && + (this+baseCoverage).intersects (glyphs); + } + + void closure_lookups (hb_closure_lookups_context_t *c) const {} + + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const + { + + hb_zip (this+markCoverage, this+markArray) + | hb_filter (c->glyph_set, hb_first) + | hb_map (hb_second) + | hb_apply ([&] (const MarkRecord& record) { record.collect_variation_indices (c, &(this+markArray)); }) + ; + + hb_map_t klass_mapping; + Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, *c->glyph_set, &klass_mapping); + + unsigned basecount = (this+baseArray).rows; + auto base_iter = + + hb_zip (this+baseCoverage, hb_range (basecount)) + | hb_filter (c->glyph_set, hb_first) + | hb_map (hb_second) + ; + + hb_sorted_vector_t<unsigned> base_indexes; + for (const unsigned row : base_iter) + { + + hb_range ((unsigned) classCount) + | hb_filter (klass_mapping) + | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; }) + | hb_sink (base_indexes) + ; + } + (this+baseArray).collect_variation_indices (c, base_indexes.iter ()); + } void collect_glyphs (hb_collect_glyphs_context_t *c) const { - if (unlikely (!(this+markCoverage).add_coverage (c->input))) return; - if (unlikely (!(this+baseCoverage).add_coverage (c->input))) return; + if (unlikely (!(this+markCoverage).collect_coverage (c->input))) return; + if (unlikely (!(this+baseCoverage).collect_coverage (c->input))) return; } const Coverage &get_coverage () const { return this+markCoverage; } @@ -1501,8 +1924,70 @@ struct MarkBasePosFormat1 bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - // TODO(subset) - return_trace (false); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); + const hb_map_t &glyph_map = *c->plan->glyph_map; + + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + out->format = format; + + hb_map_t klass_mapping; + Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, glyphset, &klass_mapping); + + if (!klass_mapping.get_population ()) return_trace (false); + out->classCount = klass_mapping.get_population (); + + auto mark_iter = + + hb_zip (this+markCoverage, this+markArray) + | hb_filter (glyphset, hb_first) + ; + + hb_sorted_vector_t<hb_codepoint_t> new_coverage; + + mark_iter + | hb_map (hb_first) + | hb_map (glyph_map) + | hb_sink (new_coverage) + ; + + if (!out->markCoverage.serialize (c->serializer, out) + .serialize (c->serializer, new_coverage.iter ())) + return_trace (false); + + out->markArray.serialize (c->serializer, out) + .serialize (c->serializer, &klass_mapping, c->plan->layout_variation_idx_map, &(this+markArray), + mark_iter + | hb_map (hb_second)); + + unsigned basecount = (this+baseArray).rows; + auto base_iter = + + hb_zip (this+baseCoverage, hb_range (basecount)) + | hb_filter (glyphset, hb_first) + ; + + new_coverage.reset (); + + base_iter + | hb_map (hb_first) + | hb_map (glyph_map) + | hb_sink (new_coverage) + ; + + if (!out->baseCoverage.serialize (c->serializer, out) + .serialize (c->serializer, new_coverage.iter ())) + return_trace (false); + + hb_sorted_vector_t<unsigned> base_indexes; + for (const unsigned row : + base_iter + | hb_map (hb_second)) + { + + hb_range ((unsigned) classCount) + | hb_filter (klass_mapping) + | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; }) + | hb_sink (base_indexes) + ; + } + out->baseArray.serialize (c->serializer, out) + .serialize (c->serializer, base_iter.len (), &(this+baseArray), c->plan->layout_variation_idx_map, base_indexes.iter ()); + + return_trace (true); } bool sanitize (hb_sanitize_context_t *c) const @@ -1560,21 +2045,88 @@ typedef AnchorMatrix LigatureAttach; /* component-major-- * mark-minor-- * ordered by class--zero-based. */ -typedef OffsetListOf<LigatureAttach> LigatureArray; - /* Array of LigatureAttach - * tables ordered by - * LigatureCoverage Index */ +/* Array of LigatureAttach tables ordered by LigatureCoverage Index */ +struct LigatureArray : OffsetListOf<LigatureAttach> +{ + template <typename Iterator, + hb_requires (hb_is_iterator (Iterator))> + bool subset (hb_subset_context_t *c, + Iterator coverage, + unsigned class_count, + const hb_map_t *klass_mapping) const + { + TRACE_SUBSET (this); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); + + auto *out = c->serializer->start_embed (this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + + for (const auto _ : + hb_zip (coverage, *this) + | hb_filter (glyphset, hb_first)) + { + auto *matrix = out->serialize_append (c->serializer); + if (unlikely (!matrix)) return_trace (false); + + matrix->serialize_subset (c, + _.second, + this, + class_count, + klass_mapping); + } + return_trace (this->len); + } +}; struct MarkLigPosFormat1 { bool intersects (const hb_set_t *glyphs) const - { return (this+markCoverage).intersects (glyphs) && - (this+ligatureCoverage).intersects (glyphs); } + { + return (this+markCoverage).intersects (glyphs) && + (this+ligatureCoverage).intersects (glyphs); + } + + void closure_lookups (hb_closure_lookups_context_t *c) const {} + + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const + { + + hb_zip (this+markCoverage, this+markArray) + | hb_filter (c->glyph_set, hb_first) + | hb_map (hb_second) + | hb_apply ([&] (const MarkRecord& record) { record.collect_variation_indices (c, &(this+markArray)); }) + ; + + hb_map_t klass_mapping; + Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, *c->glyph_set, &klass_mapping); + + unsigned ligcount = (this+ligatureArray).len; + auto lig_iter = + + hb_zip (this+ligatureCoverage, hb_range (ligcount)) + | hb_filter (c->glyph_set, hb_first) + | hb_map (hb_second) + ; + + const LigatureArray& lig_array = this+ligatureArray; + for (const unsigned i : lig_iter) + { + hb_sorted_vector_t<unsigned> lig_indexes; + unsigned row_count = lig_array[i].rows; + for (unsigned row : + hb_range (row_count)) + { + + hb_range ((unsigned) classCount) + | hb_filter (klass_mapping) + | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; }) + | hb_sink (lig_indexes) + ; + } + + lig_array[i].collect_variation_indices (c, lig_indexes.iter ()); + } + } void collect_glyphs (hb_collect_glyphs_context_t *c) const { - if (unlikely (!(this+markCoverage).add_coverage (c->input))) return; - if (unlikely (!(this+ligatureCoverage).add_coverage (c->input))) return; + if (unlikely (!(this+markCoverage).collect_coverage (c->input))) return; + if (unlikely (!(this+ligatureCoverage).collect_coverage (c->input))) return; } const Coverage &get_coverage () const { return this+markCoverage; } @@ -1625,8 +2177,56 @@ struct MarkLigPosFormat1 bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - // TODO(subset) - return_trace (false); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); + const hb_map_t &glyph_map = *c->plan->glyph_map; + + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + out->format = format; + + hb_map_t klass_mapping; + Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, glyphset, &klass_mapping); + + if (!klass_mapping.get_population ()) return_trace (false); + out->classCount = klass_mapping.get_population (); + + auto mark_iter = + + hb_zip (this+markCoverage, this+markArray) + | hb_filter (glyphset, hb_first) + ; + + auto new_mark_coverage = + + mark_iter + | hb_map_retains_sorting (hb_first) + | hb_map_retains_sorting (glyph_map) + ; + + if (!out->markCoverage.serialize (c->serializer, out) + .serialize (c->serializer, new_mark_coverage)) + return_trace (false); + + out->markArray.serialize (c->serializer, out) + .serialize (c->serializer, + &klass_mapping, + c->plan->layout_variation_idx_map, + &(this+markArray), + + mark_iter + | hb_map (hb_second)); + + auto new_ligature_coverage = + + hb_iter (this + ligatureCoverage) + | hb_filter (glyphset) + | hb_map_retains_sorting (glyph_map) + ; + + if (!out->ligatureCoverage.serialize (c->serializer, out) + .serialize (c->serializer, new_ligature_coverage)) + return_trace (false); + + out->ligatureArray.serialize_subset (c, ligatureArray, this, + hb_iter (this+ligatureCoverage), classCount, &klass_mapping); + + return_trace (true); } bool sanitize (hb_sanitize_context_t *c) const @@ -1659,6 +2259,7 @@ struct MarkLigPosFormat1 DEFINE_SIZE_STATIC (12); }; + struct MarkLigPos { template <typename context_t, typename ...Ts> @@ -1688,13 +2289,47 @@ typedef AnchorMatrix Mark2Array; /* mark2-major-- struct MarkMarkPosFormat1 { bool intersects (const hb_set_t *glyphs) const - { return (this+mark1Coverage).intersects (glyphs) && - (this+mark2Coverage).intersects (glyphs); } + { + return (this+mark1Coverage).intersects (glyphs) && + (this+mark2Coverage).intersects (glyphs); + } + + void closure_lookups (hb_closure_lookups_context_t *c) const {} + + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const + { + + hb_zip (this+mark1Coverage, this+mark1Array) + | hb_filter (c->glyph_set, hb_first) + | hb_map (hb_second) + | hb_apply ([&] (const MarkRecord& record) { record.collect_variation_indices (c, &(this+mark1Array)); }) + ; + + hb_map_t klass_mapping; + Markclass_closure_and_remap_indexes (this+mark1Coverage, this+mark1Array, *c->glyph_set, &klass_mapping); + + unsigned mark2_count = (this+mark2Array).rows; + auto mark2_iter = + + hb_zip (this+mark2Coverage, hb_range (mark2_count)) + | hb_filter (c->glyph_set, hb_first) + | hb_map (hb_second) + ; + + hb_sorted_vector_t<unsigned> mark2_indexes; + for (const unsigned row : mark2_iter) + { + + hb_range ((unsigned) classCount) + | hb_filter (klass_mapping) + | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; }) + | hb_sink (mark2_indexes) + ; + } + (this+mark2Array).collect_variation_indices (c, mark2_indexes.iter ()); + } void collect_glyphs (hb_collect_glyphs_context_t *c) const { - if (unlikely (!(this+mark1Coverage).add_coverage (c->input))) return; - if (unlikely (!(this+mark2Coverage).add_coverage (c->input))) return; + if (unlikely (!(this+mark1Coverage).collect_coverage (c->input))) return; + if (unlikely (!(this+mark2Coverage).collect_coverage (c->input))) return; } const Coverage &get_coverage () const { return this+mark1Coverage; } @@ -1721,12 +2356,15 @@ struct MarkMarkPosFormat1 unsigned int comp1 = _hb_glyph_info_get_lig_comp (&buffer->cur()); unsigned int comp2 = _hb_glyph_info_get_lig_comp (&buffer->info[j]); - if (likely (id1 == id2)) { + if (likely (id1 == id2)) + { if (id1 == 0) /* Marks belonging to the same base. */ goto good; else if (comp1 == comp2) /* Marks belonging to the same ligature component. */ goto good; - } else { + } + else + { /* If ligature ids don't match, it may be the case that one of the marks * itself is a ligature. In which case match. */ if ((id1 > 0 && !comp1) || (id2 > 0 && !comp2)) @@ -1746,8 +2384,70 @@ struct MarkMarkPosFormat1 bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - // TODO(subset) - return_trace (false); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); + const hb_map_t &glyph_map = *c->plan->glyph_map; + + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + out->format = format; + + hb_map_t klass_mapping; + Markclass_closure_and_remap_indexes (this+mark1Coverage, this+mark1Array, glyphset, &klass_mapping); + + if (!klass_mapping.get_population ()) return_trace (false); + out->classCount = klass_mapping.get_population (); + + auto mark1_iter = + + hb_zip (this+mark1Coverage, this+mark1Array) + | hb_filter (glyphset, hb_first) + ; + + hb_sorted_vector_t<hb_codepoint_t> new_coverage; + + mark1_iter + | hb_map (hb_first) + | hb_map (glyph_map) + | hb_sink (new_coverage) + ; + + if (!out->mark1Coverage.serialize (c->serializer, out) + .serialize (c->serializer, new_coverage.iter ())) + return_trace (false); + + out->mark1Array.serialize (c->serializer, out) + .serialize (c->serializer, &klass_mapping, c->plan->layout_variation_idx_map, &(this+mark1Array), + mark1_iter + | hb_map (hb_second)); + + unsigned mark2count = (this+mark2Array).rows; + auto mark2_iter = + + hb_zip (this+mark2Coverage, hb_range (mark2count)) + | hb_filter (glyphset, hb_first) + ; + + new_coverage.reset (); + + mark2_iter + | hb_map (hb_first) + | hb_map (glyph_map) + | hb_sink (new_coverage) + ; + + if (!out->mark2Coverage.serialize (c->serializer, out) + .serialize (c->serializer, new_coverage.iter ())) + return_trace (false); + + hb_sorted_vector_t<unsigned> mark2_indexes; + for (const unsigned row : + mark2_iter + | hb_map (hb_second)) + { + + hb_range ((unsigned) classCount) + | hb_filter (klass_mapping) + | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; }) + | hb_sink (mark2_indexes) + ; + } + out->mark2Array.serialize (c->serializer, out) + .serialize (c->serializer, mark2_iter.len (), &(this+mark2Array), c->plan->layout_variation_idx_map, mark2_indexes.iter ()); + + return_trace (true); } bool sanitize (hb_sanitize_context_t *c) const @@ -1853,6 +2553,12 @@ struct PosLookupSubTable } } + bool intersects (const hb_set_t *glyphs, unsigned int lookup_type) const + { + hb_intersects_context_t c (glyphs); + return dispatch (&c, lookup_type); + } + protected: union { SinglePos single; @@ -1897,18 +2603,37 @@ struct PosLookup : Lookup hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const { return dispatch (c); } + hb_closure_lookups_context_t::return_t closure_lookups (hb_closure_lookups_context_t *c, unsigned this_index) const + { + if (c->is_lookup_visited (this_index)) + return hb_closure_lookups_context_t::default_return_value (); + + c->set_lookup_visited (this_index); + if (!intersects (c->glyphs)) + { + c->set_lookup_inactive (this_index); + return hb_closure_lookups_context_t::default_return_value (); + } + c->set_recurse_func (dispatch_closure_lookups_recurse_func); + + hb_closure_lookups_context_t::return_t ret = dispatch (c); + return ret; + } + template <typename set_t> - void add_coverage (set_t *glyphs) const + void collect_coverage (set_t *glyphs) const { - hb_add_coverage_context_t<set_t> c (glyphs); + hb_collect_coverage_context_t<set_t> c (glyphs); dispatch (&c); } - HB_INTERNAL static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index); + static inline bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index); template <typename context_t> static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index); + HB_INTERNAL static hb_closure_lookups_context_t::return_t dispatch_closure_lookups_recurse_func (hb_closure_lookups_context_t *c, unsigned this_index); + template <typename context_t, typename ...Ts> typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { return Lookup::dispatch<SubTable> (c, hb_forward<Ts> (ds)...); } @@ -1930,21 +2655,39 @@ struct GPOS : GSUBGPOS static constexpr hb_tag_t tableTag = HB_OT_TAG_GPOS; const PosLookup& get_lookup (unsigned int i) const - { return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); } + { return static_cast<const PosLookup &> (GSUBGPOS::get_lookup (i)); } static inline void position_start (hb_font_t *font, hb_buffer_t *buffer); static inline void position_finish_advances (hb_font_t *font, hb_buffer_t *buffer); static inline void position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer); bool subset (hb_subset_context_t *c) const - { return GSUBGPOS::subset<PosLookup> (c); } + { + hb_subset_layout_context_t l (c, tableTag, c->plan->gpos_lookups, c->plan->gpos_features); + return GSUBGPOS::subset<PosLookup> (&l); + } bool sanitize (hb_sanitize_context_t *c) const { return GSUBGPOS::sanitize<PosLookup> (c); } - HB_INTERNAL bool is_blacklisted (hb_blob_t *blob, + HB_INTERNAL bool is_blocklisted (hb_blob_t *blob, hb_face_t *face) const; + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const + { + for (unsigned i = 0; i < GSUBGPOS::get_lookup_count (); i++) + { + if (!c->gpos_lookups->has (i)) continue; + const PosLookup &l = get_lookup (i); + l.dispatch (c); + } + } + + void closure_lookups (hb_face_t *face, + const hb_set_t *glyphs, + hb_set_t *lookup_indexes /* IN/OUT */) const + { GSUBGPOS::closure_lookups<PosLookup> (face, glyphs, lookup_indexes); } + typedef GSUBGPOS::accelerator_t<GPOS> accelerator_t; }; @@ -2060,12 +2803,19 @@ struct GPOS_accelerator_t : GPOS::accelerator_t {}; #ifndef HB_NO_OT_LAYOUT template <typename context_t> -/*static*/ inline typename context_t::return_t PosLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index) +/*static*/ typename context_t::return_t PosLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index) { const PosLookup &l = c->face->table.GPOS.get_relaxed ()->table->get_lookup (lookup_index); return l.dispatch (c); } -/*static*/ inline bool PosLookup::apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index) + +/*static*/ inline hb_closure_lookups_context_t::return_t PosLookup::dispatch_closure_lookups_recurse_func (hb_closure_lookups_context_t *c, unsigned this_index) +{ + const PosLookup &l = c->face->table.GPOS.get_relaxed ()->table->get_lookup (this_index); + return l.closure_lookups (c, this_index); +} + +/*static*/ bool PosLookup::apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index) { const PosLookup &l = c->face->table.GPOS.get_relaxed ()->table->get_lookup (lookup_index); unsigned int saved_lookup_props = c->lookup_props; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh index fc21cb056e..5f10ecb7ee 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh @@ -37,8 +37,8 @@ namespace OT { typedef hb_pair_t<hb_codepoint_t, hb_codepoint_t> hb_codepoint_pair_t; template<typename Iterator> -static inline void SingleSubst_serialize (hb_serialize_context_t *c, - Iterator it); +static void SingleSubst_serialize (hb_serialize_context_t *c, + Iterator it); struct SingleSubstFormat1 @@ -56,9 +56,11 @@ struct SingleSubstFormat1 ; } + void closure_lookups (hb_closure_lookups_context_t *c) const {} + void collect_glyphs (hb_collect_glyphs_context_t *c) const { - if (unlikely (!(this+coverage).add_coverage (c->input))) return; + if (unlikely (!(this+coverage).collect_coverage (c->input))) return; unsigned d = deltaGlyphID; + hb_iter (this+coverage) | hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; }) @@ -154,9 +156,11 @@ struct SingleSubstFormat2 ; } + void closure_lookups (hb_closure_lookups_context_t *c) const {} + void collect_glyphs (hb_collect_glyphs_context_t *c) const { - if (unlikely (!(this+coverage).add_coverage (c->input))) return; + if (unlikely (!(this+coverage).collect_coverage (c->input))) return; + hb_zip (this+coverage, substitute) | hb_map (hb_second) | hb_sink (c->output) @@ -255,9 +259,8 @@ struct SingleSubst if (glyphs) { format = 1; - auto get_delta = [=] (hb_codepoint_pair_t _) { - return (unsigned) (_.second - _.first) & 0xFFFF; - }; + auto get_delta = [=] (hb_codepoint_pair_t _) + { return (unsigned) (_.second - _.first) & 0xFFFF; }; delta = get_delta (*glyphs); if (!hb_all (++(+glyphs), delta, get_delta)) format = 2; } @@ -293,7 +296,7 @@ struct SingleSubst }; template<typename Iterator> -static inline void +static void SingleSubst_serialize (hb_serialize_context_t *c, Iterator it) { c->start_embed<SingleSubst> ()->serialize (c, it); } @@ -353,15 +356,15 @@ struct Sequence bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->glyphset (); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; if (!intersects (&glyphset)) return_trace (false); auto it = - + hb_iter (substitute) - | hb_map (glyph_map) - ; + + hb_iter (substitute) + | hb_map (glyph_map) + ; auto *out = c->serializer->start_embed (*this); return_trace (out->serialize (c->serializer, it)); @@ -395,9 +398,11 @@ struct MultipleSubstFormat1 ; } + void closure_lookups (hb_closure_lookups_context_t *c) const {} + void collect_glyphs (hb_collect_glyphs_context_t *c) const { - if (unlikely (!(this+coverage).add_coverage (c->input))) return; + if (unlikely (!(this+coverage).collect_coverage (c->input))) return; + hb_zip (this+coverage, sequence) | hb_map (hb_second) | hb_map (hb_add (this)) @@ -442,7 +447,7 @@ struct MultipleSubstFormat1 bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->glyphset (); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; auto *out = c->serializer->start_embed (*this); @@ -452,7 +457,7 @@ struct MultipleSubstFormat1 hb_sorted_vector_t<hb_codepoint_t> new_coverage; + hb_zip (this+coverage, sequence) | hb_filter (glyphset, hb_first) - | hb_filter (subset_offset_array (c, out->sequence, this, out), hb_second) + | hb_filter (subset_offset_array (c, out->sequence, this), hb_second) | hb_map (hb_first) | hb_map (glyph_map) | hb_sink (new_coverage) @@ -551,6 +556,20 @@ struct AlternateSet return_trace (true); } + unsigned + get_alternates (unsigned start_offset, + unsigned *alternate_count /* IN/OUT. May be NULL. */, + hb_codepoint_t *alternate_glyphs /* OUT. May be NULL. */) const + { + if (alternates.len && alternate_count) + { + + alternates.sub_array (start_offset, alternate_count) + | hb_sink (hb_array (alternate_glyphs, *alternate_count)) + ; + } + return alternates.len; + } + template <typename Iterator, hb_requires (hb_is_source_of (Iterator, hb_codepoint_t))> bool serialize (hb_serialize_context_t *c, @@ -563,7 +582,7 @@ struct AlternateSet bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->glyphset (); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; auto it = @@ -599,15 +618,18 @@ struct AlternateSubstFormat1 void closure (hb_closure_context_t *c) const { + hb_zip (this+coverage, alternateSet) + | hb_filter (c->glyphs, hb_first) | hb_map (hb_second) | hb_map (hb_add (this)) | hb_apply ([c] (const AlternateSet &_) { _.closure (c); }) ; } + void closure_lookups (hb_closure_lookups_context_t *c) const {} + void collect_glyphs (hb_collect_glyphs_context_t *c) const { - if (unlikely (!(this+coverage).add_coverage (c->input))) return; + if (unlikely (!(this+coverage).collect_coverage (c->input))) return; + hb_zip (this+coverage, alternateSet) | hb_map (hb_second) | hb_map (hb_add (this)) @@ -620,6 +642,14 @@ struct AlternateSubstFormat1 bool would_apply (hb_would_apply_context_t *c) const { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; } + unsigned + get_glyph_alternates (hb_codepoint_t gid, + unsigned start_offset, + unsigned *alternate_count /* IN/OUT. May be NULL. */, + hb_codepoint_t *alternate_glyphs /* OUT. May be NULL. */) const + { return (this+alternateSet[(this+coverage).get_coverage (gid)]) + .get_alternates (start_offset, alternate_count, alternate_glyphs); } + bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); @@ -652,7 +682,7 @@ struct AlternateSubstFormat1 bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->glyphset (); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; auto *out = c->serializer->start_embed (*this); @@ -662,7 +692,7 @@ struct AlternateSubstFormat1 hb_sorted_vector_t<hb_codepoint_t> new_coverage; + hb_zip (this+coverage, alternateSet) | hb_filter (glyphset, hb_first) - | hb_filter (subset_offset_array (c, out->alternateSet, this, out), hb_second) + | hb_filter (subset_offset_array (c, out->alternateSet, this), hb_second) | hb_map (hb_first) | hb_map (glyph_map) | hb_sink (new_coverage) @@ -810,7 +840,7 @@ struct Ligature bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->glyphset (); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; if (!intersects (&glyphset) || !glyphset.has (ligGlyph)) return_trace (false); @@ -822,8 +852,8 @@ struct Ligature auto *out = c->serializer->start_embed (*this); return_trace (out->serialize (c->serializer, - glyph_map[ligGlyph], - it)); + glyph_map[ligGlyph], + it)); } public: @@ -922,7 +952,7 @@ struct LigatureSet if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + hb_iter (ligature) - | hb_filter (subset_offset_array (c, out->ligature, this, out)) + | hb_filter (subset_offset_array (c, out->ligature, this)) | hb_drain ; return_trace (bool (out->ligature)); @@ -966,9 +996,11 @@ struct LigatureSubstFormat1 ; } + void closure_lookups (hb_closure_lookups_context_t *c) const {} + void collect_glyphs (hb_collect_glyphs_context_t *c) const { - if (unlikely (!(this+coverage).add_coverage (c->input))) return; + if (unlikely (!(this+coverage).collect_coverage (c->input))) return; + hb_zip (this+coverage, ligatureSet) | hb_map (hb_second) @@ -992,7 +1024,7 @@ struct LigatureSubstFormat1 { TRACE_APPLY (this); - unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); + unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); const LigatureSet &lig_set = this+ligatureSet[index]; @@ -1026,7 +1058,7 @@ struct LigatureSubstFormat1 bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->glyphset (); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; auto *out = c->serializer->start_embed (*this); @@ -1036,7 +1068,7 @@ struct LigatureSubstFormat1 hb_sorted_vector_t<hb_codepoint_t> new_coverage; + hb_zip (this+coverage, ligatureSet) | hb_filter (glyphset, hb_first) - | hb_filter (subset_offset_array (c, out->ligatureSet, this, out), hb_second) + | hb_filter (subset_offset_array (c, out->ligatureSet, this), hb_second) | hb_map (hb_first) | hb_map (glyph_map) | hb_sink (new_coverage) @@ -1114,7 +1146,6 @@ struct ChainContextSubst : ChainContext {}; struct ExtensionSubst : Extension<ExtensionSubst> { typedef struct SubstLookupSubTable SubTable; - bool is_reverse () const; }; @@ -1157,20 +1188,22 @@ struct ReverseChainSingleSubstFormat1 ; } + void closure_lookups (hb_closure_lookups_context_t *c) const {} + void collect_glyphs (hb_collect_glyphs_context_t *c) const { - if (unlikely (!(this+coverage).add_coverage (c->input))) return; + if (unlikely (!(this+coverage).collect_coverage (c->input))) return; unsigned int count; count = backtrack.len; for (unsigned int i = 0; i < count; i++) - if (unlikely (!(this+backtrack[i]).add_coverage (c->before))) return; + if (unlikely (!(this+backtrack[i]).collect_coverage (c->before))) return; const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack); count = lookahead.len; for (unsigned int i = 0; i < count; i++) - if (unlikely (!(this+lookahead[i]).add_coverage (c->after))) return; + if (unlikely (!(this+lookahead[i]).collect_coverage (c->after))) return; const ArrayOf<HBGlyphID> &substitute = StructAfter<ArrayOf<HBGlyphID>> (lookahead); count = substitute.len; @@ -1188,13 +1221,15 @@ struct ReverseChainSingleSubstFormat1 if (unlikely (c->nesting_level_left != HB_MAX_NESTING_LEVEL)) return_trace (false); /* No chaining to this type */ - unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); + unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack); const ArrayOf<HBGlyphID> &substitute = StructAfter<ArrayOf<HBGlyphID>> (lookahead); - unsigned int start_index = 0, end_index = 0; + if (unlikely (index >= substitute.len)) return_trace (false); + + unsigned int start_index = 0, end_index = 0; if (match_backtrack (c, backtrack.len, (HBUINT16 *) backtrack.arrayZ, match_coverage, this, @@ -1313,6 +1348,12 @@ struct SubstLookupSubTable } } + bool intersects (const hb_set_t *glyphs, unsigned int lookup_type) const + { + hb_intersects_context_t c (glyphs); + return dispatch (&c, lookup_type); + } + protected: union { SingleSubst single; @@ -1336,14 +1377,14 @@ struct SubstLookup : Lookup const SubTable& get_subtable (unsigned int i) const { return Lookup::get_subtable<SubTable> (i); } - HB_INTERNAL static bool lookup_type_is_reverse (unsigned int lookup_type) + static inline bool lookup_type_is_reverse (unsigned int lookup_type) { return lookup_type == SubTable::ReverseChainSingle; } bool is_reverse () const { unsigned int type = get_type (); if (unlikely (type == SubTable::Extension)) - return CastR<ExtensionSubst> (get_subtable(0)).is_reverse (); + return reinterpret_cast<const ExtensionSubst &> (get_subtable (0)).is_reverse (); return lookup_type_is_reverse (type); } @@ -1373,6 +1414,24 @@ struct SubstLookup : Lookup return ret; } + hb_closure_lookups_context_t::return_t closure_lookups (hb_closure_lookups_context_t *c, unsigned this_index) const + { + if (c->is_lookup_visited (this_index)) + return hb_closure_lookups_context_t::default_return_value (); + + c->set_lookup_visited (this_index); + if (!intersects (c->glyphs)) + { + c->set_lookup_inactive (this_index); + return hb_closure_lookups_context_t::default_return_value (); + } + + c->set_recurse_func (dispatch_closure_lookups_recurse_func); + + hb_closure_lookups_context_t::return_t ret = dispatch (c); + return ret; + } + hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const { c->set_recurse_func (dispatch_recurse_func<hb_collect_glyphs_context_t>); @@ -1380,9 +1439,9 @@ struct SubstLookup : Lookup } template <typename set_t> - void add_coverage (set_t *glyphs) const + void collect_coverage (set_t *glyphs) const { - hb_add_coverage_context_t<set_t> c (glyphs); + hb_collect_coverage_context_t<set_t> c (glyphs); dispatch (&c); } @@ -1394,7 +1453,7 @@ struct SubstLookup : Lookup return dispatch (c); } - HB_INTERNAL static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index); + static inline bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index); SubTable& serialize_subtable (hb_serialize_context_t *c, unsigned int i) @@ -1461,9 +1520,9 @@ struct SubstLookup : Lookup } template <typename context_t> - HB_INTERNAL static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index); + static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index); - HB_INTERNAL static hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned int lookup_index) + static inline hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned int lookup_index) { if (!c->should_visit_lookup (lookup_index)) return hb_empty_t (); @@ -1478,6 +1537,8 @@ struct SubstLookup : Lookup return ret; } + HB_INTERNAL static hb_closure_lookups_context_t::return_t dispatch_closure_lookups_recurse_func (hb_closure_lookups_context_t *c, unsigned lookup_index); + template <typename context_t, typename ...Ts> typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { return Lookup::dispatch<SubTable> (c, hb_forward<Ts> (ds)...); } @@ -1499,17 +1560,25 @@ struct GSUB : GSUBGPOS static constexpr hb_tag_t tableTag = HB_OT_TAG_GSUB; const SubstLookup& get_lookup (unsigned int i) const - { return CastR<SubstLookup> (GSUBGPOS::get_lookup (i)); } + { return static_cast<const SubstLookup &> (GSUBGPOS::get_lookup (i)); } bool subset (hb_subset_context_t *c) const - { return GSUBGPOS::subset<SubstLookup> (c); } + { + hb_subset_layout_context_t l (c, tableTag, c->plan->gsub_lookups, c->plan->gsub_features); + return GSUBGPOS::subset<SubstLookup> (&l); + } bool sanitize (hb_sanitize_context_t *c) const { return GSUBGPOS::sanitize<SubstLookup> (c); } - HB_INTERNAL bool is_blacklisted (hb_blob_t *blob, + HB_INTERNAL bool is_blocklisted (hb_blob_t *blob, hb_face_t *face) const; + void closure_lookups (hb_face_t *face, + const hb_set_t *glyphs, + hb_set_t *lookup_indexes /* IN/OUT */) const + { GSUBGPOS::closure_lookups<SubstLookup> (face, glyphs, lookup_indexes); } + typedef GSUBGPOS::accelerator_t<GSUB> accelerator_t; }; @@ -1522,18 +1591,22 @@ struct GSUB_accelerator_t : GSUB::accelerator_t {}; #ifndef HB_NO_OT_LAYOUT /*static*/ inline bool ExtensionSubst::is_reverse () const { - unsigned int type = get_type (); - if (unlikely (type == SubTable::Extension)) - return CastR<ExtensionSubst> (get_subtable<SubTable>()).is_reverse (); - return SubstLookup::lookup_type_is_reverse (type); + return SubstLookup::lookup_type_is_reverse (get_type ()); } template <typename context_t> -/*static*/ inline typename context_t::return_t SubstLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index) +/*static*/ typename context_t::return_t SubstLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index) { const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (lookup_index); return l.dispatch (c); } -/*static*/ inline bool SubstLookup::apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index) + +/*static*/ inline hb_closure_lookups_context_t::return_t SubstLookup::dispatch_closure_lookups_recurse_func (hb_closure_lookups_context_t *c, unsigned this_index) +{ + const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (this_index); + return l.closure_lookups (c, this_index); +} + +/*static*/ bool SubstLookup::apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index) { const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (lookup_index); unsigned int saved_lookup_props = c->lookup_props; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh index 579d17871b..36a95ead15 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh @@ -42,26 +42,22 @@ namespace OT { struct hb_intersects_context_t : - hb_dispatch_context_t<hb_intersects_context_t, bool, 0> + hb_dispatch_context_t<hb_intersects_context_t, bool> { - const char *get_name () { return "INTERSECTS"; } template <typename T> return_t dispatch (const T &obj) { return obj.intersects (this->glyphs); } static return_t default_return_value () { return false; } bool stop_sublookup_iteration (return_t r) const { return r; } const hb_set_t *glyphs; - unsigned int debug_depth; hb_intersects_context_t (const hb_set_t *glyphs_) : - glyphs (glyphs_), - debug_depth (0) {} + glyphs (glyphs_) {} }; struct hb_closure_context_t : - hb_dispatch_context_t<hb_closure_context_t, hb_empty_t, 0> + hb_dispatch_context_t<hb_closure_context_t> { - const char *get_name () { return "CLOSURE"; } typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index); template <typename T> return_t dispatch (const T &obj) { obj.closure (this); return hb_empty_t (); } @@ -76,16 +72,26 @@ struct hb_closure_context_t : nesting_level_left++; } + bool lookup_limit_exceeded () + { return lookup_count > HB_MAX_LOOKUP_INDICES; } + bool should_visit_lookup (unsigned int lookup_index) { + if (lookup_count++ > HB_MAX_LOOKUP_INDICES) + return false; + if (is_lookup_done (lookup_index)) return false; + done_lookups->set (lookup_index, glyphs->get_population ()); return true; } bool is_lookup_done (unsigned int lookup_index) { + if (unlikely (done_lookups->in_error ())) + return true; + /* Have we visited this lookup with the current set of glyphs? */ return done_lookups->get (lookup_index) == glyphs->get_population (); } @@ -95,7 +101,6 @@ struct hb_closure_context_t : hb_set_t output[1]; recurse_func_t recurse_func; unsigned int nesting_level_left; - unsigned int debug_depth; hb_closure_context_t (hb_face_t *face_, hb_set_t *glyphs_, @@ -105,8 +110,9 @@ struct hb_closure_context_t : glyphs (glyphs_), recurse_func (nullptr), nesting_level_left (nesting_level_left_), - debug_depth (0), - done_lookups (done_lookups_) {} + done_lookups (done_lookups_), + lookup_count (0) + {} ~hb_closure_context_t () { flush (); } @@ -114,19 +120,86 @@ struct hb_closure_context_t : void flush () { + hb_set_del_range (output, face->get_num_glyphs (), hb_set_get_max (output)); /* Remove invalid glyphs. */ hb_set_union (glyphs, output); hb_set_clear (output); } private: hb_map_t *done_lookups; + unsigned int lookup_count; }; +struct hb_closure_lookups_context_t : + hb_dispatch_context_t<hb_closure_lookups_context_t> +{ + typedef return_t (*recurse_func_t) (hb_closure_lookups_context_t *c, unsigned lookup_index); + template <typename T> + return_t dispatch (const T &obj) { obj.closure_lookups (this); return hb_empty_t (); } + static return_t default_return_value () { return hb_empty_t (); } + void recurse (unsigned lookup_index) + { + if (unlikely (nesting_level_left == 0 || !recurse_func)) + return; + + /* Return if new lookup was recursed to before. */ + if (is_lookup_visited (lookup_index)) + return; + + nesting_level_left--; + recurse_func (this, lookup_index); + nesting_level_left++; + } + + void set_lookup_visited (unsigned lookup_index) + { visited_lookups->add (lookup_index); } + + void set_lookup_inactive (unsigned lookup_index) + { inactive_lookups->add (lookup_index); } + + bool lookup_limit_exceeded () + { return lookup_count > HB_MAX_LOOKUP_INDICES; } + + bool is_lookup_visited (unsigned lookup_index) + { + if (unlikely (lookup_count++ > HB_MAX_LOOKUP_INDICES)) + return true; + + if (unlikely (visited_lookups->in_error ())) + return true; + + return visited_lookups->has (lookup_index); + } + + hb_face_t *face; + const hb_set_t *glyphs; + recurse_func_t recurse_func; + unsigned int nesting_level_left; + + hb_closure_lookups_context_t (hb_face_t *face_, + const hb_set_t *glyphs_, + hb_set_t *visited_lookups_, + hb_set_t *inactive_lookups_, + unsigned nesting_level_left_ = HB_MAX_NESTING_LEVEL) : + face (face_), + glyphs (glyphs_), + recurse_func (nullptr), + nesting_level_left (nesting_level_left_), + visited_lookups (visited_lookups_), + inactive_lookups (inactive_lookups_), + lookup_count (0) {} + + void set_recurse_func (recurse_func_t func) { recurse_func = func; } + + private: + hb_set_t *visited_lookups; + hb_set_t *inactive_lookups; + unsigned int lookup_count; +}; struct hb_would_apply_context_t : - hb_dispatch_context_t<hb_would_apply_context_t, bool, 0> + hb_dispatch_context_t<hb_would_apply_context_t, bool> { - const char *get_name () { return "WOULD_APPLY"; } template <typename T> return_t dispatch (const T &obj) { return obj.would_apply (this); } static return_t default_return_value () { return false; } @@ -136,7 +209,6 @@ struct hb_would_apply_context_t : const hb_codepoint_t *glyphs; unsigned int len; bool zero_context; - unsigned int debug_depth; hb_would_apply_context_t (hb_face_t *face_, const hb_codepoint_t *glyphs_, @@ -145,15 +217,12 @@ struct hb_would_apply_context_t : face (face_), glyphs (glyphs_), len (len_), - zero_context (zero_context_), - debug_depth (0) {} + zero_context (zero_context_) {} }; - struct hb_collect_glyphs_context_t : - hb_dispatch_context_t<hb_collect_glyphs_context_t, hb_empty_t, 0> + hb_dispatch_context_t<hb_collect_glyphs_context_t> { - const char *get_name () { return "COLLECT_GLYPHS"; } typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned int lookup_index); template <typename T> return_t dispatch (const T &obj) { obj.collect_glyphs (this); return hb_empty_t (); } @@ -204,7 +273,6 @@ struct hb_collect_glyphs_context_t : recurse_func_t recurse_func; hb_set_t *recursed_lookups; unsigned int nesting_level_left; - unsigned int debug_depth; hb_collect_glyphs_context_t (hb_face_t *face_, hb_set_t *glyphs_before, /* OUT. May be NULL */ @@ -219,8 +287,7 @@ struct hb_collect_glyphs_context_t : output (glyphs_output ? glyphs_output : hb_set_get_empty ()), recurse_func (nullptr), recursed_lookups (hb_set_create ()), - nesting_level_left (nesting_level_left_), - debug_depth (0) {} + nesting_level_left (nesting_level_left_) {} ~hb_collect_glyphs_context_t () { hb_set_destroy (recursed_lookups); } void set_recurse_func (recurse_func_t func) { recurse_func = func; } @@ -229,26 +296,23 @@ struct hb_collect_glyphs_context_t : template <typename set_t> -struct hb_add_coverage_context_t : - hb_dispatch_context_t<hb_add_coverage_context_t<set_t>, const Coverage &, HB_DEBUG_GET_COVERAGE> +struct hb_collect_coverage_context_t : + hb_dispatch_context_t<hb_collect_coverage_context_t<set_t>, const Coverage &> { - const char *get_name () { return "GET_COVERAGE"; } - typedef const Coverage &return_t; + typedef const Coverage &return_t; // Stoopid that we have to dupe this here. template <typename T> return_t dispatch (const T &obj) { return obj.get_coverage (); } - static return_t default_return_value () { return Null(Coverage); } + static return_t default_return_value () { return Null (Coverage); } bool stop_sublookup_iteration (return_t r) const { - r.add_coverage (set); + r.collect_coverage (set); return false; } - hb_add_coverage_context_t (set_t *set_) : - set (set_), - debug_depth (0) {} + hb_collect_coverage_context_t (set_t *set_) : + set (set_) {} set_t *set; - unsigned int debug_depth; }; @@ -276,7 +340,7 @@ struct hb_ot_apply_context_t : void set_mask (hb_mask_t mask_) { mask = mask_; } void set_syllable (uint8_t syllable_) { syllable = syllable_; } void set_match_func (match_func_t match_func_, - const void *match_data_) + const void *match_data_) { match_func = match_func_; match_data = match_data_; } enum may_match_t { @@ -355,7 +419,7 @@ struct hb_ot_apply_context_t : } void reset (unsigned int start_index_, - unsigned int num_items_) + unsigned int num_items_) { idx = start_index_; num_items = num_items_; @@ -363,7 +427,11 @@ struct hb_ot_apply_context_t : matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0); } - void reject () { num_items++; match_glyph_data--; } + void reject () + { + num_items++; + if (match_glyph_data) match_glyph_data--; + } matcher_t::may_skip_t may_skip (const hb_glyph_info_t &info) const @@ -467,7 +535,6 @@ struct hb_ot_apply_context_t : unsigned int lookup_index; unsigned int lookup_props; unsigned int nesting_level_left; - unsigned int debug_depth; bool has_glyph_classes; bool auto_zwnj; @@ -478,8 +545,8 @@ struct hb_ot_apply_context_t : hb_ot_apply_context_t (unsigned int table_index_, - hb_font_t *font_, - hb_buffer_t *buffer_) : + hb_font_t *font_, + hb_buffer_t *buffer_) : iter_input (), iter_context (), font (font_), face (font->face), buffer (buffer_), recurse_func (nullptr), @@ -487,7 +554,7 @@ struct hb_ot_apply_context_t : #ifndef HB_NO_OT_LAYOUT *face->table.GDEF->table #else - Null(GDEF) + Null (GDEF) #endif ), var_store (gdef.get_var_store ()), @@ -497,7 +564,6 @@ struct hb_ot_apply_context_t : lookup_index ((unsigned int) -1), lookup_props (0), nesting_level_left (HB_MAX_NESTING_LEVEL), - debug_depth (0), has_glyph_classes (gdef.has_glyph_classes ()), auto_zwnj (true), auto_zwj (true), @@ -593,7 +659,7 @@ struct hb_ot_apply_context_t : void replace_glyph (hb_codepoint_t glyph_index) const { _set_glyph_props (glyph_index); - buffer->replace_glyph (glyph_index); + (void) buffer->replace_glyph (glyph_index); } void replace_glyph_inplace (hb_codepoint_t glyph_index) const { @@ -601,25 +667,25 @@ struct hb_ot_apply_context_t : buffer->cur().codepoint = glyph_index; } void replace_glyph_with_ligature (hb_codepoint_t glyph_index, - unsigned int class_guess) const + unsigned int class_guess) const { _set_glyph_props (glyph_index, class_guess, true); - buffer->replace_glyph (glyph_index); + (void) buffer->replace_glyph (glyph_index); } void output_glyph_for_component (hb_codepoint_t glyph_index, - unsigned int class_guess) const + unsigned int class_guess) const { _set_glyph_props (glyph_index, class_guess, false, true); - buffer->output_glyph (glyph_index); + (void) buffer->output_glyph (glyph_index); } }; struct hb_get_subtables_context_t : - hb_dispatch_context_t<hb_get_subtables_context_t, hb_empty_t, HB_DEBUG_APPLY> + hb_dispatch_context_t<hb_get_subtables_context_t> { template <typename Type> - HB_INTERNAL static bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c) + static inline bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c) { const Type *typed_obj = (const Type *) obj; return typed_obj->apply (c); @@ -635,7 +701,7 @@ struct hb_get_subtables_context_t : obj = &obj_; apply_func = apply_func_; digest.init (); - obj_.get_coverage ().add_coverage (&digest); + obj_.get_coverage ().collect_coverage (&digest); } bool apply (OT::hb_ot_apply_context_t *c) const @@ -652,7 +718,6 @@ struct hb_get_subtables_context_t : typedef hb_vector_t<hb_applicable_t> array_t; /* Dispatch interface. */ - const char *get_name () { return "GET_SUBTABLES"; } template <typename T> return_t dispatch (const T &obj) { @@ -663,11 +728,9 @@ struct hb_get_subtables_context_t : static return_t default_return_value () { return hb_empty_t (); } hb_get_subtables_context_t (array_t &array_) : - array (array_), - debug_depth (0) {} + array (array_) {} array_t &array; - unsigned int debug_depth; }; @@ -706,15 +769,15 @@ static inline bool intersects_coverage (const hb_set_t *glyphs, const HBUINT16 & return (data+coverage).intersects (glyphs); } -static inline bool intersects_array (const hb_set_t *glyphs, - unsigned int count, - const HBUINT16 values[], - intersects_func_t intersects_func, - const void *intersects_data) +static inline bool array_is_subset_of (const hb_set_t *glyphs, + unsigned int count, + const HBUINT16 values[], + intersects_func_t intersects_func, + const void *intersects_data) { for (const HBUINT16 &_ : + hb_iter (values, count)) - if (intersects_func (glyphs, _, intersects_data)) return true; - return false; + if (!intersects_func (glyphs, _, intersects_data)) return false; + return true; } @@ -725,12 +788,12 @@ static inline void collect_glyph (hb_set_t *glyphs, const HBUINT16 &value, const static inline void collect_class (hb_set_t *glyphs, const HBUINT16 &value, const void *data) { const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); - class_def.add_class (glyphs, value); + class_def.collect_class (glyphs, value); } static inline void collect_coverage (hb_set_t *glyphs, const HBUINT16 &value, const void *data) { const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; - (data+coverage).add_coverage (glyphs); + (data+coverage).collect_coverage (glyphs); } static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED, hb_set_t *glyphs, @@ -980,7 +1043,7 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, hb_min (this_comp, last_num_components); _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp); } - buffer->next_glyph (); + (void) buffer->next_glyph (); } last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur()); @@ -991,18 +1054,19 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, buffer->idx++; } - if (!is_mark_ligature && last_lig_id) { + if (!is_mark_ligature && last_lig_id) + { /* Re-adjust components for any marks following. */ - for (unsigned int i = buffer->idx; i < buffer->len; i++) { - if (last_lig_id == _hb_glyph_info_get_lig_id (&buffer->info[i])) { - unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->info[i]); - if (!this_comp) - break; - unsigned int new_lig_comp = components_so_far - last_num_components + - hb_min (this_comp, last_num_components); - _hb_glyph_info_set_lig_props_for_mark (&buffer->info[i], lig_id, new_lig_comp); - } else - break; + for (unsigned i = buffer->idx; i < buffer->len; ++i) + { + if (last_lig_id != _hb_glyph_info_get_lig_id (&buffer->info[i])) break; + + unsigned this_comp = _hb_glyph_info_get_lig_comp (&buffer->info[i]); + if (!this_comp) break; + + unsigned new_lig_comp = components_so_far - last_num_components + + hb_min (this_comp, last_num_components); + _hb_glyph_info_set_lig_props_for_mark (&buffer->info[i], lig_id, new_lig_comp); } } return_trace (true); @@ -1057,6 +1121,17 @@ static inline bool match_lookahead (hb_ot_apply_context_t *c, struct LookupRecord { + LookupRecord* copy (hb_serialize_context_t *c, + const hb_map_t *lookup_map) const + { + TRACE_SERIALIZE (this); + auto *out = c->embed (*this); + if (unlikely (!out)) return_trace (nullptr); + + out->lookupListIndex = hb_map_get (lookup_map, lookupListIndex); + return_trace (out); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -1112,7 +1187,7 @@ static inline bool apply_lookup (hb_ot_apply_context_t *c, /* Don't recurse to ourself at same position. * Note that this test is too naive, it doesn't catch longer loops. */ - if (idx == 0 && lookupRecord[i].lookupListIndex == c->lookup_index) + if (unlikely (idx == 0 && lookupRecord[i].lookupListIndex == c->lookup_index)) continue; if (unlikely (!buffer->move_to (match_positions[idx]))) @@ -1150,7 +1225,8 @@ static inline bool apply_lookup (hb_ot_apply_context_t *c, * mean that n match positions where removed, as there might * have been marks and default-ignorables in the sequence. We * should instead drop match positions between current-position - * and current-position + n instead. + * and current-position + n instead. Though, am not sure which + * one is better. Both cases have valid uses. Sigh. * * It should be possible to construct tests for both of these cases. */ @@ -1196,7 +1272,7 @@ static inline bool apply_lookup (hb_ot_apply_context_t *c, match_positions[next] += delta; } - buffer->move_to (end); + (void) buffer->move_to (end); return_trace (true); } @@ -1228,9 +1304,9 @@ static inline bool context_intersects (const hb_set_t *glyphs, const HBUINT16 input[], /* Array of input values--start with second glyph */ ContextClosureLookupContext &lookup_context) { - return intersects_array (glyphs, - inputCount ? inputCount - 1 : 0, input, - lookup_context.funcs.intersects, lookup_context.intersects_data); + return array_is_subset_of (glyphs, + inputCount ? inputCount - 1 : 0, input, + lookup_context.funcs.intersects, lookup_context.intersects_data); } static inline void context_closure_lookup (hb_closure_context_t *c, @@ -1303,6 +1379,8 @@ struct Rule void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const { + if (unlikely (c->lookup_limit_exceeded ())) return; + const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> (inputZ.as_array ((inputCount ? inputCount - 1 : 0))); context_closure_lookup (c, @@ -1311,6 +1389,17 @@ struct Rule lookup_context); } + void closure_lookups (hb_closure_lookups_context_t *c, + ContextClosureLookupContext &lookup_context) const + { + if (unlikely (c->lookup_limit_exceeded ())) return; + if (!intersects (c->glyphs, lookup_context)) return; + + const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> + (inputZ.as_array (inputCount ? inputCount - 1 : 0)); + recurse_lookups (c, lookupCount, lookupRecord.arrayZ); + } + void collect_glyphs (hb_collect_glyphs_context_t *c, ContextCollectGlyphsLookupContext &lookup_context) const { @@ -1342,6 +1431,47 @@ struct Rule return_trace (context_apply_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, lookup_context)); } + bool serialize (hb_serialize_context_t *c, + const hb_map_t *input_mapping, /* old->new glyphid or class mapping */ + const hb_map_t *lookup_map) const + { + TRACE_SERIALIZE (this); + auto *out = c->start_embed (this); + if (unlikely (!c->extend_min (out))) return_trace (false); + + out->inputCount = inputCount; + out->lookupCount = lookupCount; + + const hb_array_t<const HBUINT16> input = inputZ.as_array (inputCount - 1); + for (const auto org : input) + { + HBUINT16 d; + d = input_mapping->get (org); + c->copy (d); + } + + const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> + (inputZ.as_array ((inputCount ? inputCount - 1 : 0))); + for (unsigned i = 0; i < (unsigned) lookupCount; i++) + c->copy (lookupRecord[i], lookup_map); + + return_trace (true); + } + + bool subset (hb_subset_context_t *c, + const hb_map_t *lookup_map, + const hb_map_t *klass_map = nullptr) const + { + TRACE_SUBSET (this); + + const hb_array_t<const HBUINT16> input = inputZ.as_array ((inputCount ? inputCount - 1 : 0)); + if (!input.length) return_trace (false); + + const hb_map_t *mapping = klass_map == nullptr ? c->plan->glyph_map : klass_map; + if (!hb_all (input, mapping)) return_trace (false); + return_trace (serialize (c->serializer, mapping, lookup_map)); + } + public: bool sanitize (hb_sanitize_context_t *c) const { @@ -1359,7 +1489,7 @@ struct Rule * glyph */ HBUINT16 lookupCount; /* Number of LookupRecords */ UnsizedArrayOf<HBUINT16> - inputZ; /* Array of match inputs--start with + inputZ; /* Array of match inputs--start with * second glyph */ /*UnsizedArrayOf<LookupRecord> lookupRecordX;*/ /* Array of LookupRecords--in @@ -1384,6 +1514,8 @@ struct RuleSet void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const { + if (unlikely (c->lookup_limit_exceeded ())) return; + return + hb_iter (rule) | hb_map (hb_add (this)) @@ -1391,6 +1523,16 @@ struct RuleSet ; } + void closure_lookups (hb_closure_lookups_context_t *c, + ContextClosureLookupContext &lookup_context) const + { + if (unlikely (c->lookup_limit_exceeded ())) return; + + hb_iter (rule) + | hb_map (hb_add (this)) + | hb_apply ([&] (const Rule &_) { _.closure_lookups (c, lookup_context); }) + ; + } + void collect_glyphs (hb_collect_glyphs_context_t *c, ContextCollectGlyphsLookupContext &lookup_context) const { @@ -1425,6 +1567,36 @@ struct RuleSet ; } + bool subset (hb_subset_context_t *c, + const hb_map_t *lookup_map, + const hb_map_t *klass_map = nullptr) const + { + TRACE_SUBSET (this); + + auto snap = c->serializer->snapshot (); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + + for (const OffsetTo<Rule>& _ : rule) + { + if (!_) continue; + auto *o = out->rule.serialize_append (c->serializer); + if (unlikely (!o)) continue; + + auto o_snap = c->serializer->snapshot (); + if (!o->serialize_subset (c, _, this, lookup_map, klass_map)) + { + out->rule.pop (); + c->serializer->revert (o_snap); + } + } + + bool ret = bool (out->rule); + if (!ret) c->serializer->revert (snap); + + return_trace (ret); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -1474,9 +1646,26 @@ struct ContextFormat1 ; } + void closure_lookups (hb_closure_lookups_context_t *c) const + { + struct ContextClosureLookupContext lookup_context = { + {intersects_glyph}, + nullptr + }; + + + hb_zip (this+coverage, ruleSet) + | hb_filter (*c->glyphs, hb_first) + | hb_map (hb_second) + | hb_map (hb_add (this)) + | hb_apply ([&] (const RuleSet &_) { _.closure_lookups (c, lookup_context); }) + ; + } + + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const {} + void collect_glyphs (hb_collect_glyphs_context_t *c) const { - (this+coverage).add_coverage (c->input); + (this+coverage).collect_coverage (c->input); struct ContextCollectGlyphsLookupContext lookup_context = { {collect_glyph}, @@ -1519,8 +1708,26 @@ struct ContextFormat1 bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - // TODO(subset) - return_trace (false); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); + const hb_map_t &glyph_map = *c->plan->glyph_map; + + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + out->format = format; + + const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups; + hb_sorted_vector_t<hb_codepoint_t> new_coverage; + + hb_zip (this+coverage, ruleSet) + | hb_filter (glyphset, hb_first) + | hb_filter (subset_offset_array (c, out->ruleSet, this, lookup_map), hb_second) + | hb_map (hb_first) + | hb_map (glyph_map) + | hb_sink (new_coverage) + ; + + out->coverage.serialize (c->serializer, out) + .serialize (c->serializer, new_coverage.iter ()); + return_trace (bool (new_coverage)); } bool sanitize (hb_sanitize_context_t *c) const @@ -1557,10 +1764,12 @@ struct ContextFormat2 }; return - + hb_enumerate (ruleSet) - | hb_map ([&] (const hb_pair_t<unsigned, const OffsetTo<RuleSet> &> p) + + hb_iter (ruleSet) + | hb_map (hb_add (this)) + | hb_enumerate + | hb_map ([&] (const hb_pair_t<unsigned, const RuleSet &> p) { return class_def.intersects_class (glyphs, p.first) && - (this+p.second).intersects (glyphs, lookup_context); }) + p.second.intersects (glyphs, lookup_context); }) | hb_any ; } @@ -1588,9 +1797,33 @@ struct ContextFormat2 ; } + void closure_lookups (hb_closure_lookups_context_t *c) const + { + if (!(this+coverage).intersects (c->glyphs)) + return; + + const ClassDef &class_def = this+classDef; + + struct ContextClosureLookupContext lookup_context = { + {intersects_class}, + &class_def + }; + + + hb_iter (ruleSet) + | hb_map (hb_add (this)) + | hb_enumerate + | hb_filter ([&] (const hb_pair_t<unsigned, const RuleSet &> p) + { return class_def.intersects_class (c->glyphs, p.first); }) + | hb_map (hb_second) + | hb_apply ([&] (const RuleSet & _) + { _.closure_lookups (c, lookup_context); }); + } + + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const {} + void collect_glyphs (hb_collect_glyphs_context_t *c) const { - (this+coverage).add_coverage (c->input); + (this+coverage).collect_coverage (c->input); const ClassDef &class_def = this+classDef; struct ContextCollectGlyphsLookupContext lookup_context = { @@ -1637,8 +1870,45 @@ struct ContextFormat2 bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - // TODO(subset) - return_trace (false); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + out->format = format; + if (unlikely (!out->coverage.serialize_subset (c, coverage, this))) + return_trace (false); + + hb_map_t klass_map; + out->classDef.serialize_subset (c, classDef, this, &klass_map); + + const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups; + bool ret = true; + int non_zero_index = 0, index = 0; + for (const auto& _ : + hb_enumerate (ruleSet) + | hb_filter (klass_map, hb_first)) + { + auto *o = out->ruleSet.serialize_append (c->serializer); + if (unlikely (!o)) + { + ret = false; + break; + } + + if (o->serialize_subset (c, _.second, this, lookup_map, &klass_map)) + non_zero_index = index; + + index++; + } + + if (!ret) return_trace (ret); + + //prune empty trailing ruleSets + --index; + while (index > non_zero_index) + { + out->ruleSet.pop (); + index--; + } + + return_trace (bool (out->ruleSet)); } bool sanitize (hb_sanitize_context_t *c) const @@ -1695,9 +1965,19 @@ struct ContextFormat3 lookup_context); } + void closure_lookups (hb_closure_lookups_context_t *c) const + { + if (!intersects (c->glyphs)) + return; + const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount)); + recurse_lookups (c, lookupCount, lookupRecord); + } + + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const {} + void collect_glyphs (hb_collect_glyphs_context_t *c) const { - (this+coverageZ[0]).add_coverage (c->input); + (this+coverageZ[0]).collect_coverage (c->input); const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount)); struct ContextCollectGlyphsLookupContext lookup_context = { @@ -1743,8 +2023,29 @@ struct ContextFormat3 bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - // TODO(subset) - return_trace (false); + auto *out = c->serializer->start_embed (this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + + out->format = format; + out->glyphCount = glyphCount; + out->lookupCount = lookupCount; + + auto coverages = coverageZ.as_array (glyphCount); + + for (const OffsetTo<Coverage>& offset : coverages) + { + /* TODO(subset) This looks like should not be necessary to write this way. */ + auto *o = c->serializer->allocate_size<OffsetTo<Coverage>> (OffsetTo<Coverage>::static_size); + if (unlikely (!o)) return_trace (false); + if (!o->serialize_subset (c, offset, this)) return_trace (false); + } + + const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount)); + const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups; + for (unsigned i = 0; i < (unsigned) lookupCount; i++) + c->serializer->copy (lookupRecord[i], lookup_map); + + return_trace (true); } bool sanitize (hb_sanitize_context_t *c) const @@ -1829,15 +2130,15 @@ static inline bool chain_context_intersects (const hb_set_t *glyphs, const HBUINT16 lookahead[], ChainContextClosureLookupContext &lookup_context) { - return intersects_array (glyphs, - backtrackCount, backtrack, - lookup_context.funcs.intersects, lookup_context.intersects_data[0]) - && intersects_array (glyphs, - inputCount ? inputCount - 1 : 0, input, - lookup_context.funcs.intersects, lookup_context.intersects_data[1]) - && intersects_array (glyphs, - lookaheadCount, lookahead, - lookup_context.funcs.intersects, lookup_context.intersects_data[2]); + return array_is_subset_of (glyphs, + backtrackCount, backtrack, + lookup_context.funcs.intersects, lookup_context.intersects_data[0]) + && array_is_subset_of (glyphs, + inputCount ? inputCount - 1 : 0, input, + lookup_context.funcs.intersects, lookup_context.intersects_data[1]) + && array_is_subset_of (glyphs, + lookaheadCount, lookahead, + lookup_context.funcs.intersects, lookup_context.intersects_data[2]); } static inline void chain_context_closure_lookup (hb_closure_context_t *c, @@ -1949,6 +2250,8 @@ struct ChainRule void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const { + if (unlikely (c->lookup_limit_exceeded ())) return; + const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input); const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead); @@ -1960,6 +2263,18 @@ struct ChainRule lookup_context); } + void closure_lookups (hb_closure_lookups_context_t *c, + ChainContextClosureLookupContext &lookup_context) const + { + if (unlikely (c->lookup_limit_exceeded ())) return; + if (!intersects (c->glyphs, lookup_context)) return; + + const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); + const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input); + const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead); + recurse_lookups (c, lookup.len, lookup.arrayZ); + } + void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const { @@ -2003,19 +2318,16 @@ struct ChainRule template<typename Iterator, hb_requires (hb_is_iterator (Iterator))> void serialize_array (hb_serialize_context_t *c, - HBUINT16 len, - Iterator it) const + HBUINT16 len, + Iterator it) const { c->copy (len); for (const auto g : it) - { - HBUINT16 gid; - gid = g; - c->copy (gid); - } + c->copy ((HBUINT16) g); } ChainRule* copy (hb_serialize_context_t *c, + const hb_map_t *lookup_map, const hb_map_t *backtrack_map, const hb_map_t *input_map = nullptr, const hb_map_t *lookahead_map = nullptr) const @@ -2038,16 +2350,29 @@ struct ChainRule serialize_array (c, lookahead.len, + lookahead.iter () | hb_map (mapping)); - const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead); - c->copy (lookup); + const ArrayOf<LookupRecord> &lookupRecord = StructAfter<ArrayOf<LookupRecord>> (lookahead); + + HBUINT16* lookupCount = c->embed (&(lookupRecord.len)); + if (!lookupCount) return_trace (nullptr); + + for (unsigned i = 0; i < lookupRecord.len; i++) + { + if (!lookup_map->has (lookupRecord[i].lookupListIndex)) + { + (*lookupCount)--; + continue; + } + if (!c->copy (lookupRecord[i], lookup_map)) return_trace (nullptr); + } return_trace (out); } bool subset (hb_subset_context_t *c, - const hb_map_t *backtrack_map = nullptr, - const hb_map_t *input_map = nullptr, - const hb_map_t *lookahead_map = nullptr) const + const hb_map_t *lookup_map, + const hb_map_t *backtrack_map = nullptr, + const hb_map_t *input_map = nullptr, + const hb_map_t *lookahead_map = nullptr) const { TRACE_SUBSET (this); @@ -2056,22 +2381,22 @@ struct ChainRule if (!backtrack_map) { - const hb_set_t &glyphset = *c->plan->glyphset (); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); if (!hb_all (backtrack, glyphset) || - !hb_all (input, glyphset) || - !hb_all (lookahead, glyphset)) - return_trace (false); + !hb_all (input, glyphset) || + !hb_all (lookahead, glyphset)) + return_trace (false); - copy (c->serializer, c->plan->glyph_map); + copy (c->serializer, lookup_map, c->plan->glyph_map); } else { if (!hb_all (backtrack, backtrack_map) || - !hb_all (input, input_map) || - !hb_all (lookahead, lookahead_map)) - return_trace (false); + !hb_all (input, input_map) || + !hb_all (lookahead, lookahead_map)) + return_trace (false); - copy (c->serializer, backtrack_map, input_map, lookahead_map); + copy (c->serializer, lookup_map, backtrack_map, input_map, lookahead_map); } return_trace (true); @@ -2120,6 +2445,8 @@ struct ChainRuleSet } void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const { + if (unlikely (c->lookup_limit_exceeded ())) return; + return + hb_iter (rule) | hb_map (hb_add (this)) @@ -2127,6 +2454,17 @@ struct ChainRuleSet ; } + void closure_lookups (hb_closure_lookups_context_t *c, + ChainContextClosureLookupContext &lookup_context) const + { + if (unlikely (c->lookup_limit_exceeded ())) return; + + + hb_iter (rule) + | hb_map (hb_add (this)) + | hb_apply ([&] (const ChainRule &_) { _.closure_lookups (c, lookup_context); }) + ; + } + void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const { return @@ -2159,9 +2497,10 @@ struct ChainRuleSet } bool subset (hb_subset_context_t *c, - const hb_map_t *backtrack_klass_map = nullptr, - const hb_map_t *input_klass_map = nullptr, - const hb_map_t *lookahead_klass_map = nullptr) const + const hb_map_t *lookup_map, + const hb_map_t *backtrack_klass_map = nullptr, + const hb_map_t *input_klass_map = nullptr, + const hb_map_t *lookahead_klass_map = nullptr) const { TRACE_SUBSET (this); @@ -2176,13 +2515,14 @@ struct ChainRuleSet if (unlikely (!o)) continue; auto o_snap = c->serializer->snapshot (); - if (!o->serialize_subset (c, _, this, out, - backtrack_klass_map, - input_klass_map, - lookahead_klass_map)) + if (!o->serialize_subset (c, _, this, + lookup_map, + backtrack_klass_map, + input_klass_map, + lookahead_klass_map)) { - out->rule.pop (); - c->serializer->revert (o_snap); + out->rule.pop (); + c->serializer->revert (o_snap); } } @@ -2240,9 +2580,26 @@ struct ChainContextFormat1 ; } + void closure_lookups (hb_closure_lookups_context_t *c) const + { + struct ChainContextClosureLookupContext lookup_context = { + {intersects_glyph}, + {nullptr, nullptr, nullptr} + }; + + + hb_zip (this+coverage, ruleSet) + | hb_filter (*c->glyphs, hb_first) + | hb_map (hb_second) + | hb_map (hb_add (this)) + | hb_apply ([&] (const ChainRuleSet &_) { _.closure_lookups (c, lookup_context); }) + ; + } + + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const {} + void collect_glyphs (hb_collect_glyphs_context_t *c) const { - (this+coverage).add_coverage (c->input); + (this+coverage).collect_coverage (c->input); struct ChainContextCollectGlyphsLookupContext lookup_context = { {collect_glyph}, @@ -2284,17 +2641,18 @@ struct ChainContextFormat1 bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->glyphset (); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; auto *out = c->serializer->start_embed (*this); if (unlikely (!c->serializer->extend_min (out))) return_trace (false); out->format = format; + const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups; hb_sorted_vector_t<hb_codepoint_t> new_coverage; + hb_zip (this+coverage, ruleSet) | hb_filter (glyphset, hb_first) - | hb_filter (subset_offset_array (c, out->ruleSet, this, out), hb_second) + | hb_filter (subset_offset_array (c, out->ruleSet, this, lookup_map), hb_second) | hb_map (hb_first) | hb_map (glyph_map) | hb_sink (new_coverage) @@ -2342,10 +2700,12 @@ struct ChainContextFormat2 }; return - + hb_enumerate (ruleSet) - | hb_map ([&] (const hb_pair_t<unsigned, const OffsetTo<ChainRuleSet> &> p) + + hb_iter (ruleSet) + | hb_map (hb_add (this)) + | hb_enumerate + | hb_map ([&] (const hb_pair_t<unsigned, const ChainRuleSet &> p) { return input_class_def.intersects_class (glyphs, p.first) && - (this+p.second).intersects (glyphs, lookup_context); }) + p.second.intersects (glyphs, lookup_context); }) | hb_any ; } @@ -2376,9 +2736,38 @@ struct ChainContextFormat2 ; } + void closure_lookups (hb_closure_lookups_context_t *c) const + { + if (!(this+coverage).intersects (c->glyphs)) + return; + + const ClassDef &backtrack_class_def = this+backtrackClassDef; + const ClassDef &input_class_def = this+inputClassDef; + const ClassDef &lookahead_class_def = this+lookaheadClassDef; + + struct ChainContextClosureLookupContext lookup_context = { + {intersects_class}, + {&backtrack_class_def, + &input_class_def, + &lookahead_class_def} + }; + + + hb_iter (ruleSet) + | hb_map (hb_add (this)) + | hb_enumerate + | hb_filter([&] (unsigned klass) + { return input_class_def.intersects_class (c->glyphs, klass); }, hb_first) + | hb_map (hb_second) + | hb_apply ([&] (const ChainRuleSet &_) + { _.closure_lookups (c, lookup_context); }) + ; + } + + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const {} + void collect_glyphs (hb_collect_glyphs_context_t *c) const { - (this+coverage).add_coverage (c->input); + (this+coverage).collect_coverage (c->input); const ClassDef &backtrack_class_def = this+backtrackClassDef; const ClassDef &input_class_def = this+inputClassDef; @@ -2443,20 +2832,26 @@ struct ChainContextFormat2 auto *out = c->serializer->start_embed (*this); if (unlikely (!c->serializer->extend_min (out))) return_trace (false); out->format = format; - out->coverage.serialize_subset (c, coverage, this, out); + out->coverage.serialize_subset (c, coverage, this); hb_map_t backtrack_klass_map; - out->backtrackClassDef.serialize_subset (c, backtrackClassDef, this, out, &backtrack_klass_map); - - // subset inputClassDef based on glyphs survived in Coverage subsetting hb_map_t input_klass_map; - out->inputClassDef.serialize_subset (c, inputClassDef, this, out, &input_klass_map); - hb_map_t lookahead_klass_map; - out->lookaheadClassDef.serialize_subset (c, lookaheadClassDef, this, out, &lookahead_klass_map); - hb_vector_t<unsigned> rulesets; + out->backtrackClassDef.serialize_subset (c, backtrackClassDef, this, &backtrack_klass_map); + // TODO: subset inputClassDef based on glyphs survived in Coverage subsetting + out->inputClassDef.serialize_subset (c, inputClassDef, this, &input_klass_map); + out->lookaheadClassDef.serialize_subset (c, lookaheadClassDef, this, &lookahead_klass_map); + + if (unlikely (!c->serializer->propagate_error (backtrack_klass_map, + input_klass_map, + lookahead_klass_map))) + return_trace (false); + + int non_zero_index = -1, index = 0; bool ret = true; + const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups; + auto last_non_zero = c->serializer->snapshot (); for (const OffsetTo<ChainRuleSet>& _ : + hb_enumerate (ruleSet) | hb_filter (input_klass_map, hb_first) | hb_map (hb_second)) @@ -2464,27 +2859,28 @@ struct ChainContextFormat2 auto *o = out->ruleSet.serialize_append (c->serializer); if (unlikely (!o)) { - ret = false; - break; + ret = false; + break; } - if (!o->serialize_subset (c, _, this, out, - &backtrack_klass_map, - &input_klass_map, - &lookahead_klass_map)) + if (o->serialize_subset (c, _, this, + lookup_map, + &backtrack_klass_map, + &input_klass_map, + &lookahead_klass_map)) { - rulesets.push (0); + last_non_zero = c->serializer->snapshot (); + non_zero_index = index; } - else rulesets.push (1); + + index++; } if (!ret) return_trace (ret); - //prune empty trailing ruleSets - unsigned count = rulesets.length; - while (count > 0 && rulesets[count-1] == 0) - { - out->ruleSet.pop (); - count--; + // prune empty trailing ruleSets + if (index > non_zero_index) { + c->serializer->revert (last_non_zero); + out->ruleSet.len = non_zero_index + 1; } return_trace (bool (out->ruleSet)); @@ -2566,11 +2962,24 @@ struct ChainContextFormat3 lookup_context); } + void closure_lookups (hb_closure_lookups_context_t *c) const + { + if (!intersects (c->glyphs)) + return; + + const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack); + const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input); + const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead); + recurse_lookups (c, lookup.len, lookup.arrayZ); + } + + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const {} + void collect_glyphs (hb_collect_glyphs_context_t *c) const { const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack); - (this+input[0]).add_coverage (c->input); + (this+input[0]).collect_coverage (c->input); const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input); const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead); @@ -2631,21 +3040,21 @@ struct ChainContextFormat3 template<typename Iterator, hb_requires (hb_is_iterator (Iterator))> - bool serialize_coverage_offsets (hb_subset_context_t *c, - Iterator it, - const void* src_base, - const void* dst_base) const + bool serialize_coverage_offsets (hb_subset_context_t *c, Iterator it, const void* base) const { TRACE_SERIALIZE (this); auto *out = c->serializer->start_embed<OffsetArrayOf<Coverage>> (); - if (unlikely (!c->serializer->allocate_size<HBUINT16> (HBUINT16::static_size))) return_trace (false); + if (unlikely (!c->serializer->allocate_size<HBUINT16> (HBUINT16::static_size))) + return_trace (false); - + it - | hb_apply (subset_offset_array (c, *out, src_base, dst_base)) - ; + for (auto& offset : it) { + auto *o = out->serialize_append (c->serializer); + if (unlikely (!o) || !o->serialize_subset (c, offset, base)) + return_trace (false); + } - return_trace (out->len); + return_trace (true); } bool subset (hb_subset_context_t *c) const @@ -2656,19 +3065,27 @@ struct ChainContextFormat3 if (unlikely (!out)) return_trace (false); if (unlikely (!c->serializer->embed (this->format))) return_trace (false); - if (!serialize_coverage_offsets (c, backtrack.iter (), this, out)) + if (!serialize_coverage_offsets (c, backtrack.iter (), this)) return_trace (false); const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack); - if (!serialize_coverage_offsets (c, input.iter (), this, out)) + if (!serialize_coverage_offsets (c, input.iter (), this)) return_trace (false); const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input); - if (!serialize_coverage_offsets (c, lookahead.iter (), this, out)) + if (!serialize_coverage_offsets (c, lookahead.iter (), this)) return_trace (false); - const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead); - return_trace (c->serializer->copy (lookup)); + const ArrayOf<LookupRecord> &lookupRecord = StructAfter<ArrayOf<LookupRecord>> (lookahead); + HBUINT16 lookupCount; + lookupCount = lookupRecord.len; + if (!c->serializer->copy (lookupCount)) return_trace (false); + + const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups; + for (unsigned i = 0; i < (unsigned) lookupCount; i++) + if (!c->serializer->copy (lookupRecord[i], lookup_map)) return_trace (false); + + return_trace (true); } bool sanitize (hb_sanitize_context_t *c) const @@ -2737,7 +3154,7 @@ struct ExtensionFormat1 template <typename X> const X& get_subtable () const - { return this + CastR<LOffsetTo<typename T::SubTable>> (extensionOffset); } + { return this + reinterpret_cast<const LOffsetTo<typename T::SubTable> &> (extensionOffset); } template <typename context_t, typename ...Ts> typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const @@ -2747,6 +3164,9 @@ struct ExtensionFormat1 return_trace (get_subtable<typename T::SubTable> ().dispatch (c, get_type (), hb_forward<Ts> (ds)...)); } + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const + { dispatch (c); } + /* This is called from may_dispatch() above with hb_sanitize_context_t. */ bool sanitize (hb_sanitize_context_t *c) const { @@ -2755,6 +3175,24 @@ struct ExtensionFormat1 extensionLookupType != T::SubTable::Extension); } + 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->format = format; + out->extensionLookupType = extensionLookupType; + + const auto& src_offset = + reinterpret_cast<const LOffsetTo<typename T::SubTable> &> (extensionOffset); + auto& dest_offset = + reinterpret_cast<LOffsetTo<typename T::SubTable> &> (out->extensionOffset); + + return_trace (dest_offset.serialize_subset (c, src_offset, this, get_type ())); + } + protected: HBUINT16 format; /* Format identifier. Set to 1. */ HBUINT16 extensionLookupType; /* Lookup type of subtable referenced @@ -2781,7 +3219,19 @@ struct Extension { switch (u.format) { case 1: return u.format1.template get_subtable<typename T::SubTable> (); - default:return Null(typename T::SubTable); + default:return Null (typename T::SubTable); + } + } + + // Specialization of dispatch for subset. dispatch() normally just + // dispatches to the sub table this points too, but for subset + // we need to run subset on this subtable too. + template <typename ...Ts> + typename hb_subset_context_t::return_t dispatch (hb_subset_context_t *c, Ts&&... ds) const + { + switch (u.format) { + case 1: return u.format1.subset (c); + default: return c->default_return_value (); } } @@ -2814,7 +3264,7 @@ struct hb_ot_layout_lookup_accelerator_t void init (const TLookup &lookup) { digest.init (); - lookup.add_coverage (&digest); + lookup.collect_coverage (&digest); subtables.init (); OT::hb_get_subtables_context_t c_get_subtables (subtables); @@ -2875,10 +3325,11 @@ struct GSUBGPOS bool find_variations_index (const int *coords, unsigned int num_coords, unsigned int *index) const { -#ifdef HB_NOVAR +#ifdef HB_NO_VAR + *index = FeatureVariations::NOT_FOUND_INDEX; return false; #endif - return (version.to_int () >= 0x00010001u ? this+featureVars : Null(FeatureVariations)) + return (version.to_int () >= 0x00010001u ? this+featureVars : Null (FeatureVariations)) .find_index (coords, num_coords, index); } const Feature& get_feature_variation (unsigned int feature_index, @@ -2897,32 +3348,100 @@ struct GSUBGPOS return get_feature (feature_index); } + void feature_variation_collect_lookups (const hb_set_t *feature_indexes, + hb_set_t *lookup_indexes /* OUT */) const + { +#ifndef HB_NO_VAR + if (version.to_int () >= 0x00010001u) + (this+featureVars).collect_lookups (feature_indexes, lookup_indexes); +#endif + } + template <typename TLookup> - bool subset (hb_subset_context_t *c) const + void closure_lookups (hb_face_t *face, + const hb_set_t *glyphs, + hb_set_t *lookup_indexes /* IN/OUT */) const + { + hb_set_t visited_lookups, inactive_lookups; + OT::hb_closure_lookups_context_t c (face, glyphs, &visited_lookups, &inactive_lookups); + + for (unsigned lookup_index : + hb_iter (lookup_indexes)) + reinterpret_cast<const TLookup &> (get_lookup (lookup_index)).closure_lookups (&c, lookup_index); + + hb_set_union (lookup_indexes, &visited_lookups); + hb_set_subtract (lookup_indexes, &inactive_lookups); + } + + template <typename TLookup> + bool subset (hb_subset_layout_context_t *c) const { TRACE_SUBSET (this); - auto *out = c->serializer->embed (*this); + auto *out = c->subset_context->serializer->embed (*this); if (unlikely (!out)) return_trace (false); - out->scriptList.serialize_subset (c, scriptList, this, out); - out->featureList.serialize_subset (c, featureList, this, out); + typedef LookupOffsetList<TLookup> TLookupList; + reinterpret_cast<OffsetTo<TLookupList> &> (out->lookupList) + .serialize_subset (c->subset_context, + reinterpret_cast<const OffsetTo<TLookupList> &> (lookupList), + this, + c); - typedef OffsetListOf<TLookup> TLookupList; - /* TODO Use intersects() to count how many subtables survive? */ - CastR<OffsetTo<TLookupList>> (out->lookupList) - .serialize_subset (c, - CastR<OffsetTo<TLookupList>> (lookupList), - this, - out); + reinterpret_cast<OffsetTo<RecordListOfFeature> &> (out->featureList) + .serialize_subset (c->subset_context, + reinterpret_cast<const OffsetTo<RecordListOfFeature> &> (featureList), + this, + c); + + out->scriptList.serialize_subset (c->subset_context, + scriptList, + this, + c); #ifndef HB_NO_VAR if (version.to_int () >= 0x00010001u) - out->featureVars.serialize_copy (c->serializer, featureVars, this, out); + { + bool ret = out->featureVars.serialize_subset (c->subset_context, featureVars, this, c); + if (!ret) + { + out->version.major = 1; + out->version.minor = 0; + } + } #endif return_trace (true); } + void prune_features (const hb_map_t *lookup_indices, /* IN */ + hb_set_t *feature_indices /* IN/OUT */) const + { +#ifndef HB_NO_VAR + // This is the set of feature indices which have alternate versions defined + // if the FeatureVariation's table and the alternate version(s) intersect the + // set of lookup indices. + hb_set_t alternate_feature_indices; + if (version.to_int () >= 0x00010001u) + (this+featureVars).closure_features (lookup_indices, &alternate_feature_indices); + if (unlikely (alternate_feature_indices.in_error())) { + feature_indices->successful = false; + return; + } +#endif + + for (unsigned i : feature_indices->iter()) + { + const Feature& f = get_feature (i); + + if (f.featureParams.is_null () + && !f.intersects_lookup_indexes (lookup_indices) +#ifndef HB_NO_VAR + && !alternate_feature_indices.has (i) +#endif + ) + feature_indices->del (i); + } + } + unsigned int get_size () const { return min_size + @@ -2938,7 +3457,7 @@ struct GSUBGPOS likely (version.major == 1) && scriptList.sanitize (c, this) && featureList.sanitize (c, this) && - CastR<OffsetTo<TLookupList>> (lookupList).sanitize (c, this)))) + reinterpret_cast<const OffsetTo<TLookupList> &> (lookupList).sanitize (c, this)))) return_trace (false); #ifndef HB_NO_VAR @@ -2954,8 +3473,8 @@ struct GSUBGPOS { void init (hb_face_t *face) { - this->table = hb_sanitize_context_t().reference_table<T> (face); - if (unlikely (this->table->is_blacklisted (this->table.get_blob (), face))) + this->table = hb_sanitize_context_t ().reference_table<T> (face); + if (unlikely (this->table->is_blocklisted (this->table.get_blob (), face))) { hb_blob_destroy (this->table.get_blob ()); this->table = hb_blob_get_empty (); @@ -2965,7 +3484,11 @@ struct GSUBGPOS this->accels = (hb_ot_layout_lookup_accelerator_t *) calloc (this->lookup_count, sizeof (hb_ot_layout_lookup_accelerator_t)); if (unlikely (!this->accels)) + { this->lookup_count = 0; + this->table.destroy (); + this->table = hb_blob_get_empty (); + } for (unsigned int i = 0; i < this->lookup_count; i++) this->accels[i].init (table->get_lookup (i)); @@ -2988,11 +3511,11 @@ struct GSUBGPOS FixedVersion<>version; /* Version of the GSUB/GPOS table--initially set * to 0x00010000u */ OffsetTo<ScriptList> - scriptList; /* ScriptList table */ + scriptList; /* ScriptList table */ OffsetTo<FeatureList> - featureList; /* FeatureList table */ + featureList; /* FeatureList table */ OffsetTo<LookupList> - lookupList; /* LookupList table */ + lookupList; /* LookupList table */ LOffsetTo<FeatureVariations> featureVars; /* Offset to Feature Variations table--from beginning of table diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh index 53eb623cf5..ffd2bf4574 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh @@ -222,7 +222,7 @@ struct JSTF FixedVersion<>version; /* Version of the JSTF table--initially set * to 0x00010000u */ RecordArrayOf<JstfScript> - scriptList; /* Array of JstfScripts--listed + scriptList; /* Array of JstfScripts--listed * alphabetically by ScriptTag */ public: DEFINE_SIZE_ARRAY (6, scriptList); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc index fba3ad1916..89df949b26 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc @@ -51,9 +51,7 @@ #include "hb-ot-name-table.hh" #include "hb-ot-os2-table.hh" -#include "hb-aat-layout-lcar-table.hh" #include "hb-aat-layout-morx-table.hh" - #include "hb-aat-layout-opbd-table.hh" // Just so we compile it; unused otherwise. /** @@ -78,7 +76,7 @@ * Tests whether a face includes any kerning data in the 'kern' table. * Does NOT test for kerning lookups in the GPOS table. * - * Return value: true if data found, false otherwise + * Return value: %true if data found, %false otherwise * **/ bool @@ -94,7 +92,7 @@ hb_ot_layout_has_kerning (hb_face_t *face) * Tests whether a face includes any state-machine kerning in the 'kern' table. * Does NOT examine the GPOS table. * - * Return value: true if data found, false otherwise + * Return value: %true if data found, %false otherwise * **/ bool @@ -114,7 +112,7 @@ hb_ot_layout_has_machine_kerning (hb_face_t *face) * * Does NOT examine the GPOS table. * - * Return value: true is data found, false otherwise + * Return value: %true is data found, %false otherwise * **/ bool @@ -143,13 +141,13 @@ hb_ot_layout_kern (const hb_ot_shape_plan_t *plan, */ bool -OT::GDEF::is_blacklisted (hb_blob_t *blob, +OT::GDEF::is_blocklisted (hb_blob_t *blob, hb_face_t *face) const { #ifdef HB_NO_OT_LAYOUT_BLACKLIST return false; #endif - /* The ugly business of blacklisting individual fonts' tables happen here! + /* The ugly business of blocklisting individual fonts' tables happen here! * See this thread for why we finally had to bend in and do this: * https://lists.freedesktop.org/archives/harfbuzz/2016-February/005489.html * @@ -270,7 +268,7 @@ _hb_ot_layout_set_glyph_props (hb_font_t *font, * * Tests whether a face has any glyph classes defined in its GDEF table. * - * Return value: true if data found, false otherwise + * Return value: %true if data found, %false otherwise * **/ hb_bool_t @@ -318,14 +316,13 @@ hb_ot_layout_get_glyphs_in_class (hb_face_t *face, return face->table.GDEF->table->get_glyphs_in_class (klass, glyphs); } - #ifndef HB_NO_LAYOUT_UNUSED /** * hb_ot_layout_get_attach_points: * @face: The #hb_face_t to work on * @glyph: The #hb_codepoint_t code point to query * @start_offset: offset of the first attachment point to retrieve - * @point_count: (inout) (allow-none): Input = the maximum number of attachment points to return; + * @point_count: (inout) (optional): Input = the maximum number of attachment points to return; * Output = the actual number of attachment points returned (may be zero) * @point_array: (out) (array length=point_count): The array of attachment points found for the query * @@ -353,7 +350,7 @@ hb_ot_layout_get_attach_points (hb_face_t *face, * @direction: The #hb_direction_t text direction to use * @glyph: The #hb_codepoint_t code point to query * @start_offset: offset of the first caret position to retrieve - * @caret_count: (inout) (allow-none): Input = the maximum number of caret positions to return; + * @caret_count: (inout) (optional): Input = the maximum number of caret positions to return; * Output = the actual number of caret positions returned (may be zero) * @caret_array: (out) (array length=caret_count): The array of caret positions found for the query * @@ -369,21 +366,7 @@ hb_ot_layout_get_ligature_carets (hb_font_t *font, unsigned int *caret_count /* IN/OUT */, hb_position_t *caret_array /* OUT */) { - unsigned int result_caret_count = 0; - unsigned int result = font->face->table.GDEF->table->get_lig_carets (font, direction, glyph, start_offset, &result_caret_count, caret_array); - if (result) - { - if (caret_count) *caret_count = result_caret_count; - } - else - { -#ifndef HB_NO_AAT - result = font->face->table.lcar->get_lig_carets (font, direction, glyph, start_offset, caret_count, caret_array); -#else - if (caret_count) *caret_count = 0; -#endif - } - return result; + return font->face->table.GDEF->table->get_lig_carets (font, direction, glyph, start_offset, caret_count, caret_array); } #endif @@ -393,38 +376,17 @@ hb_ot_layout_get_ligature_carets (hb_font_t *font, */ bool -OT::GSUB::is_blacklisted (hb_blob_t *blob HB_UNUSED, +OT::GSUB::is_blocklisted (hb_blob_t *blob HB_UNUSED, hb_face_t *face) const { #ifdef HB_NO_OT_LAYOUT_BLACKLIST return false; #endif - -#ifndef HB_NO_AAT_SHAPE - /* Mac OS X prefers morx over GSUB. It also ships with various Indic fonts, - * all by 'MUTF' foundry (Tamil MN, Tamil Sangam MN, etc.), that have broken - * GSUB/GPOS tables. Some have GSUB with zero scripts, those are ignored by - * our morx/GSUB preference code. But if GSUB has non-zero scripts, we tend - * to prefer it over morx because we want to be consistent with other OpenType - * shapers. - * - * To work around broken Indic Mac system fonts, we ignore GSUB table if - * OS/2 VendorId is 'MUTF' and font has morx table as well. - * - * https://github.com/harfbuzz/harfbuzz/issues/1410 - * https://github.com/harfbuzz/harfbuzz/issues/1348 - * https://github.com/harfbuzz/harfbuzz/issues/1391 - */ - if (unlikely (face->table.OS2->achVendID == HB_TAG ('M','U','T','F') && - face->table.morx->has_data ())) - return true; -#endif - return false; } bool -OT::GPOS::is_blacklisted (hb_blob_t *blob HB_UNUSED, +OT::GPOS::is_blocklisted (hb_blob_t *blob HB_UNUSED, hb_face_t *face HB_UNUSED) const { #ifdef HB_NO_OT_LAYOUT_BLACKLIST @@ -440,7 +402,7 @@ get_gsubgpos_table (hb_face_t *face, switch (table_tag) { case HB_OT_TAG_GSUB: return *face->table.GSUB->table; case HB_OT_TAG_GPOS: return *face->table.GPOS->table; - default: return Null(OT::GSUBGPOS); + default: return Null (OT::GSUBGPOS); } } @@ -448,9 +410,9 @@ get_gsubgpos_table (hb_face_t *face, /** * hb_ot_layout_table_get_script_tags: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @start_offset: offset of the first script tag to retrieve - * @script_count: (inout) (allow-none): Input = the maximum number of script tags to return; + * @script_count: (inout) (optional): Input = the maximum number of script tags to return; * Output = the actual number of script tags returned (may be zero) * @script_tags: (out) (array length=script_count): The array of #hb_tag_t script tags found for the query * @@ -475,14 +437,14 @@ hb_ot_layout_table_get_script_tags (hb_face_t *face, /** * hb_ot_layout_table_find_script: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_tag: #hb_tag_t of the script tag requested * @script_index: (out): The index of the requested script tag * * Fetches the index if a given script tag in the specified face's GSUB table * or GPOS table. * - * Return value: true if the script is found, false otherwise + * Return value: %true if the script is found, %false otherwise * **/ hb_bool_t @@ -519,7 +481,7 @@ hb_ot_layout_table_find_script (hb_face_t *face, /** * hb_ot_layout_table_choose_script: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_tags: Array of #hb_tag_t script tags * @script_index: (out): The index of the requested script tag * @chosen_script: (out): #hb_tag_t of the script tag requested @@ -542,11 +504,22 @@ hb_ot_layout_table_choose_script (hb_face_t *face, /** * hb_ot_layout_table_select_script: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_count: Number of script tags in the array * @script_tags: Array of #hb_tag_t script tags - * @script_index: (out): The index of the requested script - * @chosen_script: (out): #hb_tag_t of the requested script + * @script_index: (out) (optional): The index of the requested script + * @chosen_script: (out) (optional): #hb_tag_t of the requested script + * + * Selects an OpenType script for @table_tag from the @script_tags array. + * + * If the table does not have any of the requested scripts, then `DFLT`, + * `dflt`, and `latn` tags are tried in that order. If the table still does not + * have any of these scripts, @script_index and @chosen_script are set to + * #HB_OT_LAYOUT_NO_SCRIPT_INDEX. + * + * Return value: + * %true if one of the requested scripts is selected, %false if a fallback + * script is selected or if no scripts are selected. * * Since: 2.0.0 **/ @@ -604,9 +577,9 @@ hb_ot_layout_table_select_script (hb_face_t *face, /** * hb_ot_layout_table_get_feature_tags: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @start_offset: offset of the first feature tag to retrieve - * @feature_count: (inout) (allow-none): Input = the maximum number of feature tags to return; + * @feature_count: (inout) (optional): Input = the maximum number of feature tags to return; * Output = the actual number of feature tags returned (may be zero) * @feature_tags: (out) (array length=feature_count): Array of feature tags found in the table * @@ -629,14 +602,14 @@ hb_ot_layout_table_get_feature_tags (hb_face_t *face, /** * hb_ot_layout_table_find_feature: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @feature_tag: The #hb_tag_t og the requested feature tag * @feature_index: (out): The index of the requested feature * * Fetches the index for a given feature tag in the specified face's GSUB table * or GPOS table. * - * Return value: true if the feature is found, false otherwise + * Return value: %true if the feature is found, %false otherwise **/ bool hb_ot_layout_table_find_feature (hb_face_t *face, @@ -664,10 +637,10 @@ hb_ot_layout_table_find_feature (hb_face_t *face, /** * hb_ot_layout_script_get_language_tags: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_index: The index of the requested script tag * @start_offset: offset of the first language tag to retrieve - * @language_count: (inout) (allow-none): Input = the maximum number of language tags to return; + * @language_count: (inout) (optional): Input = the maximum number of language tags to return; * Output = the actual number of language tags returned (may be zero) * @language_tags: (out) (array length=language_count): Array of language tags found in the table * @@ -693,7 +666,7 @@ hb_ot_layout_script_get_language_tags (hb_face_t *face, /** * hb_ot_layout_script_find_language: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_index: The index of the requested script tag * @language_tag: The #hb_tag_t of the requested language * @language_index: The index of the requested language @@ -701,7 +674,7 @@ hb_ot_layout_script_get_language_tags (hb_face_t *face, * Fetches the index of a given language tag in the specified face's GSUB table * or GPOS table, underneath the specified script tag. * - * Return value: true if the language tag is found, false otherwise + * Return value: %true if the language tag is found, %false otherwise * * Since: ?? * Deprecated: ?? @@ -726,7 +699,7 @@ hb_ot_layout_script_find_language (hb_face_t *face, /** * hb_ot_layout_script_select_language: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_index: The index of the requested script tag * @language_count: The number of languages in the specified script * @language_tags: The array of language tags @@ -735,7 +708,7 @@ hb_ot_layout_script_find_language (hb_face_t *face, * Fetches the index of a given language tag in the specified face's GSUB table * or GPOS table, underneath the specified script index. * - * Return value: true if the language tag is found, false otherwise + * Return value: %true if the language tag is found, %false otherwise * * Since: 2.0.0 **/ @@ -769,7 +742,7 @@ hb_ot_layout_script_select_language (hb_face_t *face, /** * hb_ot_layout_language_get_required_feature_index: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_index: The index of the requested script tag * @language_index: The index of the requested language tag * @feature_index: (out): The index of the requested feature @@ -777,7 +750,7 @@ hb_ot_layout_script_select_language (hb_face_t *face, * Fetches the index of a requested feature in the given face's GSUB or GPOS table, * underneath the specified script and language. * - * Return value: true if the feature is found, false otherwise + * Return value: %true if the feature is found, %false otherwise * **/ hb_bool_t @@ -785,7 +758,7 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t *face, hb_tag_t table_tag, unsigned int script_index, unsigned int language_index, - unsigned int *feature_index) + unsigned int *feature_index /* OUT */) { return hb_ot_layout_language_get_required_feature (face, table_tag, @@ -799,16 +772,16 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t *face, /** * hb_ot_layout_language_get_required_feature: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_index: The index of the requested script tag * @language_index: The index of the requested language tag - * @feature_index: The index of the requested feature + * @feature_index: (out): The index of the requested feature * @feature_tag: (out): The #hb_tag_t of the requested feature * * Fetches the tag of a requested feature index in the given face's GSUB or GPOS table, * underneath the specified script and language. * - * Return value: true if the feature is found, false otherwise + * Return value: %true if the feature is found, %false otherwise * * Since: 0.9.30 **/ @@ -817,8 +790,8 @@ hb_ot_layout_language_get_required_feature (hb_face_t *face, hb_tag_t table_tag, unsigned int script_index, unsigned int language_index, - unsigned int *feature_index, - hb_tag_t *feature_tag) + unsigned int *feature_index /* OUT */, + hb_tag_t *feature_tag /* OUT */) { const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index); @@ -834,11 +807,11 @@ hb_ot_layout_language_get_required_feature (hb_face_t *face, /** * hb_ot_layout_language_get_feature_indexes: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_index: The index of the requested script tag * @language_index: The index of the requested language tag * @start_offset: offset of the first feature tag to retrieve - * @feature_count: (inout) (allow-none): Input = the maximum number of feature tags to return; + * @feature_count: (inout) (optional): Input = the maximum number of feature tags to return; * Output: the actual number of feature tags returned (may be zero) * @feature_indexes: (out) (array length=feature_count): The array of feature indexes found for the query * @@ -865,11 +838,11 @@ hb_ot_layout_language_get_feature_indexes (hb_face_t *face, /** * hb_ot_layout_language_get_feature_tags: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_index: The index of the requested script tag * @language_index: The index of the requested language tag * @start_offset: offset of the first feature tag to retrieve - * @feature_count: (inout) (allow-none): Input = the maximum number of feature tags to return; + * @feature_count: (inout) (optional): Input = the maximum number of feature tags to return; * Output = the actual number of feature tags returned (may be zero) * @feature_tags: (out) (array length=feature_count): The array of #hb_tag_t feature tags found for the query * @@ -906,7 +879,7 @@ hb_ot_layout_language_get_feature_tags (hb_face_t *face, /** * hb_ot_layout_language_find_feature: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_index: The index of the requested script tag * @language_index: The index of the requested language tag * @feature_tag: #hb_tag_t of the feature tag requested @@ -915,7 +888,7 @@ hb_ot_layout_language_get_feature_tags (hb_face_t *face, * Fetches the index of a given feature tag in the specified face's GSUB table * or GPOS table, underneath the specified script and language. * - * Return value: true if the feature is found, false otherwise + * Return value: %true if the feature is found, %false otherwise * **/ hb_bool_t @@ -948,10 +921,10 @@ hb_ot_layout_language_find_feature (hb_face_t *face, /** * hb_ot_layout_feature_get_lookups: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @feature_index: The index of the requested feature * @start_offset: offset of the first lookup to retrieve - * @lookup_count: (inout) (allow-none): Input = the maximum number of lookups to return; + * @lookup_count: (inout) (optional): Input = the maximum number of lookups to return; * Output = the actual number of lookups returned (may be zero) * @lookup_indexes: (out) (array length=lookup_count): The array of lookup indexes found for the query * @@ -982,7 +955,7 @@ hb_ot_layout_feature_get_lookups (hb_face_t *face, /** * hb_ot_layout_table_get_lookup_count: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * * Fetches the total number of lookups enumerated in the specified * face's GSUB table or GPOS table. @@ -1004,7 +977,7 @@ struct hb_collect_features_context_t hb_set_t *feature_indexes_) : g (get_gsubgpos_table (face, table_tag)), feature_indexes (feature_indexes_), - script_count(0),langsys_count(0) {} + script_count (0),langsys_count (0), feature_index_count (0) {} bool visited (const OT::Script &s) { @@ -1033,6 +1006,12 @@ struct hb_collect_features_context_t return visited (l, visited_langsys); } + bool visited_feature_indices (unsigned count) + { + feature_index_count += count; + return feature_index_count > HB_MAX_FEATURE_INDICES; + } + private: template <typename T> bool visited (const T &p, hb_set_t &visited_set) @@ -1054,6 +1033,7 @@ struct hb_collect_features_context_t hb_set_t visited_langsys; unsigned int script_count; unsigned int langsys_count; + unsigned int feature_index_count; }; static void @@ -1066,10 +1046,11 @@ langsys_collect_features (hb_collect_features_context_t *c, if (!features) { /* All features. */ - if (l.has_required_feature ()) + if (l.has_required_feature () && !c->visited_feature_indices (1)) c->feature_indexes->add (l.get_required_feature_index ()); - l.add_feature_indexes_to (c->feature_indexes); + if (!c->visited_feature_indices (l.featureIndex.len)) + l.add_feature_indexes_to (c->feature_indexes); } else { @@ -1131,7 +1112,7 @@ script_collect_features (hb_collect_features_context_t *c, /** * hb_ot_layout_collect_features: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @scripts: The array of scripts to collect features for * @languages: The array of languages to collect features for * @features: The array of features to collect @@ -1182,7 +1163,7 @@ hb_ot_layout_collect_features (hb_face_t *face, /** * hb_ot_layout_collect_lookups: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @scripts: The array of scripts to collect lookups for * @languages: The array of languages to collect lookups for * @features: The array of features to collect lookups for @@ -1212,6 +1193,8 @@ hb_ot_layout_collect_lookups (hb_face_t *face, for (hb_codepoint_t feature_index = HB_SET_VALUE_INVALID; hb_set_next (&feature_indexes, &feature_index);) g.get_feature (feature_index).add_lookup_indexes_to (lookup_indexes); + + g.feature_variation_collect_lookups (&feature_indexes, lookup_indexes); } @@ -1219,12 +1202,12 @@ hb_ot_layout_collect_lookups (hb_face_t *face, /** * hb_ot_layout_lookup_collect_glyphs: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @lookup_index: The index of the feature lookup to query * @glyphs_before: (out): Array of glyphs preceding the substitution range * @glyphs_input: (out): Array of input glyphs that would be substituted by the lookup - * @glyphs_after: (out): Array of glyphs following the substition range - * @glyphs_output: (out): Array of glyphs that would be the substitued output of the lookup + * @glyphs_after: (out): Array of glyphs following the substitution range + * @glyphs_output: (out): Array of glyphs that would be the substituted output of the lookup * * Fetches a list of all glyphs affected by the specified lookup in the * specified face's GSUB table or GPOS table. @@ -1271,9 +1254,9 @@ hb_ot_layout_lookup_collect_glyphs (hb_face_t *face, /** * hb_ot_layout_table_find_feature_variations: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @coords: The variation coordinates to query - * @num_coords: The number of variation coorinates + * @num_coords: The number of variation coordinates * @variations_index: (out): The array of feature variations found for the query * * Fetches a list of feature variations in the specified face's GSUB table @@ -1296,11 +1279,11 @@ hb_ot_layout_table_find_feature_variations (hb_face_t *face, /** * hb_ot_layout_feature_with_variations_get_lookups: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @feature_index: The index of the feature to query * @variations_index: The index of the feature variation to query * @start_offset: offset of the first lookup to retrieve - * @lookup_count: (inout) (allow-none): Input = the maximum number of lookups to return; + * @lookup_count: (inout) (optional): Input = the maximum number of lookups to return; * Output = the actual number of lookups returned (may be zero) * @lookup_indexes: (out) (array length=lookup_count): The array of lookups found for the query * @@ -1338,7 +1321,7 @@ hb_ot_layout_feature_with_variations_get_lookups (hb_face_t *face, * * Tests whether the specified face includes any GSUB substitutions. * - * Return value: true if data found, false otherwise + * Return value: %true if data found, %false otherwise * **/ hb_bool_t @@ -1359,7 +1342,7 @@ hb_ot_layout_has_substitution (hb_face_t *face) * Tests whether a specified lookup in the specified face would * trigger a substitution on the given glyph sequence. * - * Return value: true if a substitution would be triggered, false otherwise + * Return value: %true if a substitution would be triggered, %false otherwise * * Since: 0.9.7 **/ @@ -1374,7 +1357,6 @@ hb_ot_layout_lookup_would_substitute (hb_face_t *face, OT::hb_would_apply_context_t c (face, glyphs, glyphs_length, (bool) zero_context); const OT::SubstLookup& l = face->table.GSUB->table->get_lookup (lookup_index); - return l.would_apply (&c, &face->table.GSUB->accels[lookup_index]); } @@ -1392,7 +1374,7 @@ void hb_ot_layout_substitute_start (hb_font_t *font, hb_buffer_t *buffer) { -_hb_ot_layout_set_glyph_props (font, buffer); + _hb_ot_layout_set_glyph_props (font, buffer); } void @@ -1458,8 +1440,8 @@ hb_ot_layout_delete_glyphs_inplace (hb_buffer_t *buffer, **/ void hb_ot_layout_lookup_substitute_closure (hb_face_t *face, - unsigned int lookup_index, - hb_set_t *glyphs /* OUT */) + unsigned int lookup_index, + hb_set_t *glyphs /* OUT */) { hb_map_t done_lookups; OT::hb_closure_context_t c (face, glyphs, &done_lookups); @@ -1494,7 +1476,7 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, do { glyphs_length = glyphs->get_population (); - if (lookups != nullptr) + if (lookups) { for (hb_codepoint_t lookup_index = HB_SET_VALUE_INVALID; hb_set_next (lookups, &lookup_index);) gsub.get_lookup (lookup_index).closure (&c, lookup_index); @@ -1517,7 +1499,9 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, * hb_ot_layout_has_positioning: * @face: #hb_face_t to work upon * - * Return value: true if the face has GPOS data, false otherwise + * Tests whether the specified face includes any GPOS positioning. + * + * Return value: %true if the face has GPOS data, %false otherwise * **/ hb_bool_t @@ -1587,10 +1571,10 @@ hb_ot_layout_position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer) * specifically in their respective size ranges; other ways to differentiate fonts within * a subfamily are not covered by the `size` feature. * - * For more information on this distinction, see the `size` documentation at - * https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#tag-39size39 + * For more information on this distinction, see the [`size` feature documentation]( + * https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#tag-size). * - * Return value: true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 0.9.10 **/ @@ -1639,22 +1623,22 @@ hb_ot_layout_get_size_params (hb_face_t *face, * @face: #hb_face_t to work upon * @table_tag: table tag to query, "GSUB" or "GPOS". * @feature_index: index of feature to query. - * @label_id: (out) (allow-none): The ‘name’ table name ID that specifies a string + * @label_id: (out) (optional): The ‘name’ table name ID that specifies a string * for a user-interface label for this feature. (May be NULL.) - * @tooltip_id: (out) (allow-none): The ‘name’ table name ID that specifies a string + * @tooltip_id: (out) (optional): The ‘name’ table name ID that specifies a string * that an application can use for tooltip text for this * feature. (May be NULL.) - * @sample_id: (out) (allow-none): The ‘name’ table name ID that specifies sample text + * @sample_id: (out) (optional): The ‘name’ table name ID that specifies sample text * that illustrates the effect of this feature. (May be NULL.) - * @num_named_parameters: (out) (allow-none): Number of named parameters. (May be zero.) - * @first_param_id: (out) (allow-none): The first ‘name’ table name ID used to specify + * @num_named_parameters: (out) (optional): Number of named parameters. (May be zero.) + * @first_param_id: (out) (optional): The first ‘name’ table name ID used to specify * strings for user-interface labels for the feature * parameters. (Must be zero if numParameters is zero.) * * Fetches name indices from feature parameters for "Stylistic Set" ('ssXX') or * "Character Variant" ('cvXX') features. * - * Return value: true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 2.0.0 **/ @@ -1714,7 +1698,7 @@ hb_ot_layout_feature_get_name_ids (hb_face_t *face, * @table_tag: table tag to query, "GSUB" or "GPOS". * @feature_index: index of feature to query. * @start_offset: offset of the first character to retrieve - * @char_count: (inout) (allow-none): Input = the maximum number of characters to return; + * @char_count: (inout) (optional): Input = the maximum number of characters to return; * Output = the actual number of characters returned (may be zero) * @characters: (out caller-allocates) (array length=char_count): A buffer pointer. * The Unicode codepoints of the characters for which this feature provides @@ -1723,12 +1707,6 @@ hb_ot_layout_feature_get_name_ids (hb_face_t *face, * Fetches a list of the characters defined as having a variant under the specified * "Character Variant" ("cvXX") feature tag. * - * <note>Note: If the char_count output value is equal to its input value, then there - * is a chance there were more characters defined under the feature tag than were - * returned. This function can be called with incrementally larger start_offset - * until the char_count output value is lower than its input value, or the size - * of the characters array can be increased.</note> - * * Return value: Number of total sample characters in the cvXX feature. * * Since: 2.0.0 @@ -1742,24 +1720,10 @@ hb_ot_layout_feature_get_characters (hb_face_t *face, hb_codepoint_t *characters /* OUT. May be NULL */) { const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); - - hb_tag_t feature_tag = g.get_feature_tag (feature_index); - const OT::Feature &f = g.get_feature (feature_index); - - const OT::FeatureParams &feature_params = f.get_feature_params (); - - const OT::FeatureParamsCharacterVariants& cv_params = - feature_params.get_character_variants_params(feature_tag); - - unsigned int len = 0; - if (char_count && characters && start_offset < cv_params.characters.len) - { - len = hb_min (cv_params.characters.len - start_offset, *char_count); - for (unsigned int i = 0; i < len; ++i) - characters[i] = cv_params.characters[start_offset + i]; - } - if (char_count) *char_count = len; - return cv_params.characters.len; + return g.get_feature (feature_index) + .get_feature_params () + .get_character_variants_params(g.get_feature_tag (feature_index)) + .get_characters (start_offset, char_count, characters); } #endif @@ -1818,7 +1782,7 @@ apply_forward (OT::hb_ot_apply_context_t *c, if (applied) ret = true; else - buffer->next_glyph (); + (void) buffer->next_glyph (); } return ret; } @@ -1928,13 +1892,17 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, void hb_ot_map_t::substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const { GSUBProxy proxy (font->face); + if (!buffer->message (font, "start table GSUB")) return; apply (proxy, plan, font, buffer); + (void) buffer->message (font, "end table GSUB"); } void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const { GPOSProxy proxy (font->face); + if (!buffer->message (font, "start table GPOS")) return; apply (proxy, plan, font, buffer); + (void) buffer->message (font, "end table GPOS"); } void @@ -1952,12 +1920,12 @@ hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c, * @baseline_tag: a baseline tag * @direction: text direction. * @script_tag: script tag. - * @language_tag: language tag. + * @language_tag: language tag, currently unused. * @coord: (out): baseline value if found. * * Fetches a baseline value from the face. * - * Return value: if found baseline value in the the font. + * Return value: if found baseline value in the font. * * Since: 2.6.0 **/ @@ -1977,4 +1945,62 @@ hb_ot_layout_get_baseline (hb_font_t *font, return result; } #endif + + +struct hb_get_glyph_alternates_dispatch_t : + hb_dispatch_context_t<hb_get_glyph_alternates_dispatch_t, unsigned> +{ + static return_t default_return_value () { return 0; } + bool stop_sublookup_iteration (return_t r) const { return r; } + + hb_face_t *face; + + hb_get_glyph_alternates_dispatch_t (hb_face_t *face) : + face (face) {} + + private: + template <typename T, typename ...Ts> auto + _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN + ( obj.get_glyph_alternates (hb_forward<Ts> (ds)...) ) + template <typename T, typename ...Ts> auto + _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN + ( default_return_value () ) + public: + template <typename T, typename ...Ts> auto + dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN + ( _dispatch (obj, hb_prioritize, hb_forward<Ts> (ds)...) ) +}; + +/** + * hb_ot_layout_lookup_get_glyph_alternates: + * @face: a face. + * @lookup_index: index of the feature lookup to query. + * @glyph: a glyph id. + * @start_offset: starting offset. + * @alternate_count: (inout) (optional): Input = the maximum number of alternate glyphs to return; + * Output = the actual number of alternate glyphs returned (may be zero). + * @alternate_glyphs: (out caller-allocates) (array length=alternate_count): A glyphs buffer. + * Alternate glyphs associated with the glyph id. + * + * Fetches alternates of a glyph from a given GSUB lookup index. + * + * Return value: total number of alternates found in the specific lookup index for the given glyph id. + * + * Since: 2.6.8 + **/ +HB_EXTERN unsigned +hb_ot_layout_lookup_get_glyph_alternates (hb_face_t *face, + unsigned lookup_index, + hb_codepoint_t glyph, + unsigned start_offset, + unsigned *alternate_count /* IN/OUT. May be NULL. */, + hb_codepoint_t *alternate_glyphs /* OUT. May be NULL. */) +{ + hb_get_glyph_alternates_dispatch_t c (face); + const OT::SubstLookup &lookup = face->table.GSUB->table->get_lookup (lookup_index); + auto ret = lookup.dispatch (&c, glyph, start_offset, alternate_count, alternate_glyphs); + if (!ret && alternate_count) *alternate_count = 0; + return ret; +} + #endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h index 7e8a897cff..d47ba0fc92 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h @@ -24,7 +24,7 @@ * Red Hat Author(s): Behdad Esfahbod */ -#ifndef HB_OT_H_IN +#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb-ot.h> instead." #endif @@ -38,10 +38,35 @@ HB_BEGIN_DECLS +/** + * HB_OT_TAG_BASE: + * + * OpenType [Baseline Table](https://docs.microsoft.com/en-us/typography/opentype/spec/base). + */ #define HB_OT_TAG_BASE HB_TAG('B','A','S','E') +/** + * HB_OT_TAG_GDEF: + * + * OpenType [Glyph Definition Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef). + */ #define HB_OT_TAG_GDEF HB_TAG('G','D','E','F') +/** + * HB_OT_TAG_GSUB: + * + * OpenType [Glyph Substitution Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gsub). + */ #define HB_OT_TAG_GSUB HB_TAG('G','S','U','B') +/** + * HB_OT_TAG_GPOS: + * + * OpenType [Glyph Positioning Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos). + */ #define HB_OT_TAG_GPOS HB_TAG('G','P','O','S') +/** + * HB_OT_TAG_JSTF: + * + * OpenType [Justification Table](https://docs.microsoft.com/en-us/typography/opentype/spec/jstf). + */ #define HB_OT_TAG_JSTF HB_TAG('J','S','T','F') @@ -49,18 +74,34 @@ HB_BEGIN_DECLS * Script & Language tags. */ +/** + * HB_OT_TAG_DEFAULT_SCRIPT: + * + * OpenType script tag, `DFLT`, for features that are not script-specific. + * + */ #define HB_OT_TAG_DEFAULT_SCRIPT HB_TAG ('D', 'F', 'L', 'T') +/** + * HB_OT_TAG_DEFAULT_LANGUAGE: + * + * OpenType language tag, `dflt`. Not a valid language tag, but some fonts + * mistakenly use it. + */ #define HB_OT_TAG_DEFAULT_LANGUAGE HB_TAG ('d', 'f', 'l', 't') /** * HB_OT_MAX_TAGS_PER_SCRIPT: * + * Maximum number of OpenType tags that can correspond to a give #hb_script_t. + * * Since: 2.0.0 **/ #define HB_OT_MAX_TAGS_PER_SCRIPT 3u /** * HB_OT_MAX_TAGS_PER_LANGUAGE: * + * Maximum number of OpenType tags that can correspond to a give #hb_language_t. + * * Since: 2.0.0 **/ #define HB_OT_MAX_TAGS_PER_LANGUAGE 3u @@ -121,7 +162,6 @@ hb_ot_layout_get_glyphs_in_class (hb_face_t *face, hb_ot_layout_glyph_class_t klass, hb_set_t *glyphs /* OUT */); - /* Not that useful. Provides list of attach points for a glyph that a * client may want to cache */ HB_EXTERN unsigned int @@ -145,9 +185,29 @@ hb_ot_layout_get_ligature_carets (hb_font_t *font, * GSUB/GPOS feature query and enumeration interface */ +/** + * HB_OT_LAYOUT_NO_SCRIPT_INDEX: + * + * Special value for script index indicating unsupported script. + */ #define HB_OT_LAYOUT_NO_SCRIPT_INDEX 0xFFFFu +/** + * HB_OT_LAYOUT_NO_FEATURE_INDEX: + * + * Special value for feature index indicating unsupported feature. + */ #define HB_OT_LAYOUT_NO_FEATURE_INDEX 0xFFFFu +/** + * HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX: + * + * Special value for language index indicating default or unsupported language. + */ #define HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX 0xFFFFu +/** + * HB_OT_LAYOUT_NO_VARIATIONS_INDEX: + * + * Special value for variations index indicating unsupported variation. + */ #define HB_OT_LAYOUT_NO_VARIATIONS_INDEX 0xFFFFFFFFu HB_EXTERN unsigned int @@ -161,7 +221,7 @@ HB_EXTERN hb_bool_t hb_ot_layout_table_find_script (hb_face_t *face, hb_tag_t table_tag, hb_tag_t script_tag, - unsigned int *script_index); + unsigned int *script_index /* OUT */); HB_EXTERN hb_bool_t hb_ot_layout_table_select_script (hb_face_t *face, @@ -199,15 +259,15 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t *face, hb_tag_t table_tag, unsigned int script_index, unsigned int language_index, - unsigned int *feature_index); + unsigned int *feature_index /* OUT */); HB_EXTERN hb_bool_t hb_ot_layout_language_get_required_feature (hb_face_t *face, hb_tag_t table_tag, unsigned int script_index, unsigned int language_index, - unsigned int *feature_index, - hb_tag_t *feature_tag); + unsigned int *feature_index /* OUT */, + hb_tag_t *feature_tag /* OUT */); HB_EXTERN unsigned int hb_ot_layout_language_get_feature_indexes (hb_face_t *face, @@ -233,7 +293,7 @@ hb_ot_layout_language_find_feature (hb_face_t *face, unsigned int script_index, unsigned int language_index, hb_tag_t feature_tag, - unsigned int *feature_index); + unsigned int *feature_index /* OUT */); HB_EXTERN unsigned int hb_ot_layout_feature_get_lookups (hb_face_t *face, @@ -324,6 +384,14 @@ hb_ot_layout_feature_with_variations_get_lookups (hb_face_t *face, HB_EXTERN hb_bool_t hb_ot_layout_has_substitution (hb_face_t *face); +HB_EXTERN unsigned +hb_ot_layout_lookup_get_glyph_alternates (hb_face_t *face, + unsigned lookup_index, + hb_codepoint_t glyph, + unsigned start_offset, + unsigned *alternate_count /* IN/OUT */, + hb_codepoint_t *alternate_glyphs /* OUT */); + HB_EXTERN hb_bool_t hb_ot_layout_lookup_would_substitute (hb_face_t *face, unsigned int lookup_index, @@ -426,7 +494,7 @@ hb_ot_layout_feature_get_characters (hb_face_t *face, * @HB_OT_LAYOUT_BASELINE_TAG_MATH: The baseline about which mathematical characters are centered. * In vertical writing mode when mathematical characters rotated 90 degrees clockwise, are centered. * - * Baseline tags from https://docs.microsoft.com/en-us/typography/opentype/spec/baselinetags + * Baseline tags from [Baseline Tags](https://docs.microsoft.com/en-us/typography/opentype/spec/baselinetags) registry. * * Since: 2.6.0 */ @@ -439,6 +507,7 @@ typedef enum { HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_TOP_OR_RIGHT = HB_TAG ('i','d','t','p'), HB_OT_LAYOUT_BASELINE_TAG_MATH = HB_TAG ('m','a','t','h'), + /*< private >*/ _HB_OT_LAYOUT_BASELINE_TAG_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/ } hb_ot_layout_baseline_tag_t; @@ -450,7 +519,6 @@ hb_ot_layout_get_baseline (hb_font_t *font, hb_tag_t language_tag, hb_position_t *coord /* OUT. May be NULL. */); - HB_END_DECLS #endif /* HB_OT_LAYOUT_H */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.hh index f3bb15581a..ac61bc70de 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.hh @@ -315,12 +315,13 @@ _hb_glyph_info_get_unicode_space_fallback_type (const hb_glyph_info_t *info) } static inline bool _hb_glyph_info_ligated (const hb_glyph_info_t *info); +static inline bool _hb_glyph_info_substituted (const hb_glyph_info_t *info); static inline bool _hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info) { return (info->unicode_props() & UPROPS_MASK_IGNORABLE) && - !_hb_glyph_info_ligated (info); + !_hb_glyph_info_substituted (info); } static inline bool _hb_glyph_info_is_default_ignorable_and_not_hidden (const hb_glyph_info_t *info) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-map.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-map.hh index 0a4827d745..5f2afae281 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-map.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-map.hh @@ -134,18 +134,18 @@ struct hb_ot_map_t unsigned int get_feature_stage (unsigned int table_index, hb_tag_t feature_tag) const { const feature_map_t *map = features.bsearch (feature_tag); - return map ? map->stage[table_index] : (unsigned int) -1; + return map ? map->stage[table_index] : UINT_MAX; } void get_stage_lookups (unsigned int table_index, unsigned int stage, const struct lookup_map_t **plookups, unsigned int *lookup_count) const { - if (unlikely (stage == (unsigned int) -1)) { + if (unlikely (stage > stages[table_index].length)) + { *plookups = nullptr; *lookup_count = 0; return; } - assert (stage <= stages[table_index].length); unsigned int start = stage ? stages[table_index][stage - 1].last_lookup : 0; unsigned int end = stage < stages[table_index].length ? stages[table_index][stage].last_lookup : lookups[table_index].length; *plookups = end == start ? nullptr : &lookups[table_index][start]; @@ -213,8 +213,8 @@ struct hb_ot_map_builder_t { add_feature (feat.tag, feat.flags); } void enable_feature (hb_tag_t tag, - hb_ot_map_feature_flags_t flags=F_NONE, - unsigned int value=1) + hb_ot_map_feature_flags_t flags=F_NONE, + unsigned int value=1) { add_feature (tag, F_GLOBAL | flags, value); } void disable_feature (hb_tag_t tag) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-math-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-math-table.hh index 7529e0c080..26aa080603 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-math-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-math-table.hh @@ -48,7 +48,7 @@ struct MathValueRecord } protected: - HBINT16 value; /* The X or Y value in design units */ + HBINT16 value; /* The X or Y value in design units */ OffsetTo<Device> deviceTable; /* Offset to the device table - from the * beginning of parent table. May be NULL. * Suggested format for device table is 1. */ @@ -78,7 +78,7 @@ struct MathConstants } hb_position_t get_value (hb_ot_math_constant_t constant, - hb_font_t *font) const + hb_font_t *font) const { switch (constant) { @@ -279,14 +279,15 @@ struct MathKern protected: HBUINT16 heightCount; UnsizedArrayOf<MathValueRecord> - mathValueRecordsZ; /* Array of correction heights at - * which the kern value changes. - * Sorted by the height value in - * design units (heightCount entries), - * Followed by: - * Array of kern values corresponding - * to heights. (heightCount+1 entries). - */ + mathValueRecordsZ; + /* Array of correction heights at + * which the kern value changes. + * Sorted by the height value in + * design units (heightCount entries), + * Followed by: + * Array of kern values corresponding + * to heights. (heightCount+1 entries). + */ public: DEFINE_SIZE_ARRAY (2, mathValueRecordsZ); @@ -345,15 +346,18 @@ struct MathKernInfo } protected: - OffsetTo<Coverage> mathKernCoverage; /* Offset to Coverage table - - * from the beginning of the - * MathKernInfo table. */ - ArrayOf<MathKernInfoRecord> mathKernInfoRecords; /* Array of - * MathKernInfoRecords, - * per-glyph information for - * mathematical positioning - * of subscripts and - * superscripts. */ + OffsetTo<Coverage> + mathKernCoverage; + /* Offset to Coverage table - + * from the beginning of the + * MathKernInfo table. */ + ArrayOf<MathKernInfoRecord> + mathKernInfoRecords; + /* Array of MathKernInfoRecords, + * per-glyph information for + * mathematical positioning + * of subscripts and + * superscripts. */ public: DEFINE_SIZE_ARRAY (4, mathKernInfoRecords); @@ -471,19 +475,21 @@ struct MathGlyphPartRecord } protected: - HBGlyphID glyph; /* Glyph ID for the part. */ - HBUINT16 startConnectorLength; /* Advance width/ height of the straight bar - * connector material, in design units, is at - * the beginning of the glyph, in the - * direction of the extension. */ - HBUINT16 endConnectorLength; /* Advance width/ height of the straight bar - * connector material, in design units, is at - * the end of the glyph, in the direction of - * the extension. */ - HBUINT16 fullAdvance; /* Full advance width/height for this part, - * in the direction of the extension. - * In design units. */ - PartFlags partFlags; /* Part qualifiers. */ + HBGlyphID glyph; /* Glyph ID for the part. */ + HBUINT16 startConnectorLength; + /* Advance width/ height of the straight bar + * connector material, in design units, is at + * the beginning of the glyph, in the + * direction of the extension. */ + HBUINT16 endConnectorLength; + /* Advance width/ height of the straight bar + * connector material, in design units, is at + * the end of the glyph, in the direction of + * the extension. */ + HBUINT16 fullAdvance; /* Full advance width/height for this part, + * in the direction of the extension. + * In design units. */ + PartFlags partFlags; /* Part qualifiers. */ public: DEFINE_SIZE_STATIC (10); @@ -509,10 +515,9 @@ struct MathGlyphAssembly if (parts_count) { int64_t mult = font->dir_mult (direction); - hb_array_t<const MathGlyphPartRecord> arr = partRecords.sub_array (start_offset, parts_count); - unsigned int count = arr.length; - for (unsigned int i = 0; i < count; i++) - arr[i].extract (parts[i], mult, font); + for (auto _ : hb_zip (partRecords.sub_array (start_offset, parts_count), + hb_array (parts, *parts_count))) + _.first.extract (_.second, mult, font); } if (italics_correction) @@ -522,12 +527,15 @@ struct MathGlyphAssembly } protected: - MathValueRecord italicsCorrection; /* Italics correction of this - * MathGlyphAssembly. Should not - * depend on the assembly size. */ - ArrayOf<MathGlyphPartRecord> partRecords; /* Array of part records, from - * left to right and bottom to - * top. */ + MathValueRecord + italicsCorrection; + /* Italics correction of this + * MathGlyphAssembly. Should not + * depend on the assembly size. */ + ArrayOf<MathGlyphPartRecord> + partRecords; /* Array of part records, from + * left to right and bottom to + * top. */ public: DEFINE_SIZE_ARRAY (6, partRecords); @@ -554,13 +562,9 @@ struct MathGlyphConstruction if (variants_count) { int64_t mult = font->dir_mult (direction); - hb_array_t<const MathGlyphVariantRecord> arr = mathGlyphVariantRecord.sub_array (start_offset, variants_count); - unsigned int count = arr.length; - for (unsigned int i = 0; i < count; i++) - { - variants[i].glyph = arr[i].variantGlyph; - variants[i].advance = font->em_mult (arr[i].advanceMeasurement, mult); - } + for (auto _ : hb_zip (mathGlyphVariantRecord.sub_array (start_offset, variants_count), + hb_array (variants, *variants_count))) + _.second = {_.first.variantGlyph, font->em_mult (_.first.advanceMeasurement, mult)}; } return mathGlyphVariantRecord.len; } @@ -612,12 +616,12 @@ struct MathVariants .get_variants (direction, font, start_offset, variants_count, variants); } unsigned int get_glyph_parts (hb_codepoint_t glyph, - hb_direction_t direction, - hb_font_t *font, - unsigned int start_offset, - unsigned int *parts_count, /* IN/OUT */ - hb_ot_math_glyph_part_t *parts /* OUT */, - hb_position_t *italics_correction /* OUT */) const + hb_direction_t direction, + hb_font_t *font, + unsigned int start_offset, + unsigned int *parts_count, /* IN/OUT */ + hb_ot_math_glyph_part_t *parts /* OUT */, + hb_position_t *italics_correction /* OUT */) const { return get_glyph_construction (glyph, direction, font) .get_assembly () .get_parts (direction, font, @@ -645,27 +649,30 @@ struct MathVariants } protected: - HBUINT16 minConnectorOverlap; /* Minimum overlap of connecting - * glyphs during glyph construction, - * in design units. */ - OffsetTo<Coverage> vertGlyphCoverage; /* Offset to Coverage table - - * from the beginning of MathVariants - * table. */ - OffsetTo<Coverage> horizGlyphCoverage; /* Offset to Coverage table - - * from the beginning of MathVariants - * table. */ - HBUINT16 vertGlyphCount; /* Number of glyphs for which - * information is provided for - * vertically growing variants. */ - HBUINT16 horizGlyphCount; /* Number of glyphs for which - * information is provided for - * horizontally growing variants. */ + HBUINT16 minConnectorOverlap; + /* Minimum overlap of connecting + * glyphs during glyph construction, + * in design units. */ + OffsetTo<Coverage> vertGlyphCoverage; + /* Offset to Coverage table - + * from the beginning of MathVariants + * table. */ + OffsetTo<Coverage> horizGlyphCoverage; + /* Offset to Coverage table - + * from the beginning of MathVariants + * table. */ + HBUINT16 vertGlyphCount; /* Number of glyphs for which + * information is provided for + * vertically growing variants. */ + HBUINT16 horizGlyphCount;/* Number of glyphs for which + * information is provided for + * horizontally growing variants. */ /* Array of offsets to MathGlyphConstruction tables - from the beginning of the MathVariants table, for shapes growing in vertical/horizontal direction. */ UnsizedArrayOf<OffsetTo<MathGlyphConstruction>> - glyphConstruction; + glyphConstruction; public: DEFINE_SIZE_ARRAY (10, glyphConstruction); @@ -694,7 +701,7 @@ struct MATH } hb_position_t get_constant (hb_ot_math_constant_t constant, - hb_font_t *font) const + hb_font_t *font) const { return (this+mathConstants).get_value (constant, font); } const MathGlyphInfo &get_glyph_info () const { return this+mathGlyphInfo; } @@ -702,11 +709,14 @@ struct MATH const MathVariants &get_variants () const { return this+mathVariants; } protected: - FixedVersion<>version; /* Version of the MATH table - * initially set to 0x00010000u */ - OffsetTo<MathConstants> mathConstants;/* MathConstants table */ - OffsetTo<MathGlyphInfo> mathGlyphInfo;/* MathGlyphInfo table */ - OffsetTo<MathVariants> mathVariants; /* MathVariants table */ + FixedVersion<>version; /* Version of the MATH table + * initially set to 0x00010000u */ + OffsetTo<MathConstants> + mathConstants; /* MathConstants table */ + OffsetTo<MathGlyphInfo> + mathGlyphInfo; /* MathGlyphInfo table */ + OffsetTo<MathVariants> + mathVariants; /* MathVariants table */ public: DEFINE_SIZE_STATIC (10); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc index 9d8c6e735a..5781d25f2a 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc @@ -56,7 +56,7 @@ * * Tests whether a face has a `MATH` table. * - * Return value: true if the table is found, false otherwise + * Return value: %true if the table is found, %false otherwise * * Since: 1.3.3 **/ @@ -142,7 +142,7 @@ hb_ot_math_get_glyph_top_accent_attachment (hb_font_t *font, * * Tests whether the given glyph index is an extended shape in the face. * - * Return value: true if the glyph is an extended shape, false otherwise + * Return value: %true if the glyph is an extended shape, %false otherwise * * Since: 1.3.3 **/ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-math.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-math.h index ad864a762d..d3ffa19d85 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-math.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-math.h @@ -24,7 +24,7 @@ * Igalia Author(s): Frédéric Wang */ -#ifndef HB_OT_H_IN +#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb-ot.h> instead." #endif @@ -40,18 +40,89 @@ HB_BEGIN_DECLS * MATH */ +/** + * HB_OT_TAG_MATH: + * + * OpenType [Mathematical Typesetting Table](https://docs.microsoft.com/en-us/typography/opentype/spec/math). + * + * Since: 1.3.3 + */ #define HB_OT_TAG_MATH HB_TAG('M','A','T','H') -/* Use with hb_buffer_set_script() for math shaping. */ +/** + * HB_OT_MATH_SCRIPT: + * + * OpenType script tag for math shaping, for use with + * Use with hb_buffer_set_script(). + * + * Since: 1.3.3 + */ #define HB_OT_MATH_SCRIPT HB_TAG('m','a','t','h') /* Types */ /** * hb_ot_math_constant_t: + * @HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN: scriptPercentScaleDown + * @HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN: scriptScriptPercentScaleDown + * @HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT: delimitedSubFormulaMinHeight + * @HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT: displayOperatorMinHeight + * @HB_OT_MATH_CONSTANT_MATH_LEADING: mathLeading + * @HB_OT_MATH_CONSTANT_AXIS_HEIGHT: axisHeight + * @HB_OT_MATH_CONSTANT_ACCENT_BASE_HEIGHT: accentBaseHeight + * @HB_OT_MATH_CONSTANT_FLATTENED_ACCENT_BASE_HEIGHT: flattenedAccentBaseHeight + * @HB_OT_MATH_CONSTANT_SUBSCRIPT_SHIFT_DOWN: subscriptShiftDown + * @HB_OT_MATH_CONSTANT_SUBSCRIPT_TOP_MAX: subscriptTopMax + * @HB_OT_MATH_CONSTANT_SUBSCRIPT_BASELINE_DROP_MIN: subscriptBaselineDropMin + * @HB_OT_MATH_CONSTANT_SUPERSCRIPT_SHIFT_UP: superscriptShiftUp + * @HB_OT_MATH_CONSTANT_SUPERSCRIPT_SHIFT_UP_CRAMPED: superscriptShiftUpCramped + * @HB_OT_MATH_CONSTANT_SUPERSCRIPT_BOTTOM_MIN: superscriptBottomMin + * @HB_OT_MATH_CONSTANT_SUPERSCRIPT_BASELINE_DROP_MAX: superscriptBaselineDropMax + * @HB_OT_MATH_CONSTANT_SUB_SUPERSCRIPT_GAP_MIN: subSuperscriptGapMin + * @HB_OT_MATH_CONSTANT_SUPERSCRIPT_BOTTOM_MAX_WITH_SUBSCRIPT: superscriptBottomMaxWithSubscript + * @HB_OT_MATH_CONSTANT_SPACE_AFTER_SCRIPT: spaceAfterScript + * @HB_OT_MATH_CONSTANT_UPPER_LIMIT_GAP_MIN: upperLimitGapMin + * @HB_OT_MATH_CONSTANT_UPPER_LIMIT_BASELINE_RISE_MIN: upperLimitBaselineRiseMin + * @HB_OT_MATH_CONSTANT_LOWER_LIMIT_GAP_MIN: lowerLimitGapMin + * @HB_OT_MATH_CONSTANT_LOWER_LIMIT_BASELINE_DROP_MIN: lowerLimitBaselineDropMin + * @HB_OT_MATH_CONSTANT_STACK_TOP_SHIFT_UP: stackTopShiftUp + * @HB_OT_MATH_CONSTANT_STACK_TOP_DISPLAY_STYLE_SHIFT_UP: stackTopDisplayStyleShiftUp + * @HB_OT_MATH_CONSTANT_STACK_BOTTOM_SHIFT_DOWN: stackBottomShiftDown + * @HB_OT_MATH_CONSTANT_STACK_BOTTOM_DISPLAY_STYLE_SHIFT_DOWN: stackBottomDisplayStyleShiftDown + * @HB_OT_MATH_CONSTANT_STACK_GAP_MIN: stackGapMin + * @HB_OT_MATH_CONSTANT_STACK_DISPLAY_STYLE_GAP_MIN: stackDisplayStyleGapMin + * @HB_OT_MATH_CONSTANT_STRETCH_STACK_TOP_SHIFT_UP: stretchStackTopShiftUp + * @HB_OT_MATH_CONSTANT_STRETCH_STACK_BOTTOM_SHIFT_DOWN: stretchStackBottomShiftDown + * @HB_OT_MATH_CONSTANT_STRETCH_STACK_GAP_ABOVE_MIN: stretchStackGapAboveMin + * @HB_OT_MATH_CONSTANT_STRETCH_STACK_GAP_BELOW_MIN: stretchStackGapBelowMin + * @HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_SHIFT_UP: fractionNumeratorShiftUp + * @HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_DISPLAY_STYLE_SHIFT_UP: fractionNumeratorDisplayStyleShiftUp + * @HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_SHIFT_DOWN: fractionDenominatorShiftDown + * @HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_DISPLAY_STYLE_SHIFT_DOWN: fractionDenominatorDisplayStyleShiftDown + * @HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_GAP_MIN: fractionNumeratorGapMin + * @HB_OT_MATH_CONSTANT_FRACTION_NUM_DISPLAY_STYLE_GAP_MIN: fractionNumDisplayStyleGapMin + * @HB_OT_MATH_CONSTANT_FRACTION_RULE_THICKNESS: fractionRuleThickness + * @HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_GAP_MIN: fractionDenominatorGapMin + * @HB_OT_MATH_CONSTANT_FRACTION_DENOM_DISPLAY_STYLE_GAP_MIN: fractionDenomDisplayStyleGapMin + * @HB_OT_MATH_CONSTANT_SKEWED_FRACTION_HORIZONTAL_GAP: skewedFractionHorizontalGap + * @HB_OT_MATH_CONSTANT_SKEWED_FRACTION_VERTICAL_GAP: skewedFractionVerticalGap + * @HB_OT_MATH_CONSTANT_OVERBAR_VERTICAL_GAP: overbarVerticalGap + * @HB_OT_MATH_CONSTANT_OVERBAR_RULE_THICKNESS: overbarRuleThickness + * @HB_OT_MATH_CONSTANT_OVERBAR_EXTRA_ASCENDER: overbarExtraAscender + * @HB_OT_MATH_CONSTANT_UNDERBAR_VERTICAL_GAP: underbarVerticalGap + * @HB_OT_MATH_CONSTANT_UNDERBAR_RULE_THICKNESS: underbarRuleThickness + * @HB_OT_MATH_CONSTANT_UNDERBAR_EXTRA_DESCENDER: underbarExtraDescender + * @HB_OT_MATH_CONSTANT_RADICAL_VERTICAL_GAP: radicalVerticalGap + * @HB_OT_MATH_CONSTANT_RADICAL_DISPLAY_STYLE_VERTICAL_GAP: radicalDisplayStyleVerticalGap + * @HB_OT_MATH_CONSTANT_RADICAL_RULE_THICKNESS: radicalRuleThickness + * @HB_OT_MATH_CONSTANT_RADICAL_EXTRA_ASCENDER: radicalExtraAscender + * @HB_OT_MATH_CONSTANT_RADICAL_KERN_BEFORE_DEGREE: radicalKernBeforeDegree + * @HB_OT_MATH_CONSTANT_RADICAL_KERN_AFTER_DEGREE: radicalKernAfterDegree + * @HB_OT_MATH_CONSTANT_RADICAL_DEGREE_BOTTOM_RAISE_PERCENT: radicalDegreeBottomRaisePercent * - * The 'MATH' table constants specified at - * https://docs.microsoft.com/en-us/typography/opentype/spec/math + * The 'MATH' table constants, refer to + * [OpenType documentation](https://docs.microsoft.com/en-us/typography/opentype/spec/math#mathconstants-table) + * For more explanations. * * Since: 1.3.3 */ @@ -116,6 +187,10 @@ typedef enum { /** * hb_ot_math_kern_t: + * @HB_OT_MATH_KERN_TOP_RIGHT: The top right corner of the glyph. + * @HB_OT_MATH_KERN_TOP_LEFT: The top left corner of the glyph. + * @HB_OT_MATH_KERN_BOTTOM_RIGHT: The bottom right corner of the glyph. + * @HB_OT_MATH_KERN_BOTTOM_LEFT: The bottom left corner of the glyph. * * The math kerning-table types defined for the four corners * of a glyph. @@ -145,6 +220,8 @@ typedef struct hb_ot_math_glyph_variant_t { /** * hb_ot_math_glyph_part_flags_t: + * @HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER: This is an extender glyph part that + * can be repeated to reach the desired length. * * Flags for math glyph parts. * diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh index 1c25eda16b..929956d12b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh @@ -126,9 +126,10 @@ struct maxp } protected: - FixedVersion<>version; /* Version of the maxp table (0.5 or 1.0), - * 0x00005000u or 0x00010000u. */ - HBUINT16 numGlyphs; /* The number of glyphs in the font. */ + FixedVersion<>version;/* Version of the maxp table (0.5 or 1.0), + * 0x00005000u or 0x00010000u. */ + HBUINT16 numGlyphs; + /* The number of glyphs in the font. */ /*maxpV1Tail v1Tail[HB_VAR_ARRAY]; */ public: DEFINE_SIZE_STATIC (6); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-meta-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-meta-table.hh index 43a02d6cec..1225e26ce1 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-meta-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-meta-table.hh @@ -56,7 +56,7 @@ struct DataMap protected: Tag tag; /* A tag indicating the type of metadata. */ - LOffsetTo<UnsizedArrayOf<HBUINT8>> + LNNOffsetTo<UnsizedArrayOf<HBUINT8>> dataZ; /* Offset in bytes from the beginning of the * metadata table to the data for this tag. */ HBUINT32 dataLength; /* Length of the data. The data is not required to @@ -108,12 +108,13 @@ struct meta protected: HBUINT32 version; /* Version number of the metadata table — set to 1. */ HBUINT32 flags; /* Flags — currently unused; set to 0. */ - HBUINT32 dataOffset; /* Per Apple specification: + HBUINT32 dataOffset; + /* Per Apple specification: * Offset from the beginning of the table to the data. * Per OT specification: * Reserved. Not used; should be set to 0. */ LArrayOf<DataMap> - dataMaps; /* Array of data map records. */ + dataMaps;/* Array of data map records. */ public: DEFINE_SIZE_ARRAY (16, dataMaps); }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-meta.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-meta.cc index a1e081b245..35c8eb523f 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-meta.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-meta.cc @@ -38,12 +38,14 @@ **/ /** - * hb_ot_meta_reference_entry: + * hb_ot_meta_get_entry_tags: * @face: a face object * @start_offset: iteration's start offset - * @entries_count:(inout) (allow-none): buffer size as input, filled size as output + * @entries_count:(inout) (optional): buffer size as input, filled size as output * @entries: (out caller-allocates) (array length=entries_count): entries tags buffer * + * Fetches all available feature types. + * * Return value: Number of all available feature types. * * Since: 2.6.0 diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-meta.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-meta.h index 0278d84148..7748eb4958 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-meta.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-meta.h @@ -22,7 +22,7 @@ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ -#ifndef HB_OT_H_IN +#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb-ot.h> instead." #endif @@ -54,6 +54,7 @@ typedef enum { HB_OT_META_TAG_DESIGN_LANGUAGES = HB_TAG ('d','l','n','g'), HB_OT_META_TAG_SUPPORTED_LANGUAGES = HB_TAG ('s','l','n','g'), + /*< private >*/ _HB_OT_META_TAG_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/ } hb_ot_meta_tag_t; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-metrics.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-metrics.cc index 181ac4d57e..72aeff82d6 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-metrics.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-metrics.cc @@ -33,6 +33,15 @@ #include "hb-ot-face.hh" +/** + * SECTION:hb-ot-metrics + * @title: hb-ot-metrics + * @short_description: OpenType Metrics + * @include: hb-ot.h + * + * Functions for fetching metrics from fonts. + **/ + static float _fix_ascender_descender (float value, hb_ot_metrics_tag_t metrics_tag) { @@ -110,11 +119,11 @@ _get_gasp (hb_face_t *face, float *result, hb_ot_metrics_tag_t metrics_tag) /** * hb_ot_metrics_get_position: - * @font: a #hb_font_t object. + * @font: an #hb_font_t object. * @metrics_tag: tag of metrics value you like to fetch. * @position: (out) (optional): result of metrics value from the font. * - * It fetches metrics value corresponding to a given tag from a font. + * Fetches metrics value corresponding to @metrics_tag from @font. * * Returns: Whether found the requested metrics in the font. * Since: 2.6.0 @@ -184,10 +193,13 @@ hb_ot_metrics_get_position (hb_font_t *font, #ifndef HB_NO_VAR /** * hb_ot_metrics_get_variation: - * @font: - * @metrics_tag: + * @font: an #hb_font_t object. + * @metrics_tag: tag of metrics value you like to fetch. * - * Returns: + * Fetches metrics value corresponding to @metrics_tag from @font with the + * current font variation settings applied. + * + * Returns: The requested metric value. * * Since: 2.6.0 **/ @@ -199,10 +211,13 @@ hb_ot_metrics_get_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag) /** * hb_ot_metrics_get_x_variation: - * @font: - * @metrics_tag: + * @font: an #hb_font_t object. + * @metrics_tag: tag of metrics value you like to fetch. + * + * Fetches horizontal metrics value corresponding to @metrics_tag from @font + * with the current font variation settings applied. * - * Returns: + * Returns: The requested metric value. * * Since: 2.6.0 **/ @@ -214,10 +229,13 @@ hb_ot_metrics_get_x_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag) /** * hb_ot_metrics_get_y_variation: - * @font: - * @metrics_tag: + * @font: an #hb_font_t object. + * @metrics_tag: tag of metrics value you like to fetch. + * + * Fetches vertical metrics value corresponding to @metrics_tag from @font with + * the current font variation settings applied. * - * Returns: + * Returns: The requested metric value. * * Since: 2.6.0 **/ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-metrics.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-metrics.h index 42c7363c03..5841fc8b0f 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-metrics.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-metrics.h @@ -22,7 +22,7 @@ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ -#ifndef HB_OT_H_IN +#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb-ot.h> instead." #endif @@ -66,7 +66,8 @@ HB_BEGIN_DECLS * @HB_OT_METRICS_TAG_UNDERLINE_SIZE: underline size. * @HB_OT_METRICS_TAG_UNDERLINE_OFFSET: underline offset. * - * From https://docs.microsoft.com/en-us/typography/opentype/spec/mvar#value-tags + * Metric tags corresponding to [MVAR Value + * Tags](https://docs.microsoft.com/en-us/typography/opentype/spec/mvar#value-tags) * * Since: 2.6.0 **/ @@ -100,6 +101,7 @@ typedef enum { HB_OT_METRICS_TAG_UNDERLINE_SIZE = HB_TAG ('u','n','d','s'), HB_OT_METRICS_TAG_UNDERLINE_OFFSET = HB_TAG ('u','n','d','o'), + /*< private >*/ _HB_OT_METRICS_TAG_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/ } hb_ot_metrics_tag_t; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-name-language-static.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-name-language-static.hh index 580e7637b9..c496dc2981 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-name-language-static.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-name-language-static.hh @@ -37,12 +37,8 @@ struct hb_ot_language_map_t { - static int cmp (const void *key, const void *item) - { - unsigned int a = * (unsigned int *) key; - unsigned int b = ((const hb_ot_language_map_t *) item)->code; - return a < b ? -1 : a > b ? +1 : 0; - } + int cmp (unsigned int key) const + { return key < code ? -1 : key > code ? +1 : 0; } uint16_t code; char lang[6]; @@ -433,12 +429,7 @@ _hb_ot_name_language_for (unsigned int code, #ifdef HB_NO_OT_NAME_LANGUAGE return HB_LANGUAGE_INVALID; #endif - const hb_ot_language_map_t *entry = (const hb_ot_language_map_t *) - hb_bsearch (&code, - array, - len, - sizeof (array[0]), - hb_ot_language_map_t::cmp); + auto *entry = hb_bsearch (code, array, len); if (entry) return hb_language_from_string (entry->lang, -1); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh index 84be04c8bf..ece3c28466 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh @@ -97,17 +97,47 @@ struct NameRecord return UNSUPPORTED; } - NameRecord* copy (hb_serialize_context_t *c, - const void *src_base, - const void *dst_base) const + NameRecord* copy (hb_serialize_context_t *c, const void *base) const { TRACE_SERIALIZE (this); auto *out = c->embed (this); if (unlikely (!out)) return_trace (nullptr); - out->offset.serialize_copy (c, offset, src_base, dst_base, length); + out->offset.serialize_copy (c, offset, base, 0, hb_serialize_context_t::Tail, length); return_trace (out); } + bool isUnicode () const + { + unsigned int p = platformID; + unsigned int e = encodingID; + + return (p == 0 || + (p == 3 && (e == 0 || e == 1 || e == 10))); + } + + static int cmp (const void *pa, const void *pb) + { + const NameRecord *a = (const NameRecord *)pa; + const NameRecord *b = (const NameRecord *)pb; + + if (a->platformID != b->platformID) + return a->platformID - b->platformID; + + if (a->encodingID != b->encodingID) + return a->encodingID - b->encodingID; + + if (a->languageID != b->languageID) + return a->languageID - b->languageID; + + if (a->nameID != b->nameID) + return a->nameID - b->nameID; + + if (a->length != b->length) + return a->length - b->length; + + return 0; + } + bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -134,7 +164,7 @@ _hb_ot_name_entry_cmp_key (const void *pa, const void *pb) /* Compare by name_id, then language. */ if (a->name_id != b->name_id) - return a->name_id < b->name_id ? -1 : +1; + return a->name_id - b->name_id; if (a->language == b->language) return 0; if (!a->language) return -1; @@ -156,10 +186,10 @@ _hb_ot_name_entry_cmp (const void *pa, const void *pb) const hb_ot_name_entry_t *b = (const hb_ot_name_entry_t *) pb; if (a->entry_score != b->entry_score) - return a->entry_score < b->entry_score ? -1 : +1; + return a->entry_score - b->entry_score; if (a->entry_index != b->entry_index) - return a->entry_index < b->entry_index ? -1 : +1; + return a->entry_index - b->entry_index; return 0; } @@ -184,18 +214,25 @@ struct name this->format = 0; this->count = it.len (); - auto snap = c->snapshot (); - this->nameRecordZ.serialize (c, this->count); - if (unlikely (!c->check_assign (this->stringOffset, c->length ()))) return_trace (false); - c->revert (snap); + NameRecord *name_records = (NameRecord *) calloc (it.len (), NameRecord::static_size); + if (unlikely (!name_records)) return_trace (false); + + hb_array_t<NameRecord> records (name_records, it.len ()); + + for (const NameRecord& record : it) + { + memcpy (name_records, &record, NameRecord::static_size); + name_records++; + } - const void *dst_string_pool = &(this + this->stringOffset); + records.qsort (); - for (const auto &_ : it) c->copy (_, src_string_pool, dst_string_pool); + c->copy_all (records, src_string_pool); + free (records.arrayZ); if (unlikely (c->ran_out_of_room)) return_trace (false); - assert (this->stringOffset == c->length ()); + this->stringOffset = c->length (); return_trace (true); } @@ -210,6 +247,8 @@ struct name auto it = + nameRecordZ.as_array (count) | hb_filter (c->plan->name_ids, &NameRecord::nameID) + | hb_filter (c->plan->name_languages, &NameRecord::languageID) + | hb_filter ([&] (const NameRecord& namerecord) { return c->plan->name_legacy || namerecord.isUnicode (); }) ; name_prime->serialize (c->serializer, it, hb_addressof (this + stringOffset)); @@ -237,7 +276,7 @@ struct name { void init (hb_face_t *face) { - this->table = hb_sanitize_context_t().reference_table<name> (face); + this->table = hb_sanitize_context_t ().reference_table<name> (face); assert (this->table.get_length () >= this->table->stringOffset); this->pool = (const char *) (const void *) (this->table+this->table->stringOffset); this->pool_len = this->table.get_length () - this->table->stringOffset; @@ -281,16 +320,14 @@ struct name this->table.destroy (); } - int get_index (hb_ot_name_id_t name_id, - hb_language_t language, - unsigned int *width=nullptr) const + int get_index (hb_ot_name_id_t name_id, + hb_language_t language, + unsigned int *width=nullptr) const { const hb_ot_name_entry_t key = {name_id, {0}, language}; - const hb_ot_name_entry_t *entry = (const hb_ot_name_entry_t *) - hb_bsearch (&key, - (const hb_ot_name_entry_t *) this->names, + const hb_ot_name_entry_t *entry = hb_bsearch (key, (const hb_ot_name_entry_t *) this->names, this->names.length, - sizeof (key), + sizeof (hb_ot_name_entry_t), _hb_ot_name_entry_cmp_key); if (!entry) return -1; @@ -318,12 +355,12 @@ struct name }; /* We only implement format 0 for now. */ - HBUINT16 format; /* Format selector (=0/1). */ - HBUINT16 count; /* Number of name records. */ + HBUINT16 format; /* Format selector (=0/1). */ + HBUINT16 count; /* Number of name records. */ NNOffsetTo<UnsizedArrayOf<HBUINT8>> - stringOffset; /* Offset to start of string storage (from start of table). */ + stringOffset; /* Offset to start of string storage (from start of table). */ UnsizedArrayOf<NameRecord> - nameRecordZ; /* The name records where count is the number of records. */ + nameRecordZ; /* The name records where count is the number of records. */ public: DEFINE_SIZE_ARRAY (6, nameRecordZ); }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-name.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-name.cc index 10122b8c2e..4588226e6e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-name.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-name.cc @@ -46,7 +46,7 @@ /** * hb_ot_name_list_names: * @face: font face. - * @num_entries: (out) (allow-none): number of returned entries. + * @num_entries: (out) (optional): number of returned entries. * * Enumerates all available name IDs and language combinations. Returned * array is owned by the @face and should not be modified. It can be @@ -150,7 +150,7 @@ hb_ot_name_get_utf (hb_face_t *face, * @face: font face. * @name_id: OpenType name identifier to fetch. * @language: language to fetch the name for. - * @text_size: (inout) (allow-none): input size of @text buffer, and output size of + * @text_size: (inout) (optional): input size of @text buffer, and output size of * text written to buffer. * @text: (out caller-allocates) (array length=text_size): buffer to write fetched name into. * @@ -177,7 +177,7 @@ hb_ot_name_get_utf8 (hb_face_t *face, * @face: font face. * @name_id: OpenType name identifier to fetch. * @language: language to fetch the name for. - * @text_size: (inout) (allow-none): input size of @text buffer, and output size of + * @text_size: (inout) (optional): input size of @text buffer, and output size of * text written to buffer. * @text: (out caller-allocates) (array length=text_size): buffer to write fetched name into. * @@ -203,7 +203,7 @@ hb_ot_name_get_utf16 (hb_face_t *face, * @face: font face. * @name_id: OpenType name identifier to fetch. * @language: language to fetch the name for. - * @text_size: (inout) (allow-none): input size of @text buffer, and output size of + * @text_size: (inout) (optional): input size of @text buffer, and output size of * text written to buffer. * @text: (out caller-allocates) (array length=text_size): buffer to write fetched name into. * diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-name.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-name.h index 3b4ad581c7..9359014c8a 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-name.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-name.h @@ -22,7 +22,7 @@ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ -#ifndef HB_OT_H_IN +#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb-ot.h> instead." #endif @@ -88,8 +88,7 @@ typedef unsigned int hb_ot_name_id_t; * * Since: 2.1.0 **/ -typedef struct hb_ot_name_entry_t -{ +typedef struct hb_ot_name_entry_t { hb_ot_name_id_t name_id; /*< private >*/ hb_var_int_t var; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-table.hh index f6b150323b..8e98f87f4e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-table.hh @@ -30,6 +30,7 @@ #include "hb-open-type.hh" #include "hb-ot-os2-unicode-ranges.hh" +#include "hb-ot-cmap-table.hh" #include "hb-set.hh" @@ -172,12 +173,32 @@ struct OS2 OS2 *os2_prime = c->serializer->embed (this); if (unlikely (!os2_prime)) return_trace (false); + hb_set_t unicodes; + if (!c->plan->glyphs_requested->is_empty ()) + { + hb_map_t unicode_glyphid_map; + + OT::cmap::accelerator_t cmap; + cmap.init (c->plan->source); + cmap.collect_mapping (&unicodes, &unicode_glyphid_map); + cmap.fini (); + + hb_set_set (&unicodes, c->plan->unicodes); + + + unicode_glyphid_map.iter () + | hb_filter (c->plan->glyphs_requested, hb_second) + | hb_map (hb_first) + | hb_sink (unicodes) + ; + } + /* when --gids option is not used, no need to do collect_mapping that is + * iterating all codepoints in each subtable, which is not efficient */ uint16_t min_cp, max_cp; - find_min_and_max_codepoint (c->plan->unicodes, &min_cp, &max_cp); + find_min_and_max_codepoint (unicodes.is_empty () ? c->plan->unicodes : &unicodes, &min_cp, &max_cp); os2_prime->usFirstCharIndex = min_cp; os2_prime->usLastCharIndex = max_cp; - _update_unicode_ranges (c->plan->unicodes, os2_prime->ulUnicodeRange); + _update_unicode_ranges (unicodes.is_empty () ? c->plan->unicodes : &unicodes, os2_prime->ulUnicodeRange); return_trace (true); } @@ -216,19 +237,20 @@ struct OS2 uint16_t *min_cp, /* OUT */ uint16_t *max_cp /* OUT */) { - *min_cp = codepoints->get_min (); - *max_cp = codepoints->get_max (); + *min_cp = hb_min (0xFFFFu, codepoints->get_min ()); + *max_cp = hb_min (0xFFFFu, codepoints->get_max ()); } /* https://github.com/Microsoft/Font-Validator/blob/520aaae/OTFontFileVal/val_OS2.cs#L644-L681 */ - enum font_page_t { - HEBREW_FONT_PAGE = 0xB100, // Hebrew Windows 3.1 font page - SIMP_ARABIC_FONT_PAGE = 0xB200, // Simplified Arabic Windows 3.1 font page - TRAD_ARABIC_FONT_PAGE = 0xB300, // Traditional Arabic Windows 3.1 font page - OEM_ARABIC_FONT_PAGE = 0xB400, // OEM Arabic Windows 3.1 font page - SIMP_FARSI_FONT_PAGE = 0xBA00, // Simplified Farsi Windows 3.1 font page - TRAD_FARSI_FONT_PAGE = 0xBB00, // Traditional Farsi Windows 3.1 font page - THAI_FONT_PAGE = 0xDE00 // Thai Windows 3.1 font page + enum font_page_t + { + FONT_PAGE_HEBREW = 0xB100, /* Hebrew Windows 3.1 font page */ + FONT_PAGE_SIMP_ARABIC = 0xB200, /* Simplified Arabic Windows 3.1 font page */ + FONT_PAGE_TRAD_ARABIC = 0xB300, /* Traditional Arabic Windows 3.1 font page */ + FONT_PAGE_OEM_ARABIC = 0xB400, /* OEM Arabic Windows 3.1 font page */ + FONT_PAGE_SIMP_FARSI = 0xBA00, /* Simplified Farsi Windows 3.1 font page */ + FONT_PAGE_TRAD_FARSI = 0xBB00, /* Traditional Farsi Windows 3.1 font page */ + FONT_PAGE_THAI = 0xDE00 /* Thai Windows 3.1 font page */ }; font_page_t get_font_page () const { return (font_page_t) (version == 0 ? fsSelection & 0xFF00 : 0); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-unicode-ranges.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-unicode-ranges.hh index b0ccd00d7b..9613d2d186 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-unicode-ranges.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-unicode-ranges.hh @@ -33,19 +33,8 @@ namespace OT { struct OS2Range { - static int - cmp (const void *_key, const void *_item) - { - hb_codepoint_t cp = *((hb_codepoint_t *) _key); - const OS2Range *range = (OS2Range *) _item; - - if (cp < range->start) - return -1; - else if (cp <= range->end) - return 0; - else - return +1; - } + int cmp (hb_codepoint_t key) const + { return (key < start) ? -1 : key <= end ? 0 : +1; } hb_codepoint_t start; hb_codepoint_t end; @@ -233,13 +222,8 @@ static const OS2Range _hb_os2_unicode_ranges[] = static unsigned int _hb_ot_os2_get_unicode_range_bit (hb_codepoint_t cp) { - OS2Range *range = (OS2Range*) hb_bsearch (&cp, _hb_os2_unicode_ranges, - ARRAY_LENGTH (_hb_os2_unicode_ranges), - sizeof (OS2Range), - OS2Range::cmp); - if (range != nullptr) - return range->bit; - return -1; + auto *range = hb_sorted_array (_hb_os2_unicode_ranges).bsearch (cp); + return range ? range->bit : -1; } } /* namespace OT */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh index 38302f5518..f22d6e244d 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh @@ -35,8 +35,6 @@ #undef HB_STRING_ARRAY_LIST #undef HB_STRING_ARRAY_NAME -#define NUM_FORMAT1_NAMES 258 - /* * post -- PostScript * https://docs.microsoft.com/en-us/typography/opentype/spec/post @@ -89,7 +87,6 @@ struct post if (unlikely (!post_prime)) return_trace (false); serialize (c->serializer); - if (c->serializer->in_error () || c->serializer->ran_out_of_room) return_trace (false); return_trace (true); } @@ -167,8 +164,7 @@ struct post } hb_bytes_t st (name, len); - const uint16_t *gid = (const uint16_t *) hb_bsearch (hb_addressof (st), gids, count, - sizeof (gids[0]), cmp_key, (void *) this); + auto* gid = hb_bsearch (st, gids, count, sizeof (gids[0]), cmp_key, (void *) this); if (gid) { *glyph = *gid; @@ -185,7 +181,7 @@ struct post unsigned int get_glyph_count () const { if (version == 0x00010000) - return NUM_FORMAT1_NAMES; + return format1_names_length; if (version == 0x00020000) return glyphNameIndex->len; @@ -213,7 +209,7 @@ struct post { if (version == 0x00010000) { - if (glyph >= NUM_FORMAT1_NAMES) + if (glyph >= format1_names_length) return hb_bytes_t (); return format1_names (glyph); @@ -223,9 +219,9 @@ struct post return hb_bytes_t (); unsigned int index = glyphNameIndex->arrayZ[glyph]; - if (index < NUM_FORMAT1_NAMES) + if (index < format1_names_length) return format1_names (index); - index -= NUM_FORMAT1_NAMES; + index -= format1_names_length; if (index >= index_to_offset.length) return hb_bytes_t (); @@ -262,7 +258,7 @@ struct post * 0x00020000 for version 2.0 * 0x00025000 for version 2.5 (deprecated) * 0x00030000 for version 3.0 */ - HBFixed italicAngle; /* Italic angle in counter-clockwise degrees + HBFixed italicAngle; /* Italic angle in counter-clockwise degrees * from the vertical. Zero for upright text, * negative for text that leans to the right * (forward). */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh index 2a7a8ebbc0..244e967b12 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh @@ -92,7 +92,7 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS hb_array (substitutes, num_glyphs)); c.end_serialize (); - return ret ? c.copy<OT::SubstLookup> () : nullptr; + return ret && !c.in_error () ? c.copy<OT::SubstLookup> () : nullptr; } static OT::SubstLookup * @@ -170,7 +170,7 @@ arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UN c.end_serialize (); /* TODO sanitize the results? */ - return ret ? c.copy<OT::SubstLookup> () : nullptr; + return ret && !c.in_error () ? c.copy<OT::SubstLookup> () : nullptr; } static OT::SubstLookup * @@ -292,7 +292,7 @@ arabic_fallback_plan_create (const hb_ot_shape_plan_t *plan, { arabic_fallback_plan_t *fallback_plan = (arabic_fallback_plan_t *) calloc (1, sizeof (arabic_fallback_plan_t)); if (unlikely (!fallback_plan)) - return const_cast<arabic_fallback_plan_t *> (&Null(arabic_fallback_plan_t)); + return const_cast<arabic_fallback_plan_t *> (&Null (arabic_fallback_plan_t)); fallback_plan->num_lookups = 0; fallback_plan->free_lookups = false; @@ -309,7 +309,7 @@ arabic_fallback_plan_create (const hb_ot_shape_plan_t *plan, assert (fallback_plan->num_lookups == 0); free (fallback_plan); - return const_cast<arabic_fallback_plan_t *> (&Null(arabic_fallback_plan_t)); + return const_cast<arabic_fallback_plan_t *> (&Null (arabic_fallback_plan_t)); } static void diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-joining-list.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-joining-list.hh new file mode 100644 index 0000000000..c022d4bb06 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-joining-list.hh @@ -0,0 +1,46 @@ +/* == Start of generated function == */ +/* + * The following function is generated by running: + * + * ./gen-arabic-joining-list.py ArabicShaping.txt Scripts.txt + * + * on files with these headers: + * + * # ArabicShaping-13.0.0.txt + * # Date: 2020-01-31, 23:55:00 GMT [KW, RP] + * # Scripts-13.0.0.txt + * # Date: 2020-01-22, 00:07:43 GMT + */ + +#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_JOINING_LIST_HH +#define HB_OT_SHAPE_COMPLEX_ARABIC_JOINING_LIST_HH + +static bool +has_arabic_joining (hb_script_t script) +{ + /* List of scripts that have data in arabic-table. */ + switch ((int) script) + { + case HB_SCRIPT_ADLAM: + case HB_SCRIPT_ARABIC: + case HB_SCRIPT_CHORASMIAN: + case HB_SCRIPT_HANIFI_ROHINGYA: + case HB_SCRIPT_MANDAIC: + case HB_SCRIPT_MANICHAEAN: + case HB_SCRIPT_MONGOLIAN: + case HB_SCRIPT_NKO: + case HB_SCRIPT_PHAGS_PA: + case HB_SCRIPT_PSALTER_PAHLAVI: + case HB_SCRIPT_SOGDIAN: + case HB_SCRIPT_SYRIAC: + return true; + + default: + return false; + } +} + + +#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_JOINING_LIST_HH */ + +/* == End of generated function == */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh index 719fabd353..70ffe623c0 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh @@ -6,10 +6,10 @@ * * on files with these headers: * - * # ArabicShaping-12.0.0.txt - * # Date: 2018-09-22, 23:54:00 GMT [KW, RP] - * # Blocks-12.0.0.txt - * # Date: 2018-07-30, 19:40:00 GMT [KW] + * # ArabicShaping-13.0.0.txt + * # Date: 2020-01-31, 23:55:00 GMT [KW, RP] + * # Blocks-13.0.0.txt + * # Date: 2019-07-10, 19:06:00 GMT [KW] * UnicodeData.txt does not have a header. */ @@ -17,15 +17,15 @@ #define HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH -#define X JOINING_TYPE_X -#define R JOINING_TYPE_R -#define T JOINING_TYPE_T -#define U JOINING_TYPE_U #define A JOINING_GROUP_ALAPH #define DR JOINING_GROUP_DALATH_RISH -#define L JOINING_TYPE_L #define C JOINING_TYPE_C #define D JOINING_TYPE_D +#define L JOINING_TYPE_L +#define R JOINING_TYPE_R +#define T JOINING_TYPE_T +#define U JOINING_TYPE_U +#define X JOINING_TYPE_X static const uint8_t joining_table[] = { @@ -71,7 +71,7 @@ static const uint8_t joining_table[] = /* Mandaic */ - /* 0840 */ R,D,D,D,D,D,R,R,D,R,D,D,D,D,D,D,D,D,D,D,R,D,U,U,U,X,X,X,X,X,X,X, + /* 0840 */ R,D,D,D,D,D,R,R,D,R,D,D,D,D,D,D,D,D,D,D,R,D,R,R,R,X,X,X,X,X,X,X, /* Syriac Supplement */ @@ -80,8 +80,8 @@ static const uint8_t joining_table[] = /* Arabic Extended-A */ - /* 08A0 */ D,D,D,D,D,D,D,D,D,D,R,R,R,U,R,D,D,R,R,D,D,X,D,D,D,R,D,D,D,D,X,X, - /* 08C0 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, + /* 08A0 */ D,D,D,D,D,D,D,D,D,D,R,R,R,U,R,D,D,R,R,D,D,X,D,D,D,R,D,D,D,D,D,D, + /* 08C0 */ D,D,D,D,D,D,D,D,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, /* 08E0 */ X,X,U, #define joining_offset_0x1806u 739 @@ -139,14 +139,21 @@ static const uint8_t joining_table[] = /* 10F20 */ D,D,D,R,D,D,D,D,D,D,D,D,D,D,D,D, /* 10F40 */ D,D,D,D,D,U,X,X,X,X,X,X,X,X,X,X,X,D,D,D,R, -#define joining_offset_0x110bdu 1219 +#define joining_offset_0x10fb0u 1219 + + /* Chorasmian */ + + /* 10FA0 */ D,U,D,D,R,R,R,U,D,R,R,D,D,R,D,D, + /* 10FC0 */ U,D,R,R,D,U,U,U,U,R,D,L, + +#define joining_offset_0x110bdu 1247 /* Kaithi */ /* 110A0 */ U,X,X, /* 110C0 */ X,X,X,X,X,X,X,X,X,X,X,X,X,U, -#define joining_offset_0x1e900u 1236 +#define joining_offset_0x1e900u 1264 /* Adlam */ @@ -154,7 +161,7 @@ static const uint8_t joining_table[] = /* 1E920 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, /* 1E940 */ D,D,D,D,X,X,X,X,X,X,X,T, -}; /* Table items: 1312; occupancy: 56% */ +}; /* Table items: 1340; occupancy: 57% */ static unsigned int @@ -183,6 +190,7 @@ joining_type (hb_codepoint_t u) if (hb_in_range<hb_codepoint_t> (u, 0x10B80u, 0x10BAFu)) return joining_table[u - 0x10B80u + joining_offset_0x10b80u]; if (hb_in_range<hb_codepoint_t> (u, 0x10D00u, 0x10D23u)) return joining_table[u - 0x10D00u + joining_offset_0x10d00u]; if (hb_in_range<hb_codepoint_t> (u, 0x10F30u, 0x10F54u)) return joining_table[u - 0x10F30u + joining_offset_0x10f30u]; + if (hb_in_range<hb_codepoint_t> (u, 0x10FB0u, 0x10FCBu)) return joining_table[u - 0x10FB0u + joining_offset_0x10fb0u]; break; case 0x11u: @@ -199,15 +207,15 @@ joining_type (hb_codepoint_t u) return X; } -#undef X -#undef R -#undef T -#undef U #undef A #undef DR -#undef L #undef C #undef D +#undef L +#undef R +#undef T +#undef U +#undef X static const uint16_t shaping_table[][4] = @@ -406,16 +414,16 @@ static const struct ligature_set_t { } ligature_table[] = { { 0xFEDFu, { - { 0xFE88u, 0xFEF9u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM */ { 0xFE82u, 0xFEF5u }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM */ - { 0xFE8Eu, 0xFEFBu }, /* ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM */ { 0xFE84u, 0xFEF7u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM */ + { 0xFE88u, 0xFEF9u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM */ + { 0xFE8Eu, 0xFEFBu }, /* ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM */ }}, { 0xFEE0u, { - { 0xFE88u, 0xFEFAu }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM */ { 0xFE82u, 0xFEF6u }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM */ - { 0xFE8Eu, 0xFEFCu }, /* ARABIC LIGATURE LAM WITH ALEF FINAL FORM */ { 0xFE84u, 0xFEF8u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM */ + { 0xFE88u, 0xFEFAu }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM */ + { 0xFE8Eu, 0xFEFCu }, /* ARABIC LIGATURE LAM WITH ALEF FINAL FORM */ }}, }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-win1256.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-win1256.hh index b15e145f2f..41e3dd38ab 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-win1256.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-win1256.hh @@ -142,7 +142,7 @@ OT_UARRAY(Name##Substitute, OT_LIST(ToGlyphs)) \ ) \ OT_COVERAGE1(Name##Coverage, OT_LIST(FromGlyphs)) \ - /* ASSERT_STATIC_EXPR_ZERO (len(FromGlyphs) == len(ToGlyphs)) */ + /* static_assert_expr (len(FromGlyphs) == len(ToGlyphs)) */ #define OT_SUBLOOKUP_LIGATURE_SUBST_FORMAT1(Name, FirstGlyphs, LigatureSetOffsets) \ OT_SUBLOOKUP(Name, 1, \ @@ -151,7 +151,7 @@ OT_UARRAY(Name##LigatureSetOffsetsArray, OT_LIST(LigatureSetOffsets)) \ ) \ OT_COVERAGE1(Name##Coverage, OT_LIST(FirstGlyphs)) \ - /* ASSERT_STATIC_EXPR_ZERO (len(FirstGlyphs) == len(LigatureSetOffsets)) */ + /* static_assert_expr (len(FirstGlyphs) == len(LigatureSetOffsets)) */ #define OT_LIGATURE_SET(Name, LigatureSetOffsets) \ OT_UARRAY(Name, OT_LIST(LigatureSetOffsets)) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc index f92e6378a1..1f244f940c 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc @@ -33,7 +33,7 @@ /* buffer var allocations */ -#define arabic_shaping_action() complex_var_u8_0() /* arabic shaping action */ +#define arabic_shaping_action() complex_var_u8_auxiliary() /* arabic shaping action */ #define HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH HB_BUFFER_SCRATCH_FLAG_COMPLEX0 @@ -228,8 +228,6 @@ collect_features_arabic (hb_ot_shape_planner_t *plan) map->enable_feature (HB_TAG('c','a','l','t'), F_MANUAL_ZWJ); map->add_gsub_pause (nullptr); - /* And undo here. */ - /* The spec includes 'cswh'. Earlier versions of Windows * used to enable this by default, but testing suggests * that Windows 8 and later do not enable it by default, @@ -271,7 +269,7 @@ data_create_arabic (const hb_ot_shape_plan_t *plan) arabic_plan->mask_array[i] = plan->map.get_1_mask (arabic_features[i]); arabic_plan->do_fallback = arabic_plan->do_fallback && (FEATURE_IS_SYRIAC (arabic_features[i]) || - plan->map.needs_fallback (arabic_features[i])); + plan->map.needs_fallback (arabic_features[i])); } return arabic_plan; @@ -292,7 +290,7 @@ arabic_joining (hb_buffer_t *buffer) { unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; - unsigned int prev = (unsigned int) -1, state = 0; + unsigned int prev = UINT_MAX, state = 0; /* Check pre-context */ for (unsigned int i = 0; i < buffer->context_len[0]; i++) @@ -318,7 +316,7 @@ arabic_joining (hb_buffer_t *buffer) const arabic_state_table_entry *entry = &arabic_state_table[state][this_type]; - if (entry->prev_action != NONE && prev != (unsigned int) -1) + if (entry->prev_action != NONE && prev != UINT_MAX) { info[prev].arabic_shaping_action() = entry->prev_action; buffer->unsafe_to_break (prev, i + 1); @@ -338,7 +336,7 @@ arabic_joining (hb_buffer_t *buffer) continue; const arabic_state_table_entry *entry = &arabic_state_table[state][this_type]; - if (entry->prev_action != NONE && prev != (unsigned int) -1) + if (entry->prev_action != NONE && prev != UINT_MAX) info[prev].arabic_shaping_action() = entry->prev_action; break; } @@ -604,7 +602,7 @@ postprocess_glyphs_arabic (const hb_ot_shape_plan_t *plan, HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action); } -/* http://www.unicode.org/reports/tr53/ */ +/* https://www.unicode.org/reports/tr53/ */ static hb_codepoint_t modifier_combining_marks[] = diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc index a921f16fad..a755aea098 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc @@ -49,5 +49,25 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default = true, /* fallback_position */ }; +/* Same as default but no mark advance zeroing / fallback positioning. + * Dumbest shaper ever, basically. */ +const hb_ot_complex_shaper_t _hb_ot_complex_shaper_dumber = +{ + nullptr, /* collect_features */ + nullptr, /* override_features */ + nullptr, /* data_create */ + nullptr, /* data_destroy */ + nullptr, /* preprocess_text */ + nullptr, /* postprocess_glyphs */ + HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, + nullptr, /* decompose */ + nullptr, /* compose */ + nullptr, /* setup_masks */ + HB_TAG_NONE, /* gpos_tag */ + nullptr, /* reorder_marks */ + HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, + false, /* fallback_position */ +}; + #endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc index f5915f43ae..dbedd6af0c 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc @@ -119,7 +119,7 @@ data_destroy_hangul (void *data) #define isHangulTone(u) (hb_in_range<hb_codepoint_t> ((u), 0x302Eu, 0x302Fu)) /* buffer var allocations */ -#define hangul_shaping_feature() complex_var_u8_0() /* hangul jamo shaping feature */ +#define hangul_shaping_feature() complex_var_u8_auxiliary() /* hangul jamo shaping feature */ static bool is_zero_width_char (hb_font_t *font, @@ -205,7 +205,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED, { /* Tone mark follows a valid syllable; move it in front, unless it's zero width. */ buffer->unsafe_to_break_from_outbuffer (start, buffer->idx); - buffer->next_glyph (); + if (unlikely (!buffer->next_glyph ())) break; if (!is_zero_width_char (font, u)) { buffer->merge_out_clusters (start, end + 1); @@ -218,23 +218,25 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED, else { /* No valid syllable as base for tone mark; try to insert dotted circle. */ - if (!(buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE) && - font->has_glyph (0x25CCu)) + if (!(buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE) && + font->has_glyph (0x25CCu)) { hb_codepoint_t chars[2]; - if (!is_zero_width_char (font, u)) { + if (!is_zero_width_char (font, u)) + { chars[0] = u; chars[1] = 0x25CCu; - } else { + } else + { chars[0] = 0x25CCu; chars[1] = u; } - buffer->replace_glyphs (1, 2, chars); + (void) buffer->replace_glyphs (1, 2, chars); } else { /* No dotted circle available in the font; just leave tone mark untouched. */ - buffer->next_glyph (); + (void) buffer->next_glyph (); } } start = end = buffer->out_len; @@ -271,9 +273,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_codepoint_t s = SBase + (l - LBase) * NCount + (v - VBase) * TCount + tindex; if (font->has_glyph (s)) { - buffer->replace_glyphs (t ? 3 : 2, 1, &s); - if (unlikely (!buffer->successful)) - return; + (void) buffer->replace_glyphs (t ? 3 : 2, 1, &s); end = start + 1; continue; } @@ -285,17 +285,19 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED, * Set jamo features on the individual glyphs, and advance past them. */ buffer->cur().hangul_shaping_feature() = LJMO; - buffer->next_glyph (); + (void) buffer->next_glyph (); buffer->cur().hangul_shaping_feature() = VJMO; - buffer->next_glyph (); + (void) buffer->next_glyph (); if (t) { buffer->cur().hangul_shaping_feature() = TJMO; - buffer->next_glyph (); + (void) buffer->next_glyph (); end = start + 3; } else end = start + 2; + if (unlikely (!buffer->successful)) + break; if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) buffer->merge_out_clusters (start, end); continue; @@ -321,9 +323,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_codepoint_t new_s = s + new_tindex; if (font->has_glyph (new_s)) { - buffer->replace_glyphs (2, 1, &new_s); - if (unlikely (!buffer->successful)) - return; + (void) buffer->replace_glyphs (2, 1, &new_s); end = start + 1; continue; } @@ -347,19 +347,18 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED, (!tindex || font->has_glyph (decomposed[2]))) { unsigned int s_len = tindex ? 3 : 2; - buffer->replace_glyphs (1, s_len, decomposed); + (void) buffer->replace_glyphs (1, s_len, decomposed); /* If we decomposed an LV because of a non-combining T following, * we want to include this T in the syllable. */ if (has_glyph && !tindex) { - buffer->next_glyph (); + (void) buffer->next_glyph (); s_len++; } - if (unlikely (!buffer->successful)) - return; + break; /* We decomposed S: apply jamo features to the individual glyphs * that are now in buffer->out_info. @@ -383,17 +382,15 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED, if (has_glyph) { - /* We didn't decompose the S, so just advance past it. */ + /* We didn't decompose the S, so just advance past it and fall through. */ end = start + 1; - buffer->next_glyph (); - continue; } } /* Didn't find a recognizable syllable, so we leave end <= start; * this will prevent tone-mark reordering happening. */ - buffer->next_glyph (); + (void) buffer->next_glyph (); } buffer->swap_buffers (); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh index 670b6bf486..74bf3ca0fa 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh @@ -31,8 +31,37 @@ #include "hb.hh" +enum indic_syllable_type_t { + indic_consonant_syllable, + indic_vowel_syllable, + indic_standalone_cluster, + indic_symbol_cluster, + indic_broken_cluster, + indic_non_indic_cluster, +}; + -#line 36 "hb-ot-shape-complex-indic-machine.hh" +#line 45 "hb-ot-shape-complex-indic-machine.hh" +#define indic_syllable_machine_ex_A 10u +#define indic_syllable_machine_ex_C 1u +#define indic_syllable_machine_ex_CM 17u +#define indic_syllable_machine_ex_CS 19u +#define indic_syllable_machine_ex_DOTTEDCIRCLE 12u +#define indic_syllable_machine_ex_H 4u +#define indic_syllable_machine_ex_M 7u +#define indic_syllable_machine_ex_N 3u +#define indic_syllable_machine_ex_PLACEHOLDER 11u +#define indic_syllable_machine_ex_RS 13u +#define indic_syllable_machine_ex_Ra 16u +#define indic_syllable_machine_ex_Repha 15u +#define indic_syllable_machine_ex_SM 8u +#define indic_syllable_machine_ex_Symbol 18u +#define indic_syllable_machine_ex_V 2u +#define indic_syllable_machine_ex_ZWJ 6u +#define indic_syllable_machine_ex_ZWNJ 5u + + +#line 65 "hb-ot-shape-complex-indic-machine.hh" static const unsigned char _indic_syllable_machine_trans_keys[] = { 8u, 8u, 4u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 4u, 13u, 4u, 8u, 8u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 6u, 6u, 16u, 16u, @@ -384,18 +413,18 @@ static const int indic_syllable_machine_error = -1; static const int indic_syllable_machine_en_main = 39; -#line 36 "hb-ot-shape-complex-indic-machine.rl" +#line 46 "hb-ot-shape-complex-indic-machine.rl" -#line 93 "hb-ot-shape-complex-indic-machine.rl" +#line 102 "hb-ot-shape-complex-indic-machine.rl" #define found_syllable(syllable_type) \ HB_STMT_START { \ if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ for (unsigned int i = ts; i < te; i++) \ - info[i].syllable() = (syllable_serial << 4) | indic_##syllable_type; \ + info[i].syllable() = (syllable_serial << 4) | syllable_type; \ syllable_serial++; \ if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ } HB_STMT_END @@ -407,7 +436,7 @@ find_syllables_indic (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 411 "hb-ot-shape-complex-indic-machine.hh" +#line 440 "hb-ot-shape-complex-indic-machine.hh" { cs = indic_syllable_machine_start; ts = 0; @@ -415,7 +444,7 @@ find_syllables_indic (hb_buffer_t *buffer) act = 0; } -#line 113 "hb-ot-shape-complex-indic-machine.rl" +#line 122 "hb-ot-shape-complex-indic-machine.rl" p = 0; @@ -423,7 +452,7 @@ find_syllables_indic (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 427 "hb-ot-shape-complex-indic-machine.hh" +#line 456 "hb-ot-shape-complex-indic-machine.hh" { int _slen; int _trans; @@ -437,7 +466,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 441 "hb-ot-shape-complex-indic-machine.hh" +#line 470 "hb-ot-shape-complex-indic-machine.hh" } _keys = _indic_syllable_machine_trans_keys + (cs<<1); @@ -460,64 +489,64 @@ _eof_trans: {te = p+1;} break; case 11: -#line 89 "hb-ot-shape-complex-indic-machine.rl" - {te = p+1;{ found_syllable (non_indic_cluster); }} +#line 98 "hb-ot-shape-complex-indic-machine.rl" + {te = p+1;{ found_syllable (indic_non_indic_cluster); }} break; case 13: -#line 84 "hb-ot-shape-complex-indic-machine.rl" - {te = p;p--;{ found_syllable (consonant_syllable); }} +#line 93 "hb-ot-shape-complex-indic-machine.rl" + {te = p;p--;{ found_syllable (indic_consonant_syllable); }} break; case 14: -#line 85 "hb-ot-shape-complex-indic-machine.rl" - {te = p;p--;{ found_syllable (vowel_syllable); }} +#line 94 "hb-ot-shape-complex-indic-machine.rl" + {te = p;p--;{ found_syllable (indic_vowel_syllable); }} break; case 17: -#line 86 "hb-ot-shape-complex-indic-machine.rl" - {te = p;p--;{ found_syllable (standalone_cluster); }} +#line 95 "hb-ot-shape-complex-indic-machine.rl" + {te = p;p--;{ found_syllable (indic_standalone_cluster); }} break; case 19: -#line 87 "hb-ot-shape-complex-indic-machine.rl" - {te = p;p--;{ found_syllable (symbol_cluster); }} +#line 96 "hb-ot-shape-complex-indic-machine.rl" + {te = p;p--;{ found_syllable (indic_symbol_cluster); }} break; case 15: -#line 88 "hb-ot-shape-complex-indic-machine.rl" - {te = p;p--;{ found_syllable (broken_cluster); }} +#line 97 "hb-ot-shape-complex-indic-machine.rl" + {te = p;p--;{ found_syllable (indic_broken_cluster); }} break; case 16: -#line 89 "hb-ot-shape-complex-indic-machine.rl" - {te = p;p--;{ found_syllable (non_indic_cluster); }} +#line 98 "hb-ot-shape-complex-indic-machine.rl" + {te = p;p--;{ found_syllable (indic_non_indic_cluster); }} break; case 1: -#line 84 "hb-ot-shape-complex-indic-machine.rl" - {{p = ((te))-1;}{ found_syllable (consonant_syllable); }} +#line 93 "hb-ot-shape-complex-indic-machine.rl" + {{p = ((te))-1;}{ found_syllable (indic_consonant_syllable); }} break; case 3: -#line 85 "hb-ot-shape-complex-indic-machine.rl" - {{p = ((te))-1;}{ found_syllable (vowel_syllable); }} +#line 94 "hb-ot-shape-complex-indic-machine.rl" + {{p = ((te))-1;}{ found_syllable (indic_vowel_syllable); }} break; case 7: -#line 86 "hb-ot-shape-complex-indic-machine.rl" - {{p = ((te))-1;}{ found_syllable (standalone_cluster); }} +#line 95 "hb-ot-shape-complex-indic-machine.rl" + {{p = ((te))-1;}{ found_syllable (indic_standalone_cluster); }} break; case 8: -#line 87 "hb-ot-shape-complex-indic-machine.rl" - {{p = ((te))-1;}{ found_syllable (symbol_cluster); }} +#line 96 "hb-ot-shape-complex-indic-machine.rl" + {{p = ((te))-1;}{ found_syllable (indic_symbol_cluster); }} break; case 4: -#line 88 "hb-ot-shape-complex-indic-machine.rl" - {{p = ((te))-1;}{ found_syllable (broken_cluster); }} +#line 97 "hb-ot-shape-complex-indic-machine.rl" + {{p = ((te))-1;}{ found_syllable (indic_broken_cluster); }} break; case 6: #line 1 "NONE" { switch( act ) { case 1: - {{p = ((te))-1;} found_syllable (consonant_syllable); } + {{p = ((te))-1;} found_syllable (indic_consonant_syllable); } break; case 5: - {{p = ((te))-1;} found_syllable (broken_cluster); } + {{p = ((te))-1;} found_syllable (indic_broken_cluster); } break; case 6: - {{p = ((te))-1;} found_syllable (non_indic_cluster); } + {{p = ((te))-1;} found_syllable (indic_non_indic_cluster); } break; } } @@ -525,22 +554,22 @@ _eof_trans: case 18: #line 1 "NONE" {te = p+1;} -#line 84 "hb-ot-shape-complex-indic-machine.rl" +#line 93 "hb-ot-shape-complex-indic-machine.rl" {act = 1;} break; case 5: #line 1 "NONE" {te = p+1;} -#line 88 "hb-ot-shape-complex-indic-machine.rl" +#line 97 "hb-ot-shape-complex-indic-machine.rl" {act = 5;} break; case 12: #line 1 "NONE" {te = p+1;} -#line 89 "hb-ot-shape-complex-indic-machine.rl" +#line 98 "hb-ot-shape-complex-indic-machine.rl" {act = 6;} break; -#line 544 "hb-ot-shape-complex-indic-machine.hh" +#line 573 "hb-ot-shape-complex-indic-machine.hh" } _again: @@ -549,7 +578,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 553 "hb-ot-shape-complex-indic-machine.hh" +#line 582 "hb-ot-shape-complex-indic-machine.hh" } if ( ++p != pe ) @@ -565,7 +594,7 @@ _again: } -#line 121 "hb-ot-shape-complex-indic-machine.rl" +#line 130 "hb-ot-shape-complex-indic-machine.rl" } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.rl b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.rl deleted file mode 100644 index 5f819bd296..0000000000 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.rl +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright © 2011,2012 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ - -#ifndef HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH -#define HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH - -#include "hb.hh" - -%%{ - machine indic_syllable_machine; - alphtype unsigned char; - write data; -}%% - -%%{ - -# Same order as enum indic_category_t. Not sure how to avoid duplication. -C = 1; -V = 2; -N = 3; -H = 4; -ZWNJ = 5; -ZWJ = 6; -M = 7; -SM = 8; -A = 10; -PLACEHOLDER = 11; -DOTTEDCIRCLE = 12; -RS = 13; -Repha = 15; -Ra = 16; -CM = 17; -Symbol= 18; -CS = 19; - -c = (C | Ra); # is_consonant -n = ((ZWNJ?.RS)? (N.N?)?); # is_consonant_modifier -z = ZWJ|ZWNJ; # is_joiner -reph = (Ra H | Repha); # possible reph - -cn = c.ZWJ?.n?; -forced_rakar = ZWJ H ZWJ Ra; -symbol = Symbol.N?; -matra_group = z*.M.N?.(H | forced_rakar)?; -syllable_tail = (z?.SM.SM?.ZWNJ?)? A*; -halant_group = (z?.H.(ZWJ.N?)?); -final_halant_group = halant_group | H.ZWNJ; -medial_group = CM?; -halant_or_matra_group = (final_halant_group | matra_group*); - -complex_syllable_tail = (halant_group.cn)* medial_group halant_or_matra_group syllable_tail; - -consonant_syllable = (Repha|CS)? cn complex_syllable_tail; -vowel_syllable = reph? V.n? (ZWJ | complex_syllable_tail); -standalone_cluster = ((Repha|CS)? PLACEHOLDER | reph? DOTTEDCIRCLE).n? complex_syllable_tail; -symbol_cluster = symbol syllable_tail; -broken_cluster = reph? n? complex_syllable_tail; -other = any; - -main := |* - consonant_syllable => { found_syllable (consonant_syllable); }; - vowel_syllable => { found_syllable (vowel_syllable); }; - standalone_cluster => { found_syllable (standalone_cluster); }; - symbol_cluster => { found_syllable (symbol_cluster); }; - broken_cluster => { found_syllable (broken_cluster); }; - other => { found_syllable (non_indic_cluster); }; -*|; - - -}%% - -#define found_syllable(syllable_type) \ - HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ - for (unsigned int i = ts; i < te; i++) \ - info[i].syllable() = (syllable_serial << 4) | indic_##syllable_type; \ - syllable_serial++; \ - if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ - } HB_STMT_END - -static void -find_syllables_indic (hb_buffer_t *buffer) -{ - unsigned int p, pe, eof, ts, te, act; - int cs; - hb_glyph_info_t *info = buffer->info; - %%{ - write init; - getkey info[p].indic_category(); - }%% - - p = 0; - pe = eof = buffer->len; - - unsigned int syllable_serial = 1; - %%{ - write exec; - }%% -} - -#undef found_syllable - -#endif /* HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.cc index cc91f172c3..dd204b23c1 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.cc @@ -6,12 +6,12 @@ * * on files with these headers: * - * # IndicSyllabicCategory-12.0.0.txt - * # Date: 2019-01-31, 02:26:00 GMT [KW, RP] - * # IndicPositionalCategory-12.0.0.txt - * # Date: 2019-01-31, 02:26:00 GMT [KW, RP] - * # Blocks-12.0.0.txt - * # Date: 2018-07-30, 19:40:00 GMT [KW] + * # IndicSyllabicCategory-13.0.0.txt + * # Date: 2019-07-22, 19:55:00 GMT [KW, RP] + * # IndicPositionalCategory-13.0.0.txt + * # Date: 2019-07-23, 00:01:00 GMT [KW, RP] + * # Blocks-13.0.0.txt + * # Date: 2019-07-10, 19:06:00 GMT [KW] */ #include "hb.hh" @@ -24,32 +24,32 @@ #pragma GCC diagnostic ignored "-Wunused-macros" #define ISC_A INDIC_SYLLABIC_CATEGORY_AVAGRAHA /* 17 chars; Avagraha */ -#define ISC_Bi INDIC_SYLLABIC_CATEGORY_BINDU /* 86 chars; Bindu */ +#define ISC_Bi INDIC_SYLLABIC_CATEGORY_BINDU /* 91 chars; Bindu */ #define ISC_BJN INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER /* 20 chars; Brahmi_Joining_Number */ #define ISC_Ca INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK /* 59 chars; Cantillation_Mark */ -#define ISC_C INDIC_SYLLABIC_CATEGORY_CONSONANT /* 2160 chars; Consonant */ +#define ISC_C INDIC_SYLLABIC_CATEGORY_CONSONANT /* 2195 chars; Consonant */ #define ISC_CD INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD /* 12 chars; Consonant_Dead */ #define ISC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL /* 67 chars; Consonant_Final */ #define ISC_CHL INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER /* 5 chars; Consonant_Head_Letter */ #define ISC_CIP INDIC_SYLLABIC_CATEGORY_CONSONANT_INITIAL_POSTFIXED /* 1 chars; Consonant_Initial_Postfixed */ #define ISC_CK INDIC_SYLLABIC_CATEGORY_CONSONANT_KILLER /* 2 chars; Consonant_Killer */ -#define ISC_CM INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL /* 29 chars; Consonant_Medial */ +#define ISC_CM INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL /* 31 chars; Consonant_Medial */ #define ISC_CP INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER /* 22 chars; Consonant_Placeholder */ -#define ISC_CPR INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA /* 2 chars; Consonant_Preceding_Repha */ -#define ISC_CPrf INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED /* 9 chars; Consonant_Prefixed */ +#define ISC_CPR INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA /* 3 chars; Consonant_Preceding_Repha */ +#define ISC_CPrf INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED /* 10 chars; Consonant_Prefixed */ #define ISC_CS INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED /* 94 chars; Consonant_Subjoined */ #define ISC_CSR INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA /* 4 chars; Consonant_Succeeding_Repha */ -#define ISC_CWS INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER /* 6 chars; Consonant_With_Stacker */ +#define ISC_CWS INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER /* 8 chars; Consonant_With_Stacker */ #define ISC_GM INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK /* 3 chars; Gemination_Mark */ -#define ISC_IS INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER /* 11 chars; Invisible_Stacker */ +#define ISC_IS INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER /* 12 chars; Invisible_Stacker */ #define ISC_ZWJ INDIC_SYLLABIC_CATEGORY_JOINER /* 1 chars; Joiner */ #define ISC_ML INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER /* 1 chars; Modifying_Letter */ #define ISC_ZWNJ INDIC_SYLLABIC_CATEGORY_NON_JOINER /* 1 chars; Non_Joiner */ -#define ISC_N INDIC_SYLLABIC_CATEGORY_NUKTA /* 30 chars; Nukta */ -#define ISC_Nd INDIC_SYLLABIC_CATEGORY_NUMBER /* 481 chars; Number */ +#define ISC_N INDIC_SYLLABIC_CATEGORY_NUKTA /* 31 chars; Nukta */ +#define ISC_Nd INDIC_SYLLABIC_CATEGORY_NUMBER /* 491 chars; Number */ #define ISC_NJ INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER /* 1 chars; Number_Joiner */ #define ISC_x INDIC_SYLLABIC_CATEGORY_OTHER /* 1 chars; Other */ -#define ISC_PK INDIC_SYLLABIC_CATEGORY_PURE_KILLER /* 21 chars; Pure_Killer */ +#define ISC_PK INDIC_SYLLABIC_CATEGORY_PURE_KILLER /* 23 chars; Pure_Killer */ #define ISC_RS INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER /* 2 chars; Register_Shifter */ #define ISC_SM INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER /* 25 chars; Syllable_Modifier */ #define ISC_TL INDIC_SYLLABIC_CATEGORY_TONE_LETTER /* 7 chars; Tone_Letter */ @@ -57,19 +57,20 @@ #define ISC_V INDIC_SYLLABIC_CATEGORY_VIRAMA /* 27 chars; Virama */ #define ISC_Vs INDIC_SYLLABIC_CATEGORY_VISARGA /* 35 chars; Visarga */ #define ISC_Vo INDIC_SYLLABIC_CATEGORY_VOWEL /* 30 chars; Vowel */ -#define ISC_M INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT /* 673 chars; Vowel_Dependent */ -#define ISC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT /* 476 chars; Vowel_Independent */ +#define ISC_M INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT /* 683 chars; Vowel_Dependent */ +#define ISC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT /* 484 chars; Vowel_Independent */ -#define IMC_B INDIC_MATRA_CATEGORY_BOTTOM /* 349 chars; Bottom */ +#define IMC_B INDIC_MATRA_CATEGORY_BOTTOM /* 351 chars; Bottom */ #define IMC_BL INDIC_MATRA_CATEGORY_BOTTOM_AND_LEFT /* 1 chars; Bottom_And_Left */ -#define IMC_BR INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT /* 2 chars; Bottom_And_Right */ -#define IMC_L INDIC_MATRA_CATEGORY_LEFT /* 61 chars; Left */ -#define IMC_LR INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT /* 21 chars; Left_And_Right */ +#define IMC_BR INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT /* 4 chars; Bottom_And_Right */ +#define IMC_L INDIC_MATRA_CATEGORY_LEFT /* 64 chars; Left */ +#define IMC_LR INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT /* 22 chars; Left_And_Right */ #define IMC_x INDIC_MATRA_CATEGORY_NOT_APPLICABLE /* 1 chars; Not_Applicable */ #define IMC_O INDIC_MATRA_CATEGORY_OVERSTRUCK /* 10 chars; Overstruck */ -#define IMC_R INDIC_MATRA_CATEGORY_RIGHT /* 281 chars; Right */ -#define IMC_T INDIC_MATRA_CATEGORY_TOP /* 398 chars; Top */ +#define IMC_R INDIC_MATRA_CATEGORY_RIGHT /* 288 chars; Right */ +#define IMC_T INDIC_MATRA_CATEGORY_TOP /* 415 chars; Top */ #define IMC_TB INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM /* 10 chars; Top_And_Bottom */ +#define IMC_TBL INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_LEFT /* 2 chars; Top_And_Bottom_And_Left */ #define IMC_TBR INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT /* 1 chars; Top_And_Bottom_And_Right */ #define IMC_TL INDIC_MATRA_CATEGORY_TOP_AND_LEFT /* 6 chars; Top_And_Left */ #define IMC_TLR INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT /* 4 chars; Top_And_Left_And_Right */ @@ -81,7 +82,7 @@ #define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M) -static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { +static const uint16_t indic_table[] = { #define indic_offset_0x0028u 0 @@ -195,7 +196,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 0B38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(A,x), _(M,R), _(M,T), /* 0B40 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(x,x), _(x,x), _(M,L), /* 0B48 */ _(M,TL), _(x,x), _(x,x), _(M,LR),_(M,TLR), _(V,B), _(x,x), _(x,x), - /* 0B50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T), _(M,TR), + /* 0B50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T), _(M,T), _(M,TR), /* 0B58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), /* 0B60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x), /* 0B68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), @@ -261,7 +262,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* Malayalam */ - /* 0D00 */ _(Bi,T), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x), + /* 0D00 */ _(Bi,T), _(Bi,T), _(Bi,R), _(Vs,R), _(Bi,x), _(VI,x), _(VI,x), _(VI,x), /* 0D08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x), /* 0D10 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), /* 0D18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), @@ -270,7 +271,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 0D30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 0D38 */ _(C,x), _(C,x), _(C,x), _(PK,T), _(PK,T), _(A,x), _(M,R), _(M,R), /* 0D40 */ _(M,R), _(M,R), _(M,R), _(M,B), _(M,B), _(x,x), _(M,L), _(M,L), - /* 0D48 */ _(M,L), _(x,x), _(M,LR), _(M,LR), _(M,LR), _(V,T),_(CPR,x), _(x,x), + /* 0D48 */ _(M,L), _(x,x), _(M,LR), _(M,LR), _(M,LR), _(V,T),_(CPR,T), _(x,x), /* 0D50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(CD,x), _(CD,x), _(CD,x), _(M,R), /* 0D58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(VI,x), /* 0D60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x), @@ -280,7 +281,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* Sinhala */ - /* 0D80 */ _(x,x), _(x,x), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x), + /* 0D80 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x), /* 0D88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), /* 0D90 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), /* 0D98 */ _(x,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), @@ -308,7 +309,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 1020 */ _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), /* 1028 */ _(VI,x), _(VI,x), _(VI,x), _(M,R), _(M,R), _(M,T), _(M,T), _(M,B), /* 1030 */ _(M,B), _(M,L), _(M,T), _(M,T), _(M,T), _(M,T), _(Bi,T), _(TM,B), - /* 1038 */ _(Vs,R), _(IS,x), _(PK,T), _(CM,R), _(CM,x), _(CM,B), _(CM,B), _(C,x), + /* 1038 */ _(Vs,R), _(IS,x), _(PK,T), _(CM,R),_(CM,TBL), _(CM,B), _(CM,B), _(C,x), /* 1040 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), /* 1048 */ _(Nd,x), _(Nd,x), _(x,x), _(CP,x), _(x,x), _(x,x), _(CP,x), _(x,x), /* 1050 */ _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(M,R), _(M,R), @@ -403,7 +404,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { }; /* Table items: 1792; occupancy: 70% */ -INDIC_TABLE_ELEMENT_TYPE +uint16_t hb_indic_get_categories (hb_codepoint_t u) { switch (u >> 12) @@ -488,6 +489,7 @@ hb_indic_get_categories (hb_codepoint_t u) #undef IMC_R #undef IMC_T #undef IMC_TB +#undef IMC_TBL #undef IMC_TBR #undef IMC_TL #undef IMC_TLR diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc index 26dc60ddc9..a4f2d9a847 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc @@ -29,6 +29,7 @@ #ifndef HB_NO_OT_SHAPE #include "hb-ot-shape-complex-indic.hh" +#include "hb-ot-shape-complex-indic-machine.hh" #include "hb-ot-shape-complex-vowel-constraints.hh" #include "hb-ot-layout.hh" @@ -248,6 +249,7 @@ struct indic_shape_plan_t hb_indic_would_substitute_feature_t pref; hb_indic_would_substitute_feature_t blwf; hb_indic_would_substitute_feature_t pstf; + hb_indic_would_substitute_feature_t vatu; hb_mask_t mask_array[INDIC_NUM_FEATURES]; }; @@ -286,6 +288,7 @@ data_create_indic (const hb_ot_shape_plan_t *plan) indic_plan->pref.init (&plan->map, HB_TAG('p','r','e','f'), zero_context); indic_plan->blwf.init (&plan->map, HB_TAG('b','l','w','f'), zero_context); indic_plan->pstf.init (&plan->map, HB_TAG('p','s','t','f'), zero_context); + indic_plan->vatu.init (&plan->map, HB_TAG('v','a','t','u'), zero_context); for (unsigned int i = 0; i < ARRAY_LENGTH (indic_plan->mask_array); i++) indic_plan->mask_array[i] = (indic_features[i].flags & F_GLOBAL) ? @@ -315,10 +318,16 @@ consonant_position_from_face (const indic_shape_plan_t *indic_plan, * base at 0. The font however, only has lookups matching * 930,94D in 'blwf', not the expected 94D,930 (with new-spec * table). As such, we simply match both sequences. Seems - * to work. */ + * to work. + * + * Vatu is done as well, for: + * https://github.com/harfbuzz/harfbuzz/issues/1587 + */ hb_codepoint_t glyphs[3] = {virama, consonant, virama}; if (indic_plan->blwf.would_substitute (glyphs , 2, face) || - indic_plan->blwf.would_substitute (glyphs+1, 2, face)) + indic_plan->blwf.would_substitute (glyphs+1, 2, face) || + indic_plan->vatu.would_substitute (glyphs , 2, face) || + indic_plan->vatu.would_substitute (glyphs+1, 2, face)) return POS_BELOW_C; if (indic_plan->pstf.would_substitute (glyphs , 2, face) || indic_plan->pstf.would_substitute (glyphs+1, 2, face)) @@ -329,19 +338,6 @@ consonant_position_from_face (const indic_shape_plan_t *indic_plan, return POS_BASE_C; } - -enum indic_syllable_type_t { - indic_consonant_syllable, - indic_vowel_syllable, - indic_standalone_cluster, - indic_symbol_cluster, - indic_broken_cluster, - indic_non_indic_cluster, -}; - -#include "hb-ot-shape-complex-indic-machine.hh" - - static void setup_masks_indic (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_buffer_t *buffer, @@ -642,7 +638,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, * is *not* a Halant after last consonant already. We know that is the * case for Kannada, while it reorders unconditionally in other scripts, * eg. Malayalam, Bengali, and Devanagari. We don't currently know about - * other scripts, so we blacklist Kannada. + * other scripts, so we block Kannada. * * Kannada test case: * U+0C9A,U+0CCD,U+0C9A,U+0CCD @@ -756,7 +752,28 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, * We could use buffer->sort() for this, if there was no special * reordering of pre-base stuff happening later... * We don't want to merge_clusters all of that, which buffer->sort() - * would. + * would. Here's a concrete example: + * + * Assume there's a pre-base consonant and explicit Halant before base, + * followed by a prebase-reordering (left) Matra: + * + * C,H,ZWNJ,B,M + * + * At this point in reordering we would have: + * + * M,C,H,ZWNJ,B + * + * whereas in final reordering we will bring the Matra closer to Base: + * + * C,H,ZWNJ,M,B + * + * That's why we don't want to merge-clusters anything before the Base + * at this point. But if something moved from after Base to before it, + * we should merge clusters from base to them. In final-reordering, we + * only move things around before base, and merge-clusters up to base. + * These two merge-clusters from the two sides of base will interlock + * to merge things correctly. See: + * https://github.com/harfbuzz/harfbuzz/issues/2272 */ if (indic_plan->is_old_spec || end - start > 127) buffer->merge_clusters (base, end); @@ -766,17 +783,18 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, for (unsigned int i = base; i < end; i++) if (info[i].syllable() != 255) { + unsigned int min = i; unsigned int max = i; unsigned int j = start + info[i].syllable(); while (j != i) { + min = hb_min (min, j); max = hb_max (max, j); unsigned int next = start + info[j].syllable(); info[j].syllable() = 255; /* So we don't process j later again. */ j = next; } - if (i != max) - buffer->merge_clusters (i, max + 1); + buffer->merge_clusters (hb_max (base, min), max + 1); } } @@ -930,79 +948,24 @@ initial_reordering_syllable_indic (const hb_ot_shape_plan_t *plan, } } -static inline void -insert_dotted_circles_indic (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_font_t *font, - hb_buffer_t *buffer) -{ - if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)) - return; - - /* Note: This loop is extra overhead, but should not be measurable. - * TODO Use a buffer scratch flag to remove the loop. */ - bool has_broken_syllables = false; - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 0; i < count; i++) - if ((info[i].syllable() & 0x0F) == indic_broken_cluster) - { - has_broken_syllables = true; - break; - } - if (likely (!has_broken_syllables)) - return; - - - hb_codepoint_t dottedcircle_glyph; - if (!font->get_nominal_glyph (0x25CCu, &dottedcircle_glyph)) - return; - - hb_glyph_info_t dottedcircle = {0}; - dottedcircle.codepoint = 0x25CCu; - set_indic_properties (dottedcircle); - dottedcircle.codepoint = dottedcircle_glyph; - - buffer->clear_output (); - - buffer->idx = 0; - unsigned int last_syllable = 0; - while (buffer->idx < buffer->len && buffer->successful) - { - unsigned int syllable = buffer->cur().syllable(); - indic_syllable_type_t syllable_type = (indic_syllable_type_t) (syllable & 0x0F); - if (unlikely (last_syllable != syllable && syllable_type == indic_broken_cluster)) - { - last_syllable = syllable; - - hb_glyph_info_t ginfo = dottedcircle; - ginfo.cluster = buffer->cur().cluster; - ginfo.mask = buffer->cur().mask; - ginfo.syllable() = buffer->cur().syllable(); - - /* Insert dottedcircle after possible Repha. */ - while (buffer->idx < buffer->len && buffer->successful && - last_syllable == buffer->cur().syllable() && - buffer->cur().indic_category() == OT_Repha) - buffer->next_glyph (); - - buffer->output_info (ginfo); - } - else - buffer->next_glyph (); - } - buffer->swap_buffers (); -} - static void initial_reordering_indic (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { + if (!buffer->message (font, "start reordering indic initial")) + return; + update_consonant_positions_indic (plan, font, buffer); - insert_dotted_circles_indic (plan, font, buffer); + hb_syllabic_insert_dotted_circles (font, buffer, + indic_broken_cluster, + OT_DOTTEDCIRCLE, + OT_Repha); foreach_syllable (buffer, start, end) initial_reordering_syllable_indic (plan, font->face, buffer, start, end); + + (void) buffer->message (font, "end reordering indic initial"); } static void @@ -1325,6 +1288,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan, goto reph_move; } } + /* See https://github.com/harfbuzz/harfbuzz/issues/2298#issuecomment-615318654 */ /* 6. Otherwise, reorder reph to the end of the syllable. */ @@ -1476,8 +1440,11 @@ final_reordering_indic (const hb_ot_shape_plan_t *plan, unsigned int count = buffer->len; if (unlikely (!count)) return; - foreach_syllable (buffer, start, end) - final_reordering_syllable_indic (plan, buffer, start, end); + if (buffer->message (font, "start reordering indic final")) { + foreach_syllable (buffer, start, end) + final_reordering_syllable_indic (plan, buffer, start, end); + (void) buffer->message (font, "end reordering indic final"); + } HB_BUFFER_DEALLOCATE_VAR (buffer, indic_category); HB_BUFFER_DEALLOCATE_VAR (buffer, indic_position); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.hh index 1eeed68c50..dcb28a4e84 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.hh @@ -29,16 +29,14 @@ #include "hb.hh" -#include "hb-ot-shape-complex.hh" +#include "hb-ot-shape-complex-syllabic.hh" /* buffer var allocations */ -#define indic_category() complex_var_u8_0() /* indic_category_t */ -#define indic_position() complex_var_u8_1() /* indic_position_t */ +#define indic_category() complex_var_u8_category() /* indic_category_t */ +#define indic_position() complex_var_u8_auxiliary() /* indic_position_t */ -#define INDIC_TABLE_ELEMENT_TYPE uint16_t - /* Cateories used in the OpenType spec: * https://docs.microsoft.com/en-us/typography/script-development/devanagari */ @@ -165,6 +163,7 @@ enum indic_matra_category_t { INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT, INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT, INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM = INDIC_MATRA_CATEGORY_BOTTOM, + INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_LEFT = INDIC_MATRA_CATEGORY_BOTTOM, INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT, INDIC_MATRA_CATEGORY_TOP_AND_LEFT = INDIC_MATRA_CATEGORY_TOP, INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT, @@ -176,7 +175,7 @@ enum indic_matra_category_t { #define INDIC_COMBINE_CATEGORIES(S,M) \ ( \ - ASSERT_STATIC_EXPR_ZERO (S < 255 && M < 255) + \ + static_assert_expr (S < 255 && M < 255) + \ ( S | \ ( \ ( \ @@ -193,7 +192,7 @@ enum indic_matra_category_t { ) \ ) -HB_INTERNAL INDIC_TABLE_ELEMENT_TYPE +HB_INTERNAL uint16_t hb_indic_get_categories (hb_codepoint_t u); @@ -306,17 +305,12 @@ static const hb_codepoint_t ra_chars[] = { 0x0D30u, /* Malayalam */ /* No Reph, Logical Repha */ 0x0DBBu, /* Sinhala */ /* Reph formed only with ZWJ */ - - 0x179Au, /* Khmer */ }; static inline bool is_ra (hb_codepoint_t u) { - for (unsigned int i = 0; i < ARRAY_LENGTH (ra_chars); i++) - if (u == ra_chars[i]) - return true; - return false; + return hb_array (ra_chars).lfind (u); } static inline void @@ -324,7 +318,7 @@ set_indic_properties (hb_glyph_info_t &info) { hb_codepoint_t u = info.codepoint; unsigned int type = hb_indic_get_categories (u); - indic_category_t cat = (indic_category_t) (type & 0x7Fu); + indic_category_t cat = (indic_category_t) (type & 0xFFu); indic_position_t pos = (indic_position_t) (type >> 8); @@ -369,6 +363,7 @@ set_indic_properties (hb_glyph_info_t &info) else if (unlikely (u == 0x1133Bu || u == 0x1133Cu)) cat = OT_N; else if (unlikely (u == 0x0AFBu)) cat = OT_N; /* https://github.com/harfbuzz/harfbuzz/issues/552 */ + else if (unlikely (u == 0x0B55u)) cat = OT_N; /* https://github.com/harfbuzz/harfbuzz/issues/2849 */ else if (unlikely (u == 0x0980u)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/issues/538 */ else if (unlikely (u == 0x09FCu)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/pull/1613 */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-khmer-machine.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-khmer-machine.hh index a040318d34..82ab186a41 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-khmer-machine.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-khmer-machine.hh @@ -1,211 +1,179 @@ - #line 1 "hb-ot-shape-complex-khmer-machine.rl" /* - * Copyright © 2011,2012 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ +* Copyright © 2011,2012 Google, Inc. +* +* This is part of HarfBuzz, a text shaping library. +* +* Permission is hereby granted, without written agreement and without +* license or royalty fees, to use, copy, modify, and distribute this +* software and its documentation for any purpose, provided that the +* above copyright notice and the following two paragraphs appear in +* all copies of this software. +* +* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR +* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN +* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +* DAMAGE. +* +* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, +* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS +* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO +* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. +* +* Google Author(s): Behdad Esfahbod +*/ #ifndef HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH #define HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH #include "hb.hh" +enum khmer_syllable_type_t { + khmer_consonant_syllable, + khmer_broken_cluster, + khmer_non_khmer_cluster, +}; + -#line 36 "hb-ot-shape-complex-khmer-machine.hh" +#line 41 "hb-ot-shape-complex-khmer-machine.hh" +#define khmer_syllable_machine_ex_C 1u +#define khmer_syllable_machine_ex_Coeng 14u +#define khmer_syllable_machine_ex_DOTTEDCIRCLE 12u +#define khmer_syllable_machine_ex_PLACEHOLDER 11u +#define khmer_syllable_machine_ex_Ra 16u +#define khmer_syllable_machine_ex_Robatic 20u +#define khmer_syllable_machine_ex_V 2u +#define khmer_syllable_machine_ex_VAbv 26u +#define khmer_syllable_machine_ex_VBlw 27u +#define khmer_syllable_machine_ex_VPre 28u +#define khmer_syllable_machine_ex_VPst 29u +#define khmer_syllable_machine_ex_Xgroup 21u +#define khmer_syllable_machine_ex_Ygroup 22u +#define khmer_syllable_machine_ex_ZWJ 6u +#define khmer_syllable_machine_ex_ZWNJ 5u + + +#line 59 "hb-ot-shape-complex-khmer-machine.hh" static const unsigned char _khmer_syllable_machine_trans_keys[] = { - 5u, 26u, 5u, 21u, 5u, 26u, 5u, 21u, 1u, 16u, 5u, 21u, 5u, 26u, 5u, 21u, - 5u, 26u, 5u, 21u, 5u, 21u, 5u, 26u, 5u, 21u, 1u, 16u, 5u, 21u, 5u, 26u, - 5u, 21u, 5u, 26u, 5u, 21u, 5u, 26u, 1u, 29u, 5u, 29u, 5u, 29u, 5u, 29u, - 22u, 22u, 5u, 22u, 5u, 29u, 5u, 29u, 5u, 29u, 1u, 16u, 5u, 26u, 5u, 29u, - 5u, 29u, 22u, 22u, 5u, 22u, 5u, 29u, 5u, 29u, 1u, 16u, 5u, 29u, 5u, 29u, - 0 + 2u, 8u, 2u, 6u, 2u, 8u, 2u, 6u, + 0u, 0u, 2u, 6u, 2u, 8u, 2u, 6u, + 2u, 8u, 2u, 6u, 2u, 6u, 2u, 8u, + 2u, 6u, 0u, 0u, 2u, 6u, 2u, 8u, + 2u, 6u, 2u, 8u, 2u, 6u, 2u, 8u, + 0u, 11u, 2u, 11u, 2u, 11u, 2u, 11u, + 7u, 7u, 2u, 7u, 2u, 11u, 2u, 11u, + 2u, 11u, 0u, 0u, 2u, 8u, 2u, 11u, + 2u, 11u, 7u, 7u, 2u, 7u, 2u, 11u, + 2u, 11u, 0u, 0u, 2u, 11u, 2u, 11u, + 0u }; -static const char _khmer_syllable_machine_key_spans[] = { - 22, 17, 22, 17, 16, 17, 22, 17, - 22, 17, 17, 22, 17, 16, 17, 22, - 17, 22, 17, 22, 29, 25, 25, 25, - 1, 18, 25, 25, 25, 16, 22, 25, - 25, 1, 18, 25, 25, 16, 25, 25 +static const signed char _khmer_syllable_machine_char_class[] = { + 0, 0, 1, 1, 2, 2, 1, 1, + 1, 1, 3, 3, 1, 4, 1, 0, + 1, 1, 1, 5, 6, 7, 1, 1, + 1, 8, 9, 10, 11, 0 }; static const short _khmer_syllable_machine_index_offsets[] = { - 0, 23, 41, 64, 82, 99, 117, 140, - 158, 181, 199, 217, 240, 258, 275, 293, - 316, 334, 357, 375, 398, 428, 454, 480, - 506, 508, 527, 553, 579, 605, 622, 645, - 671, 697, 699, 718, 744, 770, 787, 813 + 0, 7, 12, 19, 24, 25, 30, 37, + 42, 49, 54, 59, 66, 71, 72, 77, + 84, 89, 96, 101, 108, 120, 130, 140, + 150, 151, 157, 167, 177, 187, 188, 195, + 205, 215, 216, 222, 232, 242, 243, 253, + 0 }; -static const char _khmer_syllable_machine_indicies[] = { - 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2, - 3, 0, 0, 0, 0, 4, 0, 1, - 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3, - 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 0, 0, 0, 0, 4, 0, - 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 4, 0, 6, 6, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 0, 7, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 8, 0, 9, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 10, 0, 0, - 0, 0, 4, 0, 9, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 10, 0, 11, 11, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 12, 0, - 0, 0, 0, 4, 0, 11, 11, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 12, 0, 14, - 14, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 15, - 13, 14, 14, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 15, 16, 16, 16, 16, 17, 16, - 18, 18, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 17, 16, 19, 19, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 19, 16, 20, 20, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 21, 16, 22, 22, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 23, 16, 16, - 16, 16, 17, 16, 22, 22, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 23, 16, 24, 24, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 25, 16, - 16, 16, 16, 17, 16, 24, 24, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 25, 16, 14, - 14, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 26, 15, - 16, 16, 16, 16, 17, 16, 28, 28, - 27, 27, 29, 29, 27, 27, 27, 27, - 2, 2, 27, 30, 27, 28, 27, 27, - 27, 27, 15, 19, 27, 27, 27, 17, - 23, 25, 21, 27, 32, 32, 31, 31, - 31, 31, 31, 31, 31, 33, 31, 31, - 31, 31, 31, 2, 3, 6, 31, 31, - 31, 4, 10, 12, 8, 31, 34, 34, - 31, 31, 31, 31, 31, 31, 31, 35, - 31, 31, 31, 31, 31, 31, 3, 6, - 31, 31, 31, 4, 10, 12, 8, 31, - 5, 5, 31, 31, 31, 31, 31, 31, - 31, 35, 31, 31, 31, 31, 31, 31, - 4, 6, 31, 31, 31, 31, 31, 31, - 8, 31, 6, 31, 7, 7, 31, 31, - 31, 31, 31, 31, 31, 35, 31, 31, - 31, 31, 31, 31, 8, 6, 31, 36, - 36, 31, 31, 31, 31, 31, 31, 31, - 35, 31, 31, 31, 31, 31, 31, 10, - 6, 31, 31, 31, 4, 31, 31, 8, - 31, 37, 37, 31, 31, 31, 31, 31, - 31, 31, 35, 31, 31, 31, 31, 31, - 31, 12, 6, 31, 31, 31, 4, 10, - 31, 8, 31, 34, 34, 31, 31, 31, - 31, 31, 31, 31, 33, 31, 31, 31, - 31, 31, 31, 3, 6, 31, 31, 31, - 4, 10, 12, 8, 31, 28, 28, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 28, 31, 14, 14, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 15, 38, - 38, 38, 38, 17, 38, 40, 40, 39, - 39, 39, 39, 39, 39, 39, 41, 39, - 39, 39, 39, 39, 39, 15, 19, 39, - 39, 39, 17, 23, 25, 21, 39, 18, - 18, 39, 39, 39, 39, 39, 39, 39, - 41, 39, 39, 39, 39, 39, 39, 17, - 19, 39, 39, 39, 39, 39, 39, 21, - 39, 19, 39, 20, 20, 39, 39, 39, - 39, 39, 39, 39, 41, 39, 39, 39, - 39, 39, 39, 21, 19, 39, 42, 42, - 39, 39, 39, 39, 39, 39, 39, 41, - 39, 39, 39, 39, 39, 39, 23, 19, - 39, 39, 39, 17, 39, 39, 21, 39, - 43, 43, 39, 39, 39, 39, 39, 39, - 39, 41, 39, 39, 39, 39, 39, 39, - 25, 19, 39, 39, 39, 17, 23, 39, - 21, 39, 44, 44, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, - 39, 44, 39, 45, 45, 39, 39, 39, - 39, 39, 39, 39, 30, 39, 39, 39, - 39, 39, 26, 15, 19, 39, 39, 39, - 17, 23, 25, 21, 39, 40, 40, 39, - 39, 39, 39, 39, 39, 39, 30, 39, - 39, 39, 39, 39, 39, 15, 19, 39, - 39, 39, 17, 23, 25, 21, 39, 0 +static const signed char _khmer_syllable_machine_indicies[] = { + 1, 0, 0, 2, 3, 0, 4, 1, + 0, 0, 0, 3, 1, 0, 0, 0, + 3, 0, 4, 5, 0, 0, 0, 4, + 6, 7, 0, 0, 0, 8, 9, 0, + 0, 0, 10, 0, 4, 9, 0, 0, + 0, 10, 11, 0, 0, 0, 12, 0, + 4, 11, 0, 0, 0, 12, 14, 13, + 13, 13, 15, 14, 16, 16, 16, 15, + 16, 17, 18, 16, 16, 16, 17, 19, + 20, 16, 16, 16, 21, 22, 16, 16, + 16, 23, 16, 17, 22, 16, 16, 16, + 23, 24, 16, 16, 16, 25, 16, 17, + 24, 16, 16, 16, 25, 14, 16, 16, + 26, 15, 16, 17, 29, 28, 30, 2, + 31, 28, 15, 19, 17, 23, 25, 21, + 33, 32, 34, 2, 3, 6, 4, 10, + 12, 8, 35, 32, 36, 32, 3, 6, + 4, 10, 12, 8, 5, 32, 36, 32, + 4, 6, 32, 32, 32, 8, 6, 7, + 32, 36, 32, 8, 6, 37, 32, 36, + 32, 10, 6, 4, 32, 32, 8, 38, + 32, 36, 32, 12, 6, 4, 10, 32, + 8, 35, 32, 34, 32, 3, 6, 4, + 10, 12, 8, 29, 14, 39, 39, 39, + 15, 39, 17, 41, 40, 42, 40, 15, + 19, 17, 23, 25, 21, 18, 40, 42, + 40, 17, 19, 40, 40, 40, 21, 19, + 20, 40, 42, 40, 21, 19, 43, 40, + 42, 40, 23, 19, 17, 40, 40, 21, + 44, 40, 42, 40, 25, 19, 17, 23, + 40, 21, 45, 46, 40, 31, 26, 15, + 19, 17, 23, 25, 21, 41, 40, 31, + 40, 15, 19, 17, 23, 25, 21, 0 }; -static const char _khmer_syllable_machine_trans_targs[] = { - 20, 1, 28, 22, 23, 3, 24, 5, - 25, 7, 26, 9, 27, 20, 10, 31, - 20, 32, 12, 33, 14, 34, 16, 35, - 18, 36, 39, 20, 21, 30, 37, 20, - 0, 29, 2, 4, 6, 8, 20, 20, - 11, 13, 15, 17, 38, 19 +static const signed char _khmer_syllable_machine_index_defaults[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 13, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 28, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 39, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 0 }; -static const char _khmer_syllable_machine_trans_actions[] = { - 1, 0, 2, 2, 2, 0, 0, 0, - 2, 0, 2, 0, 2, 3, 0, 4, - 5, 2, 0, 0, 0, 2, 0, 2, - 0, 2, 4, 8, 2, 9, 0, 10, - 0, 0, 0, 0, 0, 0, 11, 12, - 0, 0, 0, 0, 4, 0 +static const signed char _khmer_syllable_machine_cond_targs[] = { + 20, 1, 28, 22, 23, 3, 24, 5, + 25, 7, 26, 9, 27, 20, 10, 31, + 20, 32, 12, 33, 14, 34, 16, 35, + 18, 36, 39, 20, 20, 21, 30, 37, + 20, 0, 29, 2, 4, 6, 8, 20, + 20, 11, 13, 15, 17, 38, 19, 0 }; -static const char _khmer_syllable_machine_to_state_actions[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 6, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 +static const signed char _khmer_syllable_machine_cond_actions[] = { + 1, 0, 2, 2, 2, 0, 0, 0, + 2, 0, 2, 0, 2, 3, 0, 4, + 5, 2, 0, 0, 0, 2, 0, 2, + 0, 2, 4, 0, 8, 2, 9, 0, + 10, 0, 0, 0, 0, 0, 0, 11, + 12, 0, 0, 0, 0, 4, 0, 0 }; -static const char _khmer_syllable_machine_from_state_actions[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 +static const signed char _khmer_syllable_machine_to_state_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0 }; -static const unsigned char _khmer_syllable_machine_eof_trans[] = { - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 14, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 0, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 39, 40, - 40, 40, 40, 40, 40, 40, 40, 40 +static const signed char _khmer_syllable_machine_from_state_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0 +}; + +static const signed char _khmer_syllable_machine_eof_trans[] = { + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 14, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 28, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 40, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 0 }; static const int khmer_syllable_machine_start = 20; @@ -215,156 +183,271 @@ static const int khmer_syllable_machine_error = -1; static const int khmer_syllable_machine_en_main = 20; -#line 36 "hb-ot-shape-complex-khmer-machine.rl" +#line 43 "hb-ot-shape-complex-khmer-machine.rl" -#line 80 "hb-ot-shape-complex-khmer-machine.rl" +#line 86 "hb-ot-shape-complex-khmer-machine.rl" #define found_syllable(syllable_type) \ - HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ - for (unsigned int i = ts; i < te; i++) \ - info[i].syllable() = (syllable_serial << 4) | khmer_##syllable_type; \ - syllable_serial++; \ - if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ - } HB_STMT_END +HB_STMT_START { \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ + for (unsigned int i = ts; i < te; i++) \ + info[i].syllable() = (syllable_serial << 4) | syllable_type; \ + syllable_serial++; \ + if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ + } HB_STMT_END static void find_syllables_khmer (hb_buffer_t *buffer) { - unsigned int p, pe, eof, ts, te, act HB_UNUSED; - int cs; - hb_glyph_info_t *info = buffer->info; - -#line 242 "hb-ot-shape-complex-khmer-machine.hh" + unsigned int p, pe, eof, ts, te, act HB_UNUSED; + int cs; + hb_glyph_info_t *info = buffer->info; + +#line 210 "hb-ot-shape-complex-khmer-machine.hh" { - cs = khmer_syllable_machine_start; - ts = 0; - te = 0; - act = 0; + cs = (int)khmer_syllable_machine_start; + ts = 0; + te = 0; + act = 0; } - -#line 100 "hb-ot-shape-complex-khmer-machine.rl" - - - p = 0; - pe = eof = buffer->len; - - unsigned int syllable_serial = 1; - -#line 258 "hb-ot-shape-complex-khmer-machine.hh" + +#line 106 "hb-ot-shape-complex-khmer-machine.rl" + + + p = 0; + pe = eof = buffer->len; + + unsigned int syllable_serial = 1; + +#line 226 "hb-ot-shape-complex-khmer-machine.hh" { - int _slen; - int _trans; - const unsigned char *_keys; - const char *_inds; - if ( p == pe ) - goto _test_eof; -_resume: - switch ( _khmer_syllable_machine_from_state_actions[cs] ) { - case 7: + unsigned int _trans = 0; + const unsigned char * _keys; + const signed char * _inds; + int _ic; + _resume: {} + if ( p == pe && p != eof ) + goto _out; + switch ( _khmer_syllable_machine_from_state_actions[cs] ) { + case 7: { + { #line 1 "NONE" - {ts = p;} - break; -#line 272 "hb-ot-shape-complex-khmer-machine.hh" - } - - _keys = _khmer_syllable_machine_trans_keys + (cs<<1); - _inds = _khmer_syllable_machine_indicies + _khmer_syllable_machine_index_offsets[cs]; - - _slen = _khmer_syllable_machine_key_spans[cs]; - _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].khmer_category()) && - ( info[p].khmer_category()) <= _keys[1] ? - ( info[p].khmer_category()) - _keys[0] : _slen ]; - -_eof_trans: - cs = _khmer_syllable_machine_trans_targs[_trans]; - - if ( _khmer_syllable_machine_trans_actions[_trans] == 0 ) - goto _again; - - switch ( _khmer_syllable_machine_trans_actions[_trans] ) { - case 2: + {ts = p;}} + +#line 241 "hb-ot-shape-complex-khmer-machine.hh" + + + break; + } + } + + if ( p == eof ) { + if ( _khmer_syllable_machine_eof_trans[cs] > 0 ) { + _trans = (unsigned int)_khmer_syllable_machine_eof_trans[cs] - 1; + } + } + else { + _keys = ( _khmer_syllable_machine_trans_keys + ((cs<<1))); + _inds = ( _khmer_syllable_machine_indicies + (_khmer_syllable_machine_index_offsets[cs])); + + if ( (info[p].khmer_category()) <= 29 && (info[p].khmer_category()) >= 1 ) { + _ic = (int)_khmer_syllable_machine_char_class[(int)(info[p].khmer_category()) - 1]; + if ( _ic <= (int)(*( _keys+1)) && _ic >= (int)(*( _keys)) ) + _trans = (unsigned int)(*( _inds + (int)( _ic - (int)(*( _keys)) ) )); + else + _trans = (unsigned int)_khmer_syllable_machine_index_defaults[cs]; + } + else { + _trans = (unsigned int)_khmer_syllable_machine_index_defaults[cs]; + } + + } + cs = (int)_khmer_syllable_machine_cond_targs[_trans]; + + if ( _khmer_syllable_machine_cond_actions[_trans] != 0 ) { + + switch ( _khmer_syllable_machine_cond_actions[_trans] ) { + case 2: { + { #line 1 "NONE" - {te = p+1;} - break; - case 8: -#line 76 "hb-ot-shape-complex-khmer-machine.rl" - {te = p+1;{ found_syllable (non_khmer_cluster); }} - break; - case 10: -#line 74 "hb-ot-shape-complex-khmer-machine.rl" - {te = p;p--;{ found_syllable (consonant_syllable); }} - break; - case 12: -#line 75 "hb-ot-shape-complex-khmer-machine.rl" - {te = p;p--;{ found_syllable (broken_cluster); }} - break; - case 11: -#line 76 "hb-ot-shape-complex-khmer-machine.rl" - {te = p;p--;{ found_syllable (non_khmer_cluster); }} - break; - case 1: -#line 74 "hb-ot-shape-complex-khmer-machine.rl" - {{p = ((te))-1;}{ found_syllable (consonant_syllable); }} - break; - case 5: -#line 75 "hb-ot-shape-complex-khmer-machine.rl" - {{p = ((te))-1;}{ found_syllable (broken_cluster); }} - break; - case 3: + {te = p+1;}} + +#line 279 "hb-ot-shape-complex-khmer-machine.hh" + + + break; + } + case 8: { + { +#line 82 "hb-ot-shape-complex-khmer-machine.rl" + {te = p+1;{ +#line 82 "hb-ot-shape-complex-khmer-machine.rl" + found_syllable (khmer_non_khmer_cluster); } + }} + +#line 292 "hb-ot-shape-complex-khmer-machine.hh" + + + break; + } + case 10: { + { +#line 80 "hb-ot-shape-complex-khmer-machine.rl" + {te = p;p = p - 1;{ +#line 80 "hb-ot-shape-complex-khmer-machine.rl" + found_syllable (khmer_consonant_syllable); } + }} + +#line 305 "hb-ot-shape-complex-khmer-machine.hh" + + + break; + } + case 12: { + { +#line 81 "hb-ot-shape-complex-khmer-machine.rl" + {te = p;p = p - 1;{ +#line 81 "hb-ot-shape-complex-khmer-machine.rl" + found_syllable (khmer_broken_cluster); } + }} + +#line 318 "hb-ot-shape-complex-khmer-machine.hh" + + + break; + } + case 11: { + { +#line 82 "hb-ot-shape-complex-khmer-machine.rl" + {te = p;p = p - 1;{ +#line 82 "hb-ot-shape-complex-khmer-machine.rl" + found_syllable (khmer_non_khmer_cluster); } + }} + +#line 331 "hb-ot-shape-complex-khmer-machine.hh" + + + break; + } + case 1: { + { +#line 80 "hb-ot-shape-complex-khmer-machine.rl" + {p = ((te))-1; + { +#line 80 "hb-ot-shape-complex-khmer-machine.rl" + found_syllable (khmer_consonant_syllable); } + }} + +#line 345 "hb-ot-shape-complex-khmer-machine.hh" + + + break; + } + case 5: { + { +#line 81 "hb-ot-shape-complex-khmer-machine.rl" + {p = ((te))-1; + { +#line 81 "hb-ot-shape-complex-khmer-machine.rl" + found_syllable (khmer_broken_cluster); } + }} + +#line 359 "hb-ot-shape-complex-khmer-machine.hh" + + + break; + } + case 3: { + { #line 1 "NONE" - { switch( act ) { - case 2: - {{p = ((te))-1;} found_syllable (broken_cluster); } - break; - case 3: - {{p = ((te))-1;} found_syllable (non_khmer_cluster); } - break; - } - } - break; - case 4: + {switch( act ) { + case 2: { + p = ((te))-1; + { +#line 81 "hb-ot-shape-complex-khmer-machine.rl" + found_syllable (khmer_broken_cluster); } + break; + } + case 3: { + p = ((te))-1; + { +#line 82 "hb-ot-shape-complex-khmer-machine.rl" + found_syllable (khmer_non_khmer_cluster); } + break; + } + }} + } + +#line 385 "hb-ot-shape-complex-khmer-machine.hh" + + + break; + } + case 4: { + { #line 1 "NONE" - {te = p+1;} -#line 75 "hb-ot-shape-complex-khmer-machine.rl" - {act = 2;} - break; - case 9: + {te = p+1;}} + +#line 395 "hb-ot-shape-complex-khmer-machine.hh" + + { +#line 81 "hb-ot-shape-complex-khmer-machine.rl" + {act = 2;}} + +#line 401 "hb-ot-shape-complex-khmer-machine.hh" + + + break; + } + case 9: { + { #line 1 "NONE" - {te = p+1;} -#line 76 "hb-ot-shape-complex-khmer-machine.rl" - {act = 3;} - break; -#line 342 "hb-ot-shape-complex-khmer-machine.hh" - } - -_again: - switch ( _khmer_syllable_machine_to_state_actions[cs] ) { - case 6: + {te = p+1;}} + +#line 411 "hb-ot-shape-complex-khmer-machine.hh" + + { +#line 82 "hb-ot-shape-complex-khmer-machine.rl" + {act = 3;}} + +#line 417 "hb-ot-shape-complex-khmer-machine.hh" + + + break; + } + } + + } + + if ( p == eof ) { + if ( cs >= 20 ) + goto _out; + } + else { + switch ( _khmer_syllable_machine_to_state_actions[cs] ) { + case 6: { + { #line 1 "NONE" - {ts = 0;} - break; -#line 351 "hb-ot-shape-complex-khmer-machine.hh" - } - - if ( ++p != pe ) - goto _resume; - _test_eof: {} - if ( p == eof ) - { - if ( _khmer_syllable_machine_eof_trans[cs] > 0 ) { - _trans = _khmer_syllable_machine_eof_trans[cs] - 1; - goto _eof_trans; - } + {ts = 0;}} + +#line 437 "hb-ot-shape-complex-khmer-machine.hh" + + + break; + } + } + + p += 1; + goto _resume; + } + _out: {} } - - } - -#line 108 "hb-ot-shape-complex-khmer-machine.rl" - + +#line 114 "hb-ot-shape-complex-khmer-machine.rl" + } #undef found_syllable diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-khmer-machine.rl b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-khmer-machine.rl deleted file mode 100644 index e7f14533dd..0000000000 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-khmer-machine.rl +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright © 2011,2012 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ - -#ifndef HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH -#define HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH - -#include "hb.hh" - -%%{ - machine khmer_syllable_machine; - alphtype unsigned char; - write data; -}%% - -%%{ - -# Same order as enum khmer_category_t. Not sure how to avoid duplication. -C = 1; -V = 2; -ZWNJ = 5; -ZWJ = 6; -PLACEHOLDER = 11; -DOTTEDCIRCLE = 12; -Coeng= 14; -Ra = 16; -Robatic = 20; -Xgroup = 21; -Ygroup = 22; -VAbv = 26; -VBlw = 27; -VPre = 28; -VPst = 29; - -c = (C | Ra | V); -cn = c.((ZWJ|ZWNJ)?.Robatic)?; -joiner = (ZWJ | ZWNJ); -xgroup = (joiner*.Xgroup)*; -ygroup = Ygroup*; - -# This grammar was experimentally extracted from what Uniscribe allows. - -matra_group = VPre? xgroup VBlw? xgroup (joiner?.VAbv)? xgroup VPst?; -syllable_tail = xgroup matra_group xgroup (Coeng.c)? ygroup; - - -broken_cluster = (Coeng.cn)* (Coeng | syllable_tail); -consonant_syllable = (cn|PLACEHOLDER|DOTTEDCIRCLE) broken_cluster; -other = any; - -main := |* - consonant_syllable => { found_syllable (consonant_syllable); }; - broken_cluster => { found_syllable (broken_cluster); }; - other => { found_syllable (non_khmer_cluster); }; -*|; - - -}%% - -#define found_syllable(syllable_type) \ - HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ - for (unsigned int i = ts; i < te; i++) \ - info[i].syllable() = (syllable_serial << 4) | khmer_##syllable_type; \ - syllable_serial++; \ - if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ - } HB_STMT_END - -static void -find_syllables_khmer (hb_buffer_t *buffer) -{ - unsigned int p, pe, eof, ts, te, act HB_UNUSED; - int cs; - hb_glyph_info_t *info = buffer->info; - %%{ - write init; - getkey info[p].khmer_category(); - }%% - - p = 0; - pe = eof = buffer->len; - - unsigned int syllable_serial = 1; - %%{ - write exec; - }%% -} - -#undef found_syllable - -#endif /* HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-khmer.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-khmer.cc index fd8a9be978..dddba142a3 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-khmer.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-khmer.cc @@ -29,6 +29,7 @@ #ifndef HB_NO_OT_SHAPE #include "hb-ot-shape-complex-khmer.hh" +#include "hb-ot-shape-complex-khmer-machine.hh" #include "hb-ot-layout.hh" @@ -140,29 +141,6 @@ override_features_khmer (hb_ot_shape_planner_t *plan) struct khmer_shape_plan_t { - bool get_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const - { - hb_codepoint_t glyph = virama_glyph; - if (unlikely (virama_glyph == (hb_codepoint_t) -1)) - { - if (!font->get_nominal_glyph (0x17D2u, &glyph)) - glyph = 0; - /* Technically speaking, the spec says we should apply 'locl' to virama too. - * Maybe one day... */ - - /* Our get_nominal_glyph() function needs a font, so we can't get the virama glyph - * during shape planning... Instead, overwrite it here. It's safe. Don't worry! */ - virama_glyph = glyph; - } - - *pglyph = glyph; - return glyph != 0; - } - - mutable hb_codepoint_t virama_glyph; - - hb_indic_would_substitute_feature_t pref; - hb_mask_t mask_array[KHMER_NUM_FEATURES]; }; @@ -173,10 +151,6 @@ data_create_khmer (const hb_ot_shape_plan_t *plan) if (unlikely (!khmer_plan)) return nullptr; - khmer_plan->virama_glyph = (hb_codepoint_t) -1; - - khmer_plan->pref.init (&plan->map, HB_TAG('p','r','e','f'), true); - for (unsigned int i = 0; i < ARRAY_LENGTH (khmer_plan->mask_array); i++) khmer_plan->mask_array[i] = (khmer_features[i].flags & F_GLOBAL) ? 0 : plan->map.get_1_mask (khmer_features[i].tag); @@ -190,15 +164,6 @@ data_destroy_khmer (void *data) free (data); } - -enum khmer_syllable_type_t { - khmer_consonant_syllable, - khmer_broken_cluster, - khmer_non_khmer_cluster, -}; - -#include "hb-ot-shape-complex-khmer-machine.hh" - static void setup_masks_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_buffer_t *buffer, @@ -325,79 +290,22 @@ reorder_syllable_khmer (const hb_ot_shape_plan_t *plan, } } -static inline void -insert_dotted_circles_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_font_t *font, - hb_buffer_t *buffer) -{ - if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)) - return; - - /* Note: This loop is extra overhead, but should not be measurable. - * TODO Use a buffer scratch flag to remove the loop. */ - bool has_broken_syllables = false; - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 0; i < count; i++) - if ((info[i].syllable() & 0x0F) == khmer_broken_cluster) - { - has_broken_syllables = true; - break; - } - if (likely (!has_broken_syllables)) - return; - - - hb_codepoint_t dottedcircle_glyph; - if (!font->get_nominal_glyph (0x25CCu, &dottedcircle_glyph)) - return; - - hb_glyph_info_t dottedcircle = {0}; - dottedcircle.codepoint = 0x25CCu; - set_khmer_properties (dottedcircle); - dottedcircle.codepoint = dottedcircle_glyph; - - buffer->clear_output (); - - buffer->idx = 0; - unsigned int last_syllable = 0; - while (buffer->idx < buffer->len && buffer->successful) - { - unsigned int syllable = buffer->cur().syllable(); - khmer_syllable_type_t syllable_type = (khmer_syllable_type_t) (syllable & 0x0F); - if (unlikely (last_syllable != syllable && syllable_type == khmer_broken_cluster)) - { - last_syllable = syllable; - - hb_glyph_info_t ginfo = dottedcircle; - ginfo.cluster = buffer->cur().cluster; - ginfo.mask = buffer->cur().mask; - ginfo.syllable() = buffer->cur().syllable(); - - /* Insert dottedcircle after possible Repha. */ - while (buffer->idx < buffer->len && buffer->successful && - last_syllable == buffer->cur().syllable() && - buffer->cur().khmer_category() == OT_Repha) - buffer->next_glyph (); - - buffer->output_info (ginfo); - } - else - buffer->next_glyph (); - } - buffer->swap_buffers (); -} - static void reorder_khmer (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { - insert_dotted_circles_khmer (plan, font, buffer); - - foreach_syllable (buffer, start, end) - reorder_syllable_khmer (plan, font->face, buffer, start, end); - + if (buffer->message (font, "start reordering khmer")) + { + hb_syllabic_insert_dotted_circles (font, buffer, + khmer_broken_cluster, + OT_DOTTEDCIRCLE, + OT_Repha); + + foreach_syllable (buffer, start, end) + reorder_syllable_khmer (plan, font->face, buffer, start, end); + (void) buffer->message (font, "end reordering khmer"); + } HB_BUFFER_DEALLOCATE_VAR (buffer, khmer_category); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-khmer.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-khmer.hh index 11a77bfd4b..e24d68a8b5 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-khmer.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-khmer.hh @@ -54,7 +54,7 @@ set_khmer_properties (hb_glyph_info_t &info) { hb_codepoint_t u = info.codepoint; unsigned int type = hb_indic_get_categories (u); - khmer_category_t cat = (khmer_category_t) (type & 0x7Fu); + khmer_category_t cat = (khmer_category_t) (type & 0xFFu); indic_position_t pos = (indic_position_t) (type >> 8); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh index c2f4c0045c..c09497896d 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh @@ -31,8 +31,43 @@ #include "hb.hh" +enum myanmar_syllable_type_t { + myanmar_consonant_syllable, + myanmar_punctuation_cluster, + myanmar_broken_cluster, + myanmar_non_myanmar_cluster, +}; + -#line 36 "hb-ot-shape-complex-myanmar-machine.hh" +#line 43 "hb-ot-shape-complex-myanmar-machine.hh" +#define myanmar_syllable_machine_ex_A 10u +#define myanmar_syllable_machine_ex_As 18u +#define myanmar_syllable_machine_ex_C 1u +#define myanmar_syllable_machine_ex_CS 19u +#define myanmar_syllable_machine_ex_D 32u +#define myanmar_syllable_machine_ex_D0 20u +#define myanmar_syllable_machine_ex_DB 3u +#define myanmar_syllable_machine_ex_GB 11u +#define myanmar_syllable_machine_ex_H 4u +#define myanmar_syllable_machine_ex_IV 2u +#define myanmar_syllable_machine_ex_MH 21u +#define myanmar_syllable_machine_ex_MR 22u +#define myanmar_syllable_machine_ex_MW 23u +#define myanmar_syllable_machine_ex_MY 24u +#define myanmar_syllable_machine_ex_P 31u +#define myanmar_syllable_machine_ex_PT 25u +#define myanmar_syllable_machine_ex_Ra 16u +#define myanmar_syllable_machine_ex_V 8u +#define myanmar_syllable_machine_ex_VAbv 26u +#define myanmar_syllable_machine_ex_VBlw 27u +#define myanmar_syllable_machine_ex_VPre 28u +#define myanmar_syllable_machine_ex_VPst 29u +#define myanmar_syllable_machine_ex_VS 30u +#define myanmar_syllable_machine_ex_ZWJ 6u +#define myanmar_syllable_machine_ex_ZWNJ 5u + + +#line 71 "hb-ot-shape-complex-myanmar-machine.hh" static const unsigned char _myanmar_syllable_machine_trans_keys[] = { 1u, 32u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 16u, 3u, 29u, 3u, 29u, 3u, 29u, @@ -293,18 +328,18 @@ static const int myanmar_syllable_machine_error = -1; static const int myanmar_syllable_machine_en_main = 0; -#line 36 "hb-ot-shape-complex-myanmar-machine.rl" +#line 44 "hb-ot-shape-complex-myanmar-machine.rl" -#line 94 "hb-ot-shape-complex-myanmar-machine.rl" +#line 101 "hb-ot-shape-complex-myanmar-machine.rl" #define found_syllable(syllable_type) \ HB_STMT_START { \ if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ for (unsigned int i = ts; i < te; i++) \ - info[i].syllable() = (syllable_serial << 4) | myanmar_##syllable_type; \ + info[i].syllable() = (syllable_serial << 4) | syllable_type; \ syllable_serial++; \ if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ } HB_STMT_END @@ -316,7 +351,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 320 "hb-ot-shape-complex-myanmar-machine.hh" +#line 355 "hb-ot-shape-complex-myanmar-machine.hh" { cs = myanmar_syllable_machine_start; ts = 0; @@ -324,7 +359,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) act = 0; } -#line 114 "hb-ot-shape-complex-myanmar-machine.rl" +#line 121 "hb-ot-shape-complex-myanmar-machine.rl" p = 0; @@ -332,7 +367,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 336 "hb-ot-shape-complex-myanmar-machine.hh" +#line 371 "hb-ot-shape-complex-myanmar-machine.hh" { int _slen; int _trans; @@ -346,7 +381,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 350 "hb-ot-shape-complex-myanmar-machine.hh" +#line 385 "hb-ot-shape-complex-myanmar-machine.hh" } _keys = _myanmar_syllable_machine_trans_keys + (cs<<1); @@ -365,38 +400,38 @@ _eof_trans: switch ( _myanmar_syllable_machine_trans_actions[_trans] ) { case 6: -#line 86 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p+1;{ found_syllable (consonant_syllable); }} +#line 93 "hb-ot-shape-complex-myanmar-machine.rl" + {te = p+1;{ found_syllable (myanmar_consonant_syllable); }} break; case 4: -#line 87 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p+1;{ found_syllable (non_myanmar_cluster); }} +#line 94 "hb-ot-shape-complex-myanmar-machine.rl" + {te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }} break; case 10: -#line 88 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p+1;{ found_syllable (punctuation_cluster); }} +#line 95 "hb-ot-shape-complex-myanmar-machine.rl" + {te = p+1;{ found_syllable (myanmar_punctuation_cluster); }} break; case 8: -#line 89 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p+1;{ found_syllable (broken_cluster); }} +#line 96 "hb-ot-shape-complex-myanmar-machine.rl" + {te = p+1;{ found_syllable (myanmar_broken_cluster); }} break; case 3: -#line 90 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p+1;{ found_syllable (non_myanmar_cluster); }} +#line 97 "hb-ot-shape-complex-myanmar-machine.rl" + {te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }} break; case 5: -#line 86 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p;p--;{ found_syllable (consonant_syllable); }} +#line 93 "hb-ot-shape-complex-myanmar-machine.rl" + {te = p;p--;{ found_syllable (myanmar_consonant_syllable); }} break; case 7: -#line 89 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p;p--;{ found_syllable (broken_cluster); }} +#line 96 "hb-ot-shape-complex-myanmar-machine.rl" + {te = p;p--;{ found_syllable (myanmar_broken_cluster); }} break; case 9: -#line 90 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p;p--;{ found_syllable (non_myanmar_cluster); }} +#line 97 "hb-ot-shape-complex-myanmar-machine.rl" + {te = p;p--;{ found_syllable (myanmar_non_myanmar_cluster); }} break; -#line 400 "hb-ot-shape-complex-myanmar-machine.hh" +#line 435 "hb-ot-shape-complex-myanmar-machine.hh" } _again: @@ -405,7 +440,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 409 "hb-ot-shape-complex-myanmar-machine.hh" +#line 444 "hb-ot-shape-complex-myanmar-machine.hh" } if ( ++p != pe ) @@ -421,7 +456,7 @@ _again: } -#line 122 "hb-ot-shape-complex-myanmar-machine.rl" +#line 129 "hb-ot-shape-complex-myanmar-machine.rl" } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.rl b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.rl deleted file mode 100644 index 67133cd734..0000000000 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.rl +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright © 2011,2012 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ - -#ifndef HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH -#define HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH - -#include "hb.hh" - -%%{ - machine myanmar_syllable_machine; - alphtype unsigned char; - write data; -}%% - -%%{ - -# Same order as enum myanmar_category_t. Not sure how to avoid duplication. -A = 10; -As = 18; -C = 1; -D = 32; -D0 = 20; -DB = 3; -GB = 11; -H = 4; -IV = 2; -MH = 21; -MR = 22; -MW = 23; -MY = 24; -PT = 25; -V = 8; -VAbv = 26; -VBlw = 27; -VPre = 28; -VPst = 29; -VS = 30; -ZWJ = 6; -ZWNJ = 5; -Ra = 16; -P = 31; -CS = 19; - -j = ZWJ|ZWNJ; # Joiners -k = (Ra As H); # Kinzi - -c = C|Ra; # is_consonant - -medial_group = MY? As? MR? ((MW MH? | MH) As?)?; -main_vowel_group = (VPre.VS?)* VAbv* VBlw* A* (DB As?)?; -post_vowel_group = VPst MH? As* VAbv* A* (DB As?)?; -pwo_tone_group = PT A* DB? As?; - -complex_syllable_tail = As* medial_group main_vowel_group post_vowel_group* pwo_tone_group* V* j?; -syllable_tail = (H (c|IV).VS?)* (H | complex_syllable_tail); - -consonant_syllable = (k|CS)? (c|IV|D|GB).VS? syllable_tail; -punctuation_cluster = P V; -broken_cluster = k? VS? syllable_tail; -other = any; - -main := |* - consonant_syllable => { found_syllable (consonant_syllable); }; - j => { found_syllable (non_myanmar_cluster); }; - punctuation_cluster => { found_syllable (punctuation_cluster); }; - broken_cluster => { found_syllable (broken_cluster); }; - other => { found_syllable (non_myanmar_cluster); }; -*|; - - -}%% - -#define found_syllable(syllable_type) \ - HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ - for (unsigned int i = ts; i < te; i++) \ - info[i].syllable() = (syllable_serial << 4) | myanmar_##syllable_type; \ - syllable_serial++; \ - if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ - } HB_STMT_END - -static void -find_syllables_myanmar (hb_buffer_t *buffer) -{ - unsigned int p, pe, eof, ts, te, act HB_UNUSED; - int cs; - hb_glyph_info_t *info = buffer->info; - %%{ - write init; - getkey info[p].myanmar_category(); - }%% - - p = 0; - pe = eof = buffer->len; - - unsigned int syllable_serial = 1; - %%{ - write exec; - }%% -} - -#undef found_syllable - -#endif /* HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc index fc3490d716..bc5dcb904c 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc @@ -29,6 +29,7 @@ #ifndef HB_NO_OT_SHAPE #include "hb-ot-shape-complex-myanmar.hh" +#include "hb-ot-shape-complex-myanmar-machine.hh" /* @@ -98,23 +99,6 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan) } static void -override_features_myanmar (hb_ot_shape_planner_t *plan) -{ - plan->map.disable_feature (HB_TAG('l','i','g','a')); -} - - -enum myanmar_syllable_type_t { - myanmar_consonant_syllable, - myanmar_punctuation_cluster, - myanmar_broken_cluster, - myanmar_non_myanmar_cluster, -}; - -#include "hb-ot-shape-complex-myanmar-machine.hh" - - -static void setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_buffer_t *buffer, hb_font_t *font HB_UNUSED) @@ -271,72 +255,21 @@ reorder_syllable_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED, } } -static inline void -insert_dotted_circles_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_font_t *font, - hb_buffer_t *buffer) -{ - if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)) - return; - - /* Note: This loop is extra overhead, but should not be measurable. - * TODO Use a buffer scratch flag to remove the loop. */ - bool has_broken_syllables = false; - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 0; i < count; i++) - if ((info[i].syllable() & 0x0F) == myanmar_broken_cluster) - { - has_broken_syllables = true; - break; - } - if (likely (!has_broken_syllables)) - return; - - - hb_codepoint_t dottedcircle_glyph; - if (!font->get_nominal_glyph (0x25CCu, &dottedcircle_glyph)) - return; - - hb_glyph_info_t dottedcircle = {0}; - dottedcircle.codepoint = 0x25CCu; - set_myanmar_properties (dottedcircle); - dottedcircle.codepoint = dottedcircle_glyph; - - buffer->clear_output (); - - buffer->idx = 0; - unsigned int last_syllable = 0; - while (buffer->idx < buffer->len && buffer->successful) - { - unsigned int syllable = buffer->cur().syllable(); - myanmar_syllable_type_t syllable_type = (myanmar_syllable_type_t) (syllable & 0x0F); - if (unlikely (last_syllable != syllable && syllable_type == myanmar_broken_cluster)) - { - last_syllable = syllable; - - hb_glyph_info_t ginfo = dottedcircle; - ginfo.cluster = buffer->cur().cluster; - ginfo.mask = buffer->cur().mask; - ginfo.syllable() = buffer->cur().syllable(); - - buffer->output_info (ginfo); - } - else - buffer->next_glyph (); - } - buffer->swap_buffers (); -} - static void reorder_myanmar (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { - insert_dotted_circles_myanmar (plan, font, buffer); + if (buffer->message (font, "start reordering myanmar")) + { + hb_syllabic_insert_dotted_circles (font, buffer, + myanmar_broken_cluster, + OT_GB); - foreach_syllable (buffer, start, end) - reorder_syllable_myanmar (plan, font->face, buffer, start, end); + foreach_syllable (buffer, start, end) + reorder_syllable_myanmar (plan, font->face, buffer, start, end); + (void) buffer->message (font, "end reordering myanmar"); + } HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_category); HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_position); @@ -346,7 +279,7 @@ reorder_myanmar (const hb_ot_shape_plan_t *plan, const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar = { collect_features_myanmar, - override_features_myanmar, + nullptr, /* override_features */ nullptr, /* data_create */ nullptr, /* data_destroy */ nullptr, /* preprocess_text */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.hh index 7b9821e6ba..a6d68aae57 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.hh @@ -64,7 +64,7 @@ set_myanmar_properties (hb_glyph_info_t &info) { hb_codepoint_t u = info.codepoint; unsigned int type = hb_indic_get_categories (u); - unsigned int cat = type & 0x7Fu; + unsigned int cat = type & 0xFFu; indic_position_t pos = (indic_position_t) (type >> 8); /* Myanmar diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-syllabic.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-syllabic.cc new file mode 100644 index 0000000000..46509abee2 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-syllabic.cc @@ -0,0 +1,100 @@ +/* + * Copyright © 2021 Behdad Esfahbod. + * + * 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.hh" + +#ifndef HB_NO_OT_SHAPE + +#include "hb-ot-shape-complex-syllabic.hh" + + +void +hb_syllabic_insert_dotted_circles (hb_font_t *font, + hb_buffer_t *buffer, + unsigned int broken_syllable_type, + unsigned int dottedcircle_category, + int repha_category) +{ + if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)) + return; + + /* Note: This loop is extra overhead, but should not be measurable. + * TODO Use a buffer scratch flag to remove the loop. */ + bool has_broken_syllables = false; + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + for (unsigned int i = 0; i < count; i++) + if ((info[i].syllable() & 0x0F) == broken_syllable_type) + { + has_broken_syllables = true; + break; + } + if (likely (!has_broken_syllables)) + return; + + + hb_codepoint_t dottedcircle_glyph; + if (!font->get_nominal_glyph (0x25CCu, &dottedcircle_glyph)) + return; + + hb_glyph_info_t dottedcircle = {0}; + dottedcircle.codepoint = 0x25CCu; + dottedcircle.complex_var_u8_category() = dottedcircle_category; + dottedcircle.codepoint = dottedcircle_glyph; + + buffer->clear_output (); + + buffer->idx = 0; + unsigned int last_syllable = 0; + while (buffer->idx < buffer->len && buffer->successful) + { + unsigned int syllable = buffer->cur().syllable(); + if (unlikely (last_syllable != syllable && (syllable & 0x0F) == broken_syllable_type)) + { + last_syllable = syllable; + + hb_glyph_info_t ginfo = dottedcircle; + ginfo.cluster = buffer->cur().cluster; + ginfo.mask = buffer->cur().mask; + ginfo.syllable() = buffer->cur().syllable(); + + /* Insert dottedcircle after possible Repha. */ + if (repha_category != -1) + { + while (buffer->idx < buffer->len && buffer->successful && + last_syllable == buffer->cur().syllable() && + buffer->cur().complex_var_u8_category() == (unsigned) repha_category) + (void) buffer->next_glyph (); + } + + (void) buffer->output_info (ginfo); + } + else + (void) buffer->next_glyph (); + } + buffer->swap_buffers (); +} + + +#endif diff --git a/src/3rdparty/harfbuzz-ng/src/dump-khmer-data.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-syllabic.hh index cffbb92df7..c80b8fee1d 100644 --- a/src/3rdparty/harfbuzz-ng/src/dump-khmer-data.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-syllabic.hh @@ -1,5 +1,5 @@ /* - * Copyright © 2018 Google, Inc. + * Copyright © 2021 Behdad Esfahbod. * * This is part of HarfBuzz, a text shaping library. * @@ -20,22 +20,22 @@ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod */ -#include "hb-ot-shape-complex-khmer.hh" +#ifndef HB_OT_SHAPE_COMPLEX_SYLLABIC_HH +#define HB_OT_SHAPE_COMPLEX_SYLLABIC_HH + +#include "hb.hh" + +#include "hb-ot-shape-complex.hh" + + +HB_INTERNAL void +hb_syllabic_insert_dotted_circles (hb_font_t *font, + hb_buffer_t *buffer, + unsigned int broken_syllable_type, + unsigned int dottedcircle_category, + int repha_category = -1); + -int -main () -{ - for (hb_codepoint_t u = 0; u <= 0x10FFFF; u++) - { - hb_glyph_info_t info; - info.codepoint = u; - set_khmer_properties (info); - if (info.khmer_category() != INDIC_SYLLABIC_CATEGORY_OTHER) - printf("U+%04X %u\n", u, - info.khmer_category()); - } -} +#endif /* HB_OT_SHAPE_COMPLEX_SYLLABIC_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc index 347ea2e7ac..4c3068173b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc @@ -323,20 +323,19 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan, buffer->clear_output (); unsigned int count = buffer->len; - for (buffer->idx = 0; buffer->idx < count && buffer->successful;) + for (buffer->idx = 0; buffer->idx < count /* No need for: && buffer->successful */;) { hb_codepoint_t u = buffer->cur().codepoint; - if (likely (!IS_SARA_AM (u))) { - buffer->next_glyph (); + if (likely (!IS_SARA_AM (u))) + { + if (unlikely (!buffer->next_glyph ())) break; continue; } /* Is SARA AM. Decompose and reorder. */ - hb_glyph_info_t &nikhahit = buffer->output_glyph (NIKHAHIT_FROM_SARA_AM (u)); - _hb_glyph_info_set_continuation (&nikhahit); - buffer->replace_glyph (SARA_AA_FROM_SARA_AM (u)); - if (unlikely (!buffer->successful)) - return; + (void) buffer->output_glyph (NIKHAHIT_FROM_SARA_AM (u)); + _hb_glyph_info_set_continuation (&buffer->prev()); + if (unlikely (!buffer->replace_glyph (SARA_AA_FROM_SARA_AM (u)))) break; /* Make Nikhahit be recognized as a ccc=0 mark when zeroing widths. */ unsigned int end = buffer->out_len; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-machine.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-machine.hh index 462342c618..b4b2b75100 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-machine.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-machine.hh @@ -1,560 +1,727 @@ - #line 1 "hb-ot-shape-complex-use-machine.rl" /* - * Copyright © 2015 Mozilla Foundation. - * Copyright © 2015 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. - * - * Mozilla Author(s): Jonathan Kew - * Google Author(s): Behdad Esfahbod - */ +* Copyright © 2015 Mozilla Foundation. +* Copyright © 2015 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. +* +* Mozilla Author(s): Jonathan Kew +* Google Author(s): Behdad Esfahbod +*/ #ifndef HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH #define HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH #include "hb.hh" +#include "hb-ot-shape-complex-syllabic.hh" + +/* buffer var allocations */ +#define use_category() complex_var_u8_category() + +#define USE(Cat) use_syllable_machine_ex_##Cat + +enum use_syllable_type_t { + use_independent_cluster, + use_virama_terminated_cluster, + use_sakot_terminated_cluster, + use_standard_cluster, + use_number_joiner_terminated_cluster, + use_numeral_cluster, + use_symbol_cluster, + use_hieroglyph_cluster, + use_broken_cluster, + use_non_cluster, +}; + -#line 38 "hb-ot-shape-complex-use-machine.hh" +#line 57 "hb-ot-shape-complex-use-machine.hh" +#define use_syllable_machine_ex_B 1u +#define use_syllable_machine_ex_CMAbv 31u +#define use_syllable_machine_ex_CMBlw 32u +#define use_syllable_machine_ex_CS 43u +#define use_syllable_machine_ex_FAbv 24u +#define use_syllable_machine_ex_FBlw 25u +#define use_syllable_machine_ex_FMAbv 45u +#define use_syllable_machine_ex_FMBlw 46u +#define use_syllable_machine_ex_FMPst 47u +#define use_syllable_machine_ex_FPst 26u +#define use_syllable_machine_ex_G 49u +#define use_syllable_machine_ex_GB 5u +#define use_syllable_machine_ex_H 12u +#define use_syllable_machine_ex_HN 13u +#define use_syllable_machine_ex_HVM 44u +#define use_syllable_machine_ex_J 50u +#define use_syllable_machine_ex_MAbv 27u +#define use_syllable_machine_ex_MBlw 28u +#define use_syllable_machine_ex_MPre 30u +#define use_syllable_machine_ex_MPst 29u +#define use_syllable_machine_ex_N 4u +#define use_syllable_machine_ex_O 0u +#define use_syllable_machine_ex_R 18u +#define use_syllable_machine_ex_S 19u +#define use_syllable_machine_ex_SB 51u +#define use_syllable_machine_ex_SE 52u +#define use_syllable_machine_ex_SMAbv 41u +#define use_syllable_machine_ex_SMBlw 42u +#define use_syllable_machine_ex_SUB 11u +#define use_syllable_machine_ex_Sk 48u +#define use_syllable_machine_ex_VAbv 33u +#define use_syllable_machine_ex_VBlw 34u +#define use_syllable_machine_ex_VMAbv 37u +#define use_syllable_machine_ex_VMBlw 38u +#define use_syllable_machine_ex_VMPre 23u +#define use_syllable_machine_ex_VMPst 39u +#define use_syllable_machine_ex_VPre 22u +#define use_syllable_machine_ex_VPst 35u +#define use_syllable_machine_ex_ZWNJ 14u + + +#line 99 "hb-ot-shape-complex-use-machine.hh" static const unsigned char _use_syllable_machine_trans_keys[] = { - 12u, 48u, 1u, 15u, 1u, 1u, 12u, 48u, 1u, 1u, 0u, 48u, 21u, 21u, 11u, 48u, - 11u, 48u, 1u, 15u, 1u, 1u, 11u, 48u, 22u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, - 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u, 1u, 1u, 24u, 48u, - 23u, 48u, 23u, 48u, 23u, 48u, 22u, 48u, 22u, 48u, 22u, 48u, 22u, 48u, 11u, 48u, - 1u, 48u, 11u, 48u, 13u, 21u, 4u, 4u, 13u, 13u, 11u, 48u, 11u, 48u, 41u, 42u, - 42u, 42u, 11u, 48u, 11u, 48u, 22u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, - 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u, 24u, 48u, 23u, 48u, 23u, 48u, - 23u, 48u, 22u, 48u, 22u, 48u, 22u, 48u, 22u, 48u, 11u, 48u, 1u, 48u, 1u, 15u, - 4u, 4u, 13u, 21u, 13u, 13u, 12u, 48u, 1u, 48u, 11u, 48u, 41u, 42u, 42u, 42u, - 21u, 42u, 1u, 5u, 0 + 1u, 1u, 1u, 1u, 0u, 37u, 5u, 34u, + 5u, 34u, 1u, 1u, 10u, 34u, 11u, 34u, + 12u, 33u, 13u, 33u, 14u, 33u, 31u, 32u, + 32u, 32u, 12u, 34u, 12u, 34u, 12u, 34u, + 1u, 1u, 12u, 34u, 11u, 34u, 11u, 34u, + 11u, 34u, 10u, 34u, 10u, 34u, 10u, 34u, + 5u, 34u, 1u, 34u, 7u, 7u, 3u, 3u, + 5u, 34u, 27u, 28u, 28u, 28u, 5u, 34u, + 10u, 34u, 11u, 34u, 12u, 33u, 13u, 33u, + 14u, 33u, 31u, 32u, 32u, 32u, 12u, 34u, + 12u, 34u, 12u, 34u, 12u, 34u, 11u, 34u, + 11u, 34u, 11u, 34u, 10u, 34u, 10u, 34u, + 10u, 34u, 5u, 34u, 1u, 34u, 1u, 1u, + 3u, 3u, 7u, 7u, 1u, 34u, 5u, 34u, + 27u, 28u, 28u, 28u, 1u, 4u, 36u, 38u, + 35u, 38u, 35u, 37u, 0u }; -static const char _use_syllable_machine_key_spans[] = { - 37, 15, 1, 37, 1, 49, 1, 38, - 38, 15, 1, 38, 27, 26, 24, 23, - 22, 2, 1, 25, 25, 25, 1, 25, - 26, 26, 26, 27, 27, 27, 27, 38, - 48, 38, 9, 1, 1, 38, 38, 2, - 1, 38, 38, 27, 26, 24, 23, 22, - 2, 1, 25, 25, 25, 25, 26, 26, - 26, 27, 27, 27, 27, 38, 48, 15, - 1, 9, 1, 37, 48, 38, 2, 1, - 22, 5 +static const signed char _use_syllable_machine_char_class[] = { + 0, 1, 2, 2, 3, 4, 2, 2, + 2, 2, 2, 5, 6, 7, 2, 2, + 2, 2, 8, 9, 2, 2, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 2, 24, 25, 26, + 2, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 0 }; static const short _use_syllable_machine_index_offsets[] = { - 0, 38, 54, 56, 94, 96, 146, 148, - 187, 226, 242, 244, 283, 311, 338, 363, - 387, 410, 413, 415, 441, 467, 493, 495, - 521, 548, 575, 602, 630, 658, 686, 714, - 753, 802, 841, 851, 853, 855, 894, 933, - 936, 938, 977, 1016, 1044, 1071, 1096, 1120, - 1143, 1146, 1148, 1174, 1200, 1226, 1252, 1279, - 1306, 1333, 1361, 1389, 1417, 1445, 1484, 1533, - 1549, 1551, 1561, 1563, 1601, 1650, 1689, 1692, - 1694, 1717 + 0, 1, 2, 40, 70, 100, 101, 126, + 150, 172, 193, 213, 215, 216, 239, 262, + 285, 286, 309, 333, 357, 381, 406, 431, + 456, 486, 520, 521, 522, 552, 554, 555, + 585, 610, 634, 656, 677, 697, 699, 700, + 723, 746, 769, 792, 816, 840, 864, 889, + 914, 939, 969, 1003, 1004, 1005, 1006, 1040, + 1070, 1072, 1073, 1077, 1080, 1084, 0 +}; + +static const signed char _use_syllable_machine_indicies[] = { + 1, 2, 4, 5, 6, 7, 8, 1, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 13, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 9, 36, 6, 37, + 39, 40, 38, 38, 38, 41, 42, 43, + 44, 45, 46, 47, 41, 48, 5, 49, + 50, 51, 52, 53, 54, 55, 38, 38, + 38, 56, 57, 58, 59, 40, 39, 40, + 38, 38, 38, 41, 42, 43, 44, 45, + 46, 47, 41, 48, 49, 49, 50, 51, + 52, 53, 54, 55, 38, 38, 38, 56, + 57, 58, 59, 40, 39, 41, 42, 43, + 44, 45, 38, 38, 38, 38, 38, 38, + 50, 51, 52, 53, 54, 55, 38, 38, + 38, 42, 57, 58, 59, 61, 42, 43, + 44, 45, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 53, 54, 55, 38, 38, + 38, 38, 57, 58, 59, 61, 43, 44, + 45, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 57, 58, 59, 44, 45, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 57, 58, + 59, 45, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 57, 58, 59, 57, 58, 58, + 43, 44, 45, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 53, 54, 55, 38, + 38, 38, 38, 57, 58, 59, 61, 43, + 44, 45, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 54, 55, 38, 38, + 38, 38, 57, 58, 59, 61, 43, 44, + 45, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 55, 38, 38, 38, + 38, 57, 58, 59, 61, 63, 43, 44, + 45, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 57, 58, 59, 61, 42, 43, 44, + 45, 38, 38, 38, 38, 38, 38, 50, + 51, 52, 53, 54, 55, 38, 38, 38, + 42, 57, 58, 59, 61, 42, 43, 44, + 45, 38, 38, 38, 38, 38, 38, 38, + 51, 52, 53, 54, 55, 38, 38, 38, + 42, 57, 58, 59, 61, 42, 43, 44, + 45, 38, 38, 38, 38, 38, 38, 38, + 38, 52, 53, 54, 55, 38, 38, 38, + 42, 57, 58, 59, 61, 41, 42, 43, + 44, 45, 38, 47, 41, 38, 38, 38, + 50, 51, 52, 53, 54, 55, 38, 38, + 38, 42, 57, 58, 59, 61, 41, 42, + 43, 44, 45, 38, 38, 41, 38, 38, + 38, 50, 51, 52, 53, 54, 55, 38, + 38, 38, 42, 57, 58, 59, 61, 41, + 42, 43, 44, 45, 46, 47, 41, 38, + 38, 38, 50, 51, 52, 53, 54, 55, + 38, 38, 38, 42, 57, 58, 59, 61, + 39, 40, 38, 38, 38, 41, 42, 43, + 44, 45, 46, 47, 41, 48, 38, 49, + 50, 51, 52, 53, 54, 55, 38, 38, + 38, 56, 57, 58, 59, 40, 39, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 42, 43, 44, 45, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 53, 54, 55, + 60, 60, 60, 60, 57, 58, 59, 61, + 65, 7, 39, 40, 38, 38, 38, 41, + 42, 43, 44, 45, 46, 47, 41, 48, + 5, 49, 50, 51, 52, 53, 54, 55, + 12, 67, 38, 56, 57, 58, 59, 40, + 12, 67, 67, 1, 70, 69, 69, 69, + 13, 14, 15, 16, 17, 18, 19, 13, + 20, 22, 22, 23, 24, 25, 26, 27, + 28, 69, 69, 69, 32, 33, 34, 35, + 70, 13, 14, 15, 16, 17, 69, 69, + 69, 69, 69, 69, 23, 24, 25, 26, + 27, 28, 69, 69, 69, 14, 33, 34, + 35, 71, 14, 15, 16, 17, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 26, + 27, 28, 69, 69, 69, 69, 33, 34, + 35, 71, 15, 16, 17, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 33, 34, 35, + 16, 17, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 33, 34, 35, 17, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 33, 34, + 35, 33, 34, 34, 15, 16, 17, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 26, 27, 28, 69, 69, 69, 69, 33, + 34, 35, 71, 15, 16, 17, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 27, 28, 69, 69, 69, 69, 33, 34, + 35, 71, 15, 16, 17, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 28, 69, 69, 69, 69, 33, 34, 35, + 71, 15, 16, 17, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 33, 34, 35, 71, + 14, 15, 16, 17, 69, 69, 69, 69, + 69, 69, 23, 24, 25, 26, 27, 28, + 69, 69, 69, 14, 33, 34, 35, 71, + 14, 15, 16, 17, 69, 69, 69, 69, + 69, 69, 69, 24, 25, 26, 27, 28, + 69, 69, 69, 14, 33, 34, 35, 71, + 14, 15, 16, 17, 69, 69, 69, 69, + 69, 69, 69, 69, 25, 26, 27, 28, + 69, 69, 69, 14, 33, 34, 35, 71, + 13, 14, 15, 16, 17, 69, 19, 13, + 69, 69, 69, 23, 24, 25, 26, 27, + 28, 69, 69, 69, 14, 33, 34, 35, + 71, 13, 14, 15, 16, 17, 69, 69, + 13, 69, 69, 69, 23, 24, 25, 26, + 27, 28, 69, 69, 69, 14, 33, 34, + 35, 71, 13, 14, 15, 16, 17, 18, + 19, 13, 69, 69, 69, 23, 24, 25, + 26, 27, 28, 69, 69, 69, 14, 33, + 34, 35, 71, 1, 70, 69, 69, 69, + 13, 14, 15, 16, 17, 18, 19, 13, + 20, 69, 22, 23, 24, 25, 26, 27, + 28, 69, 69, 69, 32, 33, 34, 35, + 70, 1, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 14, 15, 16, 17, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 26, 27, 28, 69, 69, 69, 69, 33, + 34, 35, 71, 1, 73, 10, 5, 69, + 69, 5, 1, 70, 10, 69, 69, 13, + 14, 15, 16, 17, 18, 19, 13, 20, + 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 69, 32, 33, 34, 35, 70, + 1, 70, 69, 69, 69, 13, 14, 15, + 16, 17, 18, 19, 13, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 69, 69, + 69, 32, 33, 34, 35, 70, 29, 30, + 30, 5, 72, 72, 5, 75, 74, 36, + 36, 75, 74, 75, 36, 74, 37, 0 }; -static const char _use_syllable_machine_indicies[] = { - 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 1, 0, 3, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 4, 2, 3, 2, - 6, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 6, 5, 5, 5, 6, 5, 7, 5, - 8, 9, 10, 8, 11, 12, 10, 10, - 10, 10, 10, 3, 13, 14, 10, 15, - 8, 8, 16, 17, 10, 10, 18, 19, - 20, 21, 22, 23, 24, 18, 25, 26, - 27, 28, 29, 30, 10, 31, 32, 33, - 10, 34, 35, 36, 37, 38, 39, 40, - 13, 10, 42, 41, 44, 1, 43, 43, - 45, 43, 43, 43, 43, 43, 46, 47, - 48, 49, 50, 51, 52, 53, 47, 54, - 46, 55, 56, 57, 58, 43, 59, 60, - 61, 43, 43, 43, 43, 62, 63, 64, - 65, 1, 43, 44, 1, 43, 43, 45, - 43, 43, 43, 43, 43, 66, 47, 48, - 49, 50, 51, 52, 53, 47, 54, 55, - 55, 56, 57, 58, 43, 59, 60, 61, - 43, 43, 43, 43, 62, 63, 64, 65, - 1, 43, 44, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 68, 67, 44, 67, 44, 1, 43, 43, - 45, 43, 43, 43, 43, 43, 43, 47, - 48, 49, 50, 51, 52, 53, 47, 54, - 55, 55, 56, 57, 58, 43, 59, 60, - 61, 43, 43, 43, 43, 62, 63, 64, - 65, 1, 43, 47, 48, 49, 50, 51, - 43, 43, 43, 43, 43, 43, 56, 57, - 58, 43, 59, 60, 61, 43, 43, 43, - 43, 48, 63, 64, 65, 69, 43, 48, - 49, 50, 51, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 59, 60, 61, - 43, 43, 43, 43, 43, 63, 64, 65, - 69, 43, 49, 50, 51, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 63, - 64, 65, 43, 50, 51, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 63, - 64, 65, 43, 51, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 63, 64, - 65, 43, 63, 64, 43, 64, 43, 49, - 50, 51, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 59, 60, 61, 43, - 43, 43, 43, 43, 63, 64, 65, 69, - 43, 49, 50, 51, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 60, - 61, 43, 43, 43, 43, 43, 63, 64, - 65, 69, 43, 49, 50, 51, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 61, 43, 43, 43, 43, 43, - 63, 64, 65, 69, 43, 71, 70, 49, - 50, 51, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 63, 64, 65, 69, - 43, 48, 49, 50, 51, 43, 43, 43, - 43, 43, 43, 56, 57, 58, 43, 59, - 60, 61, 43, 43, 43, 43, 48, 63, - 64, 65, 69, 43, 48, 49, 50, 51, - 43, 43, 43, 43, 43, 43, 43, 57, - 58, 43, 59, 60, 61, 43, 43, 43, - 43, 48, 63, 64, 65, 69, 43, 48, - 49, 50, 51, 43, 43, 43, 43, 43, - 43, 43, 43, 58, 43, 59, 60, 61, - 43, 43, 43, 43, 48, 63, 64, 65, - 69, 43, 47, 48, 49, 50, 51, 43, - 53, 47, 43, 43, 43, 56, 57, 58, - 43, 59, 60, 61, 43, 43, 43, 43, - 48, 63, 64, 65, 69, 43, 47, 48, - 49, 50, 51, 43, 72, 47, 43, 43, - 43, 56, 57, 58, 43, 59, 60, 61, - 43, 43, 43, 43, 48, 63, 64, 65, - 69, 43, 47, 48, 49, 50, 51, 43, - 43, 47, 43, 43, 43, 56, 57, 58, - 43, 59, 60, 61, 43, 43, 43, 43, - 48, 63, 64, 65, 69, 43, 47, 48, - 49, 50, 51, 52, 53, 47, 43, 43, - 43, 56, 57, 58, 43, 59, 60, 61, - 43, 43, 43, 43, 48, 63, 64, 65, - 69, 43, 44, 1, 43, 43, 45, 43, - 43, 43, 43, 43, 43, 47, 48, 49, - 50, 51, 52, 53, 47, 54, 43, 55, - 56, 57, 58, 43, 59, 60, 61, 43, - 43, 43, 43, 62, 63, 64, 65, 1, - 43, 44, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 68, - 67, 67, 67, 67, 67, 67, 67, 48, - 49, 50, 51, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 59, 60, 61, - 67, 67, 67, 67, 67, 63, 64, 65, - 69, 67, 44, 1, 43, 43, 45, 43, - 43, 43, 43, 43, 43, 47, 48, 49, - 50, 51, 52, 53, 47, 54, 46, 55, - 56, 57, 58, 43, 59, 60, 61, 43, - 43, 43, 43, 62, 63, 64, 65, 1, - 43, 74, 73, 73, 73, 73, 73, 73, - 73, 75, 73, 11, 76, 74, 73, 44, - 1, 43, 43, 45, 43, 43, 43, 43, - 43, 77, 47, 48, 49, 50, 51, 52, - 53, 47, 54, 46, 55, 56, 57, 58, - 43, 59, 60, 61, 43, 78, 79, 43, - 62, 63, 64, 65, 1, 43, 44, 1, - 43, 43, 45, 43, 43, 43, 43, 43, - 43, 47, 48, 49, 50, 51, 52, 53, - 47, 54, 46, 55, 56, 57, 58, 43, - 59, 60, 61, 43, 78, 79, 43, 62, - 63, 64, 65, 1, 43, 78, 79, 80, - 79, 80, 3, 6, 81, 81, 82, 81, - 81, 81, 81, 81, 83, 18, 19, 20, - 21, 22, 23, 24, 18, 25, 27, 27, - 28, 29, 30, 81, 31, 32, 33, 81, - 81, 81, 81, 37, 38, 39, 40, 6, - 81, 3, 6, 81, 81, 82, 81, 81, - 81, 81, 81, 81, 18, 19, 20, 21, - 22, 23, 24, 18, 25, 27, 27, 28, - 29, 30, 81, 31, 32, 33, 81, 81, - 81, 81, 37, 38, 39, 40, 6, 81, - 18, 19, 20, 21, 22, 81, 81, 81, - 81, 81, 81, 28, 29, 30, 81, 31, - 32, 33, 81, 81, 81, 81, 19, 38, - 39, 40, 84, 81, 19, 20, 21, 22, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 31, 32, 33, 81, 81, 81, - 81, 81, 38, 39, 40, 84, 81, 20, - 21, 22, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 38, 39, 40, 81, - 21, 22, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 38, 39, 40, 81, - 22, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 38, 39, 40, 81, 38, - 39, 81, 39, 81, 20, 21, 22, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 31, 32, 33, 81, 81, 81, 81, - 81, 38, 39, 40, 84, 81, 20, 21, - 22, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 32, 33, 81, 81, - 81, 81, 81, 38, 39, 40, 84, 81, - 20, 21, 22, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 33, - 81, 81, 81, 81, 81, 38, 39, 40, - 84, 81, 20, 21, 22, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 38, - 39, 40, 84, 81, 19, 20, 21, 22, - 81, 81, 81, 81, 81, 81, 28, 29, - 30, 81, 31, 32, 33, 81, 81, 81, - 81, 19, 38, 39, 40, 84, 81, 19, - 20, 21, 22, 81, 81, 81, 81, 81, - 81, 81, 29, 30, 81, 31, 32, 33, - 81, 81, 81, 81, 19, 38, 39, 40, - 84, 81, 19, 20, 21, 22, 81, 81, - 81, 81, 81, 81, 81, 81, 30, 81, - 31, 32, 33, 81, 81, 81, 81, 19, - 38, 39, 40, 84, 81, 18, 19, 20, - 21, 22, 81, 24, 18, 81, 81, 81, - 28, 29, 30, 81, 31, 32, 33, 81, - 81, 81, 81, 19, 38, 39, 40, 84, - 81, 18, 19, 20, 21, 22, 81, 85, - 18, 81, 81, 81, 28, 29, 30, 81, - 31, 32, 33, 81, 81, 81, 81, 19, - 38, 39, 40, 84, 81, 18, 19, 20, - 21, 22, 81, 81, 18, 81, 81, 81, - 28, 29, 30, 81, 31, 32, 33, 81, - 81, 81, 81, 19, 38, 39, 40, 84, - 81, 18, 19, 20, 21, 22, 23, 24, - 18, 81, 81, 81, 28, 29, 30, 81, - 31, 32, 33, 81, 81, 81, 81, 19, - 38, 39, 40, 84, 81, 3, 6, 81, - 81, 82, 81, 81, 81, 81, 81, 81, - 18, 19, 20, 21, 22, 23, 24, 18, - 25, 81, 27, 28, 29, 30, 81, 31, - 32, 33, 81, 81, 81, 81, 37, 38, - 39, 40, 6, 81, 3, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 4, 81, 81, 81, 81, 81, - 81, 81, 19, 20, 21, 22, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 31, 32, 33, 81, 81, 81, 81, 81, - 38, 39, 40, 84, 81, 3, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 4, 86, 87, 81, 14, - 81, 81, 81, 81, 81, 81, 81, 88, - 81, 14, 81, 6, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 6, 86, 86, 86, 6, - 86, 9, 81, 81, 81, 9, 81, 81, - 81, 81, 81, 3, 6, 14, 81, 82, - 81, 81, 81, 81, 81, 81, 18, 19, - 20, 21, 22, 23, 24, 18, 25, 26, - 27, 28, 29, 30, 81, 31, 32, 33, - 81, 34, 35, 81, 37, 38, 39, 40, - 6, 81, 3, 6, 81, 81, 82, 81, - 81, 81, 81, 81, 81, 18, 19, 20, - 21, 22, 23, 24, 18, 25, 26, 27, - 28, 29, 30, 81, 31, 32, 33, 81, - 81, 81, 81, 37, 38, 39, 40, 6, - 81, 34, 35, 81, 35, 81, 78, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 78, 79, 80, 9, 86, 86, - 86, 9, 86, 0 +static const signed char _use_syllable_machine_index_defaults[] = { + 0, 0, 6, 38, 38, 60, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 62, 38, 38, 38, 38, 38, 38, 38, + 38, 60, 64, 66, 38, 68, 68, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 72, 69, 69, 69, 69, + 69, 69, 72, 74, 74, 74, 0 }; -static const char _use_syllable_machine_trans_targs[] = { - 5, 9, 5, 41, 2, 5, 1, 53, - 6, 7, 5, 34, 37, 63, 64, 67, - 68, 72, 43, 44, 45, 46, 47, 57, - 58, 60, 69, 61, 54, 55, 56, 50, - 51, 52, 70, 71, 73, 62, 48, 49, - 5, 5, 5, 5, 8, 0, 33, 12, - 13, 14, 15, 16, 27, 28, 30, 31, - 24, 25, 26, 19, 20, 21, 32, 17, - 18, 5, 11, 5, 10, 22, 5, 23, - 29, 5, 35, 36, 5, 38, 39, 40, - 5, 5, 3, 42, 4, 59, 5, 65, - 66 +static const signed char _use_syllable_machine_cond_targs[] = { + 2, 31, 42, 2, 2, 3, 2, 26, + 28, 51, 52, 54, 29, 32, 33, 34, + 35, 36, 46, 47, 48, 55, 49, 43, + 44, 45, 39, 40, 41, 56, 57, 58, + 50, 37, 38, 2, 59, 61, 2, 4, + 5, 6, 7, 8, 9, 10, 21, 22, + 23, 24, 18, 19, 20, 13, 14, 15, + 25, 11, 12, 2, 2, 16, 2, 17, + 2, 27, 2, 30, 2, 2, 0, 1, + 2, 53, 2, 60, 0 }; -static const char _use_syllable_machine_trans_actions[] = { - 1, 0, 2, 3, 0, 4, 0, 5, - 0, 5, 8, 0, 5, 9, 0, 9, - 3, 0, 5, 5, 0, 0, 0, 5, - 5, 5, 3, 3, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 3, 0, 0, - 10, 11, 12, 13, 5, 0, 5, 0, - 0, 0, 0, 0, 0, 0, 0, 5, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 14, 5, 15, 0, 0, 16, 0, - 0, 17, 0, 0, 18, 5, 0, 0, - 19, 20, 0, 3, 0, 5, 21, 0, - 0 +static const signed char _use_syllable_machine_cond_actions[] = { + 1, 2, 2, 0, 5, 0, 6, 0, + 0, 0, 0, 2, 0, 2, 2, 0, + 0, 0, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 0, 0, 0, + 2, 0, 0, 7, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 10, 0, 11, 0, + 12, 0, 13, 0, 14, 15, 0, 0, + 16, 0, 17, 0, 0 }; -static const char _use_syllable_machine_to_state_actions[] = { - 0, 0, 0, 0, 0, 6, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0 +static const signed char _use_syllable_machine_to_state_actions[] = { + 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0 }; -static const char _use_syllable_machine_from_state_actions[] = { - 0, 0, 0, 0, 0, 7, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0 +static const signed char _use_syllable_machine_from_state_actions[] = { + 0, 0, 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0 }; -static const short _use_syllable_machine_eof_trans[] = { - 1, 3, 3, 6, 6, 0, 42, 44, - 44, 68, 68, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 71, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 68, 44, 74, 77, 74, 44, 44, 81, - 81, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 87, - 82, 82, 82, 87, 82, 82, 82, 82, - 81, 87 +static const signed char _use_syllable_machine_eof_trans[] = { + 1, 1, 4, 39, 39, 61, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 63, 39, 39, 39, 39, 39, 39, 39, + 39, 61, 65, 67, 39, 69, 69, 70, + 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 73, 70, 70, 70, 70, + 70, 70, 73, 75, 75, 75, 0 }; -static const int use_syllable_machine_start = 5; -static const int use_syllable_machine_first_final = 5; +static const int use_syllable_machine_start = 2; +static const int use_syllable_machine_first_final = 2; static const int use_syllable_machine_error = -1; -static const int use_syllable_machine_en_main = 5; +static const int use_syllable_machine_en_main = 2; -#line 38 "hb-ot-shape-complex-use-machine.rl" +#line 59 "hb-ot-shape-complex-use-machine.rl" -#line 162 "hb-ot-shape-complex-use-machine.rl" +#line 176 "hb-ot-shape-complex-use-machine.rl" #define found_syllable(syllable_type) \ - HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ - for (unsigned int i = ts; i < te; i++) \ - info[i].syllable() = (syllable_serial << 4) | use_##syllable_type; \ - syllable_serial++; \ - if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ - } HB_STMT_END - -static void -find_syllables_use (hb_buffer_t *buffer) +HB_STMT_START { \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", (*ts).second.first, (*te).second.first, #syllable_type); \ + for (unsigned i = (*ts).second.first; i < (*te).second.first; ++i) \ + info[i].syllable() = (syllable_serial << 4) | syllable_type; \ + syllable_serial++; \ + if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ + } HB_STMT_END + + +template <typename Iter> +struct machine_index_t : +hb_iter_with_fallback_t<machine_index_t<Iter>, +typename Iter::item_t> { - unsigned int p, pe, eof, ts, te, act; - int cs; - hb_glyph_info_t *info = buffer->info; - -#line 396 "hb-ot-shape-complex-use-machine.hh" - { - cs = use_syllable_machine_start; - ts = 0; - te = 0; - act = 0; - } + machine_index_t (const Iter& it) : it (it) {} + machine_index_t (const machine_index_t& o) : it (o.it) {} + + static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator; + static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator; + + typename Iter::item_t __item__ () const { return *it; } + typename Iter::item_t __item_at__ (unsigned i) const { return it[i]; } + unsigned __len__ () const { return it.len (); } + void __next__ () { ++it; } + void __forward__ (unsigned n) { it += n; } + void __prev__ () { --it; } + void __rewind__ (unsigned n) { it -= n; } + void operator = (unsigned n) + { unsigned index = (*it).first; if (index < n) it += n - index; else if (index > n) it -= index - n; } + void operator = (const machine_index_t& o) { *this = (*o.it).first; } + bool operator == (const machine_index_t& o) const { return (*it).first == (*o.it).first; } + bool operator != (const machine_index_t& o) const { return !(*this == o); } + + private: + Iter it; +}; +struct +{ + template <typename Iter, + hb_requires (hb_is_iterable (Iter))> + machine_index_t<hb_iter_type<Iter>> + operator () (Iter&& it) const + { return machine_index_t<hb_iter_type<Iter>> (hb_iter (it)); } +} +HB_FUNCOBJ (machine_index); -#line 182 "hb-ot-shape-complex-use-machine.rl" - p = 0; - pe = eof = buffer->len; +static bool +not_standard_default_ignorable (const hb_glyph_info_t &i) +{ return !(i.use_category() == USE(O) && _hb_glyph_info_is_default_ignorable (&i)); } - unsigned int syllable_serial = 1; - -#line 412 "hb-ot-shape-complex-use-machine.hh" +static inline void +find_syllables_use (hb_buffer_t *buffer) +{ + hb_glyph_info_t *info = buffer->info; + auto p = + + hb_iter (info, buffer->len) + | hb_enumerate + | hb_filter ([] (const hb_glyph_info_t &i) { return not_standard_default_ignorable (i); }, + hb_second) + | hb_filter ([&] (const hb_pair_t<unsigned, const hb_glyph_info_t &> p) { - int _slen; - int _trans; - const unsigned char *_keys; - const char *_inds; - if ( p == pe ) - goto _test_eof; -_resume: - switch ( _use_syllable_machine_from_state_actions[cs] ) { - case 7: -#line 1 "NONE" - {ts = p;} - break; -#line 426 "hb-ot-shape-complex-use-machine.hh" - } - - _keys = _use_syllable_machine_trans_keys + (cs<<1); - _inds = _use_syllable_machine_indicies + _use_syllable_machine_index_offsets[cs]; - - _slen = _use_syllable_machine_key_spans[cs]; - _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].use_category()) && - ( info[p].use_category()) <= _keys[1] ? - ( info[p].use_category()) - _keys[0] : _slen ]; - -_eof_trans: - cs = _use_syllable_machine_trans_targs[_trans]; - - if ( _use_syllable_machine_trans_actions[_trans] == 0 ) - goto _again; - - switch ( _use_syllable_machine_trans_actions[_trans] ) { - case 5: -#line 1 "NONE" - {te = p+1;} - break; - case 12: -#line 150 "hb-ot-shape-complex-use-machine.rl" - {te = p+1;{ found_syllable (independent_cluster); }} - break; - case 14: -#line 153 "hb-ot-shape-complex-use-machine.rl" - {te = p+1;{ found_syllable (standard_cluster); }} - break; - case 10: -#line 157 "hb-ot-shape-complex-use-machine.rl" - {te = p+1;{ found_syllable (broken_cluster); }} - break; - case 8: -#line 158 "hb-ot-shape-complex-use-machine.rl" - {te = p+1;{ found_syllable (non_cluster); }} - break; - case 11: -#line 150 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (independent_cluster); }} - break; - case 15: -#line 151 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (virama_terminated_cluster); }} - break; - case 16: -#line 152 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (sakot_terminated_cluster); }} - break; - case 13: -#line 153 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (standard_cluster); }} - break; - case 18: -#line 154 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (number_joiner_terminated_cluster); }} - break; - case 17: -#line 155 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (numeral_cluster); }} - break; - case 19: -#line 156 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (symbol_cluster); }} - break; - case 20: -#line 157 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (broken_cluster); }} - break; - case 21: -#line 158 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (non_cluster); }} - break; - case 1: -#line 153 "hb-ot-shape-complex-use-machine.rl" - {{p = ((te))-1;}{ found_syllable (standard_cluster); }} - break; - case 4: -#line 157 "hb-ot-shape-complex-use-machine.rl" - {{p = ((te))-1;}{ found_syllable (broken_cluster); }} - break; - case 2: -#line 1 "NONE" - { switch( act ) { - case 8: - {{p = ((te))-1;} found_syllable (broken_cluster); } - break; - case 9: - {{p = ((te))-1;} found_syllable (non_cluster); } - break; - } + if (p.second.use_category() == USE(ZWNJ)) + for (unsigned i = p.first + 1; i < buffer->len; ++i) + if (not_standard_default_ignorable (info[i])) + return !_hb_glyph_info_is_unicode_mark (&info[i]); + return true; + }) + | hb_enumerate + | machine_index + ; + auto pe = p + p.len (); + auto eof = +pe; + auto ts = +p; + auto te = +p; + unsigned int act HB_UNUSED; + int cs; + +#line 443 "hb-ot-shape-complex-use-machine.hh" + { + cs = (int)use_syllable_machine_start; + ts = 0; + te = 0; } - break; - case 3: + +#line 260 "hb-ot-shape-complex-use-machine.rl" + + + unsigned int syllable_serial = 1; + +#line 455 "hb-ot-shape-complex-use-machine.hh" + { + unsigned int _trans = 0; + const unsigned char * _keys; + const signed char * _inds; + int _ic; + _resume: {} + if ( p == pe && p != eof ) + goto _out; + switch ( _use_syllable_machine_from_state_actions[cs] ) { + case 4: { + { #line 1 "NONE" - {te = p+1;} -#line 157 "hb-ot-shape-complex-use-machine.rl" - {act = 8;} - break; - case 9: + {ts = p;}} + +#line 470 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + } + + if ( p == eof ) { + if ( _use_syllable_machine_eof_trans[cs] > 0 ) { + _trans = (unsigned int)_use_syllable_machine_eof_trans[cs] - 1; + } + } + else { + _keys = ( _use_syllable_machine_trans_keys + ((cs<<1))); + _inds = ( _use_syllable_machine_indicies + (_use_syllable_machine_index_offsets[cs])); + + if ( ((*p).second.second.use_category()) <= 52 ) { + _ic = (int)_use_syllable_machine_char_class[(int)((*p).second.second.use_category()) - 0]; + if ( _ic <= (int)(*( _keys+1)) && _ic >= (int)(*( _keys)) ) + _trans = (unsigned int)(*( _inds + (int)( _ic - (int)(*( _keys)) ) )); + else + _trans = (unsigned int)_use_syllable_machine_index_defaults[cs]; + } + else { + _trans = (unsigned int)_use_syllable_machine_index_defaults[cs]; + } + + } + cs = (int)_use_syllable_machine_cond_targs[_trans]; + + if ( _use_syllable_machine_cond_actions[_trans] != 0 ) { + + switch ( _use_syllable_machine_cond_actions[_trans] ) { + case 2: { + { #line 1 "NONE" - {te = p+1;} -#line 158 "hb-ot-shape-complex-use-machine.rl" - {act = 9;} - break; -#line 532 "hb-ot-shape-complex-use-machine.hh" - } - -_again: - switch ( _use_syllable_machine_to_state_actions[cs] ) { - case 6: + {te = p+1;}} + +#line 508 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 5: { + { +#line 163 "hb-ot-shape-complex-use-machine.rl" + {te = p+1;{ +#line 163 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_independent_cluster); } + }} + +#line 521 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 9: { + { +#line 166 "hb-ot-shape-complex-use-machine.rl" + {te = p+1;{ +#line 166 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_standard_cluster); } + }} + +#line 534 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 7: { + { +#line 171 "hb-ot-shape-complex-use-machine.rl" + {te = p+1;{ +#line 171 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_broken_cluster); } + }} + +#line 547 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 6: { + { +#line 172 "hb-ot-shape-complex-use-machine.rl" + {te = p+1;{ +#line 172 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_non_cluster); } + }} + +#line 560 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 10: { + { +#line 164 "hb-ot-shape-complex-use-machine.rl" + {te = p;p = p - 1;{ +#line 164 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_virama_terminated_cluster); } + }} + +#line 573 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 11: { + { +#line 165 "hb-ot-shape-complex-use-machine.rl" + {te = p;p = p - 1;{ +#line 165 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_sakot_terminated_cluster); } + }} + +#line 586 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 8: { + { +#line 166 "hb-ot-shape-complex-use-machine.rl" + {te = p;p = p - 1;{ +#line 166 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_standard_cluster); } + }} + +#line 599 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 13: { + { +#line 167 "hb-ot-shape-complex-use-machine.rl" + {te = p;p = p - 1;{ +#line 167 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_number_joiner_terminated_cluster); } + }} + +#line 612 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 12: { + { +#line 168 "hb-ot-shape-complex-use-machine.rl" + {te = p;p = p - 1;{ +#line 168 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_numeral_cluster); } + }} + +#line 625 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 14: { + { +#line 169 "hb-ot-shape-complex-use-machine.rl" + {te = p;p = p - 1;{ +#line 169 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_symbol_cluster); } + }} + +#line 638 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 17: { + { +#line 170 "hb-ot-shape-complex-use-machine.rl" + {te = p;p = p - 1;{ +#line 170 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_hieroglyph_cluster); } + }} + +#line 651 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 15: { + { +#line 171 "hb-ot-shape-complex-use-machine.rl" + {te = p;p = p - 1;{ +#line 171 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_broken_cluster); } + }} + +#line 664 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 16: { + { +#line 172 "hb-ot-shape-complex-use-machine.rl" + {te = p;p = p - 1;{ +#line 172 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_non_cluster); } + }} + +#line 677 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 1: { + { +#line 171 "hb-ot-shape-complex-use-machine.rl" + {p = ((te))-1; + { +#line 171 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_broken_cluster); } + }} + +#line 691 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + } + + } + + if ( p == eof ) { + if ( cs >= 2 ) + goto _out; + } + else { + switch ( _use_syllable_machine_to_state_actions[cs] ) { + case 3: { + { #line 1 "NONE" - {ts = 0;} - break; -#line 541 "hb-ot-shape-complex-use-machine.hh" - } - - if ( ++p != pe ) - goto _resume; - _test_eof: {} - if ( p == eof ) - { - if ( _use_syllable_machine_eof_trans[cs] > 0 ) { - _trans = _use_syllable_machine_eof_trans[cs] - 1; - goto _eof_trans; - } + {ts = 0;}} + +#line 711 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + } + + p += 1; + goto _resume; + } + _out: {} } - - } - -#line 190 "hb-ot-shape-complex-use-machine.rl" - + +#line 265 "hb-ot-shape-complex-use-machine.rl" + } #undef found_syllable diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-machine.rl b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-machine.rl deleted file mode 100644 index 9b75b5c6e2..0000000000 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-machine.rl +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright © 2015 Mozilla Foundation. - * Copyright © 2015 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. - * - * Mozilla Author(s): Jonathan Kew - * Google Author(s): Behdad Esfahbod - */ - -#ifndef HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH -#define HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH - -#include "hb.hh" - -%%{ - machine use_syllable_machine; - alphtype unsigned char; - write data; -}%% - -%%{ - -# Same order as enum use_category_t. Not sure how to avoid duplication. - -O = 0; # OTHER - -B = 1; # BASE -IND = 3; # BASE_IND -N = 4; # BASE_NUM -GB = 5; # BASE_OTHER -CGJ = 6; # CGJ -#F = 7; # CONS_FINAL -#FM = 8; # CONS_FINAL_MOD -#M = 9; # CONS_MED -#CM = 10; # CONS_MOD -SUB = 11; # CONS_SUB -H = 12; # HALANT - -HN = 13; # HALANT_NUM -ZWNJ = 14; # Zero width non-joiner -ZWJ = 15; # Zero width joiner -WJ = 16; # Word joiner -Rsv = 17; # Reserved characters -R = 18; # REPHA -S = 19; # SYM -#SM = 20; # SYM_MOD -VS = 21; # VARIATION_SELECTOR -#V = 36; # VOWEL -#VM = 40; # VOWEL_MOD -CS = 43; # CONS_WITH_STACKER -HVM = 44; # HALANT_OR_VOWEL_MODIFIER -Sk = 48; # SAKOT - -FAbv = 24; # CONS_FINAL_ABOVE -FBlw = 25; # CONS_FINAL_BELOW -FPst = 26; # CONS_FINAL_POST -MAbv = 27; # CONS_MED_ABOVE -MBlw = 28; # CONS_MED_BELOW -MPst = 29; # CONS_MED_POST -MPre = 30; # CONS_MED_PRE -CMAbv = 31; # CONS_MOD_ABOVE -CMBlw = 32; # CONS_MOD_BELOW -VAbv = 33; # VOWEL_ABOVE / VOWEL_ABOVE_BELOW / VOWEL_ABOVE_BELOW_POST / VOWEL_ABOVE_POST -VBlw = 34; # VOWEL_BELOW / VOWEL_BELOW_POST -VPst = 35; # VOWEL_POST UIPC = Right -VPre = 22; # VOWEL_PRE / VOWEL_PRE_ABOVE / VOWEL_PRE_ABOVE_POST / VOWEL_PRE_POST -VMAbv = 37; # VOWEL_MOD_ABOVE -VMBlw = 38; # VOWEL_MOD_BELOW -VMPst = 39; # VOWEL_MOD_POST -VMPre = 23; # VOWEL_MOD_PRE -SMAbv = 41; # SYM_MOD_ABOVE -SMBlw = 42; # SYM_MOD_BELOW -FMAbv = 45; # CONS_FINAL_MOD UIPC = Top -FMBlw = 46; # CONS_FINAL_MOD UIPC = Bottom -FMPst = 47; # CONS_FINAL_MOD UIPC = Not_Applicable - -h = H | HVM | Sk; - -# Override: Adhoc ZWJ placement. https://github.com/harfbuzz/harfbuzz/issues/542#issuecomment-353169729 -consonant_modifiers = CMAbv* CMBlw* ((ZWJ?.h.ZWJ? B | SUB) VS? CMAbv? CMBlw*)*; -# Override: Allow two MBlw. https://github.com/harfbuzz/harfbuzz/issues/376 -medial_consonants = MPre? MAbv? MBlw?.MBlw? MPst?; -dependent_vowels = VPre* VAbv* VBlw* VPst*; -vowel_modifiers = HVM? VMPre* VMAbv* VMBlw* VMPst*; -final_consonants = FAbv* FBlw* FPst*; -final_modifiers = FMAbv* FMBlw* | FMPst?; - -complex_syllable_start = (R | CS)? (B | GB) VS?; -complex_syllable_middle = - consonant_modifiers - medial_consonants - dependent_vowels - vowel_modifiers - (Sk B)* -; -complex_syllable_tail = - complex_syllable_middle - final_consonants - final_modifiers -; -number_joiner_terminated_cluster_tail = (HN N VS?)* HN; -numeral_cluster_tail = (HN N VS?)+; -symbol_cluster_tail = SMAbv+ SMBlw* | SMBlw+; - -virama_terminated_cluster = - complex_syllable_start - consonant_modifiers - ZWJ?.h.ZWJ? -; -sakot_terminated_cluster = - complex_syllable_start - complex_syllable_middle - Sk -; -standard_cluster = - complex_syllable_start - complex_syllable_tail -; -broken_cluster = - R? - (complex_syllable_tail | number_joiner_terminated_cluster_tail | numeral_cluster_tail | symbol_cluster_tail) -; - -number_joiner_terminated_cluster = N VS? number_joiner_terminated_cluster_tail; -numeral_cluster = N VS? numeral_cluster_tail?; -symbol_cluster = (S | GB) VS? symbol_cluster_tail?; -independent_cluster = (IND | O | Rsv | WJ) VS?; -other = any; - -main := |* - independent_cluster => { found_syllable (independent_cluster); }; - virama_terminated_cluster => { found_syllable (virama_terminated_cluster); }; - sakot_terminated_cluster => { found_syllable (sakot_terminated_cluster); }; - standard_cluster => { found_syllable (standard_cluster); }; - number_joiner_terminated_cluster => { found_syllable (number_joiner_terminated_cluster); }; - numeral_cluster => { found_syllable (numeral_cluster); }; - symbol_cluster => { found_syllable (symbol_cluster); }; - broken_cluster => { found_syllable (broken_cluster); }; - other => { found_syllable (non_cluster); }; -*|; - - -}%% - -#define found_syllable(syllable_type) \ - HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ - for (unsigned int i = ts; i < te; i++) \ - info[i].syllable() = (syllable_serial << 4) | use_##syllable_type; \ - syllable_serial++; \ - if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ - } HB_STMT_END - -static void -find_syllables_use (hb_buffer_t *buffer) -{ - unsigned int p, pe, eof, ts, te, act; - int cs; - hb_glyph_info_t *info = buffer->info; - %%{ - write init; - getkey info[p].use_category(); - }%% - - p = 0; - pe = eof = buffer->len; - - unsigned int syllable_serial = 1; - %%{ - write exec; - }%% -} - -#undef found_syllable - -#endif /* HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-table.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-table.hh index e3889b3e60..a35894ce81 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-table.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-table.hh @@ -2,71 +2,86 @@ /* * The following table is generated by running: * - * ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt + * ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt ArabicShaping.txt Blocks.txt IndicSyllabicCategory-Additional.txt IndicPositionalCategory-Additional.txt * * on files with these headers: * - * # IndicSyllabicCategory-12.0.0.txt - * # Date: 2019-01-31, 02:26:00 GMT [KW, RP] - * # IndicPositionalCategory-12.0.0.txt - * # Date: 2019-01-31, 02:26:00 GMT [KW, RP] - * # Blocks-12.0.0.txt - * # Date: 2018-07-30, 19:40:00 GMT [KW] + * # IndicSyllabicCategory-13.0.0.txt + * # Date: 2019-07-22, 19:55:00 GMT [KW, RP] + * # IndicPositionalCategory-13.0.0.txt + * # Date: 2019-07-23, 00:01:00 GMT [KW, RP] + * # ArabicShaping-13.0.0.txt + * # Date: 2020-01-31, 23:55:00 GMT [KW, RP] + * # Blocks-13.0.0.txt + * # Date: 2019-07-10, 19:06:00 GMT [KW] + * # Override values For Indic_Syllabic_Category + * # Not derivable + * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17 + * # Updated for Unicode 10.0 by Andrew Glass 2017-07-25 + * # Updated for Unicode 12.1 by Andrew Glass 2019-05-24 + * # Updated for Unicode 13.0 by Andrew Glass 2020-07-28 + * # Override values For Indic_Positional_Category + * # Not derivable + * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17 + * # Updated for Unicode 10.0 by Andrew Glass 2017-07-25 + * # Ammended for Unicode 10.0 by Andrew Glass 2018-09-21 + * # Updated for L2/19-083 by Andrew Glass 2019-05-06 + * # Updated for Unicode 12.1 by Andrew Glass 2019-05-30 + * # Updated for Unicode 13.0 by Andrew Glass 2020-07-28 * UnicodeData.txt does not have a header. */ -#include "hb.hh" +#ifndef HB_OT_SHAPE_COMPLEX_USE_TABLE_HH +#define HB_OT_SHAPE_COMPLEX_USE_TABLE_HH -#ifndef HB_NO_OT_SHAPE +#include "hb.hh" -#include "hb-ot-shape-complex-use.hh" +#include "hb-ot-shape-complex-use-machine.hh" #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-macros" -#define B USE_B /* BASE */ -#define CGJ USE_CGJ /* CGJ */ -#define CS USE_CS /* CONS_WITH_STACKER */ -#define GB USE_GB /* BASE_OTHER */ -#define H USE_H /* HALANT */ -#define HN USE_HN /* HALANT_NUM */ -#define HVM USE_HVM /* HALANT_OR_VOWEL_MODIFIER */ -#define IND USE_IND /* BASE_IND */ -#define N USE_N /* BASE_NUM */ -#define O USE_O /* OTHER */ -#define R USE_R /* REPHA */ -#define Rsv USE_Rsv /* Reserved */ -#define S USE_S /* SYM */ -#define SUB USE_SUB /* CONS_SUB */ -#define Sk USE_Sk /* SAKOT */ -#define VS USE_VS /* VARIATION_SELECTOR */ -#define WJ USE_WJ /* Word_Joiner */ -#define ZWJ USE_ZWJ /* ZWJ */ -#define ZWNJ USE_ZWNJ /* ZWNJ */ -#define CMBlw USE_CMBlw -#define CMAbv USE_CMAbv -#define FBlw USE_FBlw -#define FPst USE_FPst -#define FAbv USE_FAbv -#define FMBlw USE_FMBlw -#define FMPst USE_FMPst -#define FMAbv USE_FMAbv -#define MPre USE_MPre -#define MBlw USE_MBlw -#define MPst USE_MPst -#define MAbv USE_MAbv -#define SMBlw USE_SMBlw -#define SMAbv USE_SMAbv -#define VPre USE_VPre -#define VBlw USE_VBlw -#define VPst USE_VPst -#define VAbv USE_VAbv -#define VMPre USE_VMPre -#define VMBlw USE_VMBlw -#define VMPst USE_VMPst -#define VMAbv USE_VMAbv +#define B USE(B) /* BASE */ +#define CS USE(CS) /* CONS_WITH_STACKER */ +#define G USE(G) /* HIEROGLYPH */ +#define GB USE(GB) /* BASE_OTHER */ +#define H USE(H) /* HALANT */ +#define HN USE(HN) /* HALANT_NUM */ +#define HVM USE(HVM) /* HALANT_OR_VOWEL_MODIFIER */ +#define J USE(J) /* HIEROGLYPH_JOINER */ +#define N USE(N) /* BASE_NUM */ +#define O USE(O) /* OTHER */ +#define R USE(R) /* REPHA */ +#define S USE(S) /* SYM */ +#define SB USE(SB) /* HIEROGLYPH_SEGMENT_BEGIN */ +#define SE USE(SE) /* HIEROGLYPH_SEGMENT_END */ +#define SUB USE(SUB) /* CONS_SUB */ +#define Sk USE(Sk) /* SAKOT */ +#define ZWNJ USE(ZWNJ) /* ZWNJ */ +#define CMAbv USE(CMAbv) +#define CMBlw USE(CMBlw) +#define FAbv USE(FAbv) +#define FBlw USE(FBlw) +#define FPst USE(FPst) +#define FMAbv USE(FMAbv) +#define FMBlw USE(FMBlw) +#define FMPst USE(FMPst) +#define MAbv USE(MAbv) +#define MBlw USE(MBlw) +#define MPst USE(MPst) +#define MPre USE(MPre) +#define SMAbv USE(SMAbv) +#define SMBlw USE(SMBlw) +#define VAbv USE(VAbv) +#define VBlw USE(VBlw) +#define VPst USE(VPst) +#define VPre USE(VPre) +#define VMAbv USE(VMAbv) +#define VMBlw USE(VMBlw) +#define VMPst USE(VMPst) +#define VMPre USE(VMPre) #pragma GCC diagnostic pop -static const USE_TABLE_ELEMENT_TYPE use_table[] = { +static const uint8_t use_table[] = { #define use_offset_0x0028u 0 @@ -86,13 +101,31 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 00C0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* 00D0 */ O, O, O, O, O, O, O, GB, -#define use_offset_0x0348u 80 +#define use_offset_0x0640u 80 + + + /* Arabic */ + + /* 0640 */ B, O, O, O, O, O, O, O, + +#define use_offset_0x07c8u 88 - /* Combining Diacritical Marks */ - O, O, O, O, O, O, O, CGJ, + /* NKo */ + O, O, B, B, B, B, B, B, + /* 07D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 07E0 */ B, B, B, B, B, B, B, B, B, B, B, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, + /* 07F0 */ VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, O, O, O, B, O, O, VMAbv, O, O, -#define use_offset_0x0900u 88 +#define use_offset_0x0840u 144 + + + /* Mandaic */ + + /* 0840 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 0850 */ B, B, B, B, B, B, B, B, B, CMBlw, CMBlw, CMBlw, O, O, O, O, + +#define use_offset_0x0900u 176 /* Devanagari */ @@ -112,7 +145,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 0990 */ B, O, O, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 09A0 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, /* 09B0 */ B, O, B, O, O, O, B, B, B, B, O, O, CMBlw, B, VPst, VPre, - /* 09C0 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, O, O, VPst, VPst, H, IND, O, + /* 09C0 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, O, O, VPre, VPre, H, O, O, /* 09D0 */ O, O, O, O, O, O, O, VPst, O, O, O, O, B, B, O, B, /* 09E0 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, /* 09F0 */ B, B, O, O, O, O, O, O, O, O, O, O, B, O, FMAbv, O, @@ -145,18 +178,18 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 0B10 */ B, O, O, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0B20 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, /* 0B30 */ B, O, B, B, O, B, B, B, B, B, O, O, CMBlw, B, VPst, VAbv, - /* 0B40 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPst, O, O, VPst, VPst, H, O, O, - /* 0B50 */ O, O, O, O, O, O, VAbv, VAbv, O, O, O, O, B, B, O, B, + /* 0B40 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, O, O, VPre, VPre, H, O, O, + /* 0B50 */ O, O, O, O, O, VAbv, VAbv, VAbv, O, O, O, O, B, B, O, B, /* 0B60 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, /* 0B70 */ O, B, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Tamil */ - /* 0B80 */ O, O, VMAbv, IND, O, B, B, B, B, B, B, O, O, O, B, B, + /* 0B80 */ O, O, VMAbv, O, O, B, B, B, B, B, B, O, O, O, B, B, /* 0B90 */ B, O, B, B, B, B, O, O, O, B, B, O, B, O, B, B, /* 0BA0 */ O, O, O, B, B, O, O, O, B, B, B, O, O, O, B, B, /* 0BB0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, VPst, VPst, - /* 0BC0 */ VAbv, VPst, VPst, O, O, O, VPre, VPre, VPre, O, VPst, VPst, VPst, H, O, O, + /* 0BC0 */ VAbv, VPst, VPst, O, O, O, VPre, VPre, VPre, O, VPre, VPre, VPre, H, O, O, /* 0BD0 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, O, O, /* 0BE0 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B, /* 0BF0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, @@ -185,44 +218,46 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* Malayalam */ - /* 0D00 */ VMAbv, VMAbv, VMPst, VMPst, O, B, B, B, B, B, B, B, B, O, B, B, + /* 0D00 */ VMAbv, VMAbv, VMPst, VMPst, B, B, B, B, B, B, B, B, B, O, B, B, /* 0D10 */ B, O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0D20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0D30 */ B, B, B, B, B, B, B, B, B, B, B, VAbv, VAbv, B, VPst, VPst, - /* 0D40 */ VPst, VPst, VPst, VBlw, VBlw, O, VPre, VPre, VPre, O, VPst, VPst, VPst, H, R, O, - /* 0D50 */ O, O, O, O, IND, IND, IND, VPst, O, O, O, O, O, O, O, B, + /* 0D40 */ VPst, VPst, VPst, VBlw, VBlw, O, VPre, VPre, VPre, O, VPre, VPre, VPre, H, R, O, + /* 0D50 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, O, B, /* 0D60 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, - /* 0D70 */ O, O, O, O, O, O, O, O, O, O, IND, IND, IND, IND, IND, IND, + /* 0D70 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Sinhala */ - /* 0D80 */ O, O, VMPst, VMPst, O, B, B, B, B, B, B, B, B, B, B, B, + /* 0D80 */ O, VMAbv, VMPst, VMPst, O, B, B, B, B, B, B, B, B, B, B, B, /* 0D90 */ B, B, B, B, B, B, B, O, O, O, B, B, B, B, B, B, /* 0DA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0DB0 */ B, B, O, B, B, B, B, B, B, B, B, B, O, B, O, O, /* 0DC0 */ B, B, B, B, B, B, B, O, O, O, H, O, O, O, O, VPst, - /* 0DD0 */ VPst, VPst, VAbv, VAbv, VBlw, O, VBlw, O, VPst, VPre, VPst, VPre, VPst, VPst, VPst, VPst, + /* 0DD0 */ VPst, VPst, VAbv, VAbv, VBlw, O, VBlw, O, VPst, VPre, VPre, VPre, VPre, VPre, VPre, VPst, /* 0DE0 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B, /* 0DF0 */ O, O, VPst, VPst, O, O, O, O, -#define use_offset_0x0f18u 1360 +#define use_offset_0x0f00u 1448 /* Tibetan */ - VBlw, VBlw, O, O, O, O, O, O, + + /* 0F00 */ B, B, O, O, B, B, B, O, O, O, O, O, O, O, O, O, + /* 0F10 */ O, O, O, O, O, O, O, O, VBlw, VBlw, O, O, O, O, O, O, /* 0F20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0F30 */ B, B, B, B, O, FMBlw, O, FMBlw, O, CMAbv, O, O, O, O, VPst, VPre, + /* 0F30 */ B, B, B, B, O, FBlw, O, FBlw, O, CMAbv, O, O, O, O, VPst, VPre, /* 0F40 */ B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, B, /* 0F50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0F60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, - /* 0F70 */ O, VBlw, VBlw, VAbv, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VMAbv, VMPst, - /* 0F80 */ VBlw, VAbv, VMAbv, VMAbv, VBlw, IND, VMAbv, VMAbv, B, B, B, B, B, SUB, SUB, SUB, + /* 0F70 */ O, CMBlw, VBlw, VAbv, VAbv, VBlw, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VMAbv, O, + /* 0F80 */ VBlw, VAbv, VMAbv, VMAbv, VBlw, O, VMAbv, VMAbv, B, B, B, B, B, SUB, SUB, SUB, /* 0F90 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, SUB, SUB, SUB, SUB, SUB, SUB, SUB, /* 0FA0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, /* 0FB0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, O, O, - /* 0FC0 */ O, O, O, O, O, O, FMBlw, O, + /* 0FC0 */ O, O, O, O, O, O, FBlw, O, -#define use_offset_0x1000u 1536 +#define use_offset_0x1000u 1648 /* Myanmar */ @@ -238,7 +273,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 1080 */ B, B, MBlw, VPst, VPre, VAbv, VAbv, VMPst, VMPst, VMPst, VMPst, VMPst, VMPst, VMBlw, B, VMPst, /* 1090 */ B, B, B, B, B, B, B, B, B, B, VMPst, VMPst, VPst, VAbv, O, O, -#define use_offset_0x1700u 1696 +#define use_offset_0x1700u 1808 /* Tagalog */ @@ -266,12 +301,27 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 1780 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1790 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 17A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 17B0 */ B, B, B, B, O, O, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VPst, VPst, - /* 17C0 */ VPst, VPre, VPre, VPre, VPst, VPst, VMAbv, VMPst, VPst, VMAbv, VMAbv, FMAbv, FAbv, CMAbv, FMAbv, FMAbv, + /* 17B0 */ B, B, B, B, O, O, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VPre, VPre, + /* 17C0 */ VPre, VPre, VPre, VPre, VPre, VPre, VMAbv, VMPst, VPst, VMAbv, VMAbv, FMAbv, FAbv, CMAbv, FMAbv, VMAbv, /* 17D0 */ FMAbv, VAbv, H, FMAbv, O, O, O, O, O, O, O, O, B, FMAbv, O, O, /* 17E0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* 17F0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + + /* Mongolian */ -#define use_offset_0x1900u 1936 + /* 1800 */ B, O, O, O, O, O, O, B, O, O, B, O, O, O, O, O, + /* 1810 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 1820 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1830 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1840 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1850 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1860 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1870 */ B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, O, + /* 1880 */ GB, GB, GB, GB, GB, CMAbv, CMAbv, B, B, B, B, B, B, B, B, B, + /* 1890 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18A0 */ B, B, B, B, B, B, B, B, B, CMBlw, B, O, O, O, O, O, + +#define use_offset_0x1900u 2240 /* Limbu */ @@ -279,7 +329,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 1900 */ GB, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1910 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, O, /* 1920 */ VAbv, VAbv, VBlw, VPst, VPst, VAbv, VAbv, VAbv, VAbv, SUB, SUB, SUB, O, O, O, O, - /* 1930 */ FPst, FPst, VMBlw, FPst, FPst, FPst, FPst, FPst, FPst, FBlw, VAbv, FMBlw, O, O, O, O, + /* 1930 */ FPst, FPst, VMBlw, FPst, FPst, FPst, FPst, FPst, FPst, FBlw, VMAbv, FMBlw, O, O, O, O, /* 1940 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B, /* Tai Le */ @@ -302,7 +352,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* Buginese */ /* 1A00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1A10 */ B, B, B, B, B, B, B, VAbv, VBlw, VPre, VPst, VAbv, O, O, O, O, + /* 1A10 */ B, B, B, B, B, B, B, VAbv, VAbv, VPre, VPst, VAbv, O, O, O, O, /* Tai Tham */ @@ -311,11 +361,11 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 1A40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1A50 */ B, B, B, B, B, MPre, MBlw, SUB, FAbv, FAbv, MAbv, SUB, SUB, SUB, SUB, O, /* 1A60 */ Sk, VPst, VAbv, VPst, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VAbv, VBlw, VPst, VPre, VPre, - /* 1A70 */ VPre, VPre, VPre, VAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VAbv, FMAbv, FMAbv, O, O, FMBlw, + /* 1A70 */ VPre, VPre, VPre, VAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VAbv, VMAbv, VMAbv, O, O, VMBlw, /* 1A80 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* 1A90 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, -#define use_offset_0x1b00u 2352 +#define use_offset_0x1b00u 2656 /* Balinese */ @@ -324,7 +374,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 1B10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1B30 */ B, B, B, B, CMAbv, VPst, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VPre, - /* 1B40 */ VPst, VPst, VAbv, VAbv, H, B, B, B, B, B, B, B, O, O, O, O, + /* 1B40 */ VPre, VPre, VAbv, VAbv, H, B, B, B, B, B, B, B, O, O, O, O, /* 1B50 */ B, B, B, B, B, B, B, B, B, B, O, GB, GB, O, O, GB, /* 1B60 */ O, S, GB, S, S, S, S, S, GB, S, S, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv, /* 1B70 */ SMAbv, SMAbv, SMAbv, SMAbv, O, O, O, O, O, O, O, O, O, O, O, O, @@ -351,58 +401,68 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 1C30 */ FAbv, FAbv, FAbv, FAbv, VMPre, VMPre, FMAbv, CMBlw, O, O, O, O, O, O, O, O, /* 1C40 */ B, B, B, B, B, B, B, B, B, B, O, O, O, B, B, B, -#define use_offset_0x1cd0u 2688 +#define use_offset_0x1cd0u 2992 /* Vedic Extensions */ /* 1CD0 */ VMAbv, VMAbv, VMAbv, O, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMAbv, VMAbv, VMBlw, VMBlw, VMBlw, VMBlw, /* 1CE0 */ VMAbv, VMPst, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, O, O, O, O, VMBlw, O, O, - /* 1CF0 */ O, O, IND, IND, VMAbv, CS, CS, VMPst, VMAbv, VMAbv, GB, O, O, O, O, O, + /* 1CF0 */ O, O, O, O, VMAbv, CS, CS, VMPst, VMAbv, VMAbv, GB, O, O, O, O, O, -#define use_offset_0x1df8u 2736 +#define use_offset_0x1df8u 3040 /* Combining Diacritical Marks Supplement */ O, O, O, FMAbv, O, O, O, O, -#define use_offset_0x2008u 2744 +#define use_offset_0x2008u 3048 /* General Punctuation */ - O, O, O, O, ZWNJ, ZWJ, O, O, + O, O, O, O, ZWNJ, O, O, O, /* 2010 */ GB, GB, GB, GB, GB, O, O, O, -#define use_offset_0x2060u 2760 +#define use_offset_0x2070u 3064 - /* 2060 */ WJ, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Superscripts and Subscripts */ /* 2070 */ O, O, O, O, FMPst, O, O, O, O, O, O, O, O, O, O, O, /* 2080 */ O, O, FMPst, FMPst, FMPst, O, O, O, -#define use_offset_0x20f0u 2800 +#define use_offset_0x20f0u 3088 /* Combining Diacritical Marks for Symbols */ /* 20F0 */ VMAbv, O, O, O, O, O, O, O, -#define use_offset_0x25c8u 2808 +#define use_offset_0x25c8u 3096 /* Geometric Shapes */ - O, O, O, O, GB, O, O, O, + O, O, O, O, B, O, O, O, + +#define use_offset_0x2d30u 3104 + -#define use_offset_0xa800u 2816 + /* Tifinagh */ + + /* 2D30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 2D40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 2D50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 2D60 */ B, B, B, B, B, B, B, B, O, O, O, O, O, O, O, B, + /* 2D70 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, H, + +#define use_offset_0xa800u 3184 /* Syloti Nagri */ /* A800 */ B, B, VAbv, B, B, B, H, B, B, B, B, VMAbv, B, B, B, B, /* A810 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A820 */ B, B, B, VPst, VPst, VBlw, VAbv, VPst, O, O, O, O, O, O, O, O, + /* A820 */ B, B, B, VPst, VPst, VBlw, VAbv, VPst, O, O, O, O, VBlw, O, O, O, /* A830 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Phags-pa */ @@ -459,7 +519,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* AA00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* AA10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* AA20 */ B, B, B, B, B, B, B, B, B, VMAbv, VAbv, VAbv, VAbv, VBlw, VAbv, VPre, - /* AA30 */ VPre, VAbv, VBlw, MPst, MPre, MBlw, MBlw, O, O, O, O, O, O, O, O, O, + /* AA30 */ VPre, VAbv, VBlw, MPst, MPre, MAbv, MBlw, O, O, O, O, O, O, O, O, O, /* AA40 */ B, B, B, FAbv, B, B, B, B, B, B, B, B, FAbv, FPst, O, O, /* AA50 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, @@ -482,7 +542,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* AAE0 */ B, B, B, B, B, B, B, B, B, B, B, VPre, VBlw, VAbv, VPre, VPst, /* AAF0 */ O, O, O, O, O, VMPst, H, O, -#define use_offset_0xabc0u 3576 +#define use_offset_0xabc0u 3944 /* Meetei Mayek */ @@ -492,26 +552,74 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* ABE0 */ B, B, B, VPst, VPst, VAbv, VPst, VPst, VBlw, VPst, VPst, O, VMPst, VBlw, O, O, /* ABF0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, -#define use_offset_0xfe00u 3640 - - - /* Variation Selectors */ - - /* FE00 */ VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, - -#define use_offset_0x10a00u 3656 +#define use_offset_0x10a00u 4008 /* Kharoshthi */ - /* 10A00 */ B, VBlw, VBlw, VBlw, O, VAbv, VBlw, O, O, O, O, O, VBlw, VBlw, VMBlw, VMAbv, + /* 10A00 */ B, VBlw, VBlw, VBlw, O, VAbv, VBlw, O, O, O, O, O, VPst, VMBlw, VMBlw, VMAbv, /* 10A10 */ B, B, B, B, O, B, B, B, O, B, B, B, B, B, B, B, /* 10A20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 10A30 */ B, B, B, B, B, B, O, O, CMAbv, CMBlw, CMBlw, O, O, O, O, H, /* 10A40 */ B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, O, -#define use_offset_0x11000u 3736 +#define use_offset_0x10ac0u 4088 + + + /* Manichaean */ + /* 10AC0 */ B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, B, + /* 10AD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 10AE0 */ B, B, B, B, B, CMBlw, CMBlw, O, + +#define use_offset_0x10b80u 4128 + + + /* Psalter Pahlavi */ + + /* 10B80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 10B90 */ B, B, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 10BA0 */ O, O, O, O, O, O, O, O, O, B, B, B, B, B, B, O, + +#define use_offset_0x10d00u 4176 + + + /* Hanifi Rohingya */ + + /* 10D00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 10D10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 10D20 */ B, B, B, B, VMAbv, VMAbv, VMAbv, CMAbv, O, O, O, O, O, O, O, O, + /* 10D30 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + +#define use_offset_0x10e80u 4240 + + + /* Yezidi */ + + /* 10E80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 10E90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 10EA0 */ B, B, B, B, B, B, B, B, B, B, O, VAbv, VAbv, O, O, O, + /* 10EB0 */ B, B, O, O, O, O, O, O, + +#define use_offset_0x10f30u 4296 + + + /* Sogdian */ + + /* 10F30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 10F40 */ B, B, B, B, B, B, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, + /* 10F50 */ VMBlw, B, B, B, B, O, O, O, + +#define use_offset_0x10fb0u 4336 + + + /* Chorasmian */ + + /* 10FB0 */ B, O, B, B, B, B, B, O, B, B, B, B, B, B, B, B, + /* 10FC0 */ O, B, B, B, B, O, O, O, O, B, B, B, O, O, O, O, + /* 10FD0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 10FE0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 10FF0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Brahmi */ @@ -531,7 +639,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 110A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 110B0 */ VPst, VPre, VPst, VBlw, VBlw, VAbv, VAbv, VPst, VPst, H, CMBlw, O, O, O, O, O, -#define use_offset_0x11100u 3928 +#define use_offset_0x11100u 4608 /* Chakma */ @@ -539,8 +647,8 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11100 */ VMAbv, VMAbv, VMAbv, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11110 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11120 */ B, B, B, B, B, B, B, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VBlw, VAbv, VAbv, - /* 11130 */ VBlw, VAbv, VAbv, H, CMBlw, O, B, B, B, B, B, B, B, B, B, B, - /* 11140 */ O, O, O, O, B, VPst, VPst, O, O, O, O, O, O, O, O, O, + /* 11130 */ VBlw, VAbv, VAbv, H, CMAbv, O, B, B, B, B, B, B, B, B, B, B, + /* 11140 */ O, O, O, O, B, VPst, VPst, B, O, O, O, O, O, O, O, O, /* Mahajani */ @@ -554,8 +662,8 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11190 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 111A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 111B0 */ B, B, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, - /* 111C0 */ H, B, R, R, O, O, O, O, GB, FMBlw, CMBlw, VAbv, VBlw, O, O, O, - /* 111D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* 111C0 */ H, B, R, R, O, O, O, O, GB, FMBlw, CMBlw, VAbv, VBlw, O, VPre, VMAbv, + /* 111D0 */ B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, /* Sinhala Archaic Numbers */ @@ -569,7 +677,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11220 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPst, VPst, VBlw, /* 11230 */ VAbv, VAbv, VAbv, VAbv, VMAbv, H, CMAbv, CMAbv, O, O, O, O, O, O, VMAbv, O, -#define use_offset_0x11280u 4248 +#define use_offset_0x11280u 4928 /* Multani */ @@ -592,12 +700,12 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11310 */ B, O, O, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11320 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, /* 11330 */ B, O, B, B, O, B, B, B, B, B, O, CMBlw, CMBlw, B, VPst, VPst, - /* 11340 */ VAbv, VPst, VPst, VPst, VPst, O, O, VPre, VPre, O, O, VPst, VPst, HVM, O, O, + /* 11340 */ VAbv, VPst, VPst, VPst, VPst, O, O, VPre, VPre, O, O, VPre, VPre, HVM, O, O, /* 11350 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, B, B, /* 11360 */ B, B, VPst, VPst, O, O, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, /* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, -#define use_offset_0x11400u 4496 +#define use_offset_0x11400u 5176 /* Newa */ @@ -608,7 +716,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11430 */ B, B, B, B, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, /* 11440 */ VPst, VPst, H, VMAbv, VMAbv, VMPst, CMBlw, B, O, O, O, O, O, O, O, O, /* 11450 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, FMAbv, B, - /* 11460 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 11460 */ CS, CS, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* 11470 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Tirhuta */ @@ -616,11 +724,11 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11480 */ O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11490 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 114A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 114B0 */ VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VPre, VAbv, VPst, VPst, VPst, VPst, VMAbv, + /* 114B0 */ VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VPre, VAbv, VPre, VPre, VPst, VPre, VMAbv, /* 114C0 */ VMAbv, VMAbv, H, CMBlw, B, O, O, O, O, O, O, O, O, O, O, O, /* 114D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, -#define use_offset_0x11580u 4720 +#define use_offset_0x11580u 5400 /* Siddham */ @@ -628,7 +736,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11580 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11590 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 115A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, VPst, - /* 115B0 */ VPre, VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPst, VPst, VPst, VMAbv, VMAbv, VMPst, H, + /* 115B0 */ VPre, VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, VPre, VPre, VMAbv, VMAbv, VMPst, H, /* 115C0 */ CMBlw, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* 115D0 */ O, O, O, O, O, O, O, O, B, B, B, B, VBlw, VBlw, O, O, /* 115E0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, @@ -663,7 +771,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11720 */ VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VAbv, VBlw, VAbv, VAbv, VAbv, O, O, O, O, /* 11730 */ B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, -#define use_offset_0x11800u 5168 +#define use_offset_0x11800u 5848 /* Dogra */ @@ -673,7 +781,19 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11820 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPre, VPst, VBlw, /* 11830 */ VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VMAbv, VMPst, H, CMBlw, O, O, O, O, O, -#define use_offset_0x119a0u 5232 +#define use_offset_0x11900u 5912 + + + /* Dives Akuru */ + + /* 11900 */ B, B, B, B, B, B, B, O, O, B, O, O, B, B, B, B, + /* 11910 */ B, B, B, B, O, B, B, O, B, B, B, B, B, B, B, B, + /* 11920 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11930 */ VPst, VPst, VPst, VPst, VPst, VPre, O, VPre, VPre, O, O, VMAbv, VMAbv, VPst, H, R, + /* 11940 */ MPst, R, MPst, CMBlw, O, O, O, O, O, O, O, O, O, O, O, O, + /* 11950 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + +#define use_offset_0x119a0u 6008 /* Nandinagari */ @@ -701,7 +821,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11A80 */ B, B, B, B, R, R, R, R, R, R, FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, /* 11A90 */ FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, VMAbv, VMPst, CMAbv, H, O, O, O, B, O, O, -#define use_offset_0x11c00u 5488 +#define use_offset_0x11c00u 6264 /* Bhaiksuki */ @@ -722,7 +842,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11CA0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, SUB, SUB, SUB, SUB, SUB, SUB, SUB, /* 11CB0 */ VBlw, VPre, VBlw, VAbv, VPst, VMAbv, VMAbv, O, -#define use_offset_0x11d00u 5672 +#define use_offset_0x11d00u 6448 /* Masaram Gondi */ @@ -742,7 +862,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11D90 */ VAbv, VAbv, O, VPst, VPst, VMAbv, VMPst, H, O, O, O, O, O, O, O, O, /* 11DA0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, -#define use_offset_0x11ee0u 5848 +#define use_offset_0x11ee0u 6624 /* Makasar */ @@ -750,9 +870,204 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11EE0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11EF0 */ B, B, GB, VAbv, VBlw, VPre, VPst, O, -}; /* Table items: 5872; occupancy: 74% */ +#define use_offset_0x13000u 6648 + + + /* Egyptian Hieroglyphs */ + + /* 13000 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13010 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13020 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13030 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13040 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13050 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13060 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13070 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13080 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13090 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 130A0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 130B0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 130C0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 130D0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 130E0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 130F0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13100 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13110 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13120 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13130 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13140 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13150 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13160 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13170 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13180 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13190 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 131A0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 131B0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 131C0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 131D0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 131E0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 131F0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13200 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13210 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13220 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13230 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13240 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13250 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13260 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13270 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13280 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13290 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 132A0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 132B0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 132C0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 132D0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 132E0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 132F0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13300 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13310 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13320 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13330 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13340 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13350 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13360 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13370 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13380 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13390 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 133A0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 133B0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 133C0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 133D0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 133E0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 133F0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13400 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13410 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, + /* 13420 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, O, + + /* Egyptian Hieroglyph Format Controls */ + + /* 13430 */ J, J, J, J, J, J, J, SB, SE, O, O, O, O, O, O, O, + +#define use_offset_0x16b00u 7736 + + + /* Pahawh Hmong */ + + /* 16B00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 16B10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 16B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 16B30 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, + +#define use_offset_0x16f00u 7792 + + + /* Miao */ + + /* 16F00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 16F10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 16F20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 16F30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 16F40 */ B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, CMBlw, + /* 16F50 */ O, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, + /* 16F60 */ VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, + /* 16F70 */ VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, + /* 16F80 */ VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, O, O, O, O, O, O, O, VMBlw, + /* 16F90 */ VMBlw, VMBlw, VMBlw, O, O, O, O, O, + +#define use_offset_0x16fe0u 7944 + + + /* Ideographic Symbols and Punctuation */ + + /* 16FE0 */ O, O, O, O, B, O, O, O, + +#define use_offset_0x18b00u 7952 + + + /* Khitan Small Script */ + + /* 18B00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18B10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18B30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18B40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18B50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18B60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18B70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18B80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18B90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18BA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18BB0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18BC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18BD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18BE0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18BF0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18C00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18C10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18C20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18C30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18C40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18C50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18C60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18C70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18C80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18C90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18CA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18CB0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18CC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 18CD0 */ B, B, B, B, B, B, O, O, + +#define use_offset_0x1bc00u 8424 + + + /* Duployan */ + + /* 1BC00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1BC10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1BC20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1BC30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1BC40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1BC50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1BC60 */ B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, + /* 1BC70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, + /* 1BC80 */ B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, O, + /* 1BC90 */ B, B, B, B, B, B, B, B, B, B, O, O, O, CMBlw, CMBlw, O, + +#define use_offset_0x1e100u 8584 + + + /* Nyiakeng Puachue Hmong */ + + /* 1E100 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1E110 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1E120 */ B, B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, + /* 1E130 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, B, B, B, B, B, B, B, O, O, + /* 1E140 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, B, B, + +#define use_offset_0x1e2c0u 8664 + + + /* Wancho */ + + /* 1E2C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1E2D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1E2E0 */ B, B, B, B, B, B, B, B, B, B, B, B, VMAbv, VMAbv, VMAbv, VMAbv, + /* 1E2F0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + +#define use_offset_0x1e900u 8728 + + + /* Adlam */ -USE_TABLE_ELEMENT_TYPE + /* 1E900 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1E910 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1E920 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1E930 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1E940 */ B, B, B, B, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, B, O, O, O, O, + /* 1E950 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + +}; /* Table items: 8824; occupancy: 79% */ + +static inline uint8_t hb_use_get_category (hb_codepoint_t u) { switch (u >> 12) @@ -760,14 +1075,16 @@ hb_use_get_category (hb_codepoint_t u) case 0x0u: if (hb_in_range<hb_codepoint_t> (u, 0x0028u, 0x003Fu)) return use_table[u - 0x0028u + use_offset_0x0028u]; if (hb_in_range<hb_codepoint_t> (u, 0x00A0u, 0x00D7u)) return use_table[u - 0x00A0u + use_offset_0x00a0u]; - if (hb_in_range<hb_codepoint_t> (u, 0x0348u, 0x034Fu)) return use_table[u - 0x0348u + use_offset_0x0348u]; + if (hb_in_range<hb_codepoint_t> (u, 0x0640u, 0x0647u)) return use_table[u - 0x0640u + use_offset_0x0640u]; + if (hb_in_range<hb_codepoint_t> (u, 0x07C8u, 0x07FFu)) return use_table[u - 0x07C8u + use_offset_0x07c8u]; + if (hb_in_range<hb_codepoint_t> (u, 0x0840u, 0x085Fu)) return use_table[u - 0x0840u + use_offset_0x0840u]; if (hb_in_range<hb_codepoint_t> (u, 0x0900u, 0x0DF7u)) return use_table[u - 0x0900u + use_offset_0x0900u]; - if (hb_in_range<hb_codepoint_t> (u, 0x0F18u, 0x0FC7u)) return use_table[u - 0x0F18u + use_offset_0x0f18u]; + if (hb_in_range<hb_codepoint_t> (u, 0x0F00u, 0x0FC7u)) return use_table[u - 0x0F00u + use_offset_0x0f00u]; break; case 0x1u: if (hb_in_range<hb_codepoint_t> (u, 0x1000u, 0x109Fu)) return use_table[u - 0x1000u + use_offset_0x1000u]; - if (hb_in_range<hb_codepoint_t> (u, 0x1700u, 0x17EFu)) return use_table[u - 0x1700u + use_offset_0x1700u]; + if (hb_in_range<hb_codepoint_t> (u, 0x1700u, 0x18AFu)) return use_table[u - 0x1700u + use_offset_0x1700u]; if (hb_in_range<hb_codepoint_t> (u, 0x1900u, 0x1A9Fu)) return use_table[u - 0x1900u + use_offset_0x1900u]; if (hb_in_range<hb_codepoint_t> (u, 0x1B00u, 0x1C4Fu)) return use_table[u - 0x1B00u + use_offset_0x1b00u]; if (hb_in_range<hb_codepoint_t> (u, 0x1CD0u, 0x1CFFu)) return use_table[u - 0x1CD0u + use_offset_0x1cd0u]; @@ -776,9 +1093,10 @@ hb_use_get_category (hb_codepoint_t u) case 0x2u: if (hb_in_range<hb_codepoint_t> (u, 0x2008u, 0x2017u)) return use_table[u - 0x2008u + use_offset_0x2008u]; - if (hb_in_range<hb_codepoint_t> (u, 0x2060u, 0x2087u)) return use_table[u - 0x2060u + use_offset_0x2060u]; + if (hb_in_range<hb_codepoint_t> (u, 0x2070u, 0x2087u)) return use_table[u - 0x2070u + use_offset_0x2070u]; if (hb_in_range<hb_codepoint_t> (u, 0x20F0u, 0x20F7u)) return use_table[u - 0x20F0u + use_offset_0x20f0u]; if (hb_in_range<hb_codepoint_t> (u, 0x25C8u, 0x25CFu)) return use_table[u - 0x25C8u + use_offset_0x25c8u]; + if (hb_in_range<hb_codepoint_t> (u, 0x2D30u, 0x2D7Fu)) return use_table[u - 0x2D30u + use_offset_0x2d30u]; break; case 0xAu: @@ -786,75 +1104,100 @@ hb_use_get_category (hb_codepoint_t u) if (hb_in_range<hb_codepoint_t> (u, 0xABC0u, 0xABFFu)) return use_table[u - 0xABC0u + use_offset_0xabc0u]; break; - case 0xFu: - if (hb_in_range<hb_codepoint_t> (u, 0xFE00u, 0xFE0Fu)) return use_table[u - 0xFE00u + use_offset_0xfe00u]; - break; - case 0x10u: if (hb_in_range<hb_codepoint_t> (u, 0x10A00u, 0x10A4Fu)) return use_table[u - 0x10A00u + use_offset_0x10a00u]; + if (hb_in_range<hb_codepoint_t> (u, 0x10AC0u, 0x10AE7u)) return use_table[u - 0x10AC0u + use_offset_0x10ac0u]; + if (hb_in_range<hb_codepoint_t> (u, 0x10B80u, 0x10BAFu)) return use_table[u - 0x10B80u + use_offset_0x10b80u]; + if (hb_in_range<hb_codepoint_t> (u, 0x10D00u, 0x10D3Fu)) return use_table[u - 0x10D00u + use_offset_0x10d00u]; + if (hb_in_range<hb_codepoint_t> (u, 0x10E80u, 0x10EB7u)) return use_table[u - 0x10E80u + use_offset_0x10e80u]; + if (hb_in_range<hb_codepoint_t> (u, 0x10F30u, 0x10F57u)) return use_table[u - 0x10F30u + use_offset_0x10f30u]; + if (hb_in_range<hb_codepoint_t> (u, 0x10FB0u, 0x110BFu)) return use_table[u - 0x10FB0u + use_offset_0x10fb0u]; break; case 0x11u: - if (hb_in_range<hb_codepoint_t> (u, 0x11000u, 0x110BFu)) return use_table[u - 0x11000u + use_offset_0x11000u]; + if (hb_in_range<hb_codepoint_t> (u, 0x10FB0u, 0x110BFu)) return use_table[u - 0x10FB0u + use_offset_0x10fb0u]; if (hb_in_range<hb_codepoint_t> (u, 0x11100u, 0x1123Fu)) return use_table[u - 0x11100u + use_offset_0x11100u]; if (hb_in_range<hb_codepoint_t> (u, 0x11280u, 0x11377u)) return use_table[u - 0x11280u + use_offset_0x11280u]; if (hb_in_range<hb_codepoint_t> (u, 0x11400u, 0x114DFu)) return use_table[u - 0x11400u + use_offset_0x11400u]; if (hb_in_range<hb_codepoint_t> (u, 0x11580u, 0x1173Fu)) return use_table[u - 0x11580u + use_offset_0x11580u]; if (hb_in_range<hb_codepoint_t> (u, 0x11800u, 0x1183Fu)) return use_table[u - 0x11800u + use_offset_0x11800u]; + if (hb_in_range<hb_codepoint_t> (u, 0x11900u, 0x1195Fu)) return use_table[u - 0x11900u + use_offset_0x11900u]; if (hb_in_range<hb_codepoint_t> (u, 0x119A0u, 0x11A9Fu)) return use_table[u - 0x119A0u + use_offset_0x119a0u]; if (hb_in_range<hb_codepoint_t> (u, 0x11C00u, 0x11CB7u)) return use_table[u - 0x11C00u + use_offset_0x11c00u]; if (hb_in_range<hb_codepoint_t> (u, 0x11D00u, 0x11DAFu)) return use_table[u - 0x11D00u + use_offset_0x11d00u]; if (hb_in_range<hb_codepoint_t> (u, 0x11EE0u, 0x11EF7u)) return use_table[u - 0x11EE0u + use_offset_0x11ee0u]; break; + case 0x13u: + if (hb_in_range<hb_codepoint_t> (u, 0x13000u, 0x1343Fu)) return use_table[u - 0x13000u + use_offset_0x13000u]; + break; + + case 0x16u: + if (hb_in_range<hb_codepoint_t> (u, 0x16B00u, 0x16B37u)) return use_table[u - 0x16B00u + use_offset_0x16b00u]; + if (hb_in_range<hb_codepoint_t> (u, 0x16F00u, 0x16F97u)) return use_table[u - 0x16F00u + use_offset_0x16f00u]; + if (hb_in_range<hb_codepoint_t> (u, 0x16FE0u, 0x16FE7u)) return use_table[u - 0x16FE0u + use_offset_0x16fe0u]; + break; + + case 0x18u: + if (hb_in_range<hb_codepoint_t> (u, 0x18B00u, 0x18CD7u)) return use_table[u - 0x18B00u + use_offset_0x18b00u]; + break; + + case 0x1Bu: + if (hb_in_range<hb_codepoint_t> (u, 0x1BC00u, 0x1BC9Fu)) return use_table[u - 0x1BC00u + use_offset_0x1bc00u]; + break; + + case 0x1Eu: + if (hb_in_range<hb_codepoint_t> (u, 0x1E100u, 0x1E14Fu)) return use_table[u - 0x1E100u + use_offset_0x1e100u]; + if (hb_in_range<hb_codepoint_t> (u, 0x1E2C0u, 0x1E2FFu)) return use_table[u - 0x1E2C0u + use_offset_0x1e2c0u]; + if (hb_in_range<hb_codepoint_t> (u, 0x1E900u, 0x1E95Fu)) return use_table[u - 0x1E900u + use_offset_0x1e900u]; + break; + default: break; } - return USE_O; + return USE(O); } #undef B -#undef CGJ #undef CS +#undef G #undef GB #undef H #undef HN #undef HVM -#undef IND +#undef J #undef N #undef O #undef R -#undef Rsv #undef S +#undef SB +#undef SE #undef SUB #undef Sk -#undef VS -#undef WJ -#undef ZWJ #undef ZWNJ -#undef CMBlw #undef CMAbv +#undef CMBlw +#undef FAbv #undef FBlw #undef FPst -#undef FAbv +#undef FMAbv #undef FMBlw #undef FMPst -#undef FMAbv -#undef MPre +#undef MAbv #undef MBlw #undef MPst -#undef MAbv -#undef SMBlw +#undef MPre #undef SMAbv -#undef VPre +#undef SMBlw +#undef VAbv #undef VBlw #undef VPst -#undef VAbv -#undef VMPre +#undef VPre +#undef VMAbv #undef VMBlw #undef VMPst -#undef VMAbv +#undef VMPre -#endif +#endif /* HB_OT_SHAPE_COMPLEX_USE_TABLE_HH */ /* == End of generated table == */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use.cc index 10f5822c00..0d0b7e771e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use.cc @@ -30,13 +30,12 @@ #ifndef HB_NO_OT_SHAPE -#include "hb-ot-shape-complex-use.hh" +#include "hb-ot-shape-complex-use-machine.hh" +#include "hb-ot-shape-complex-use-table.hh" #include "hb-ot-shape-complex-arabic.hh" +#include "hb-ot-shape-complex-arabic-joining-list.hh" #include "hb-ot-shape-complex-vowel-constraints.hh" -/* buffer var allocations */ -#define use_category() complex_var_u8_0() - /* * Universal Shaping Engine. @@ -68,11 +67,11 @@ use_topographical_features[] = }; /* Same order as use_topographical_features. */ enum joining_form_t { - USE_ISOL, - USE_INIT, - USE_MEDI, - USE_FINA, - _USE_NONE + JOINING_FORM_ISOL, + JOINING_FORM_INIT, + JOINING_FORM_MEDI, + JOINING_FORM_FINA, + _JOINING_FORM_NONE }; static const hb_tag_t use_other_features[] = @@ -152,40 +151,6 @@ struct use_shape_plan_t arabic_shape_plan_t *arabic_plan; }; -static bool -has_arabic_joining (hb_script_t script) -{ - /* List of scripts that have data in arabic-table. */ - switch ((int) script) - { - /* Unicode-1.1 additions */ - case HB_SCRIPT_ARABIC: - - /* Unicode-3.0 additions */ - case HB_SCRIPT_MONGOLIAN: - case HB_SCRIPT_SYRIAC: - - /* Unicode-5.0 additions */ - case HB_SCRIPT_NKO: - case HB_SCRIPT_PHAGS_PA: - - /* Unicode-6.0 additions */ - case HB_SCRIPT_MANDAIC: - - /* Unicode-7.0 additions */ - case HB_SCRIPT_MANICHAEAN: - case HB_SCRIPT_PSALTER_PAHLAVI: - - /* Unicode-9.0 additions */ - case HB_SCRIPT_ADLAM: - - return true; - - default: - return false; - } -} - static void * data_create_use (const hb_ot_shape_plan_t *plan) { @@ -219,21 +184,6 @@ data_destroy_use (void *data) free (data); } -enum use_syllable_type_t { - use_independent_cluster, - use_virama_terminated_cluster, - use_sakot_terminated_cluster, - use_standard_cluster, - use_number_joiner_terminated_cluster, - use_numeral_cluster, - use_symbol_cluster, - use_broken_cluster, - use_non_cluster, -}; - -#include "hb-ot-shape-complex-use-machine.hh" - - static void setup_masks_use (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, @@ -271,7 +221,7 @@ setup_rphf_mask (const hb_ot_shape_plan_t *plan, foreach_syllable (buffer, start, end) { - unsigned int limit = info[start].use_category() == USE_R ? 1 : hb_min (3u, end - start); + unsigned int limit = info[start].use_category() == USE(R) ? 1 : hb_min (3u, end - start); for (unsigned int i = start; i < start + limit; i++) info[i].mask |= mask; } @@ -285,7 +235,7 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan, if (use_plan->arabic_plan) return; - static_assert ((USE_INIT < 4 && USE_ISOL < 4 && USE_MEDI < 4 && USE_FINA < 4), ""); + static_assert ((JOINING_FORM_INIT < 4 && JOINING_FORM_ISOL < 4 && JOINING_FORM_MEDI < 4 && JOINING_FORM_FINA < 4), ""); hb_mask_t masks[4], all_masks = 0; for (unsigned int i = 0; i < 4; i++) { @@ -299,7 +249,7 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan, hb_mask_t other_masks = ~all_masks; unsigned int last_start = 0; - joining_form_t last_form = _USE_NONE; + joining_form_t last_form = _JOINING_FORM_NONE; hb_glyph_info_t *info = buffer->info; foreach_syllable (buffer, start, end) { @@ -308,9 +258,10 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan, { case use_independent_cluster: case use_symbol_cluster: + case use_hieroglyph_cluster: case use_non_cluster: /* These don't join. Nothing to do. */ - last_form = _USE_NONE; + last_form = _JOINING_FORM_NONE; break; case use_virama_terminated_cluster: @@ -320,18 +271,18 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan, case use_numeral_cluster: case use_broken_cluster: - bool join = last_form == USE_FINA || last_form == USE_ISOL; + bool join = last_form == JOINING_FORM_FINA || last_form == JOINING_FORM_ISOL; if (join) { /* Fixup previous syllable's form. */ - last_form = last_form == USE_FINA ? USE_MEDI : USE_INIT; + last_form = last_form == JOINING_FORM_FINA ? JOINING_FORM_MEDI : JOINING_FORM_INIT; for (unsigned int i = last_start; i < start; i++) info[i].mask = (info[i].mask & other_masks) | masks[last_form]; } /* Form for this syllable. */ - last_form = join ? USE_FINA : USE_ISOL; + last_form = join ? JOINING_FORM_FINA : JOINING_FORM_ISOL; for (unsigned int i = start; i < end; i++) info[i].mask = (info[i].mask & other_masks) | masks[last_form]; @@ -367,11 +318,11 @@ record_rphf_use (const hb_ot_shape_plan_t *plan, foreach_syllable (buffer, start, end) { - /* Mark a substituted repha as USE_R. */ + /* Mark a substituted repha as USE(R). */ for (unsigned int i = start; i < end && (info[i].mask & mask); i++) if (_hb_glyph_info_substituted (&info[i])) { - info[i].use_category() = USE_R; + info[i].use_category() = USE(R); break; } } @@ -390,7 +341,7 @@ record_pref_use (const hb_ot_shape_plan_t *plan HB_UNUSED, for (unsigned int i = start; i < end; i++) if (_hb_glyph_info_substituted (&info[i])) { - info[i].use_category() = USE_VPre; + info[i].use_category() = USE(VPre); break; } } @@ -399,7 +350,7 @@ record_pref_use (const hb_ot_shape_plan_t *plan HB_UNUSED, static inline bool is_halant_use (const hb_glyph_info_t &info) { - return (info.use_category() == USE_H || info.use_category() == USE_HVM) && + return (info.use_category() == USE(H) || info.use_category() == USE(HVM)) && !_hb_glyph_info_ligated (&info); } @@ -418,25 +369,24 @@ reorder_syllable_use (hb_buffer_t *buffer, unsigned int start, unsigned int end) hb_glyph_info_t *info = buffer->info; -#define POST_BASE_FLAGS64 (FLAG64 (USE_FM) | \ - FLAG64 (USE_FAbv) | \ - FLAG64 (USE_FBlw) | \ - FLAG64 (USE_FPst) | \ - FLAG64 (USE_MAbv) | \ - FLAG64 (USE_MBlw) | \ - FLAG64 (USE_MPst) | \ - FLAG64 (USE_MPre) | \ - FLAG64 (USE_VAbv) | \ - FLAG64 (USE_VBlw) | \ - FLAG64 (USE_VPst) | \ - FLAG64 (USE_VPre) | \ - FLAG64 (USE_VMAbv) | \ - FLAG64 (USE_VMBlw) | \ - FLAG64 (USE_VMPst) | \ - FLAG64 (USE_VMPre)) +#define POST_BASE_FLAGS64 (FLAG64 (USE(FAbv)) | \ + FLAG64 (USE(FBlw)) | \ + FLAG64 (USE(FPst)) | \ + FLAG64 (USE(MAbv)) | \ + FLAG64 (USE(MBlw)) | \ + FLAG64 (USE(MPst)) | \ + FLAG64 (USE(MPre)) | \ + FLAG64 (USE(VAbv)) | \ + FLAG64 (USE(VBlw)) | \ + FLAG64 (USE(VPst)) | \ + FLAG64 (USE(VPre)) | \ + FLAG64 (USE(VMAbv)) | \ + FLAG64 (USE(VMBlw)) | \ + FLAG64 (USE(VMPst)) | \ + FLAG64 (USE(VMPre))) /* Move things forward. */ - if (info[start].use_category() == USE_R && end - start > 1) + if (info[start].use_category() == USE(R) && end - start > 1) { /* Got a repha. Reorder it towards the end, but before the first post-base * glyph. */ @@ -473,7 +423,7 @@ reorder_syllable_use (hb_buffer_t *buffer, unsigned int start, unsigned int end) * shift things in between forward. */ j = i + 1; } - else if (((flag) & (FLAG (USE_VPre) | FLAG (USE_VMPre))) && + else if (((flag) & (FLAG (USE(VPre)) | FLAG (USE(VMPre)))) && /* Only move the first component of a MultipleSubst. */ 0 == _hb_glyph_info_get_lig_comp (&info[i]) && j < i) @@ -486,73 +436,23 @@ reorder_syllable_use (hb_buffer_t *buffer, unsigned int start, unsigned int end) } } -static inline void -insert_dotted_circles_use (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_font_t *font, - hb_buffer_t *buffer) -{ - if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)) - return; - - /* Note: This loop is extra overhead, but should not be measurable. - * TODO Use a buffer scratch flag to remove the loop. */ - bool has_broken_syllables = false; - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 0; i < count; i++) - if ((info[i].syllable() & 0x0F) == use_broken_cluster) - { - has_broken_syllables = true; - break; - } - if (likely (!has_broken_syllables)) - return; - - hb_glyph_info_t dottedcircle = {0}; - if (!font->get_nominal_glyph (0x25CCu, &dottedcircle.codepoint)) - return; - dottedcircle.use_category() = hb_use_get_category (0x25CC); - - buffer->clear_output (); - - buffer->idx = 0; - unsigned int last_syllable = 0; - while (buffer->idx < buffer->len && buffer->successful) - { - unsigned int syllable = buffer->cur().syllable(); - use_syllable_type_t syllable_type = (use_syllable_type_t) (syllable & 0x0F); - if (unlikely (last_syllable != syllable && syllable_type == use_broken_cluster)) - { - last_syllable = syllable; - - hb_glyph_info_t ginfo = dottedcircle; - ginfo.cluster = buffer->cur().cluster; - ginfo.mask = buffer->cur().mask; - ginfo.syllable() = buffer->cur().syllable(); - - /* Insert dottedcircle after possible Repha. */ - while (buffer->idx < buffer->len && buffer->successful && - last_syllable == buffer->cur().syllable() && - buffer->cur().use_category() == USE_R) - buffer->next_glyph (); - - buffer->output_info (ginfo); - } - else - buffer->next_glyph (); - } - buffer->swap_buffers (); -} - static void reorder_use (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { - insert_dotted_circles_use (plan, font, buffer); + if (buffer->message (font, "start reordering USE")) + { + hb_syllabic_insert_dotted_circles (font, buffer, + use_broken_cluster, + USE(B), + USE(R)); - foreach_syllable (buffer, start, end) - reorder_syllable_use (buffer, start, end); + foreach_syllable (buffer, start, end) + reorder_syllable_use (buffer, start, end); + + (void) buffer->message (font, "end reordering USE"); + } HB_BUFFER_DEALLOCATE_VAR (buffer, use_category); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use.hh deleted file mode 100644 index ce6645ecd3..0000000000 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use.hh +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright © 2015 Mozilla Foundation. - * Copyright © 2015 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. - * - * Mozilla Author(s): Jonathan Kew - * Google Author(s): Behdad Esfahbod - */ - -#ifndef HB_OT_SHAPE_COMPLEX_USE_HH -#define HB_OT_SHAPE_COMPLEX_USE_HH - -#include "hb.hh" - - -#include "hb-ot-shape-complex.hh" - - -#define USE_TABLE_ELEMENT_TYPE uint8_t - -/* Cateories used in the Universal Shaping Engine spec: - * https://docs.microsoft.com/en-us/typography/script-development/use - */ -/* Note: This enum is duplicated in the -machine.rl source file. - * Not sure how to avoid duplication. */ -enum use_category_t { - USE_O = 0, /* OTHER */ - - USE_B = 1, /* BASE */ - USE_IND = 3, /* BASE_IND */ - USE_N = 4, /* BASE_NUM */ - USE_GB = 5, /* BASE_OTHER */ - USE_CGJ = 6, /* CGJ */ -// USE_F = 7, /* CONS_FINAL */ - USE_FM = 8, /* CONS_FINAL_MOD */ -// USE_M = 9, /* CONS_MED */ -// USE_CM = 10, /* CONS_MOD */ - USE_SUB = 11, /* CONS_SUB */ - USE_H = 12, /* HALANT */ - - USE_HN = 13, /* HALANT_NUM */ - USE_ZWNJ = 14, /* Zero width non-joiner */ - USE_ZWJ = 15, /* Zero width joiner */ - USE_WJ = 16, /* Word joiner */ - USE_Rsv = 17, /* Reserved characters */ - USE_R = 18, /* REPHA */ - USE_S = 19, /* SYM */ -// USE_SM = 20, /* SYM_MOD */ - USE_VS = 21, /* VARIATION_SELECTOR */ -// USE_V = 36, /* VOWEL */ -// USE_VM = 40, /* VOWEL_MOD */ - USE_CS = 43, /* CONS_WITH_STACKER */ - - /* https://github.com/harfbuzz/harfbuzz/issues/1102 */ - USE_HVM = 44, /* HALANT_OR_VOWEL_MODIFIER */ - - USE_Sk = 48, /* SAKOT */ - - USE_FAbv = 24, /* CONS_FINAL_ABOVE */ - USE_FBlw = 25, /* CONS_FINAL_BELOW */ - USE_FPst = 26, /* CONS_FINAL_POST */ - USE_MAbv = 27, /* CONS_MED_ABOVE */ - USE_MBlw = 28, /* CONS_MED_BELOW */ - USE_MPst = 29, /* CONS_MED_POST */ - USE_MPre = 30, /* CONS_MED_PRE */ - USE_CMAbv = 31, /* CONS_MOD_ABOVE */ - USE_CMBlw = 32, /* CONS_MOD_BELOW */ - USE_VAbv = 33, /* VOWEL_ABOVE / VOWEL_ABOVE_BELOW / VOWEL_ABOVE_BELOW_POST / VOWEL_ABOVE_POST */ - USE_VBlw = 34, /* VOWEL_BELOW / VOWEL_BELOW_POST */ - USE_VPst = 35, /* VOWEL_POST UIPC = Right */ - USE_VPre = 22, /* VOWEL_PRE / VOWEL_PRE_ABOVE / VOWEL_PRE_ABOVE_POST / VOWEL_PRE_POST */ - USE_VMAbv = 37, /* VOWEL_MOD_ABOVE */ - USE_VMBlw = 38, /* VOWEL_MOD_BELOW */ - USE_VMPst = 39, /* VOWEL_MOD_POST */ - USE_VMPre = 23, /* VOWEL_MOD_PRE */ - USE_SMAbv = 41, /* SYM_MOD_ABOVE */ - USE_SMBlw = 42, /* SYM_MOD_BELOW */ - USE_FMAbv = 45, /* CONS_FINAL_MOD UIPC = Top */ - USE_FMBlw = 46, /* CONS_FINAL_MOD UIPC = Bottom */ - USE_FMPst = 47, /* CONS_FINAL_MOD UIPC = Not_Applicable */ -}; - -HB_INTERNAL USE_TABLE_ELEMENT_TYPE -hb_use_get_category (hb_codepoint_t u); - -#endif /* HB_OT_SHAPE_COMPLEX_USE_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-vowel-constraints.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-vowel-constraints.cc index 2f8041323a..1037626998 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-vowel-constraints.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-vowel-constraints.cc @@ -2,15 +2,16 @@ /* * The following functions are generated by running: * - * ./gen-vowel-constraints.py use Scripts.txt + * ./gen-vowel-constraints.py ms-use/IndicShapingInvalidCluster.txt Scripts.txt * * on files with these headers: * - * # Copied from https://docs.microsoft.com/en-us/typography/script-development/use - * # On October 23, 2018; with documentd dated 02/07/2018. + * # IndicShapingInvalidCluster.txt + * # Date: 2015-03-12, 21:17:00 GMT [AG] + * # Date: 2019-11-08, 23:22:00 GMT [AG] * - * # Scripts-12.0.0.txt - * # Date: 2019-01-28, 22:16:47 GMT + * # Scripts-13.0.0.txt + * # Date: 2020-01-22, 00:07:43 GMT */ #include "hb.hh" @@ -22,15 +23,15 @@ static void _output_dotted_circle (hb_buffer_t *buffer) { - hb_glyph_info_t &dottedcircle = buffer->output_glyph (0x25CCu); - _hb_glyph_info_reset_continuation (&dottedcircle); + (void) buffer->output_glyph (0x25CCu); + _hb_glyph_info_reset_continuation (&buffer->prev()); } static void _output_with_dotted_circle (hb_buffer_t *buffer) { _output_dotted_circle (buffer); - buffer->next_glyph (); + (void) buffer->next_glyph (); } void @@ -50,7 +51,6 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, * * https://github.com/harfbuzz/harfbuzz/issues/1019 */ - bool processed = false; buffer->clear_output (); unsigned int count = buffer->len; switch ((unsigned) buffer->props.script) @@ -96,16 +96,14 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, buffer->idx + 2 < count && 0x0907u == buffer->cur (2).codepoint) { - buffer->next_glyph (); - buffer->next_glyph (); - _output_dotted_circle (buffer); + (void) buffer->next_glyph (); + matched = true; } break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_BENGALI: @@ -124,10 +122,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, matched = 0x09E2u == buffer->cur (1).codepoint; break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_GURMUKHI: @@ -161,10 +158,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, } break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_GUJARATI: @@ -186,10 +182,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, matched = 0x0ABEu == buffer->cur (1).codepoint; break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_ORIYA: @@ -205,10 +200,23 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, matched = 0x0B57u == buffer->cur (1).codepoint; break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); + if (matched) _output_with_dotted_circle (buffer); + } + break; + + case HB_SCRIPT_TAMIL: + for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;) + { + bool matched = false; + if (0x0B85u == buffer->cur ().codepoint && + 0x0BC2u == buffer->cur (1).codepoint) + { + matched = true; + } + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_TELUGU: @@ -229,10 +237,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, matched = 0x0C55u == buffer->cur (1).codepoint; break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_KANNADA: @@ -248,10 +255,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, matched = 0x0CCCu == buffer->cur (1).codepoint; break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_MALAYALAM: @@ -275,10 +281,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, } break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_SINHALA: @@ -305,16 +310,15 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, switch (buffer->cur (1).codepoint) { case 0x0DCAu: case 0x0DD9u: case 0x0DDAu: case 0x0DDCu: - case 0x0DDDu: + case 0x0DDDu: case 0x0DDEu: matched = true; break; } break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_BRAHMI: @@ -333,10 +337,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, matched = 0x11042u == buffer->cur (1).codepoint; break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_KHUDAWADI: @@ -355,10 +358,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, } break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_TIRHUTA: @@ -382,10 +384,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, } break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_MODI: @@ -403,10 +404,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, } break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_TAKRI: @@ -427,21 +427,15 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, matched = 0x116B2u == buffer->cur (1).codepoint; break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; default: break; } - if (processed) - { - if (buffer->idx < count) - buffer->next_glyph (); - buffer->swap_buffers (); - } + buffer->swap_buffers (); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex.hh index 2691622135..19e24b9f30 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex.hh @@ -35,8 +35,8 @@ /* buffer var allocations, used by complex shapers */ -#define complex_var_u8_0() var2.u8[2] -#define complex_var_u8_1() var2.u8[3] +#define complex_var_u8_category() var2.u8[2] +#define complex_var_u8_auxiliary() var2.u8[3] #define HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS 32 @@ -50,8 +50,9 @@ enum hb_ot_shape_zero_width_marks_type_t { /* Master OT shaper list */ #define HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS \ - HB_COMPLEX_SHAPER_IMPLEMENT (default) /* should be first */ \ HB_COMPLEX_SHAPER_IMPLEMENT (arabic) \ + HB_COMPLEX_SHAPER_IMPLEMENT (default) \ + HB_COMPLEX_SHAPER_IMPLEMENT (dumber) \ HB_COMPLEX_SHAPER_IMPLEMENT (hangul) \ HB_COMPLEX_SHAPER_IMPLEMENT (hebrew) \ HB_COMPLEX_SHAPER_IMPLEMENT (indic) \ @@ -60,7 +61,7 @@ enum hb_ot_shape_zero_width_marks_type_t { HB_COMPLEX_SHAPER_IMPLEMENT (myanmar_zawgyi) \ HB_COMPLEX_SHAPER_IMPLEMENT (thai) \ HB_COMPLEX_SHAPER_IMPLEMENT (use) \ - /* ^--- Add new shapers here */ + /* ^--- Add new shapers here; keep sorted. */ struct hb_ot_complex_shaper_t @@ -185,27 +186,8 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) case HB_SCRIPT_ARABIC: /* Unicode-3.0 additions */ - case HB_SCRIPT_MONGOLIAN: case HB_SCRIPT_SYRIAC: - /* Unicode-5.0 additions */ - case HB_SCRIPT_NKO: - case HB_SCRIPT_PHAGS_PA: - - /* Unicode-6.0 additions */ - case HB_SCRIPT_MANDAIC: - - /* Unicode-7.0 additions */ - case HB_SCRIPT_MANICHAEAN: - case HB_SCRIPT_PSALTER_PAHLAVI: - - /* Unicode-9.0 additions */ - case HB_SCRIPT_ADLAM: - - /* Unicode-11.0 additions */ - case HB_SCRIPT_HANIFI_ROHINGYA: - case HB_SCRIPT_SOGDIAN: - /* For Arabic script, use the Arabic shaper even if no OT script tag was found. * This is because we do fallback shaping for Arabic script (and not others). * But note that Arabic shaping is applicable only to horizontal layout; for @@ -283,8 +265,9 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) return &_hb_ot_complex_shaper_myanmar; - /* https://github.com/harfbuzz/harfbuzz/issues/1162 */ +#define HB_SCRIPT_MYANMAR_ZAWGYI ((hb_script_t) HB_TAG ('Q','a','a','g')) case HB_SCRIPT_MYANMAR_ZAWGYI: + /* https://github.com/harfbuzz/harfbuzz/issues/1162 */ return &_hb_ot_complex_shaper_myanmar_zawgyi; @@ -293,7 +276,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) case HB_SCRIPT_TIBETAN: /* Unicode-3.0 additions */ - //case HB_SCRIPT_MONGOLIAN: + case HB_SCRIPT_MONGOLIAN: //case HB_SCRIPT_SINHALA: /* Unicode-3.2 additions */ @@ -314,8 +297,8 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) /* Unicode-5.0 additions */ case HB_SCRIPT_BALINESE: - //case HB_SCRIPT_NKO: - //case HB_SCRIPT_PHAGS_PA: + case HB_SCRIPT_NKO: + case HB_SCRIPT_PHAGS_PA: /* Unicode-5.1 additions */ case HB_SCRIPT_CHAM: @@ -336,10 +319,11 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) /* Unicode-6.0 additions */ case HB_SCRIPT_BATAK: case HB_SCRIPT_BRAHMI: - //case HB_SCRIPT_MANDAIC: + case HB_SCRIPT_MANDAIC: /* Unicode-6.1 additions */ case HB_SCRIPT_CHAKMA: + case HB_SCRIPT_MIAO: case HB_SCRIPT_SHARADA: case HB_SCRIPT_TAKRI: @@ -349,18 +333,19 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) case HB_SCRIPT_KHOJKI: case HB_SCRIPT_KHUDAWADI: case HB_SCRIPT_MAHAJANI: - //case HB_SCRIPT_MANICHAEAN: + case HB_SCRIPT_MANICHAEAN: case HB_SCRIPT_MODI: case HB_SCRIPT_PAHAWH_HMONG: - //case HB_SCRIPT_PSALTER_PAHLAVI: + case HB_SCRIPT_PSALTER_PAHLAVI: case HB_SCRIPT_SIDDHAM: case HB_SCRIPT_TIRHUTA: /* Unicode-8.0 additions */ case HB_SCRIPT_AHOM: + case HB_SCRIPT_MULTANI: /* Unicode-9.0 additions */ - //case HB_SCRIPT_ADLAM: + case HB_SCRIPT_ADLAM: case HB_SCRIPT_BHAIKSUKI: case HB_SCRIPT_MARCHEN: case HB_SCRIPT_NEWA: @@ -373,12 +358,21 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) /* Unicode-11.0 additions */ case HB_SCRIPT_DOGRA: case HB_SCRIPT_GUNJALA_GONDI: - //case HB_SCRIPT_HANIFI_ROHINGYA: + case HB_SCRIPT_HANIFI_ROHINGYA: case HB_SCRIPT_MAKASAR: - //case HB_SCRIPT_SOGDIAN: + case HB_SCRIPT_MEDEFAIDRIN: + case HB_SCRIPT_OLD_SOGDIAN: + case HB_SCRIPT_SOGDIAN: /* Unicode-12.0 additions */ + case HB_SCRIPT_ELYMAIC: case HB_SCRIPT_NANDINAGARI: + case HB_SCRIPT_NYIAKENG_PUACHUE_HMONG: + case HB_SCRIPT_WANCHO: + + /* Unicode-13.0 additions */ + case HB_SCRIPT_CHORASMIAN: + case HB_SCRIPT_DIVES_AKURU: /* If the designer designed the font for the 'DFLT' script, * (or we ended up arbitrarily pick 'latn'), use the default shaper. diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc index 024bcfe04f..7d00a35ab9 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc @@ -301,7 +301,7 @@ position_mark (const hb_ot_shape_plan_t *plan HB_UNUSED, /* Don't shift down "above" marks too much. */ if ((y_gap > 0) != (pos.y_offset > 0)) { - unsigned int correction = -pos.y_offset / 2; + int correction = -pos.y_offset / 2; base_extents.y_bearing += correction; base_extents.height -= correction; pos.y_offset += correction; @@ -422,12 +422,12 @@ position_cluster (const hb_ot_shape_plan_t *plan, /* Find the base glyph */ hb_glyph_info_t *info = buffer->info; for (unsigned int i = start; i < end; i++) - if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i]))) + if (!_hb_glyph_info_is_unicode_mark (&info[i])) { /* Find mark glyphs */ unsigned int j; for (j = i + 1; j < end; j++) - if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[j]))) + if (!_hb_glyph_info_is_unicode_mark (&info[j])) break; position_around_base (plan, font, buffer, i, j, adjust_offsets_when_zeroing); @@ -452,7 +452,7 @@ _hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan, unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; for (unsigned int i = 1; i < count; i++) - if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])))) { + if (likely (!_hb_glyph_info_is_unicode_mark (&info[i]))) { position_cluster (plan, font, buffer, start, i, adjust_offsets_when_zeroing); start = i; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc index 553d532574..778b5b8bd8 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc @@ -101,8 +101,9 @@ set_glyph (hb_glyph_info_t &info, hb_font_t *font) static inline void output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph) { + /* This is very confusing indeed. */ buffer->cur().glyph_index() = glyph; - buffer->output_glyph (unichar); /* This is very confusing indeed. */ + (void) buffer->output_glyph (unichar); _hb_glyph_info_set_unicode_props (&buffer->prev(), buffer); } @@ -110,7 +111,7 @@ static inline void next_char (hb_buffer_t *buffer, hb_codepoint_t glyph) { buffer->cur().glyph_index() = glyph; - buffer->next_glyph (); + (void) buffer->next_glyph (); } static inline void @@ -229,30 +230,35 @@ handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, if (font->get_variation_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index())) { hb_codepoint_t unicode = buffer->cur().codepoint; - buffer->replace_glyphs (2, 1, &unicode); + (void) buffer->replace_glyphs (2, 1, &unicode); } else { /* Just pass on the two characters separately, let GSUB do its magic. */ set_glyph (buffer->cur(), font); - buffer->next_glyph (); + (void) buffer->next_glyph (); set_glyph (buffer->cur(), font); - buffer->next_glyph (); + (void) buffer->next_glyph (); } /* Skip any further variation selectors. */ - while (buffer->idx < end && unlikely (buffer->unicode->is_variation_selector (buffer->cur().codepoint))) + while (buffer->idx < end && + buffer->successful && + unlikely (buffer->unicode->is_variation_selector (buffer->cur().codepoint))) { set_glyph (buffer->cur(), font); - buffer->next_glyph (); + (void) buffer->next_glyph (); } - } else { + } + else + { set_glyph (buffer->cur(), font); - buffer->next_glyph (); + (void) buffer->next_glyph (); } } - if (likely (buffer->idx < end)) { + if (likely (buffer->idx < end)) + { set_glyph (buffer->cur(), font); - buffer->next_glyph (); + (void) buffer->next_glyph (); } } @@ -334,7 +340,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, { unsigned int end; for (end = buffer->idx + 1; end < count; end++) - if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[end])))) + if (unlikely (_hb_glyph_info_is_unicode_mark (&buffer->info[end]))) break; if (end < count) @@ -348,7 +354,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, sizeof (buffer->info[0]), &buffer->cur().glyph_index(), sizeof (buffer->info[0])); - buffer->next_glyphs (done); + if (unlikely (!buffer->next_glyphs (done))) break; } while (buffer->idx < end && buffer->successful) decompose_current_character (&c, might_short_circuit); @@ -360,7 +366,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, /* Find all the marks now. */ for (end = buffer->idx + 1; end < count; end++) - if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[end]))) + if (!_hb_glyph_info_is_unicode_mark(&buffer->info[end])) break; /* idx to end is one non-simple cluster. */ @@ -373,7 +379,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, /* Second round, reorder (inplace) */ - if (!all_simple) + if (!all_simple && buffer->message(font, "start reorder")) { count = buffer->len; for (unsigned int i = 0; i < count; i++) @@ -399,6 +405,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, i = end; } + (void) buffer->message(font, "end reorder"); } if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_CGJ) { @@ -408,7 +415,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, */ for (unsigned int i = 1; i + 1 < buffer->len; i++) if (buffer->info[i].codepoint == 0x034Fu/*CGJ*/ && - info_cc(buffer->info[i-1]) <= info_cc(buffer->info[i+1])) + (info_cc(buffer->info[i+1]) == 0 || info_cc(buffer->info[i-1]) <= info_cc(buffer->info[i+1]))) { _hb_glyph_info_unhide (&buffer->info[i]); } @@ -418,6 +425,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, /* Third round, recompose */ if (!all_simple && + buffer->successful && (mode == HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS || mode == HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT)) { @@ -427,15 +435,15 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, buffer->clear_output (); count = buffer->len; unsigned int starter = 0; - buffer->next_glyph (); - while (buffer->idx < count && buffer->successful) + (void) buffer->next_glyph (); + while (buffer->idx < count /* No need for: && buffer->successful */) { hb_codepoint_t composed, glyph; if (/* We don't try to compose a non-mark character with it's preceding starter. * This is both an optimization to avoid trying to compose every two neighboring * glyphs in most scripts AND a desired feature for Hangul. Apparently Hangul * fonts are not designed to mix-and-match pre-composed syllables and Jamo. */ - HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->cur()))) + _hb_glyph_info_is_unicode_mark(&buffer->cur())) { if (/* If there's anything between the starter and this char, they should have CCC * smaller than this character's. */ @@ -450,9 +458,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, font->get_nominal_glyph (composed, &glyph)) { /* Composes. */ - buffer->next_glyph (); /* Copy to out-buffer. */ - if (unlikely (!buffer->successful)) - return; + if (unlikely (!buffer->next_glyph ())) break; /* Copy to out-buffer. */ buffer->merge_out_clusters (starter, buffer->out_len); buffer->out_len--; /* Remove the second composable. */ /* Modify starter and carry on. */ @@ -465,7 +471,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, } /* Blocked, or doesn't compose. */ - buffer->next_glyph (); + if (unlikely (!buffer->next_glyph ())) break; if (info_cc (buffer->prev()) == 0) starter = buffer->out_len - 1; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc index 5d9a70cda2..86ab0b4268 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc @@ -48,6 +48,16 @@ #include "hb-aat-layout.hh" +#ifndef HB_NO_AAT_SHAPE +static inline bool +_hb_apply_morx (hb_face_t *face, const hb_segment_properties_t *props) +{ + /* https://github.com/harfbuzz/harfbuzz/issues/2124 */ + return hb_aat_layout_has_substitution (face) && + (HB_DIRECTION_IS_HORIZONTAL (props->direction) || !hb_ot_layout_has_substitution (face)); +} +#endif + /** * SECTION:hb-ot-shape * @title: hb-ot-shape @@ -63,23 +73,6 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, const hb_feature_t *user_features, unsigned int num_user_features); -#ifndef HB_NO_AAT_SHAPE -static inline bool -_hb_apply_morx (hb_face_t *face) -{ - if (hb_options ().aat && - hb_aat_layout_has_substitution (face)) - return true; - - /* Ignore empty GSUB tables. */ - return (!hb_ot_layout_has_substitution (face) || - !hb_ot_layout_table_get_script_tags (face, - HB_OT_TAG_GSUB, - 0, nullptr, nullptr)) && - hb_aat_layout_has_substitution (face); -} -#endif - hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t *face, const hb_segment_properties_t *props) : face (face), @@ -87,7 +80,7 @@ hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t *fac map (face, props), aat_map (face, props) #ifndef HB_NO_AAT_SHAPE - , apply_morx (_hb_apply_morx (face)) + , apply_morx (_hb_apply_morx (face, props)) #endif { shaper = hb_ot_shape_complex_categorize (this); @@ -95,8 +88,9 @@ hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t *fac script_zero_marks = shaper->zero_width_marks != HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE; script_fallback_mark_positioning = shaper->fallback_position; - if (apply_morx) - shaper = &_hb_ot_complex_shaper_default; + /* https://github.com/harfbuzz/harfbuzz/issues/1528 */ + if (apply_morx && shaper != &_hb_ot_complex_shaper_default) + shaper = &_hb_ot_complex_shaper_dumber; } void @@ -119,6 +113,8 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, #endif plan.rtlm_mask = plan.map.get_1_mask (HB_TAG ('r','t','l','m')); + plan.has_vert = !!plan.map.get_1_mask (HB_TAG ('v','e','r','t')); + hb_tag_t kern_tag = HB_DIRECTION_IS_HORIZONTAL (props.direction) ? HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n'); #ifndef HB_NO_OT_KERN @@ -156,17 +152,13 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, if (0) ; #ifndef HB_NO_AAT_SHAPE - else if (hb_options ().aat && hb_aat_layout_has_positioning (face)) + else if (hb_aat_layout_has_positioning (face)) plan.apply_kerx = true; #endif else if (!apply_morx && !disable_gpos && hb_ot_layout_has_positioning (face)) plan.apply_gpos = true; -#ifndef HB_NO_AAT_SHAPE - else if (hb_aat_layout_has_positioning (face)) - plan.apply_kerx = true; -#endif - if (!plan.apply_kerx && !has_gpos_kern) + if (!plan.apply_kerx && (!has_gpos_kern || !plan.apply_gpos)) { /* Apparently Apple applies kerx if GPOS kern was not applied. */ #ifndef HB_NO_AAT_SHAPE @@ -228,7 +220,13 @@ hb_ot_shape_plan_t::init0 (hb_face_t *face, { data = shaper->data_create (this); if (unlikely (!data)) + { + map.fini (); +#ifndef HB_NO_AAT_SHAPE + aat_map.fini (); +#endif return false; + } } return true; @@ -536,9 +534,7 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) hb_glyph_info_t info = dottedcircle; info.cluster = buffer->cur().cluster; info.mask = buffer->cur().mask; - buffer->output_info (info); - while (buffer->idx < buffer->len && buffer->successful) - buffer->next_glyph (); + (void) buffer->output_info (info); buffer->swap_buffers (); } @@ -594,24 +590,85 @@ hb_ensure_native_direction (hb_buffer_t *buffer) * Substitute */ -static inline void -hb_ot_mirror_chars (const hb_ot_shape_context_t *c) +static hb_codepoint_t +hb_vert_char_for (hb_codepoint_t u) { - if (HB_DIRECTION_IS_FORWARD (c->target_direction)) - return; + switch (u >> 8) + { + case 0x20: switch (u) { + case 0x2013u: return 0xfe32u; // EN DASH + case 0x2014u: return 0xfe31u; // EM DASH + case 0x2025u: return 0xfe30u; // TWO DOT LEADER + case 0x2026u: return 0xfe19u; // HORIZONTAL ELLIPSIS + } break; + case 0x30: switch (u) { + case 0x3001u: return 0xfe11u; // IDEOGRAPHIC COMMA + case 0x3002u: return 0xfe12u; // IDEOGRAPHIC FULL STOP + case 0x3008u: return 0xfe3fu; // LEFT ANGLE BRACKET + case 0x3009u: return 0xfe40u; // RIGHT ANGLE BRACKET + case 0x300au: return 0xfe3du; // LEFT DOUBLE ANGLE BRACKET + case 0x300bu: return 0xfe3eu; // RIGHT DOUBLE ANGLE BRACKET + case 0x300cu: return 0xfe41u; // LEFT CORNER BRACKET + case 0x300du: return 0xfe42u; // RIGHT CORNER BRACKET + case 0x300eu: return 0xfe43u; // LEFT WHITE CORNER BRACKET + case 0x300fu: return 0xfe44u; // RIGHT WHITE CORNER BRACKET + case 0x3010u: return 0xfe3bu; // LEFT BLACK LENTICULAR BRACKET + case 0x3011u: return 0xfe3cu; // RIGHT BLACK LENTICULAR BRACKET + case 0x3014u: return 0xfe39u; // LEFT TORTOISE SHELL BRACKET + case 0x3015u: return 0xfe3au; // RIGHT TORTOISE SHELL BRACKET + case 0x3016u: return 0xfe17u; // LEFT WHITE LENTICULAR BRACKET + case 0x3017u: return 0xfe18u; // RIGHT WHITE LENTICULAR BRACKET + } break; + case 0xfe: switch (u) { + case 0xfe4fu: return 0xfe34u; // WAVY LOW LINE + } break; + case 0xff: switch (u) { + case 0xff01u: return 0xfe15u; // FULLWIDTH EXCLAMATION MARK + case 0xff08u: return 0xfe35u; // FULLWIDTH LEFT PARENTHESIS + case 0xff09u: return 0xfe36u; // FULLWIDTH RIGHT PARENTHESIS + case 0xff0cu: return 0xfe10u; // FULLWIDTH COMMA + case 0xff1au: return 0xfe13u; // FULLWIDTH COLON + case 0xff1bu: return 0xfe14u; // FULLWIDTH SEMICOLON + case 0xff1fu: return 0xfe16u; // FULLWIDTH QUESTION MARK + case 0xff3bu: return 0xfe47u; // FULLWIDTH LEFT SQUARE BRACKET + case 0xff3du: return 0xfe48u; // FULLWIDTH RIGHT SQUARE BRACKET + case 0xff3fu: return 0xfe33u; // FULLWIDTH LOW LINE + case 0xff5bu: return 0xfe37u; // FULLWIDTH LEFT CURLY BRACKET + case 0xff5du: return 0xfe38u; // FULLWIDTH RIGHT CURLY BRACKET + } break; + } - hb_buffer_t *buffer = c->buffer; - hb_unicode_funcs_t *unicode = buffer->unicode; - hb_mask_t rtlm_mask = c->plan->rtlm_mask; + return u; +} +static inline void +hb_ot_rotate_chars (const hb_ot_shape_context_t *c) +{ + hb_buffer_t *buffer = c->buffer; unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 0; i < count; i++) { - hb_codepoint_t codepoint = unicode->mirroring (info[i].codepoint); - if (likely (codepoint == info[i].codepoint || !c->font->has_glyph (codepoint))) - info[i].mask |= rtlm_mask; - else - info[i].codepoint = codepoint; + + if (HB_DIRECTION_IS_BACKWARD (c->target_direction)) + { + hb_unicode_funcs_t *unicode = buffer->unicode; + hb_mask_t rtlm_mask = c->plan->rtlm_mask; + + for (unsigned int i = 0; i < count; i++) { + hb_codepoint_t codepoint = unicode->mirroring (info[i].codepoint); + if (unlikely (codepoint != info[i].codepoint && c->font->has_glyph (codepoint))) + info[i].codepoint = codepoint; + else + info[i].mask |= rtlm_mask; + } + } + + if (HB_DIRECTION_IS_VERTICAL (c->target_direction) && !c->plan->has_vert) + { + for (unsigned int i = 0; i < count; i++) { + hb_codepoint_t codepoint = hb_vert_char_for (info[i].codepoint); + if (unlikely (codepoint != info[i].codepoint && c->font->has_glyph (codepoint))) + info[i].codepoint = codepoint; + } } } @@ -693,7 +750,7 @@ hb_ot_shape_setup_masks (const hb_ot_shape_context_t *c) for (unsigned int i = 0; i < c->num_user_features; i++) { const hb_feature_t *feature = &c->user_features[i]; - if (!(feature->start == 0 && feature->end == (unsigned int)-1)) { + if (!(feature->start == HB_FEATURE_GLOBAL_START && feature->end == HB_FEATURE_GLOBAL_END)) { unsigned int shift; hb_mask_t mask = map->get_mask (feature->tag, &shift); buffer->set_masks (feature->value << shift, mask, feature->start, feature->end); @@ -788,7 +845,7 @@ hb_ot_substitute_default (const hb_ot_shape_context_t *c) { hb_buffer_t *buffer = c->buffer; - hb_ot_mirror_chars (c); + hb_ot_rotate_chars (c); HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index); @@ -837,8 +894,11 @@ hb_ot_substitute_post (const hb_ot_shape_context_t *c) hb_aat_layout_remove_deleted_glyphs (c->buffer); #endif - if (c->plan->shaper->postprocess_glyphs) + if (c->plan->shaper->postprocess_glyphs && + c->buffer->message(c->font, "start postprocess-glyphs")) { c->plan->shaper->postprocess_glyphs (c->plan, c->buffer, c->font); + (void) c->buffer->message(c->font, "end postprocess-glyphs"); + } } @@ -1038,12 +1098,12 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c) if (likely (!hb_unsigned_mul_overflows (c->buffer->len, HB_BUFFER_MAX_LEN_FACTOR))) { c->buffer->max_len = hb_max (c->buffer->len * HB_BUFFER_MAX_LEN_FACTOR, - (unsigned) HB_BUFFER_MAX_LEN_MIN); + (unsigned) HB_BUFFER_MAX_LEN_MIN); } if (likely (!hb_unsigned_mul_overflows (c->buffer->len, HB_BUFFER_MAX_OPS_FACTOR))) { c->buffer->max_ops = hb_max (c->buffer->len * HB_BUFFER_MAX_OPS_FACTOR, - (unsigned) HB_BUFFER_MAX_OPS_MIN); + (unsigned) HB_BUFFER_MAX_OPS_MIN); } /* Save the original direction, we use it later. */ @@ -1061,8 +1121,11 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c) hb_ensure_native_direction (c->buffer); - if (c->plan->shaper->preprocess_text) + if (c->plan->shaper->preprocess_text && + c->buffer->message(c->font, "start preprocess-text")) { c->plan->shaper->preprocess_text (c->plan, c->buffer, c->font); + (void) c->buffer->message(c->font, "end preprocess-text"); + } hb_ot_substitute_pre (c); hb_ot_position (c); @@ -1096,6 +1159,12 @@ _hb_ot_shape (hb_shape_plan_t *shape_plan, /** * hb_ot_shape_plan_collect_lookups: + * @shape_plan: #hb_shape_plan_t to query + * @table_tag: GSUB or GPOS + * @lookup_indexes: (out): The #hb_set_t set of lookups returned + * + * Computes the complete set of GSUB or GPOS lookups that are applicable + * under a given @shape_plan. * * Since: 0.9.7 **/ @@ -1130,6 +1199,15 @@ add_char (hb_font_t *font, /** * hb_ot_shape_glyphs_closure: + * @font: #hb_font_t to work upon + * @buffer: The input buffer to compute from + * @features: (array length=num_features): The features enabled on the buffer + * @num_features: The number of features enabled on the buffer + * @glyphs: (out): The #hb_set_t set of glyphs comprising the transitive closure of the query + * + * Computes the transitive closure of glyphs needed for a specified + * input buffer under the given font and feature list. The closure is + * computed as a set, not as a list. * * Since: 0.9.2 **/ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.h index 7b1bcc0637..afdff72833 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.h @@ -24,7 +24,7 @@ * Red Hat Author(s): Behdad Esfahbod */ -#ifndef HB_OT_H_IN +#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb-ot.h> instead." #endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.hh index 2cde73d854..acc98772a9 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.hh @@ -37,9 +37,9 @@ struct hb_ot_shape_plan_key_t { unsigned int variations_index[2]; - void init (hb_face_t *face, - const int *coords, - unsigned int num_coords) + void init (hb_face_t *face, + const int *coords, + unsigned num_coords) { for (unsigned int table_index = 0; table_index < 2; table_index++) hb_ot_layout_table_find_feature_variations (face, @@ -99,6 +99,7 @@ struct hb_ot_shape_plan_t #else static constexpr bool has_frac = false; #endif + bool has_vert : 1; bool has_gpos_mark : 1; bool zero_marks : 1; bool fallback_glyph_classes : 1; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-stat-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-stat-table.hh index 2cdd3a488b..6aa4fa4492 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-stat-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-stat-table.hh @@ -59,6 +59,9 @@ enum struct AxisValueFormat1 { + unsigned int get_axis_index () const { return axisIndex; } + float get_value () const { return value.to_float (); } + hb_ot_name_id_t get_value_name_id () const { return valueNameID; } bool sanitize (hb_sanitize_context_t *c) const @@ -77,13 +80,16 @@ struct AxisValueFormat1 NameID valueNameID; /* The name ID for entries in the 'name' table * that provide a display string for this * attribute value. */ - HBFixed value; /* A numeric value for this attribute value. */ + HBFixed value; /* A numeric value for this attribute value. */ public: DEFINE_SIZE_STATIC (12); }; struct AxisValueFormat2 { + unsigned int get_axis_index () const { return axisIndex; } + float get_value () const { return nominalValue.to_float (); } + hb_ot_name_id_t get_value_name_id () const { return valueNameID; } bool sanitize (hb_sanitize_context_t *c) const @@ -102,10 +108,10 @@ struct AxisValueFormat2 NameID valueNameID; /* The name ID for entries in the 'name' table * that provide a display string for this * attribute value. */ - HBFixed nominalValue; /* A numeric value for this attribute value. */ - HBFixed rangeMinValue; /* The minimum value for a range associated + HBFixed nominalValue; /* A numeric value for this attribute value. */ + HBFixed rangeMinValue; /* The minimum value for a range associated * with the specified name ID. */ - HBFixed rangeMaxValue; /* The maximum value for a range associated + HBFixed rangeMaxValue; /* The maximum value for a range associated * with the specified name ID. */ public: DEFINE_SIZE_STATIC (20); @@ -113,6 +119,9 @@ struct AxisValueFormat2 struct AxisValueFormat3 { + unsigned int get_axis_index () const { return axisIndex; } + float get_value () const { return value.to_float (); } + hb_ot_name_id_t get_value_name_id () const { return valueNameID; } bool sanitize (hb_sanitize_context_t *c) const @@ -131,8 +140,8 @@ struct AxisValueFormat3 NameID valueNameID; /* The name ID for entries in the 'name' table * that provide a display string for this * attribute value. */ - HBFixed value; /* A numeric value for this attribute value. */ - HBFixed linkedValue; /* The numeric value for a style-linked mapping + HBFixed value; /* A numeric value for this attribute value. */ + HBFixed linkedValue; /* The numeric value for a style-linked mapping * from this value. */ public: DEFINE_SIZE_STATIC (16); @@ -140,6 +149,9 @@ struct AxisValueFormat3 struct AxisValueRecord { + unsigned int get_axis_index () const { return axisIndex; } + float get_value () const { return value.to_float (); } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -150,13 +162,16 @@ struct AxisValueRecord HBUINT16 axisIndex; /* Zero-base index into the axis record array * identifying the axis to which this value * applies. Must be less than designAxisCount. */ - HBFixed value; /* A numeric value for this attribute value. */ + HBFixed value; /* A numeric value for this attribute value. */ public: DEFINE_SIZE_STATIC (6); }; struct AxisValueFormat4 { + const AxisValueRecord &get_axis_record (unsigned int axis_index) const + { return axisValues.as_array (axisCount)[axis_index]; } + hb_ot_name_id_t get_value_name_id () const { return valueNameID; } bool sanitize (hb_sanitize_context_t *c) const @@ -183,6 +198,30 @@ struct AxisValueFormat4 struct AxisValue { + bool get_value (unsigned int axis_index) const + { + switch (u.format) + { + case 1: return u.format1.get_value (); + 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; + } + } + + unsigned int get_axis_index () const + { + switch (u.format) + { + case 1: return u.format1.get_axis_index (); + case 2: return u.format2.get_axis_index (); + case 3: return u.format3.get_axis_index (); + /* case 4: Makes more sense for variable fonts which are handled by fvar in hb-style */ + default:return -1; + } + } + hb_ot_name_id_t get_value_name_id () const { switch (u.format) @@ -226,6 +265,8 @@ struct AxisValue struct StatAxisRecord { + int cmp (hb_tag_t key) const { return tag.cmp (key); } + hb_ot_name_id_t get_name_id () const { return nameID; } bool sanitize (hb_sanitize_context_t *c) const @@ -251,6 +292,25 @@ struct STAT bool has_data () const { return version.to_int (); } + bool get_value (hb_tag_t tag, float *value) const + { + unsigned int axis_index; + if (!get_design_axes ().lfind (tag, &axis_index)) return false; + + hb_array_t<const OffsetTo<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]; + if (axis_value.get_axis_index () == axis_index) + { + if (value) + *value = axis_value.get_value (axis_index); + return true; + } + } + return false; + } + unsigned get_design_axis_count () const { return designAxisCount; } hb_ot_name_id_t get_axis_record_name_id (unsigned axis_record_index) const diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-tag-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag-table.hh index d8fcd2fdb4..87830b5462 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-tag-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag-table.hh @@ -6,8 +6,8 @@ * * on files with these headers: * - * <meta name="updated_at" content="2018-11-18 05:25 AM" /> - * File-Date: 2019-04-03 + * <meta name="updated_at" content="2021-02-12 04:08 PM" /> + * File-Date: 2021-03-05 */ #ifndef HB_OT_TAG_TABLE_HH @@ -19,14 +19,18 @@ static const LangTag ot_languages[] = { {"aao", HB_TAG('A','R','A',' ')}, /* Algerian Saharan Arabic -> Arabic */ {"aat", HB_TAG('S','Q','I',' ')}, /* Arvanitika Albanian -> Albanian */ {"ab", HB_TAG('A','B','K',' ')}, /* Abkhazian */ + {"aba", HB_TAG_NONE }, /* Abé != Abaza */ {"abh", HB_TAG('A','R','A',' ')}, /* Tajiki Arabic -> Arabic */ {"abq", HB_TAG('A','B','A',' ')}, /* Abaza */ + {"abs", HB_TAG('C','P','P',' ')}, /* Ambonese Malay -> Creoles */ {"abv", HB_TAG('A','R','A',' ')}, /* Baharna Arabic -> Arabic */ {"acf", HB_TAG('F','A','N',' ')}, /* Saint Lucian Creole French -> French Antillean */ + {"acf", HB_TAG('C','P','P',' ')}, /* Saint Lucian Creole French -> Creoles */ /*{"ach", HB_TAG('A','C','H',' ')},*/ /* Acoli -> Acholi */ {"acm", HB_TAG('A','R','A',' ')}, /* Mesopotamian Arabic -> Arabic */ {"acq", HB_TAG('A','R','A',' ')}, /* Ta'izzi-Adeni Arabic -> Arabic */ -/*{"acr", HB_TAG('A','C','R',' ')},*/ /* Achi */ + {"acr", HB_TAG('A','C','R',' ')}, /* Achi */ + {"acr", HB_TAG('M','Y','N',' ')}, /* Achi -> Mayan */ {"acw", HB_TAG('A','R','A',' ')}, /* Hijazi Arabic -> Arabic */ {"acx", HB_TAG('A','R','A',' ')}, /* Omani Arabic -> Arabic */ {"acy", HB_TAG('A','R','A',' ')}, /* Cypriot Arabic -> Arabic */ @@ -38,15 +42,21 @@ static const LangTag ot_languages[] = { {"aec", HB_TAG('A','R','A',' ')}, /* Saidi Arabic -> Arabic */ {"af", HB_TAG('A','F','K',' ')}, /* Afrikaans */ {"afb", HB_TAG('A','R','A',' ')}, /* Gulf Arabic -> Arabic */ + {"afk", HB_TAG_NONE }, /* Nanubae != Afrikaans */ + {"afs", HB_TAG('C','P','P',' ')}, /* Afro-Seminole Creole -> Creoles */ + {"agu", HB_TAG('M','Y','N',' ')}, /* Aguacateco -> Mayan */ + {"agw", HB_TAG_NONE }, /* Kahua != Agaw */ {"ahg", HB_TAG('A','G','W',' ')}, /* Qimant -> Agaw */ {"aht", HB_TAG('A','T','H',' ')}, /* Ahtena -> Athapaskan */ + {"aig", HB_TAG('C','P','P',' ')}, /* Antigua and Barbuda Creole English -> Creoles */ {"aii", HB_TAG('S','W','A',' ')}, /* Assyrian Neo-Aramaic -> Swadaya Aramaic */ {"aii", HB_TAG('S','Y','R',' ')}, /* Assyrian Neo-Aramaic -> Syriac */ /*{"aio", HB_TAG('A','I','O',' ')},*/ /* Aiton */ {"aiw", HB_TAG('A','R','I',' ')}, /* Aari */ {"ajp", HB_TAG('A','R','A',' ')}, /* South Levantine Arabic -> Arabic */ {"ak", HB_TAG('A','K','A',' ')}, /* Akan [macrolanguage] */ - {"ak", HB_TAG('T','W','I',' ')}, /* Akan [macrolanguage] -> Twi */ + {"akb", HB_TAG('A','K','B',' ')}, /* Batak Angkola */ + {"akb", HB_TAG('B','T','K',' ')}, /* Batak Angkola -> Batak */ {"aln", HB_TAG('S','Q','I',' ')}, /* Gheg Albanian -> Albanian */ {"als", HB_TAG('S','Q','I',' ')}, /* Tosk Albanian -> Albanian */ /*{"alt", HB_TAG('A','L','T',' ')},*/ /* Southern Altai -> Altai */ @@ -55,6 +65,8 @@ static const LangTag ot_languages[] = { {"amw", HB_TAG('S','Y','R',' ')}, /* Western Neo-Aramaic -> Syriac */ {"an", HB_TAG('A','R','G',' ')}, /* Aragonese */ /*{"ang", HB_TAG('A','N','G',' ')},*/ /* Old English (ca. 450-1100) -> Anglo-Saxon */ + {"aoa", HB_TAG('C','P','P',' ')}, /* Angolar -> Creoles */ + {"apa", HB_TAG('A','T','H',' ')}, /* Apache [family] -> Athapaskan */ {"apc", HB_TAG('A','R','A',' ')}, /* North Levantine Arabic -> Arabic */ {"apd", HB_TAG('A','R','A',' ')}, /* Sudanese Arabic -> Arabic */ {"apj", HB_TAG('A','T','H',' ')}, /* Jicarilla Apache -> Athapaskan */ @@ -64,16 +76,20 @@ static const LangTag ot_languages[] = { {"apw", HB_TAG('A','T','H',' ')}, /* Western Apache -> Athapaskan */ {"ar", HB_TAG('A','R','A',' ')}, /* Arabic [macrolanguage] */ {"arb", HB_TAG('A','R','A',' ')}, /* Standard Arabic -> Arabic */ + {"ari", HB_TAG_NONE }, /* Arikara != Aari */ + {"ark", HB_TAG_NONE }, /* Arikapú != Rakhine */ {"arn", HB_TAG('M','A','P',' ')}, /* Mapudungun */ {"arq", HB_TAG('A','R','A',' ')}, /* Algerian Arabic -> Arabic */ {"ars", HB_TAG('A','R','A',' ')}, /* Najdi Arabic -> Arabic */ {"ary", HB_TAG('M','O','R',' ')}, /* Moroccan Arabic -> Moroccan */ + {"ary", HB_TAG('A','R','A',' ')}, /* Moroccan Arabic -> Arabic */ {"arz", HB_TAG('A','R','A',' ')}, /* Egyptian Arabic -> Arabic */ {"as", HB_TAG('A','S','M',' ')}, /* Assamese */ /*{"ast", HB_TAG('A','S','T',' ')},*/ /* Asturian */ /*{"ath", HB_TAG('A','T','H',' ')},*/ /* Athapascan [family] -> Athapaskan */ {"atj", HB_TAG('R','C','R',' ')}, /* Atikamekw -> R-Cree */ {"atv", HB_TAG('A','L','T',' ')}, /* Northern Altai -> Altai */ + {"auj", HB_TAG('B','B','R',' ')}, /* Awjilah -> Berber */ {"auz", HB_TAG('A','R','A',' ')}, /* Uzbeki Arabic -> Arabic */ {"av", HB_TAG('A','V','R',' ')}, /* Avaric -> Avar */ {"avl", HB_TAG('A','R','A',' ')}, /* Eastern Egyptian Bedawi Arabic -> Arabic */ @@ -86,17 +102,29 @@ static const LangTag ot_languages[] = { {"ayp", HB_TAG('A','R','A',' ')}, /* North Mesopotamian Arabic -> Arabic */ {"ayr", HB_TAG('A','Y','M',' ')}, /* Central Aymara -> Aymara */ {"az", HB_TAG('A','Z','E',' ')}, /* Azerbaijani [macrolanguage] */ -/*{"azb", HB_TAG('A','Z','B',' ')},*/ /* South Azerbaijani -> Torki */ + {"azb", HB_TAG('A','Z','B',' ')}, /* South Azerbaijani -> Torki */ + {"azb", HB_TAG('A','Z','E',' ')}, /* South Azerbaijani -> Azerbaijani */ + {"azd", HB_TAG('N','A','H',' ')}, /* Eastern Durango Nahuatl -> Nahuatl */ {"azj", HB_TAG('A','Z','E',' ')}, /* North Azerbaijani -> Azerbaijani */ + {"azn", HB_TAG('N','A','H',' ')}, /* Western Durango Nahuatl -> Nahuatl */ + {"azz", HB_TAG('N','A','H',' ')}, /* Highland Puebla Nahuatl -> Nahuatl */ {"ba", HB_TAG('B','S','H',' ')}, /* Bashkir */ {"bad", HB_TAG('B','A','D','0')}, /* Banda [family] */ + {"bag", HB_TAG_NONE }, /* Tuki != Baghelkhandi */ + {"bah", HB_TAG('C','P','P',' ')}, /* Bahamas Creole English -> Creoles */ {"bai", HB_TAG('B','M','L',' ')}, /* Bamileke [family] */ {"bal", HB_TAG('B','L','I',' ')}, /* Baluchi [macrolanguage] */ /*{"ban", HB_TAG('B','A','N',' ')},*/ /* Balinese */ /*{"bar", HB_TAG('B','A','R',' ')},*/ /* Bavarian */ -/*{"bbc", HB_TAG('B','B','C',' ')},*/ /* Batak Toba */ - {"bbz", HB_TAG('A','R','A',' ')}, /* Babalia Creole Arabic -> Arabic */ + {"bau", HB_TAG_NONE }, /* Bada (Nigeria) != Baulé */ + {"bbc", HB_TAG('B','B','C',' ')}, /* Batak Toba */ + {"bbc", HB_TAG('B','T','K',' ')}, /* Batak Toba -> Batak */ + {"bbj", HB_TAG('B','M','L',' ')}, /* Ghomálá' -> Bamileke */ + {"bbp", HB_TAG('B','A','D','0')}, /* West Central Banda -> Banda */ + {"bbr", HB_TAG_NONE }, /* Girawa != Berber */ + {"bbz", HB_TAG('A','R','A',' ')}, /* Babalia Creole Arabic (retired code) -> Arabic */ {"bcc", HB_TAG('B','L','I',' ')}, /* Southern Balochi -> Baluchi */ + {"bch", HB_TAG_NONE }, /* Bariai != Bench */ {"bci", HB_TAG('B','A','U',' ')}, /* Baoulé -> Baulé */ {"bcl", HB_TAG('B','I','K',' ')}, /* Central Bikol -> Bikol */ {"bcq", HB_TAG('B','C','H',' ')}, /* Bench */ @@ -107,6 +135,8 @@ static const LangTag ot_languages[] = { {"beb", HB_TAG('B','T','I',' ')}, /* Bebele -> Beti */ /*{"bem", HB_TAG('B','E','M',' ')},*/ /* Bemba (Zambia) */ {"ber", HB_TAG('B','B','R',' ')}, /* Berber [family] */ + {"bew", HB_TAG('C','P','P',' ')}, /* Betawi -> Creoles */ + {"bfl", HB_TAG('B','A','D','0')}, /* Banda-Ndélé -> Banda */ {"bfq", HB_TAG('B','A','D',' ')}, /* Badaga */ {"bft", HB_TAG('B','L','T',' ')}, /* Balti */ {"bfu", HB_TAG('L','A','H',' ')}, /* Gahri -> Lahuli */ @@ -115,7 +145,8 @@ static const LangTag ot_languages[] = { /*{"bgc", HB_TAG('B','G','C',' ')},*/ /* Haryanvi */ {"bgn", HB_TAG('B','L','I',' ')}, /* Western Balochi -> Baluchi */ {"bgp", HB_TAG('B','L','I',' ')}, /* Eastern Balochi -> Baluchi */ -/*{"bgq", HB_TAG('B','G','Q',' ')},*/ /* Bagri */ + {"bgq", HB_TAG('B','G','Q',' ')}, /* Bagri */ + {"bgq", HB_TAG('R','A','J',' ')}, /* Bagri -> Rajasthani */ {"bgr", HB_TAG('Q','I','N',' ')}, /* Bawm Chin -> Chin */ {"bhb", HB_TAG('B','H','I',' ')}, /* Bhili */ /*{"bhi", HB_TAG('B','H','I',' ')},*/ /* Bhilali -> Bhili */ @@ -123,58 +154,108 @@ static const LangTag ot_languages[] = { /*{"bho", HB_TAG('B','H','O',' ')},*/ /* Bhojpuri */ {"bhr", HB_TAG('M','L','G',' ')}, /* Bara Malagasy -> Malagasy */ {"bi", HB_TAG('B','I','S',' ')}, /* Bislama */ + {"bi", HB_TAG('C','P','P',' ')}, /* Bislama -> Creoles */ /*{"bik", HB_TAG('B','I','K',' ')},*/ /* Bikol [macrolanguage] */ + {"bil", HB_TAG_NONE }, /* Bile != Bilen */ {"bin", HB_TAG('E','D','O',' ')}, /* Edo */ + {"biu", HB_TAG('Q','I','N',' ')}, /* Biete -> Chin */ /*{"bjj", HB_TAG('B','J','J',' ')},*/ /* Kanauji */ {"bjn", HB_TAG('M','L','Y',' ')}, /* Banjar -> Malay */ + {"bjo", HB_TAG('B','A','D','0')}, /* Mid-Southern Banda -> Banda */ {"bjq", HB_TAG('M','L','G',' ')}, /* Southern Betsimisaraka Malagasy (retired code) -> Malagasy */ + {"bjs", HB_TAG('C','P','P',' ')}, /* Bajan -> Creoles */ {"bjt", HB_TAG('B','L','N',' ')}, /* Balanta-Ganja -> Balante */ + {"bkf", HB_TAG_NONE }, /* Beeke != Blackfoot */ + {"bko", HB_TAG('B','M','L',' ')}, /* Kwa' -> Bamileke */ {"bla", HB_TAG('B','K','F',' ')}, /* Siksika -> Blackfoot */ {"ble", HB_TAG('B','L','N',' ')}, /* Balanta-Kentohe -> Balante */ -/*{"blk", HB_TAG('B','L','K',' ')},*/ /* Pa’o Karen */ + {"blg", HB_TAG('I','B','A',' ')}, /* Balau (retired code) -> Iban */ + {"bli", HB_TAG_NONE }, /* Bolia != Baluchi */ + {"blk", HB_TAG('B','L','K',' ')}, /* Pa’o Karen */ + {"blk", HB_TAG('K','R','N',' ')}, /* Pa'o Karen -> Karen */ {"bln", HB_TAG('B','I','K',' ')}, /* Southern Catanduanes Bikol -> Bikol */ + {"blt", HB_TAG_NONE }, /* Tai Dam != Balti */ {"bm", HB_TAG('B','M','B',' ')}, /* Bambara (Bamanankan) */ + {"bmb", HB_TAG_NONE }, /* Bembe != Bambara (Bamanankan) */ + {"bml", HB_TAG_NONE }, /* Bomboli != Bamileke */ {"bmm", HB_TAG('M','L','G',' ')}, /* Northern Betsimisaraka Malagasy -> Malagasy */ {"bn", HB_TAG('B','E','N',' ')}, /* Bengali */ {"bo", HB_TAG('T','I','B',' ')}, /* Tibetan */ + {"bpd", HB_TAG('B','A','D','0')}, /* Banda-Banda -> Banda */ + {"bpl", HB_TAG('C','P','P',' ')}, /* Broome Pearling Lugger Pidgin -> Creoles */ + {"bpq", HB_TAG('C','P','P',' ')}, /* Banda Malay -> Creoles */ /*{"bpy", HB_TAG('B','P','Y',' ')},*/ /* Bishnupriya -> Bishnupriya Manipuri */ {"bqi", HB_TAG('L','R','C',' ')}, /* Bakhtiari -> Luri */ + {"bqk", HB_TAG('B','A','D','0')}, /* Banda-Mbrès -> Banda */ {"br", HB_TAG('B','R','E',' ')}, /* Breton */ {"bra", HB_TAG('B','R','I',' ')}, /* Braj -> Braj Bhasha */ + {"brc", HB_TAG('C','P','P',' ')}, /* Berbice Creole Dutch -> Creoles */ /*{"brh", HB_TAG('B','R','H',' ')},*/ /* Brahui */ + {"bri", HB_TAG_NONE }, /* Mokpwe != Braj Bhasha */ + {"brm", HB_TAG_NONE }, /* Barambu != Burmese */ /*{"brx", HB_TAG('B','R','X',' ')},*/ /* Bodo (India) */ {"bs", HB_TAG('B','O','S',' ')}, /* Bosnian */ + {"bsh", HB_TAG_NONE }, /* Kati != Bashkir */ /*{"bsk", HB_TAG('B','S','K',' ')},*/ /* Burushaski */ {"btb", HB_TAG('B','T','I',' ')}, /* Beti (Cameroon) (retired code) */ + {"btd", HB_TAG('B','T','D',' ')}, /* Batak Dairi (Pakpak) */ + {"btd", HB_TAG('B','T','K',' ')}, /* Batak Dairi -> Batak */ + {"bti", HB_TAG_NONE }, /* Burate != Beti */ {"btj", HB_TAG('M','L','Y',' ')}, /* Bacanese Malay -> Malay */ +/*{"btk", HB_TAG('B','T','K',' ')},*/ /* Batak [family] */ + {"btm", HB_TAG('B','T','M',' ')}, /* Batak Mandailing */ + {"btm", HB_TAG('B','T','K',' ')}, /* Batak Mandailing -> Batak */ {"bto", HB_TAG('B','I','K',' ')}, /* Rinconada Bikol -> Bikol */ -/*{"bts", HB_TAG('B','T','S',' ')},*/ /* Batak Simalungun */ + {"bts", HB_TAG('B','T','S',' ')}, /* Batak Simalungun */ + {"bts", HB_TAG('B','T','K',' ')}, /* Batak Simalungun -> Batak */ + {"btx", HB_TAG('B','T','X',' ')}, /* Batak Karo */ + {"btx", HB_TAG('B','T','K',' ')}, /* Batak Karo -> Batak */ + {"btz", HB_TAG('B','T','Z',' ')}, /* Batak Alas-Kluet */ + {"btz", HB_TAG('B','T','K',' ')}, /* Batak Alas-Kluet -> Batak */ /*{"bug", HB_TAG('B','U','G',' ')},*/ /* Buginese -> Bugis */ {"bum", HB_TAG('B','T','I',' ')}, /* Bulu (Cameroon) -> Beti */ {"bve", HB_TAG('M','L','Y',' ')}, /* Berau Malay -> Malay */ {"bvu", HB_TAG('M','L','Y',' ')}, /* Bukit Malay -> Malay */ + {"bwe", HB_TAG('K','R','N',' ')}, /* Bwe Karen -> Karen */ {"bxk", HB_TAG('L','U','H',' ')}, /* Bukusu -> Luyia */ + {"bxo", HB_TAG('C','P','P',' ')}, /* Barikanchi -> Creoles */ {"bxp", HB_TAG('B','T','I',' ')}, /* Bebil -> Beti */ {"bxr", HB_TAG('R','B','U',' ')}, /* Russia Buriat -> Russian Buriat */ {"byn", HB_TAG('B','I','L',' ')}, /* Bilin -> Bilen */ -/*{"byv", HB_TAG('B','Y','V',' ')},*/ /* Medumba */ + {"byv", HB_TAG('B','Y','V',' ')}, /* Medumba */ + {"byv", HB_TAG('B','M','L',' ')}, /* Medumba -> Bamileke */ {"bzc", HB_TAG('M','L','G',' ')}, /* Southern Betsimisaraka Malagasy -> Malagasy */ + {"bzj", HB_TAG('C','P','P',' ')}, /* Belize Kriol English -> Creoles */ + {"bzk", HB_TAG('C','P','P',' ')}, /* Nicaragua Creole English -> Creoles */ {"ca", HB_TAG('C','A','T',' ')}, /* Catalan */ + {"caa", HB_TAG('M','Y','N',' ')}, /* Chortí -> Mayan */ + {"cac", HB_TAG('M','Y','N',' ')}, /* Chuj -> Mayan */ {"caf", HB_TAG('C','R','R',' ')}, /* Southern Carrier -> Carrier */ {"caf", HB_TAG('A','T','H',' ')}, /* Southern Carrier -> Athapaskan */ -/*{"cak", HB_TAG('C','A','K',' ')},*/ /* Kaqchikel */ -/*{"cbk", HB_TAG('C','B','K',' ')},*/ /* Chavacano -> Zamboanga Chavacano */ + {"cak", HB_TAG('C','A','K',' ')}, /* Kaqchikel */ + {"cak", HB_TAG('M','Y','N',' ')}, /* Kaqchikel -> Mayan */ + {"cbk", HB_TAG('C','B','K',' ')}, /* Chavacano -> Zamboanga Chavacano */ + {"cbk", HB_TAG('C','P','P',' ')}, /* Chavacano -> Creoles */ {"cbl", HB_TAG('Q','I','N',' ')}, /* Bualkhaw Chin -> Chin */ + {"ccl", HB_TAG('C','P','P',' ')}, /* Cutchi-Swahili -> Creoles */ + {"ccm", HB_TAG('C','P','P',' ')}, /* Malaccan Creole Malay -> Creoles */ {"cco", HB_TAG('C','C','H','N')}, /* Comaltepec Chinantec -> Chinantec */ {"ccq", HB_TAG('A','R','K',' ')}, /* Chaungtha (retired code) -> Rakhine */ - {"cdo", HB_TAG('Z','H','S',' ')}, /* Min Dong Chinese -> Chinese Simplified */ + {"cdo", HB_TAG('Z','H','S',' ')}, /* Min Dong Chinese -> Chinese, Simplified */ {"ce", HB_TAG('C','H','E',' ')}, /* Chechen */ /*{"ceb", HB_TAG('C','E','B',' ')},*/ /* Cebuano */ + {"cek", HB_TAG('Q','I','N',' ')}, /* Eastern Khumi Chin -> Chin */ + {"cey", HB_TAG('Q','I','N',' ')}, /* Ekai Chin -> Chin */ {"cfm", HB_TAG('H','A','L',' ')}, /* Halam (Falam Chin) */ + {"cfm", HB_TAG('Q','I','N',' ')}, /* Falam Chin -> Chin */ /*{"cgg", HB_TAG('C','G','G',' ')},*/ /* Chiga */ {"ch", HB_TAG('C','H','A',' ')}, /* Chamorro */ + {"chf", HB_TAG('M','Y','N',' ')}, /* Tabasco Chontal -> Mayan */ + {"chg", HB_TAG_NONE }, /* Chagatai != Chaha Gurage */ + {"chh", HB_TAG_NONE }, /* Chinook != Chattisgarhi */ {"chj", HB_TAG('C','C','H','N')}, /* Ojitlán Chinantec -> Chinantec */ {"chk", HB_TAG('C','H','K','0')}, /* Chuukese */ + {"chn", HB_TAG('C','P','P',' ')}, /* Chinook jargon -> Creoles */ /*{"cho", HB_TAG('C','H','O',' ')},*/ /* Choctaw */ {"chp", HB_TAG('C','H','P',' ')}, /* Chipewyan */ {"chp", HB_TAG('S','A','Y',' ')}, /* Chipewyan -> Sayisi */ @@ -186,57 +267,85 @@ static const LangTag ot_languages[] = { {"ciw", HB_TAG('O','J','B',' ')}, /* Chippewa -> Ojibway */ /*{"cja", HB_TAG('C','J','A',' ')},*/ /* Western Cham */ /*{"cjm", HB_TAG('C','J','M',' ')},*/ /* Eastern Cham */ - {"cjy", HB_TAG('Z','H','S',' ')}, /* Jinyu Chinese -> Chinese Simplified */ + {"cjy", HB_TAG('Z','H','S',' ')}, /* Jinyu Chinese -> Chinese, Simplified */ {"cka", HB_TAG('Q','I','N',' ')}, /* Khumi Awa Chin (retired code) -> Chin */ {"ckb", HB_TAG('K','U','R',' ')}, /* Central Kurdish -> Kurdish */ + {"ckn", HB_TAG('Q','I','N',' ')}, /* Kaang Chin -> Chin */ + {"cks", HB_TAG('C','P','P',' ')}, /* Tayo -> Creoles */ {"ckt", HB_TAG('C','H','K',' ')}, /* Chukot -> Chukchi */ + {"ckz", HB_TAG('M','Y','N',' ')}, /* Cakchiquel-Quiché Mixed Language -> Mayan */ {"clc", HB_TAG('A','T','H',' ')}, /* Chilcotin -> Athapaskan */ {"cld", HB_TAG('S','Y','R',' ')}, /* Chaldean Neo-Aramaic -> Syriac */ {"cle", HB_TAG('C','C','H','N')}, /* Lealao Chinantec -> Chinantec */ - {"cmn", HB_TAG('Z','H','S',' ')}, /* Mandarin Chinese -> Chinese Simplified */ + {"clj", HB_TAG('Q','I','N',' ')}, /* Laitu Chin -> Chin */ + {"clt", HB_TAG('Q','I','N',' ')}, /* Lautu Chin -> Chin */ + {"cmn", HB_TAG('Z','H','S',' ')}, /* Mandarin Chinese -> Chinese, Simplified */ {"cmr", HB_TAG('Q','I','N',' ')}, /* Mro-Khimi Chin -> Chin */ {"cnb", HB_TAG('Q','I','N',' ')}, /* Chinbon Chin -> Chin */ {"cnh", HB_TAG('Q','I','N',' ')}, /* Hakha Chin -> Chin */ {"cnk", HB_TAG('Q','I','N',' ')}, /* Khumi Chin -> Chin */ {"cnl", HB_TAG('C','C','H','N')}, /* Lalana Chinantec -> Chinantec */ + {"cnp", HB_TAG('Z','H','S',' ')}, /* Northern Ping Chinese -> Chinese, Simplified */ + {"cnr", HB_TAG('S','R','B',' ')}, /* Montenegrin -> Serbian */ {"cnt", HB_TAG('C','C','H','N')}, /* Tepetotutla Chinantec -> Chinantec */ + {"cnu", HB_TAG('B','B','R',' ')}, /* Chenoua -> Berber */ {"cnw", HB_TAG('Q','I','N',' ')}, /* Ngawn Chin -> Chin */ {"co", HB_TAG('C','O','S',' ')}, /* Corsican */ {"coa", HB_TAG('M','L','Y',' ')}, /* Cocos Islands Malay -> Malay */ + {"cob", HB_TAG('M','Y','N',' ')}, /* Chicomuceltec -> Mayan */ /*{"cop", HB_TAG('C','O','P',' ')},*/ /* Coptic */ {"coq", HB_TAG('A','T','H',' ')}, /* Coquille -> Athapaskan */ {"cpa", HB_TAG('C','C','H','N')}, /* Palantla Chinantec -> Chinantec */ {"cpe", HB_TAG('C','P','P',' ')}, /* English-based creoles and pidgins [family] -> Creoles */ {"cpf", HB_TAG('C','P','P',' ')}, /* French-based creoles and pidgins [family] -> Creoles */ + {"cpi", HB_TAG('C','P','P',' ')}, /* Chinese Pidgin English -> Creoles */ /*{"cpp", HB_TAG('C','P','P',' ')},*/ /* Portuguese-based creoles and pidgins [family] -> Creoles */ - {"cpx", HB_TAG('Z','H','S',' ')}, /* Pu-Xian Chinese -> Chinese Simplified */ + {"cpx", HB_TAG('Z','H','S',' ')}, /* Pu-Xian Chinese -> Chinese, Simplified */ {"cqd", HB_TAG('H','M','N',' ')}, /* Chuanqiandian Cluster Miao -> Hmong */ {"cqu", HB_TAG('Q','U','H',' ')}, /* Chilean Quechua (retired code) -> Quechua (Bolivia) */ + {"cqu", HB_TAG('Q','U','Z',' ')}, /* Chilean Quechua (retired code) -> Quechua */ {"cr", HB_TAG('C','R','E',' ')}, /* Cree [macrolanguage] */ - {"cr", HB_TAG('Y','C','R',' ')}, /* Cree [macrolanguage] -> Y-Cree */ {"crh", HB_TAG('C','R','T',' ')}, /* Crimean Tatar */ + {"cri", HB_TAG('C','P','P',' ')}, /* Sãotomense -> Creoles */ {"crj", HB_TAG('E','C','R',' ')}, /* Southern East Cree -> Eastern Cree */ + {"crj", HB_TAG('Y','C','R',' ')}, /* Southern East Cree -> Y-Cree */ + {"crj", HB_TAG('C','R','E',' ')}, /* Southern East Cree -> Cree */ {"crk", HB_TAG('W','C','R',' ')}, /* Plains Cree -> West-Cree */ + {"crk", HB_TAG('Y','C','R',' ')}, /* Plains Cree -> Y-Cree */ + {"crk", HB_TAG('C','R','E',' ')}, /* Plains Cree -> Cree */ {"crl", HB_TAG('E','C','R',' ')}, /* Northern East Cree -> Eastern Cree */ + {"crl", HB_TAG('Y','C','R',' ')}, /* Northern East Cree -> Y-Cree */ + {"crl", HB_TAG('C','R','E',' ')}, /* Northern East Cree -> Cree */ {"crm", HB_TAG('M','C','R',' ')}, /* Moose Cree */ {"crm", HB_TAG('L','C','R',' ')}, /* Moose Cree -> L-Cree */ + {"crm", HB_TAG('C','R','E',' ')}, /* Moose Cree -> Cree */ {"crp", HB_TAG('C','P','P',' ')}, /* Creoles and pidgins [family] -> Creoles */ + {"crr", HB_TAG_NONE }, /* Carolina Algonquian != Carrier */ + {"crs", HB_TAG('C','P','P',' ')}, /* Seselwa Creole French -> Creoles */ + {"crt", HB_TAG_NONE }, /* Iyojwa'ja Chorote != Crimean Tatar */ {"crx", HB_TAG('C','R','R',' ')}, /* Carrier */ {"crx", HB_TAG('A','T','H',' ')}, /* Carrier -> Athapaskan */ {"cs", HB_TAG('C','S','Y',' ')}, /* Czech */ {"csa", HB_TAG('C','C','H','N')}, /* Chiltepec Chinantec -> Chinantec */ /*{"csb", HB_TAG('C','S','B',' ')},*/ /* Kashubian */ {"csh", HB_TAG('Q','I','N',' ')}, /* Asho Chin -> Chin */ + {"csj", HB_TAG('Q','I','N',' ')}, /* Songlai Chin -> Chin */ + {"csl", HB_TAG_NONE }, /* Chinese Sign Language != Church Slavonic */ {"cso", HB_TAG('C','C','H','N')}, /* Sochiapam Chinantec -> Chinantec */ + {"csp", HB_TAG('Z','H','S',' ')}, /* Southern Ping Chinese -> Chinese, Simplified */ + {"csv", HB_TAG('Q','I','N',' ')}, /* Sumtu Chin -> Chin */ {"csw", HB_TAG('N','C','R',' ')}, /* Swampy Cree -> N-Cree */ {"csw", HB_TAG('N','H','C',' ')}, /* Swampy Cree -> Norway House Cree */ + {"csw", HB_TAG('C','R','E',' ')}, /* Swampy Cree -> Cree */ {"csy", HB_TAG('Q','I','N',' ')}, /* Siyin Chin -> Chin */ {"ctc", HB_TAG('A','T','H',' ')}, /* Chetco -> Athapaskan */ {"ctd", HB_TAG('Q','I','N',' ')}, /* Tedim Chin -> Chin */ {"cte", HB_TAG('C','C','H','N')}, /* Tepinapa Chinantec -> Chinantec */ /*{"ctg", HB_TAG('C','T','G',' ')},*/ /* Chittagonian */ + {"cth", HB_TAG('Q','I','N',' ')}, /* Thaiphum Chin -> Chin */ {"ctl", HB_TAG('C','C','H','N')}, /* Tlacoatzintepec Chinantec -> Chinantec */ {"cts", HB_TAG('B','I','K',' ')}, /* Northern Catanduanes Bikol -> Bikol */ + {"ctu", HB_TAG('M','Y','N',' ')}, /* Chol -> Mayan */ {"cu", HB_TAG('C','S','L',' ')}, /* Church Slavonic */ {"cuc", HB_TAG('C','C','H','N')}, /* Usila Chinantec -> Chinantec */ /*{"cuk", HB_TAG('C','U','K',' ')},*/ /* San Blas Kuna */ @@ -244,56 +353,73 @@ static const LangTag ot_languages[] = { {"cvn", HB_TAG('C','C','H','N')}, /* Valle Nacional Chinantec -> Chinantec */ {"cwd", HB_TAG('D','C','R',' ')}, /* Woods Cree */ {"cwd", HB_TAG('T','C','R',' ')}, /* Woods Cree -> TH-Cree */ + {"cwd", HB_TAG('C','R','E',' ')}, /* Woods Cree -> Cree */ {"cy", HB_TAG('W','E','L',' ')}, /* Welsh */ - {"czh", HB_TAG('Z','H','S',' ')}, /* Huizhou Chinese -> Chinese Simplified */ - {"czo", HB_TAG('Z','H','S',' ')}, /* Min Zhong Chinese -> Chinese Simplified */ + {"czh", HB_TAG('Z','H','S',' ')}, /* Huizhou Chinese -> Chinese, Simplified */ + {"czo", HB_TAG('Z','H','S',' ')}, /* Min Zhong Chinese -> Chinese, Simplified */ {"czt", HB_TAG('Q','I','N',' ')}, /* Zotung Chin -> Chin */ {"da", HB_TAG('D','A','N',' ')}, /* Danish */ +/*{"dag", HB_TAG('D','A','G',' ')},*/ /* Dagbani */ {"dao", HB_TAG('Q','I','N',' ')}, /* Daai Chin -> Chin */ {"dap", HB_TAG('N','I','S',' ')}, /* Nisi (India) (retired code) */ /*{"dar", HB_TAG('D','A','R',' ')},*/ /* Dargwa */ /*{"dax", HB_TAG('D','A','X',' ')},*/ /* Dayi */ + {"dcr", HB_TAG('C','P','P',' ')}, /* Negerhollands -> Creoles */ {"de", HB_TAG('D','E','U',' ')}, /* German */ {"den", HB_TAG('S','L','A',' ')}, /* Slave (Athapascan) [macrolanguage] -> Slavey */ {"den", HB_TAG('A','T','H',' ')}, /* Slave (Athapascan) [macrolanguage] -> Athapaskan */ -/*{"dgo", HB_TAG('D','G','O',' ')},*/ /* Dogri */ + {"dep", HB_TAG('C','P','P',' ')}, /* Pidgin Delaware -> Creoles */ + {"dgo", HB_TAG('D','G','O',' ')}, /* Dogri (individual language) */ + {"dgo", HB_TAG('D','G','R',' ')}, /* Dogri (macrolanguage) */ {"dgr", HB_TAG('A','T','H',' ')}, /* Dogrib -> Athapaskan */ {"dhd", HB_TAG('M','A','W',' ')}, /* Dhundari -> Marwari */ /*{"dhg", HB_TAG('D','H','G',' ')},*/ /* Dhangu */ + {"dhv", HB_TAG_NONE }, /* Dehu != Divehi (Dhivehi, Maldivian) (deprecated) */ {"dib", HB_TAG('D','N','K',' ')}, /* South Central Dinka -> Dinka */ {"dik", HB_TAG('D','N','K',' ')}, /* Southwestern Dinka -> Dinka */ {"din", HB_TAG('D','N','K',' ')}, /* Dinka [macrolanguage] */ {"dip", HB_TAG('D','N','K',' ')}, /* Northeastern Dinka -> Dinka */ -/*{"diq", HB_TAG('D','I','Q',' ')},*/ /* Dimli */ + {"diq", HB_TAG('D','I','Q',' ')}, /* Dimli */ + {"diq", HB_TAG('Z','Z','A',' ')}, /* Dimli -> Zazaki */ {"diw", HB_TAG('D','N','K',' ')}, /* Northwestern Dinka -> Dinka */ {"dje", HB_TAG('D','J','R',' ')}, /* Zarma */ + {"djk", HB_TAG('C','P','P',' ')}, /* Eastern Maroon Creole -> Creoles */ {"djr", HB_TAG('D','J','R','0')}, /* Djambarrpuyngu */ {"dks", HB_TAG('D','N','K',' ')}, /* Southeastern Dinka -> Dinka */ {"dng", HB_TAG('D','U','N',' ')}, /* Dungan */ /*{"dnj", HB_TAG('D','N','J',' ')},*/ /* Dan */ - {"doi", HB_TAG('D','G','R',' ')}, /* Dogri [macrolanguage] */ + {"dnk", HB_TAG_NONE }, /* Dengka != Dinka */ + {"doi", HB_TAG('D','G','R',' ')}, /* Dogri (macrolanguage) [macrolanguage] */ {"drh", HB_TAG('M','N','G',' ')}, /* Darkhat (retired code) -> Mongolian */ + {"dri", HB_TAG_NONE }, /* C'Lela != Dari */ {"drw", HB_TAG('D','R','I',' ')}, /* Darwazi (retired code) -> Dari */ + {"drw", HB_TAG('F','A','R',' ')}, /* Darwazi (retired code) -> Persian */ {"dsb", HB_TAG('L','S','B',' ')}, /* Lower Sorbian */ {"dty", HB_TAG('N','E','P',' ')}, /* Dotyali -> Nepali */ /*{"duj", HB_TAG('D','U','J',' ')},*/ /* Dhuwal (retired code) */ + {"dun", HB_TAG_NONE }, /* Dusun Deyah != Dungan */ {"dup", HB_TAG('M','L','Y',' ')}, /* Duano -> Malay */ {"dv", HB_TAG('D','I','V',' ')}, /* Divehi (Dhivehi, Maldivian) */ {"dv", HB_TAG('D','H','V',' ')}, /* Divehi (Dhivehi, Maldivian) (deprecated) */ + {"dwk", HB_TAG('K','U','I',' ')}, /* Dawik Kui -> Kui */ {"dwu", HB_TAG('D','U','J',' ')}, /* Dhuwal */ {"dwy", HB_TAG('D','U','J',' ')}, /* Dhuwaya -> Dhuwal */ {"dyu", HB_TAG('J','U','L',' ')}, /* Dyula -> Jula */ {"dz", HB_TAG('D','Z','N',' ')}, /* Dzongkha */ + {"dzn", HB_TAG_NONE }, /* Dzando != Dzongkha */ + {"ecr", HB_TAG_NONE }, /* Eteocretan != Eastern Cree */ {"ee", HB_TAG('E','W','E',' ')}, /* Ewe */ /*{"efi", HB_TAG('E','F','I',' ')},*/ /* Efik */ {"ekk", HB_TAG('E','T','I',' ')}, /* Standard Estonian -> Estonian */ + {"eky", HB_TAG('K','R','N',' ')}, /* Eastern Kayah -> Karen */ {"el", HB_TAG('E','L','L',' ')}, /* Modern Greek (1453-) -> Greek */ {"emk", HB_TAG('E','M','K',' ')}, /* Eastern Maninkakan */ {"emk", HB_TAG('M','N','K',' ')}, /* Eastern Maninkakan -> Maninka */ + {"emy", HB_TAG('M','Y','N',' ')}, /* Epigraphic Mayan -> Mayan */ {"en", HB_TAG('E','N','G',' ')}, /* English */ {"enb", HB_TAG('K','A','L',' ')}, /* Markweeta -> Kalenjin */ - {"enf", HB_TAG('F','N','E',' ')}, /* Forest Enets -> Forest Nenets */ - {"enh", HB_TAG('T','N','E',' ')}, /* Tundra Enets -> Tundra Nenets */ + {"enf", HB_TAG('F','N','E',' ')}, /* Forest Enets */ + {"enh", HB_TAG('T','N','E',' ')}, /* Tundra Enets */ {"eo", HB_TAG('N','T','O',' ')}, /* Esperanto */ {"es", HB_TAG('E','S','P',' ')}, /* Spanish */ {"esg", HB_TAG('G','O','N',' ')}, /* Aheri Gondi -> Gondi */ @@ -303,13 +429,18 @@ static const LangTag ot_languages[] = { {"et", HB_TAG('E','T','I',' ')}, /* Estonian [macrolanguage] */ {"eto", HB_TAG('B','T','I',' ')}, /* Eton (Cameroon) -> Beti */ {"eu", HB_TAG('E','U','Q',' ')}, /* Basque */ + {"euq", HB_TAG_NONE }, /* Basque [family] != Basque */ {"eve", HB_TAG('E','V','N',' ')}, /* Even */ {"evn", HB_TAG('E','V','K',' ')}, /* Evenki */ {"ewo", HB_TAG('B','T','I',' ')}, /* Ewondo -> Beti */ {"eyo", HB_TAG('K','A','L',' ')}, /* Keiyo -> Kalenjin */ {"fa", HB_TAG('F','A','R',' ')}, /* Persian [macrolanguage] */ + {"fab", HB_TAG('C','P','P',' ')}, /* Fa d'Ambu -> Creoles */ {"fan", HB_TAG('F','A','N','0')}, /* Fang (Equatorial Guinea) */ -/*{"fat", HB_TAG('F','A','T',' ')},*/ /* Fanti */ + {"fan", HB_TAG('B','T','I',' ')}, /* Fang (Equatorial Guinea) -> Beti */ + {"far", HB_TAG_NONE }, /* Fataleka != Persian */ + {"fat", HB_TAG('F','A','T',' ')}, /* Fanti */ + {"fat", HB_TAG('A','K','A',' ')}, /* Fanti -> Akan */ {"fbl", HB_TAG('B','I','K',' ')}, /* West Albay Bikol -> Bikol */ {"ff", HB_TAG('F','U','L',' ')}, /* Fulah [macrolanguage] */ {"ffm", HB_TAG('F','U','L',' ')}, /* Maasina Fulfulde -> Fulah */ @@ -318,9 +449,13 @@ static const LangTag ot_languages[] = { {"fj", HB_TAG('F','J','I',' ')}, /* Fijian */ {"flm", HB_TAG('H','A','L',' ')}, /* Halam (Falam Chin) (retired code) */ {"flm", HB_TAG('Q','I','N',' ')}, /* Falam Chin (retired code) -> Chin */ -/*{"fmp", HB_TAG('F','M','P',' ')},*/ /* Fe’fe’ */ + {"fmp", HB_TAG('F','M','P',' ')}, /* Fe’fe’ */ + {"fmp", HB_TAG('B','M','L',' ')}, /* Fe'fe' -> Bamileke */ + {"fng", HB_TAG('C','P','P',' ')}, /* Fanagalo -> Creoles */ {"fo", HB_TAG('F','O','S',' ')}, /* Faroese */ /*{"fon", HB_TAG('F','O','N',' ')},*/ /* Fon */ + {"fos", HB_TAG_NONE }, /* Siraya != Faroese */ + {"fpe", HB_TAG('C','P','P',' ')}, /* Fernando Po Creole English -> Creoles */ {"fr", HB_TAG('F','R','A',' ')}, /* French */ /*{"frc", HB_TAG('F','R','C',' ')},*/ /* Cajun French */ /*{"frp", HB_TAG('F','R','P',' ')},*/ /* Arpitan */ @@ -328,60 +463,89 @@ static const LangTag ot_languages[] = { {"fuc", HB_TAG('F','U','L',' ')}, /* Pulaar -> Fulah */ {"fue", HB_TAG('F','U','L',' ')}, /* Borgu Fulfulde -> Fulah */ {"fuf", HB_TAG('F','T','A',' ')}, /* Pular -> Futa */ + {"fuf", HB_TAG('F','U','L',' ')}, /* Pular -> Fulah */ {"fuh", HB_TAG('F','U','L',' ')}, /* Western Niger Fulfulde -> Fulah */ {"fui", HB_TAG('F','U','L',' ')}, /* Bagirmi Fulfulde -> Fulah */ {"fuq", HB_TAG('F','U','L',' ')}, /* Central-Eastern Niger Fulfulde -> Fulah */ {"fur", HB_TAG('F','R','L',' ')}, /* Friulian */ -/*{"fuv", HB_TAG('F','U','V',' ')},*/ /* Nigerian Fulfulde */ + {"fuv", HB_TAG('F','U','V',' ')}, /* Nigerian Fulfulde */ + {"fuv", HB_TAG('F','U','L',' ')}, /* Nigerian Fulfulde -> Fulah */ {"fy", HB_TAG('F','R','I',' ')}, /* Western Frisian -> Frisian */ {"ga", HB_TAG('I','R','I',' ')}, /* Irish */ {"gaa", HB_TAG('G','A','D',' ')}, /* Ga */ + {"gac", HB_TAG('C','P','P',' ')}, /* Mixed Great Andamanese -> Creoles */ + {"gad", HB_TAG_NONE }, /* Gaddang != Ga */ + {"gae", HB_TAG_NONE }, /* Guarequena != Scottish Gaelic (Gaelic) */ /*{"gag", HB_TAG('G','A','G',' ')},*/ /* Gagauz */ - {"gan", HB_TAG('Z','H','S',' ')}, /* Gan Chinese -> Chinese Simplified */ + {"gal", HB_TAG_NONE }, /* Galolen != Galician */ + {"gan", HB_TAG('Z','H','S',' ')}, /* Gan Chinese -> Chinese, Simplified */ + {"gar", HB_TAG_NONE }, /* Galeya != Garshuni */ + {"gaw", HB_TAG_NONE }, /* Nobonob != Garhwali */ {"gax", HB_TAG('O','R','O',' ')}, /* Borana-Arsi-Guji Oromo -> Oromo */ {"gaz", HB_TAG('O','R','O',' ')}, /* West Central Oromo -> Oromo */ {"gbm", HB_TAG('G','A','W',' ')}, /* Garhwali */ {"gce", HB_TAG('A','T','H',' ')}, /* Galice -> Athapaskan */ + {"gcf", HB_TAG('C','P','P',' ')}, /* Guadeloupean Creole French -> Creoles */ + {"gcl", HB_TAG('C','P','P',' ')}, /* Grenadian Creole English -> Creoles */ + {"gcr", HB_TAG('C','P','P',' ')}, /* Guianese Creole French -> Creoles */ {"gd", HB_TAG('G','A','E',' ')}, /* Scottish Gaelic (Gaelic) */ {"gda", HB_TAG('R','A','J',' ')}, /* Gade Lohar -> Rajasthani */ /*{"gez", HB_TAG('G','E','Z',' ')},*/ /* Geez */ {"ggo", HB_TAG('G','O','N',' ')}, /* Southern Gondi (retired code) -> Gondi */ + {"gha", HB_TAG('B','B','R',' ')}, /* Ghadamès -> Berber */ + {"ghk", HB_TAG('K','R','N',' ')}, /* Geko Karen -> Karen */ + {"gho", HB_TAG('B','B','R',' ')}, /* Ghomara -> Berber */ + {"gib", HB_TAG('C','P','P',' ')}, /* Gibanawa -> Creoles */ /*{"gih", HB_TAG('G','I','H',' ')},*/ /* Githabul */ {"gil", HB_TAG('G','I','L','0')}, /* Kiribati (Gilbertese) */ {"gju", HB_TAG('R','A','J',' ')}, /* Gujari -> Rajasthani */ -/*{"gkp", HB_TAG('G','K','P',' ')},*/ /* Guinea Kpelle -> Kpelle (Guinea) */ + {"gkp", HB_TAG('G','K','P',' ')}, /* Guinea Kpelle -> Kpelle (Guinea) */ + {"gkp", HB_TAG('K','P','L',' ')}, /* Guinea Kpelle -> Kpelle */ {"gl", HB_TAG('G','A','L',' ')}, /* Galician */ {"gld", HB_TAG('N','A','N',' ')}, /* Nanai */ /*{"glk", HB_TAG('G','L','K',' ')},*/ /* Gilaki */ + {"gmz", HB_TAG_NONE }, /* Mgbolizhia != Gumuz */ {"gn", HB_TAG('G','U','A',' ')}, /* Guarani [macrolanguage] */ + {"gnb", HB_TAG('Q','I','N',' ')}, /* Gangte -> Chin */ /*{"gnn", HB_TAG('G','N','N',' ')},*/ /* Gumatj */ {"gno", HB_TAG('G','O','N',' ')}, /* Northern Gondi -> Gondi */ {"gnw", HB_TAG('G','U','A',' ')}, /* Western Bolivian Guaraní -> Guarani */ /*{"gog", HB_TAG('G','O','G',' ')},*/ /* Gogo */ {"gom", HB_TAG('K','O','K',' ')}, /* Goan Konkani -> Konkani */ /*{"gon", HB_TAG('G','O','N',' ')},*/ /* Gondi [macrolanguage] */ + {"goq", HB_TAG('C','P','P',' ')}, /* Gorap -> Creoles */ + {"gox", HB_TAG('B','A','D','0')}, /* Gobu -> Banda */ + {"gpe", HB_TAG('C','P','P',' ')}, /* Ghanaian Pidgin English -> Creoles */ + {"gro", HB_TAG_NONE }, /* Groma != Garo */ + {"grr", HB_TAG('B','B','R',' ')}, /* Taznatit -> Berber */ {"grt", HB_TAG('G','R','O',' ')}, /* Garo */ {"gru", HB_TAG('S','O','G',' ')}, /* Kistane -> Sodo Gurage */ {"gsw", HB_TAG('A','L','S',' ')}, /* Alsatian */ {"gu", HB_TAG('G','U','J',' ')}, /* Gujarati */ + {"gua", HB_TAG_NONE }, /* Shiki != Guarani */ /*{"guc", HB_TAG('G','U','C',' ')},*/ /* Wayuu */ /*{"guf", HB_TAG('G','U','F',' ')},*/ /* Gupapuyngu */ {"gug", HB_TAG('G','U','A',' ')}, /* Paraguayan Guaraní -> Guarani */ {"gui", HB_TAG('G','U','A',' ')}, /* Eastern Bolivian Guaraní -> Guarani */ {"guk", HB_TAG('G','M','Z',' ')}, /* Gumuz */ - {"guk", HB_TAG('G','U','K',' ')}, /* Gumuz (SIL fonts) */ + {"gul", HB_TAG('C','P','P',' ')}, /* Sea Island Creole English -> Creoles */ {"gun", HB_TAG('G','U','A',' ')}, /* Mbyá Guaraní -> Guarani */ /*{"guz", HB_TAG('G','U','Z',' ')},*/ /* Gusii */ {"gv", HB_TAG('M','N','X',' ')}, /* Manx */ {"gwi", HB_TAG('A','T','H',' ')}, /* Gwichʼin -> Athapaskan */ + {"gyn", HB_TAG('C','P','P',' ')}, /* Guyanese Creole English -> Creoles */ {"ha", HB_TAG('H','A','U',' ')}, /* Hausa */ {"haa", HB_TAG('A','T','H',' ')}, /* Han -> Athapaskan */ {"hae", HB_TAG('O','R','O',' ')}, /* Eastern Oromo -> Oromo */ - {"hak", HB_TAG('Z','H','S',' ')}, /* Hakka Chinese -> Chinese Simplified */ + {"hai", HB_TAG_NONE }, /* Haida [macrolanguage] != Haitian (Haitian Creole) */ + {"hak", HB_TAG('Z','H','S',' ')}, /* Hakka Chinese -> Chinese, Simplified */ + {"hal", HB_TAG_NONE }, /* Halang != Halam (Falam Chin) */ {"har", HB_TAG('H','R','I',' ')}, /* Harari */ /*{"haw", HB_TAG('H','A','W',' ')},*/ /* Hawaiian */ /*{"hay", HB_TAG('H','A','Y',' ')},*/ /* Haya */ /*{"haz", HB_TAG('H','A','Z',' ')},*/ /* Hazaragi */ + {"hbn", HB_TAG_NONE }, /* Heiban != Hammer-Banna */ + {"hca", HB_TAG('C','P','P',' ')}, /* Andaman Creole Hindi -> Creoles */ {"he", HB_TAG('I','W','R',' ')}, /* Hebrew */ {"hea", HB_TAG('H','M','N',' ')}, /* Northern Qiandong Miao -> Hmong */ {"hi", HB_TAG('H','I','N',' ')}, /* Hindi */ @@ -401,6 +565,7 @@ static const LangTag ot_languages[] = { /*{"hmn", HB_TAG('H','M','N',' ')},*/ /* Hmong [macrolanguage] */ {"hmp", HB_TAG('H','M','N',' ')}, /* Northern Mashan Hmong -> Hmong */ {"hmq", HB_TAG('H','M','N',' ')}, /* Eastern Qiandong Miao -> Hmong */ + {"hmr", HB_TAG('Q','I','N',' ')}, /* Hmar -> Chin */ {"hms", HB_TAG('H','M','N',' ')}, /* Southern Qiandong Miao -> Hmong */ {"hmw", HB_TAG('H','M','N',' ')}, /* Western Mashan Hmong -> Hmong */ {"hmy", HB_TAG('H','M','N',' ')}, /* Southern Guiyang Hmong -> Hmong */ @@ -410,17 +575,23 @@ static const LangTag ot_languages[] = { {"hnj", HB_TAG('H','M','N',' ')}, /* Hmong Njua -> Hmong */ {"hno", HB_TAG('H','N','D',' ')}, /* Northern Hindko -> Hindko */ {"ho", HB_TAG('H','M','O',' ')}, /* Hiri Motu */ + {"ho", HB_TAG('C','P','P',' ')}, /* Hiri Motu -> Creoles */ {"hoc", HB_TAG('H','O',' ',' ')}, /* Ho */ {"hoi", HB_TAG('A','T','H',' ')}, /* Holikachuk -> Athapaskan */ {"hoj", HB_TAG('H','A','R',' ')}, /* Hadothi -> Harauti */ + {"hoj", HB_TAG('R','A','J',' ')}, /* Hadothi -> Rajasthani */ {"hr", HB_TAG('H','R','V',' ')}, /* Croatian */ + {"hra", HB_TAG('Q','I','N',' ')}, /* Hrangkhol -> Chin */ {"hrm", HB_TAG('H','M','N',' ')}, /* Horned Miao -> Hmong */ {"hsb", HB_TAG('U','S','B',' ')}, /* Upper Sorbian */ - {"hsn", HB_TAG('Z','H','S',' ')}, /* Xiang Chinese -> Chinese Simplified */ + {"hsn", HB_TAG('Z','H','S',' ')}, /* Xiang Chinese -> Chinese, Simplified */ {"ht", HB_TAG('H','A','I',' ')}, /* Haitian (Haitian Creole) */ + {"ht", HB_TAG('C','P','P',' ')}, /* Haitian -> Creoles */ {"hu", HB_TAG('H','U','N',' ')}, /* Hungarian */ {"huj", HB_TAG('H','M','N',' ')}, /* Northern Guiyang Hmong -> Hmong */ {"hup", HB_TAG('A','T','H',' ')}, /* Hupa -> Athapaskan */ + {"hus", HB_TAG('M','Y','N',' ')}, /* Huastec -> Mayan */ + {"hwc", HB_TAG('C','P','P',' ')}, /* Hawai'i Creole English -> Creoles */ {"hy", HB_TAG('H','Y','E','0')}, /* Armenian -> Armenian East */ {"hy", HB_TAG('H','Y','E',' ')}, /* Armenian */ {"hyw", HB_TAG('H','Y','E',' ')}, /* Western Armenian -> Armenian */ @@ -428,38 +599,65 @@ static const LangTag ot_languages[] = { {"ia", HB_TAG('I','N','A',' ')}, /* Interlingua (International Auxiliary Language Association) */ /*{"iba", HB_TAG('I','B','A',' ')},*/ /* Iban */ /*{"ibb", HB_TAG('I','B','B',' ')},*/ /* Ibibio */ + {"iby", HB_TAG('I','J','O',' ')}, /* Ibani -> Ijo */ + {"icr", HB_TAG('C','P','P',' ')}, /* Islander Creole English -> Creoles */ {"id", HB_TAG('I','N','D',' ')}, /* Indonesian */ + {"id", HB_TAG('M','L','Y',' ')}, /* Indonesian -> Malay */ {"ida", HB_TAG('L','U','H',' ')}, /* Idakho-Isukha-Tiriki -> Luyia */ + {"idb", HB_TAG('C','P','P',' ')}, /* Indo-Portuguese -> Creoles */ {"ie", HB_TAG('I','L','E',' ')}, /* Interlingue */ {"ig", HB_TAG('I','B','O',' ')}, /* Igbo */ {"igb", HB_TAG('E','B','I',' ')}, /* Ebira */ + {"ihb", HB_TAG('C','P','P',' ')}, /* Iha Based Pidgin -> Creoles */ {"ii", HB_TAG('Y','I','M',' ')}, /* Sichuan Yi -> Yi Modern */ {"ijc", HB_TAG('I','J','O',' ')}, /* Izon -> Ijo */ + {"ije", HB_TAG('I','J','O',' ')}, /* Biseni -> Ijo */ + {"ijn", HB_TAG('I','J','O',' ')}, /* Kalabari -> Ijo */ /*{"ijo", HB_TAG('I','J','O',' ')},*/ /* Ijo [family] */ + {"ijs", HB_TAG('I','J','O',' ')}, /* Southeast Ijo -> Ijo */ {"ik", HB_TAG('I','P','K',' ')}, /* Inupiaq [macrolanguage] -> Inupiat */ {"ike", HB_TAG('I','N','U',' ')}, /* Eastern Canadian Inuktitut -> Inuktitut */ {"ikt", HB_TAG('I','N','U',' ')}, /* Inuinnaqtun -> Inuktitut */ /*{"ilo", HB_TAG('I','L','O',' ')},*/ /* Iloko -> Ilokano */ {"in", HB_TAG('I','N','D',' ')}, /* Indonesian (retired code) */ + {"in", HB_TAG('M','L','Y',' ')}, /* Indonesian (retired code) -> Malay */ {"ing", HB_TAG('A','T','H',' ')}, /* Degexit'an -> Athapaskan */ {"inh", HB_TAG('I','N','G',' ')}, /* Ingush */ {"io", HB_TAG('I','D','O',' ')}, /* Ido */ + {"iri", HB_TAG_NONE }, /* Rigwe != Irish */ {"is", HB_TAG('I','S','L',' ')}, /* Icelandic */ + {"ism", HB_TAG_NONE }, /* Masimasi != Inari Sami */ {"it", HB_TAG('I','T','A',' ')}, /* Italian */ + {"itz", HB_TAG('M','Y','N',' ')}, /* Itzá -> Mayan */ {"iu", HB_TAG('I','N','U',' ')}, /* Inuktitut [macrolanguage] */ {"iw", HB_TAG('I','W','R',' ')}, /* Hebrew (retired code) */ + {"ixl", HB_TAG('M','Y','N',' ')}, /* Ixil -> Mayan */ {"ja", HB_TAG('J','A','N',' ')}, /* Japanese */ + {"jac", HB_TAG('M','Y','N',' ')}, /* Popti' -> Mayan */ {"jak", HB_TAG('M','L','Y',' ')}, /* Jakun -> Malay */ -/*{"jam", HB_TAG('J','A','M',' ')},*/ /* Jamaican Creole English -> Jamaican Creole */ + {"jam", HB_TAG('J','A','M',' ')}, /* Jamaican Creole English -> Jamaican Creole */ + {"jam", HB_TAG('C','P','P',' ')}, /* Jamaican Creole English -> Creoles */ + {"jan", HB_TAG_NONE }, /* Jandai != Japanese */ {"jax", HB_TAG('M','L','Y',' ')}, /* Jambi Malay -> Malay */ + {"jbe", HB_TAG('B','B','R',' ')}, /* Judeo-Berber -> Berber */ + {"jbn", HB_TAG('B','B','R',' ')}, /* Nafusi -> Berber */ /*{"jbo", HB_TAG('J','B','O',' ')},*/ /* Lojban */ /*{"jct", HB_TAG('J','C','T',' ')},*/ /* Krymchak */ + {"jgo", HB_TAG('B','M','L',' ')}, /* Ngomba -> Bamileke */ {"ji", HB_TAG('J','I','I',' ')}, /* Yiddish (retired code) */ + {"jii", HB_TAG_NONE }, /* Jiiddu != Yiddish */ + {"jkm", HB_TAG('K','R','N',' ')}, /* Mobwa Karen -> Karen */ + {"jkp", HB_TAG('K','R','N',' ')}, /* Paku Karen -> Karen */ + {"jud", HB_TAG_NONE }, /* Worodougou != Ladino */ + {"jul", HB_TAG_NONE }, /* Jirel != Jula */ {"jv", HB_TAG('J','A','V',' ')}, /* Javanese */ + {"jvd", HB_TAG('C','P','P',' ')}, /* Javindo -> Creoles */ {"jw", HB_TAG('J','A','V',' ')}, /* Javanese (retired code) */ {"ka", HB_TAG('K','A','T',' ')}, /* Georgian */ - {"kaa", HB_TAG('K','R','K',' ')}, /* Kara-Kalpak -> Karakalpak */ + {"kaa", HB_TAG('K','R','K',' ')}, /* Karakalpak */ {"kab", HB_TAG('K','A','B','0')}, /* Kabyle */ + {"kab", HB_TAG('B','B','R',' ')}, /* Kabyle -> Berber */ + {"kac", HB_TAG_NONE }, /* Kachin != Kachchi */ {"kam", HB_TAG('K','M','B',' ')}, /* Kamba (Kenya) */ {"kar", HB_TAG('K','R','N',' ')}, /* Karen [family] */ {"kbd", HB_TAG('K','A','B',' ')}, /* Kabardian */ @@ -467,82 +665,139 @@ static const LangTag ot_languages[] = { {"kca", HB_TAG('K','H','K',' ')}, /* Khanty -> Khanty-Kazim */ {"kca", HB_TAG('K','H','S',' ')}, /* Khanty -> Khanty-Shurishkar */ {"kca", HB_TAG('K','H','V',' ')}, /* Khanty -> Khanty-Vakhi */ + {"kcn", HB_TAG('C','P','P',' ')}, /* Nubi -> Creoles */ /*{"kde", HB_TAG('K','D','E',' ')},*/ /* Makonde */ {"kdr", HB_TAG('K','R','M',' ')}, /* Karaim */ {"kdt", HB_TAG('K','U','Y',' ')}, /* Kuy */ -/*{"kea", HB_TAG('K','E','A',' ')},*/ /* Kabuverdianu (Crioulo) */ -/*{"kek", HB_TAG('K','E','K',' ')},*/ /* Kekchi */ + {"kea", HB_TAG('K','E','A',' ')}, /* Kabuverdianu (Crioulo) */ + {"kea", HB_TAG('C','P','P',' ')}, /* Kabuverdianu -> Creoles */ + {"keb", HB_TAG_NONE }, /* Kélé != Kebena */ + {"kek", HB_TAG('K','E','K',' ')}, /* Kekchi */ + {"kek", HB_TAG('M','Y','N',' ')}, /* Kekchí -> Mayan */ {"kex", HB_TAG('K','K','N',' ')}, /* Kukna -> Kokni */ {"kfa", HB_TAG('K','O','D',' ')}, /* Kodava -> Kodagu */ {"kfr", HB_TAG('K','A','C',' ')}, /* Kachhi -> Kachchi */ {"kfx", HB_TAG('K','U','L',' ')}, /* Kullu Pahari -> Kulvi */ {"kfy", HB_TAG('K','M','N',' ')}, /* Kumaoni */ {"kg", HB_TAG('K','O','N','0')}, /* Kongo [macrolanguage] */ + {"kge", HB_TAG_NONE }, /* Komering != Khutsuri Georgian */ {"kha", HB_TAG('K','S','I',' ')}, /* Khasi */ {"khb", HB_TAG('X','B','D',' ')}, /* Lü */ {"khk", HB_TAG('M','N','G',' ')}, /* Halh Mongolian -> Mongolian */ + {"khn", HB_TAG_NONE }, /* Khandesi != Khamti Shan (Microsoft fonts) */ + {"khs", HB_TAG_NONE }, /* Kasua != Khanty-Shurishkar */ + {"kht", HB_TAG('K','H','T',' ')}, /* Khamti -> Khamti Shan */ {"kht", HB_TAG('K','H','N',' ')}, /* Khamti -> Khamti Shan (Microsoft fonts) */ - {"kht", HB_TAG('K','H','T',' ')}, /* Khamti -> Khamti Shan (OpenType spec and SIL fonts) */ + {"khv", HB_TAG_NONE }, /* Khvarshi != Khanty-Vakhi */ /*{"khw", HB_TAG('K','H','W',' ')},*/ /* Khowar */ {"ki", HB_TAG('K','I','K',' ')}, /* Kikuyu (Gikuyu) */ -/*{"kiu", HB_TAG('K','I','U',' ')},*/ /* Kirmanjki */ + {"kis", HB_TAG_NONE }, /* Kis != Kisii */ + {"kiu", HB_TAG('K','I','U',' ')}, /* Kirmanjki */ + {"kiu", HB_TAG('Z','Z','A',' ')}, /* Kirmanjki -> Zazaki */ {"kj", HB_TAG('K','U','A',' ')}, /* Kuanyama */ + {"kjb", HB_TAG('M','Y','N',' ')}, /* Q'anjob'al -> Mayan */ /*{"kjd", HB_TAG('K','J','D',' ')},*/ /* Southern Kiwai */ {"kjh", HB_TAG('K','H','A',' ')}, /* Khakas -> Khakass */ -/*{"kjp", HB_TAG('K','J','P',' ')},*/ /* Pwo Eastern Karen -> Eastern Pwo Karen */ + {"kjp", HB_TAG('K','J','P',' ')}, /* Pwo Eastern Karen -> Eastern Pwo Karen */ + {"kjp", HB_TAG('K','R','N',' ')}, /* Pwo Eastern Karen -> Karen */ + {"kjt", HB_TAG('K','R','N',' ')}, /* Phrae Pwo Karen -> Karen */ /*{"kjz", HB_TAG('K','J','Z',' ')},*/ /* Bumthangkha */ {"kk", HB_TAG('K','A','Z',' ')}, /* Kazakh */ + {"kkn", HB_TAG_NONE }, /* Kon Keu != Kokni */ {"kkz", HB_TAG('A','T','H',' ')}, /* Kaska -> Athapaskan */ {"kl", HB_TAG('G','R','N',' ')}, /* Greenlandic */ + {"klm", HB_TAG_NONE }, /* Migum != Kalmyk */ {"kln", HB_TAG('K','A','L',' ')}, /* Kalenjin [macrolanguage] */ {"km", HB_TAG('K','H','M',' ')}, /* Khmer */ {"kmb", HB_TAG('M','B','N',' ')}, /* Kimbundu -> Mbundu */ + {"kmn", HB_TAG_NONE }, /* Awtuw != Kumaoni */ + {"kmo", HB_TAG_NONE }, /* Kwoma != Komo */ {"kmr", HB_TAG('K','U','R',' ')}, /* Northern Kurdish -> Kurdish */ + {"kms", HB_TAG_NONE }, /* Kamasau != Komso */ + {"kmv", HB_TAG('C','P','P',' ')}, /* Karipúna Creole French -> Creoles */ {"kmw", HB_TAG('K','M','O',' ')}, /* Komo (Democratic Republic of Congo) */ /*{"kmz", HB_TAG('K','M','Z',' ')},*/ /* Khorasani Turkish -> Khorasani Turkic */ {"kn", HB_TAG('K','A','N',' ')}, /* Kannada */ {"knc", HB_TAG('K','N','R',' ')}, /* Central Kanuri -> Kanuri */ {"kng", HB_TAG('K','O','N','0')}, /* Koongo -> Kongo */ + {"knj", HB_TAG('M','Y','N',' ')}, /* Western Kanjobal -> Mayan */ {"knn", HB_TAG('K','O','K',' ')}, /* Konkani */ + {"knr", HB_TAG_NONE }, /* Kaningra != Kanuri */ {"ko", HB_TAG('K','O','R',' ')}, /* Korean */ + {"ko", HB_TAG('K','O','H',' ')}, /* Korean -> Korean Old Hangul */ + {"kod", HB_TAG_NONE }, /* Kodi != Kodagu */ + {"koh", HB_TAG_NONE }, /* Koyo != Korean Old Hangul */ {"koi", HB_TAG('K','O','P',' ')}, /* Komi-Permyak */ + {"koi", HB_TAG('K','O','M',' ')}, /* Komi-Permyak -> Komi */ /*{"kok", HB_TAG('K','O','K',' ')},*/ /* Konkani [macrolanguage] */ + {"kop", HB_TAG_NONE }, /* Waube != Komi-Permyak */ /*{"kos", HB_TAG('K','O','S',' ')},*/ /* Kosraean */ {"koy", HB_TAG('A','T','H',' ')}, /* Koyukon -> Athapaskan */ + {"koz", HB_TAG_NONE }, /* Korak != Komi-Zyrian */ {"kpe", HB_TAG('K','P','L',' ')}, /* Kpelle [macrolanguage] */ + {"kpl", HB_TAG_NONE }, /* Kpala != Kpelle */ + {"kpp", HB_TAG('K','R','N',' ')}, /* Paku Karen (retired code) -> Karen */ {"kpv", HB_TAG('K','O','Z',' ')}, /* Komi-Zyrian */ + {"kpv", HB_TAG('K','O','M',' ')}, /* Komi-Zyrian -> Komi */ {"kpy", HB_TAG('K','Y','K',' ')}, /* Koryak */ {"kqs", HB_TAG('K','I','S',' ')}, /* Northern Kissi -> Kisii */ {"kqy", HB_TAG('K','R','T',' ')}, /* Koorete */ {"kr", HB_TAG('K','N','R',' ')}, /* Kanuri [macrolanguage] */ {"krc", HB_TAG('K','A','R',' ')}, /* Karachay-Balkar -> Karachay */ {"krc", HB_TAG('B','A','L',' ')}, /* Karachay-Balkar -> Balkar */ -/*{"kri", HB_TAG('K','R','I',' ')},*/ /* Krio */ + {"kri", HB_TAG('K','R','I',' ')}, /* Krio */ + {"kri", HB_TAG('C','P','P',' ')}, /* Krio -> Creoles */ + {"krk", HB_TAG_NONE }, /* Kerek != Karakalpak */ /*{"krl", HB_TAG('K','R','L',' ')},*/ /* Karelian */ + {"krm", HB_TAG_NONE }, /* Krim (retired code) != Karaim */ + {"krn", HB_TAG_NONE }, /* Sapo != Karen */ {"krt", HB_TAG('K','N','R',' ')}, /* Tumari Kanuri -> Kanuri */ {"kru", HB_TAG('K','U','U',' ')}, /* Kurukh */ {"ks", HB_TAG('K','S','H',' ')}, /* Kashmiri */ {"ksh", HB_TAG('K','S','H','0')}, /* Kölsch -> Ripuarian */ + {"ksi", HB_TAG_NONE }, /* Krisa != Khasi */ + {"ksm", HB_TAG_NONE }, /* Kumba != Kildin Sami */ {"kss", HB_TAG('K','I','S',' ')}, /* Southern Kisi -> Kisii */ -/*{"ksw", HB_TAG('K','S','W',' ')},*/ /* S’gaw Karen */ + {"ksw", HB_TAG('K','S','W',' ')}, /* S’gaw Karen */ + {"ksw", HB_TAG('K','R','N',' ')}, /* S'gaw Karen -> Karen */ {"ktb", HB_TAG('K','E','B',' ')}, /* Kambaata -> Kebena */ {"ktu", HB_TAG('K','O','N',' ')}, /* Kituba (Democratic Republic of Congo) -> Kikongo */ {"ktw", HB_TAG('A','T','H',' ')}, /* Kato -> Athapaskan */ {"ku", HB_TAG('K','U','R',' ')}, /* Kurdish [macrolanguage] */ + {"kui", HB_TAG_NONE }, /* Kuikúro-Kalapálo != Kui */ + {"kul", HB_TAG_NONE }, /* Kulere != Kulvi */ /*{"kum", HB_TAG('K','U','M',' ')},*/ /* Kumyk */ {"kuu", HB_TAG('A','T','H',' ')}, /* Upper Kuskokwim -> Athapaskan */ + {"kuw", HB_TAG('B','A','D','0')}, /* Kpagua -> Banda */ + {"kuy", HB_TAG_NONE }, /* Kuuku-Ya'u != Kuy */ {"kv", HB_TAG('K','O','M',' ')}, /* Komi [macrolanguage] */ {"kvb", HB_TAG('M','L','Y',' ')}, /* Kubu -> Malay */ + {"kvl", HB_TAG('K','R','N',' ')}, /* Kayaw -> Karen */ + {"kvq", HB_TAG('K','R','N',' ')}, /* Geba Karen -> Karen */ {"kvr", HB_TAG('M','L','Y',' ')}, /* Kerinci -> Malay */ + {"kvt", HB_TAG('K','R','N',' ')}, /* Lahta Karen -> Karen */ + {"kvu", HB_TAG('K','R','N',' ')}, /* Yinbaw Karen -> Karen */ + {"kvy", HB_TAG('K','R','N',' ')}, /* Yintale Karen -> Karen */ {"kw", HB_TAG('C','O','R',' ')}, /* Cornish */ + {"kww", HB_TAG('C','P','P',' ')}, /* Kwinti -> Creoles */ {"kwy", HB_TAG('K','O','N','0')}, /* San Salvador Kongo -> Kongo */ {"kxc", HB_TAG('K','M','S',' ')}, /* Konso -> Komso */ {"kxd", HB_TAG('M','L','Y',' ')}, /* Brunei -> Malay */ - {"kxu", HB_TAG('K','U','I',' ')}, /* Kui (India) */ + {"kxf", HB_TAG('K','R','N',' ')}, /* Manumanaw Karen -> Karen */ + {"kxk", HB_TAG('K','R','N',' ')}, /* Zayein Karen -> Karen */ + {"kxl", HB_TAG('K','U','U',' ')}, /* Nepali Kurux (retired code) -> Kurukh */ + {"kxu", HB_TAG('K','U','I',' ')}, /* Kui (India) (retired code) */ {"ky", HB_TAG('K','I','R',' ')}, /* Kirghiz (Kyrgyz) */ -/*{"kyu", HB_TAG('K','Y','U',' ')},*/ /* Western Kayah */ + {"kyk", HB_TAG_NONE }, /* Kamayo != Koryak */ + {"kyu", HB_TAG('K','Y','U',' ')}, /* Western Kayah */ + {"kyu", HB_TAG('K','R','N',' ')}, /* Western Kayah -> Karen */ {"la", HB_TAG('L','A','T',' ')}, /* Latin */ + {"lac", HB_TAG('M','Y','N',' ')}, /* Lacandon -> Mayan */ {"lad", HB_TAG('J','U','D',' ')}, /* Ladino */ + {"lah", HB_TAG_NONE }, /* Lahnda [macrolanguage] != Lahuli */ + {"lak", HB_TAG_NONE }, /* Laka (Nigeria) != Lak */ + {"lam", HB_TAG_NONE }, /* Lamba != Lambani */ + {"laz", HB_TAG_NONE }, /* Aribwatsa != Laz */ {"lb", HB_TAG('L','T','Z',' ')}, /* Luxembourgish */ {"lbe", HB_TAG('L','A','K',' ')}, /* Lak */ {"lbj", HB_TAG('L','D','K',' ')}, /* Ladakhi */ @@ -550,85 +805,129 @@ static const LangTag ot_languages[] = { {"lce", HB_TAG('M','L','Y',' ')}, /* Loncong -> Malay */ {"lcf", HB_TAG('M','L','Y',' ')}, /* Lubu -> Malay */ {"ldi", HB_TAG('K','O','N','0')}, /* Laari -> Kongo */ + {"ldk", HB_TAG_NONE }, /* Leelau != Ladakhi */ /*{"lez", HB_TAG('L','E','Z',' ')},*/ /* Lezghian -> Lezgi */ {"lg", HB_TAG('L','U','G',' ')}, /* Ganda */ {"li", HB_TAG('L','I','M',' ')}, /* Limburgish */ {"lif", HB_TAG('L','M','B',' ')}, /* Limbu */ /*{"lij", HB_TAG('L','I','J',' ')},*/ /* Ligurian */ + {"lir", HB_TAG('C','P','P',' ')}, /* Liberian English -> Creoles */ /*{"lis", HB_TAG('L','I','S',' ')},*/ /* Lisu */ {"liw", HB_TAG('M','L','Y',' ')}, /* Col -> Malay */ + {"liy", HB_TAG('B','A','D','0')}, /* Banda-Bambari -> Banda */ /*{"ljp", HB_TAG('L','J','P',' ')},*/ /* Lampung Api -> Lampung */ {"lkb", HB_TAG('L','U','H',' ')}, /* Kabras -> Luyia */ /*{"lki", HB_TAG('L','K','I',' ')},*/ /* Laki */ {"lko", HB_TAG('L','U','H',' ')}, /* Khayo -> Luyia */ {"lks", HB_TAG('L','U','H',' ')}, /* Kisa -> Luyia */ {"lld", HB_TAG('L','A','D',' ')}, /* Ladin */ + {"lma", HB_TAG_NONE }, /* East Limba != Low Mari */ + {"lmb", HB_TAG_NONE }, /* Merei != Limbu */ {"lmn", HB_TAG('L','A','M',' ')}, /* Lambadi -> Lambani */ /*{"lmo", HB_TAG('L','M','O',' ')},*/ /* Lombard */ + {"lmw", HB_TAG_NONE }, /* Lake Miwok != Lomwe */ {"ln", HB_TAG('L','I','N',' ')}, /* Lingala */ + {"lna", HB_TAG('B','A','D','0')}, /* Langbashe -> Banda */ + {"lnl", HB_TAG('B','A','D','0')}, /* South Central Banda -> Banda */ {"lo", HB_TAG('L','A','O',' ')}, /* Lao */ /*{"lom", HB_TAG('L','O','M',' ')},*/ /* Loma (Liberia) */ + {"lou", HB_TAG('C','P','P',' ')}, /* Louisiana Creole -> Creoles */ /*{"lrc", HB_TAG('L','R','C',' ')},*/ /* Northern Luri -> Luri */ {"lri", HB_TAG('L','U','H',' ')}, /* Marachi -> Luyia */ {"lrm", HB_TAG('L','U','H',' ')}, /* Marama -> Luyia */ + {"lrt", HB_TAG('C','P','P',' ')}, /* Larantuka Malay -> Creoles */ + {"lsb", HB_TAG_NONE }, /* Burundian Sign Language != Lower Sorbian */ {"lsm", HB_TAG('L','U','H',' ')}, /* Saamia -> Luyia */ {"lt", HB_TAG('L','T','H',' ')}, /* Lithuanian */ {"ltg", HB_TAG('L','V','I',' ')}, /* Latgalian -> Latvian */ + {"lth", HB_TAG_NONE }, /* Thur != Lithuanian */ {"lto", HB_TAG('L','U','H',' ')}, /* Tsotso -> Luyia */ {"lts", HB_TAG('L','U','H',' ')}, /* Tachoni -> Luyia */ {"lu", HB_TAG('L','U','B',' ')}, /* Luba-Katanga */ /*{"lua", HB_TAG('L','U','A',' ')},*/ /* Luba-Lulua */ /*{"luo", HB_TAG('L','U','O',' ')},*/ /* Luo (Kenya and Tanzania) */ {"lus", HB_TAG('M','I','Z',' ')}, /* Lushai -> Mizo */ + {"lus", HB_TAG('Q','I','N',' ')}, /* Lushai -> Chin */ {"luy", HB_TAG('L','U','H',' ')}, /* Luyia [macrolanguage] */ {"luz", HB_TAG('L','R','C',' ')}, /* Southern Luri -> Luri */ {"lv", HB_TAG('L','V','I',' ')}, /* Latvian [macrolanguage] */ + {"lvi", HB_TAG_NONE }, /* Lavi != Latvian */ {"lvs", HB_TAG('L','V','I',' ')}, /* Standard Latvian -> Latvian */ {"lwg", HB_TAG('L','U','H',' ')}, /* Wanga -> Luyia */ - {"lzh", HB_TAG('Z','H','T',' ')}, /* Literary Chinese -> Chinese Traditional */ + {"lzh", HB_TAG('Z','H','T',' ')}, /* Literary Chinese -> Chinese, Traditional */ {"lzz", HB_TAG('L','A','Z',' ')}, /* Laz */ /*{"mad", HB_TAG('M','A','D',' ')},*/ /* Madurese -> Madura */ /*{"mag", HB_TAG('M','A','G',' ')},*/ /* Magahi */ {"mai", HB_TAG('M','T','H',' ')}, /* Maithili */ + {"maj", HB_TAG_NONE }, /* Jalapa De Díaz Mazatec != Majang */ {"mak", HB_TAG('M','K','R',' ')}, /* Makasar */ -/*{"mam", HB_TAG('M','A','M',' ')},*/ /* Mam */ + {"mam", HB_TAG('M','A','M',' ')}, /* Mam */ + {"mam", HB_TAG('M','Y','N',' ')}, /* Mam -> Mayan */ {"man", HB_TAG('M','N','K',' ')}, /* Mandingo [macrolanguage] -> Maninka */ + {"map", HB_TAG_NONE }, /* Austronesian [family] != Mapudungun */ + {"maw", HB_TAG_NONE }, /* Mampruli != Marwari */ {"max", HB_TAG('M','L','Y',' ')}, /* North Moluccan Malay -> Malay */ + {"max", HB_TAG('C','P','P',' ')}, /* North Moluccan Malay -> Creoles */ + {"mbf", HB_TAG('C','P','P',' ')}, /* Baba Malay -> Creoles */ + {"mbn", HB_TAG_NONE }, /* Macaguán != Mbundu */ /*{"mbo", HB_TAG('M','B','O',' ')},*/ /* Mbo (Cameroon) */ + {"mch", HB_TAG_NONE }, /* Maquiritari != Manchu */ + {"mcm", HB_TAG('C','P','P',' ')}, /* Malaccan Creole Portuguese -> Creoles */ + {"mcr", HB_TAG_NONE }, /* Menya != Moose Cree */ {"mct", HB_TAG('B','T','I',' ')}, /* Mengisa -> Beti */ + {"mde", HB_TAG_NONE }, /* Maba (Chad) != Mende */ {"mdf", HB_TAG('M','O','K',' ')}, /* Moksha */ /*{"mdr", HB_TAG('M','D','R',' ')},*/ /* Mandar */ {"mdy", HB_TAG('M','L','E',' ')}, /* Male (Ethiopia) */ {"men", HB_TAG('M','D','E',' ')}, /* Mende (Sierra Leone) */ {"meo", HB_TAG('M','L','Y',' ')}, /* Kedah Malay -> Malay */ /*{"mer", HB_TAG('M','E','R',' ')},*/ /* Meru */ -/*{"mfa", HB_TAG('M','F','A',' ')},*/ /* Pattani Malay */ + {"mfa", HB_TAG('M','F','A',' ')}, /* Pattani Malay */ + {"mfa", HB_TAG('M','L','Y',' ')}, /* Pattani Malay -> Malay */ {"mfb", HB_TAG('M','L','Y',' ')}, /* Bangka -> Malay */ -/*{"mfe", HB_TAG('M','F','E',' ')},*/ /* Morisyen */ + {"mfe", HB_TAG('M','F','E',' ')}, /* Morisyen */ + {"mfe", HB_TAG('C','P','P',' ')}, /* Morisyen -> Creoles */ + {"mfp", HB_TAG('C','P','P',' ')}, /* Makassar Malay -> Creoles */ {"mg", HB_TAG('M','L','G',' ')}, /* Malagasy [macrolanguage] */ {"mh", HB_TAG('M','A','H',' ')}, /* Marshallese */ + {"mhc", HB_TAG('M','Y','N',' ')}, /* Mocho -> Mayan */ {"mhr", HB_TAG('L','M','A',' ')}, /* Eastern Mari -> Low Mari */ {"mhv", HB_TAG('A','R','K',' ')}, /* Arakanese (retired code) -> Rakhine */ {"mi", HB_TAG('M','R','I',' ')}, /* Maori */ -/*{"min", HB_TAG('M','I','N',' ')},*/ /* Minangkabau */ + {"min", HB_TAG('M','I','N',' ')}, /* Minangkabau */ + {"min", HB_TAG('M','L','Y',' ')}, /* Minangkabau -> Malay */ + {"miz", HB_TAG_NONE }, /* Coatzospan Mixtec != Mizo */ {"mk", HB_TAG('M','K','D',' ')}, /* Macedonian */ + {"mkn", HB_TAG('C','P','P',' ')}, /* Kupang Malay -> Creoles */ + {"mkr", HB_TAG_NONE }, /* Malas != Makasar */ {"mku", HB_TAG('M','N','K',' ')}, /* Konyanka Maninka -> Maninka */ /*{"mkw", HB_TAG('M','K','W',' ')},*/ /* Kituba (Congo) */ {"ml", HB_TAG('M','A','L',' ')}, /* Malayalam -> Malayalam Traditional */ {"ml", HB_TAG('M','L','R',' ')}, /* Malayalam -> Malayalam Reformed */ + {"mle", HB_TAG_NONE }, /* Manambu != Male */ + {"mln", HB_TAG_NONE }, /* Malango != Malinke */ {"mlq", HB_TAG('M','L','N',' ')}, /* Western Maninkakan -> Malinke */ {"mlq", HB_TAG('M','N','K',' ')}, /* Western Maninkakan -> Maninka */ + {"mlr", HB_TAG_NONE }, /* Vame != Malayalam Reformed */ {"mmr", HB_TAG('H','M','N',' ')}, /* Western Xiangxi Miao -> Hmong */ {"mn", HB_TAG('M','N','G',' ')}, /* Mongolian [macrolanguage] */ {"mnc", HB_TAG('M','C','H',' ')}, /* Manchu */ + {"mnd", HB_TAG_NONE }, /* Mondé != Mandinka */ + {"mng", HB_TAG_NONE }, /* Eastern Mnong != Mongolian */ + {"mnh", HB_TAG('B','A','D','0')}, /* Mono (Democratic Republic of Congo) -> Banda */ /*{"mni", HB_TAG('M','N','I',' ')},*/ /* Manipuri */ {"mnk", HB_TAG('M','N','D',' ')}, /* Mandinka */ {"mnk", HB_TAG('M','N','K',' ')}, /* Mandinka -> Maninka */ - {"mnp", HB_TAG('Z','H','S',' ')}, /* Min Bei Chinese -> Chinese Simplified */ + {"mnp", HB_TAG('Z','H','S',' ')}, /* Min Bei Chinese -> Chinese, Simplified */ {"mns", HB_TAG('M','A','N',' ')}, /* Mansi */ {"mnw", HB_TAG('M','O','N',' ')}, /* Mon */ + {"mnx", HB_TAG_NONE }, /* Manikion != Manx */ {"mo", HB_TAG('M','O','L',' ')}, /* Moldavian (retired code) */ + {"mod", HB_TAG('C','P','P',' ')}, /* Mobilian -> Creoles */ /*{"moh", HB_TAG('M','O','H',' ')},*/ /* Mohawk */ + {"mok", HB_TAG_NONE }, /* Morori != Moksha */ + {"mop", HB_TAG('M','Y','N',' ')}, /* Mopán Maya -> Mayan */ + {"mor", HB_TAG_NONE }, /* Moro != Moroccan */ /*{"mos", HB_TAG('M','O','S',' ')},*/ /* Mossi */ {"mpe", HB_TAG('M','A','J',' ')}, /* Majang */ {"mqg", HB_TAG('M','L','Y',' ')}, /* Kota Bangun Kutai Malay -> Malay */ @@ -639,9 +938,14 @@ static const LangTag ot_languages[] = { {"msc", HB_TAG('M','N','K',' ')}, /* Sankaran Maninka -> Maninka */ {"msh", HB_TAG('M','L','G',' ')}, /* Masikoro Malagasy -> Malagasy */ {"msi", HB_TAG('M','L','Y',' ')}, /* Sabah Malay -> Malay */ + {"msi", HB_TAG('C','P','P',' ')}, /* Sabah Malay -> Creoles */ {"mt", HB_TAG('M','T','S',' ')}, /* Maltese */ + {"mth", HB_TAG_NONE }, /* Munggui != Maithili */ {"mtr", HB_TAG('M','A','W',' ')}, /* Mewari -> Marwari */ + {"mts", HB_TAG_NONE }, /* Yora != Maltese */ + {"mud", HB_TAG('C','P','P',' ')}, /* Mednyj Aleut -> Creoles */ {"mui", HB_TAG('M','L','Y',' ')}, /* Musi -> Malay */ + {"mun", HB_TAG_NONE }, /* Munda [family] != Mundari */ {"mup", HB_TAG('R','A','J',' ')}, /* Malvi -> Rajasthani */ {"muq", HB_TAG('H','M','N',' ')}, /* Eastern Xiangxi Miao -> Hmong */ /*{"mus", HB_TAG('M','U','S',' ')},*/ /* Creek -> Muscogee */ @@ -650,49 +954,101 @@ static const LangTag ot_languages[] = { {"mvf", HB_TAG('M','N','G',' ')}, /* Peripheral Mongolian -> Mongolian */ {"mwk", HB_TAG('M','N','K',' ')}, /* Kita Maninkakan -> Maninka */ /*{"mwl", HB_TAG('M','W','L',' ')},*/ /* Mirandese */ + {"mwq", HB_TAG('Q','I','N',' ')}, /* Mün Chin -> Chin */ {"mwr", HB_TAG('M','A','W',' ')}, /* Marwari [macrolanguage] */ -/*{"mww", HB_TAG('M','W','W',' ')},*/ /* Hmong Daw */ + {"mww", HB_TAG('M','W','W',' ')}, /* Hmong Daw */ + {"mww", HB_TAG('H','M','N',' ')}, /* Hmong Daw -> Hmong */ {"my", HB_TAG('B','R','M',' ')}, /* Burmese */ {"mym", HB_TAG('M','E','N',' ')}, /* Me’en */ /*{"myn", HB_TAG('M','Y','N',' ')},*/ /* Mayan [family] */ {"myq", HB_TAG('M','N','K',' ')}, /* Forest Maninka (retired code) -> Maninka */ {"myv", HB_TAG('E','R','Z',' ')}, /* Erzya */ + {"mzb", HB_TAG('B','B','R',' ')}, /* Tumzabt -> Berber */ /*{"mzn", HB_TAG('M','Z','N',' ')},*/ /* Mazanderani */ + {"mzs", HB_TAG('C','P','P',' ')}, /* Macanese -> Creoles */ {"na", HB_TAG('N','A','U',' ')}, /* Nauru -> Nauruan */ -/*{"nag", HB_TAG('N','A','G',' ')},*/ /* Naga Pidgin -> Naga-Assamese */ + {"nag", HB_TAG('N','A','G',' ')}, /* Naga Pidgin -> Naga-Assamese */ + {"nag", HB_TAG('C','P','P',' ')}, /* Naga Pidgin -> Creoles */ /*{"nah", HB_TAG('N','A','H',' ')},*/ /* Nahuatl [family] */ - {"nan", HB_TAG('Z','H','S',' ')}, /* Min Nan Chinese -> Chinese Simplified */ + {"nan", HB_TAG('Z','H','S',' ')}, /* Min Nan Chinese -> Chinese, Simplified */ /*{"nap", HB_TAG('N','A','P',' ')},*/ /* Neapolitan */ + {"nas", HB_TAG_NONE }, /* Naasioi != Naskapi */ + {"naz", HB_TAG('N','A','H',' ')}, /* Coatepec Nahuatl -> Nahuatl */ {"nb", HB_TAG('N','O','R',' ')}, /* Norwegian Bokmål -> Norwegian */ + {"nch", HB_TAG('N','A','H',' ')}, /* Central Huasteca Nahuatl -> Nahuatl */ + {"nci", HB_TAG('N','A','H',' ')}, /* Classical Nahuatl -> Nahuatl */ + {"ncj", HB_TAG('N','A','H',' ')}, /* Northern Puebla Nahuatl -> Nahuatl */ + {"ncl", HB_TAG('N','A','H',' ')}, /* Michoacán Nahuatl -> Nahuatl */ + {"ncr", HB_TAG_NONE }, /* Ncane != N-Cree */ + {"ncx", HB_TAG('N','A','H',' ')}, /* Central Puebla Nahuatl -> Nahuatl */ {"nd", HB_TAG('N','D','B',' ')}, /* North Ndebele -> Ndebele */ + {"ndb", HB_TAG_NONE }, /* Kenswei Nsei != Ndebele */ /*{"ndc", HB_TAG('N','D','C',' ')},*/ /* Ndau */ + {"ndg", HB_TAG_NONE }, /* Ndengereko != Ndonga */ /*{"nds", HB_TAG('N','D','S',' ')},*/ /* Low Saxon */ {"ne", HB_TAG('N','E','P',' ')}, /* Nepali [macrolanguage] */ + {"nef", HB_TAG('C','P','P',' ')}, /* Nefamese -> Creoles */ /*{"new", HB_TAG('N','E','W',' ')},*/ /* Newari */ {"ng", HB_TAG('N','D','G',' ')}, /* Ndonga */ /*{"nga", HB_TAG('N','G','A',' ')},*/ /* Ngbaka */ {"ngl", HB_TAG('L','M','W',' ')}, /* Lomwe */ - {"ngo", HB_TAG('S','X','T',' ')}, /* Ngoni -> Sutu */ + {"ngm", HB_TAG('C','P','P',' ')}, /* Ngatik Men's Creole -> Creoles */ + {"ngo", HB_TAG('S','X','T',' ')}, /* Ngoni (retired code) -> Sutu */ + {"ngr", HB_TAG_NONE }, /* Engdewu != Nagari */ + {"ngu", HB_TAG('N','A','H',' ')}, /* Guerrero Nahuatl -> Nahuatl */ + {"nhc", HB_TAG('N','A','H',' ')}, /* Tabasco Nahuatl -> Nahuatl */ {"nhd", HB_TAG('G','U','A',' ')}, /* Chiripá -> Guarani */ + {"nhe", HB_TAG('N','A','H',' ')}, /* Eastern Huasteca Nahuatl -> Nahuatl */ + {"nhg", HB_TAG('N','A','H',' ')}, /* Tetelcingo Nahuatl -> Nahuatl */ + {"nhi", HB_TAG('N','A','H',' ')}, /* Zacatlán-Ahuacatlán-Tepetzintla Nahuatl -> Nahuatl */ + {"nhk", HB_TAG('N','A','H',' ')}, /* Isthmus-Cosoleacaque Nahuatl -> Nahuatl */ + {"nhm", HB_TAG('N','A','H',' ')}, /* Morelos Nahuatl -> Nahuatl */ + {"nhn", HB_TAG('N','A','H',' ')}, /* Central Nahuatl -> Nahuatl */ + {"nhp", HB_TAG('N','A','H',' ')}, /* Isthmus-Pajapan Nahuatl -> Nahuatl */ + {"nhq", HB_TAG('N','A','H',' ')}, /* Huaxcaleca Nahuatl -> Nahuatl */ + {"nht", HB_TAG('N','A','H',' ')}, /* Ometepec Nahuatl -> Nahuatl */ + {"nhv", HB_TAG('N','A','H',' ')}, /* Temascaltepec Nahuatl -> Nahuatl */ + {"nhw", HB_TAG('N','A','H',' ')}, /* Western Huasteca Nahuatl -> Nahuatl */ + {"nhx", HB_TAG('N','A','H',' ')}, /* Isthmus-Mecayapan Nahuatl -> Nahuatl */ + {"nhy", HB_TAG('N','A','H',' ')}, /* Northern Oaxaca Nahuatl -> Nahuatl */ + {"nhz", HB_TAG('N','A','H',' ')}, /* Santa María La Alta Nahuatl -> Nahuatl */ {"niq", HB_TAG('K','A','L',' ')}, /* Nandi -> Kalenjin */ + {"nis", HB_TAG_NONE }, /* Nimi != Nisi */ /*{"niu", HB_TAG('N','I','U',' ')},*/ /* Niuean */ {"niv", HB_TAG('G','I','L',' ')}, /* Gilyak */ + {"njt", HB_TAG('C','P','P',' ')}, /* Ndyuka-Trio Pidgin -> Creoles */ {"njz", HB_TAG('N','I','S',' ')}, /* Nyishi -> Nisi */ + {"nko", HB_TAG_NONE }, /* Nkonya != N’Ko */ + {"nkx", HB_TAG('I','J','O',' ')}, /* Nkoroo -> Ijo */ {"nl", HB_TAG('N','L','D',' ')}, /* Dutch */ + {"nla", HB_TAG('B','M','L',' ')}, /* Ngombale -> Bamileke */ {"nle", HB_TAG('L','U','H',' ')}, /* East Nyala -> Luyia */ + {"nln", HB_TAG('N','A','H',' ')}, /* Durango Nahuatl (retired code) -> Nahuatl */ + {"nlv", HB_TAG('N','A','H',' ')}, /* Orizaba Nahuatl -> Nahuatl */ {"nn", HB_TAG('N','Y','N',' ')}, /* Norwegian Nynorsk (Nynorsk, Norwegian) */ + {"nn", HB_TAG('N','O','R',' ')}, /* Norwegian Nynorsk -> Norwegian */ + {"nnh", HB_TAG('B','M','L',' ')}, /* Ngiemboon -> Bamileke */ + {"nnz", HB_TAG('B','M','L',' ')}, /* Nda'nda' -> Bamileke */ {"no", HB_TAG('N','O','R',' ')}, /* Norwegian [macrolanguage] */ {"nod", HB_TAG('N','T','A',' ')}, /* Northern Thai -> Northern Tai */ /*{"noe", HB_TAG('N','O','E',' ')},*/ /* Nimadi */ /*{"nog", HB_TAG('N','O','G',' ')},*/ /* Nogai */ /*{"nov", HB_TAG('N','O','V',' ')},*/ /* Novial */ {"npi", HB_TAG('N','E','P',' ')}, /* Nepali */ + {"npl", HB_TAG('N','A','H',' ')}, /* Southeastern Puebla Nahuatl -> Nahuatl */ {"nqo", HB_TAG('N','K','O',' ')}, /* N’Ko */ {"nr", HB_TAG('N','D','B',' ')}, /* South Ndebele -> Ndebele */ {"nsk", HB_TAG('N','A','S',' ')}, /* Naskapi */ -/*{"nso", HB_TAG('N','S','O',' ')},*/ /* Pedi -> Sotho, Northern */ + {"nsm", HB_TAG_NONE }, /* Sumi Naga != Northern Sami */ +/*{"nso", HB_TAG('N','S','O',' ')},*/ /* Northern Sotho */ + {"nsu", HB_TAG('N','A','H',' ')}, /* Sierra Negra Nahuatl -> Nahuatl */ + {"nto", HB_TAG_NONE }, /* Ntomba != Esperanto */ + {"nue", HB_TAG('B','A','D','0')}, /* Ngundu -> Banda */ + {"nuu", HB_TAG('B','A','D','0')}, /* Ngbundu -> Banda */ + {"nuz", HB_TAG('N','A','H',' ')}, /* Tlamacazapa Nahuatl -> Nahuatl */ {"nv", HB_TAG('N','A','V',' ')}, /* Navajo */ {"nv", HB_TAG('A','T','H',' ')}, /* Navajo -> Athapaskan */ + {"nwe", HB_TAG('B','M','L',' ')}, /* Ngwe -> Bamileke */ {"ny", HB_TAG('C','H','I',' ')}, /* Chichewa (Chewa, Nyanja) */ {"nyd", HB_TAG('L','U','H',' ')}, /* Nyore -> Luyia */ /*{"nym", HB_TAG('N','Y','M',' ')},*/ /* Nyamwezi */ @@ -704,21 +1060,33 @@ static const LangTag ot_languages[] = { {"ojc", HB_TAG('O','J','B',' ')}, /* Central Ojibwa -> Ojibway */ {"ojg", HB_TAG('O','J','B',' ')}, /* Eastern Ojibwa -> Ojibway */ {"ojs", HB_TAG('O','C','R',' ')}, /* Severn Ojibwa -> Oji-Cree */ + {"ojs", HB_TAG('O','J','B',' ')}, /* Severn Ojibwa -> Ojibway */ {"ojw", HB_TAG('O','J','B',' ')}, /* Western Ojibwa -> Ojibway */ + {"okd", HB_TAG('I','J','O',' ')}, /* Okodia -> Ijo */ {"oki", HB_TAG('K','A','L',' ')}, /* Okiek -> Kalenjin */ {"okm", HB_TAG('K','O','H',' ')}, /* Middle Korean (10th-16th cent.) -> Korean Old Hangul */ + {"okr", HB_TAG('I','J','O',' ')}, /* Kirike -> Ijo */ {"om", HB_TAG('O','R','O',' ')}, /* Oromo [macrolanguage] */ + {"onx", HB_TAG('C','P','P',' ')}, /* Onin Based Pidgin -> Creoles */ + {"oor", HB_TAG('C','P','P',' ')}, /* Oorlams -> Creoles */ {"or", HB_TAG('O','R','I',' ')}, /* Odia (formerly Oriya) [macrolanguage] */ {"orc", HB_TAG('O','R','O',' ')}, /* Orma -> Oromo */ {"orn", HB_TAG('M','L','Y',' ')}, /* Orang Kanaq -> Malay */ + {"oro", HB_TAG_NONE }, /* Orokolo != Oromo */ + {"orr", HB_TAG('I','J','O',' ')}, /* Oruma -> Ijo */ {"ors", HB_TAG('M','L','Y',' ')}, /* Orang Seletar -> Malay */ {"ory", HB_TAG('O','R','I',' ')}, /* Odia (formerly Oriya) */ {"os", HB_TAG('O','S','S',' ')}, /* Ossetian */ {"otw", HB_TAG('O','J','B',' ')}, /* Ottawa -> Ojibway */ + {"oua", HB_TAG('B','B','R',' ')}, /* Tagargrent -> Berber */ {"pa", HB_TAG('P','A','N',' ')}, /* Punjabi */ + {"paa", HB_TAG_NONE }, /* Papuan [family] != Palestinian Aramaic */ /*{"pag", HB_TAG('P','A','G',' ')},*/ /* Pangasinan */ + {"pal", HB_TAG_NONE }, /* Pahlavi != Pali */ /*{"pam", HB_TAG('P','A','M',' ')},*/ /* Pampanga -> Pampangan */ {"pap", HB_TAG('P','A','P','0')}, /* Papiamento -> Papiamentu */ + {"pap", HB_TAG('C','P','P',' ')}, /* Papiamento -> Creoles */ + {"pas", HB_TAG_NONE }, /* Papasena != Pashto */ /*{"pau", HB_TAG('P','A','U',' ')},*/ /* Palauan */ {"pbt", HB_TAG('P','A','S',' ')}, /* Southern Pashto -> Pashto */ {"pbu", HB_TAG('P','A','S',' ')}, /* Northern Pashto -> Pashto */ @@ -726,84 +1094,147 @@ static const LangTag ot_languages[] = { /*{"pcd", HB_TAG('P','C','D',' ')},*/ /* Picard */ {"pce", HB_TAG('P','L','G',' ')}, /* Ruching Palaung -> Palaung */ {"pck", HB_TAG('Q','I','N',' ')}, /* Paite Chin -> Chin */ + {"pcm", HB_TAG('C','P','P',' ')}, /* Nigerian Pidgin -> Creoles */ /*{"pdc", HB_TAG('P','D','C',' ')},*/ /* Pennsylvania German */ + {"pdu", HB_TAG('K','R','N',' ')}, /* Kayan -> Karen */ + {"pea", HB_TAG('C','P','P',' ')}, /* Peranakan Indonesian -> Creoles */ {"pel", HB_TAG('M','L','Y',' ')}, /* Pekal -> Malay */ {"pes", HB_TAG('F','A','R',' ')}, /* Iranian Persian -> Persian */ + {"pey", HB_TAG('C','P','P',' ')}, /* Petjo -> Creoles */ {"pga", HB_TAG('A','R','A',' ')}, /* Sudanese Creole Arabic -> Arabic */ + {"pga", HB_TAG('C','P','P',' ')}, /* Sudanese Creole Arabic -> Creoles */ /*{"phk", HB_TAG('P','H','K',' ')},*/ /* Phake */ {"pi", HB_TAG('P','A','L',' ')}, /* Pali */ -/*{"pih", HB_TAG('P','I','H',' ')},*/ /* Pitcairn-Norfolk -> Norfolk */ + {"pih", HB_TAG('P','I','H',' ')}, /* Pitcairn-Norfolk -> Norfolk */ + {"pih", HB_TAG('C','P','P',' ')}, /* Pitcairn-Norfolk -> Creoles */ + {"pil", HB_TAG_NONE }, /* Yom != Filipino */ + {"pis", HB_TAG('C','P','P',' ')}, /* Pijin -> Creoles */ + {"pkh", HB_TAG('Q','I','N',' ')}, /* Pankhu -> Chin */ {"pko", HB_TAG('K','A','L',' ')}, /* Pökoot -> Kalenjin */ {"pl", HB_TAG('P','L','K',' ')}, /* Polish */ + {"plg", HB_TAG_NONE }, /* Pilagá != Palaung */ + {"plk", HB_TAG_NONE }, /* Kohistani Shina != Polish */ {"pll", HB_TAG('P','L','G',' ')}, /* Shwe Palaung -> Palaung */ - {"plp", HB_TAG('P','A','P',' ')}, /* Palpa */ + {"pln", HB_TAG('C','P','P',' ')}, /* Palenquero -> Creoles */ + {"plp", HB_TAG('P','A','P',' ')}, /* Palpa (retired code) */ {"plt", HB_TAG('M','L','G',' ')}, /* Plateau Malagasy -> Malagasy */ + {"pml", HB_TAG('C','P','P',' ')}, /* Lingua Franca -> Creoles */ /*{"pms", HB_TAG('P','M','S',' ')},*/ /* Piemontese */ + {"pmy", HB_TAG('C','P','P',' ')}, /* Papuan Malay -> Creoles */ /*{"pnb", HB_TAG('P','N','B',' ')},*/ /* Western Panjabi */ -/*{"poh", HB_TAG('P','O','H',' ')},*/ /* Poqomchi' -> Pocomchi */ + {"poc", HB_TAG('M','Y','N',' ')}, /* Poqomam -> Mayan */ + {"poh", HB_TAG('P','O','H',' ')}, /* Poqomchi' -> Pocomchi */ + {"poh", HB_TAG('M','Y','N',' ')}, /* Poqomchi' -> Mayan */ /*{"pon", HB_TAG('P','O','N',' ')},*/ /* Pohnpeian */ + {"pov", HB_TAG('C','P','P',' ')}, /* Upper Guinea Crioulo -> Creoles */ {"ppa", HB_TAG('B','A','G',' ')}, /* Pao (retired code) -> Baghelkhandi */ + {"pre", HB_TAG('C','P','P',' ')}, /* Principense -> Creoles */ /*{"pro", HB_TAG('P','R','O',' ')},*/ /* Old Provençal (to 1500) -> Provençal / Old Provençal */ {"prs", HB_TAG('D','R','I',' ')}, /* Dari */ + {"prs", HB_TAG('F','A','R',' ')}, /* Dari -> Persian */ {"ps", HB_TAG('P','A','S',' ')}, /* Pashto [macrolanguage] */ {"pse", HB_TAG('M','L','Y',' ')}, /* Central Malay -> Malay */ {"pst", HB_TAG('P','A','S',' ')}, /* Central Pashto -> Pashto */ {"pt", HB_TAG('P','T','G',' ')}, /* Portuguese */ -/*{"pwo", HB_TAG('P','W','O',' ')},*/ /* Pwo Western Karen -> Western Pwo Karen */ + {"pub", HB_TAG('Q','I','N',' ')}, /* Purum -> Chin */ + {"puz", HB_TAG('Q','I','N',' ')}, /* Purum Naga (retired code) -> Chin */ + {"pwo", HB_TAG('P','W','O',' ')}, /* Pwo Western Karen -> Western Pwo Karen */ + {"pwo", HB_TAG('K','R','N',' ')}, /* Pwo Western Karen -> Karen */ + {"pww", HB_TAG('K','R','N',' ')}, /* Pwo Northern Karen -> Karen */ {"qu", HB_TAG('Q','U','Z',' ')}, /* Quechua [macrolanguage] */ {"qub", HB_TAG('Q','W','H',' ')}, /* Huallaga Huánuco Quechua -> Quechua (Peru) */ -/*{"quc", HB_TAG('Q','U','C',' ')},*/ /* K’iche’ */ + {"qub", HB_TAG('Q','U','Z',' ')}, /* Huallaga Huánuco Quechua -> Quechua */ + {"quc", HB_TAG('Q','U','C',' ')}, /* K’iche’ */ + {"quc", HB_TAG('M','Y','N',' ')}, /* K'iche' -> Mayan */ {"qud", HB_TAG('Q','V','I',' ')}, /* Calderón Highland Quichua -> Quechua (Ecuador) */ + {"qud", HB_TAG('Q','U','Z',' ')}, /* Calderón Highland Quichua -> Quechua */ {"quf", HB_TAG('Q','U','Z',' ')}, /* Lambayeque Quechua -> Quechua */ {"qug", HB_TAG('Q','V','I',' ')}, /* Chimborazo Highland Quichua -> Quechua (Ecuador) */ -/*{"quh", HB_TAG('Q','U','H',' ')},*/ /* South Bolivian Quechua -> Quechua (Bolivia) */ + {"qug", HB_TAG('Q','U','Z',' ')}, /* Chimborazo Highland Quichua -> Quechua */ + {"quh", HB_TAG('Q','U','H',' ')}, /* South Bolivian Quechua -> Quechua (Bolivia) */ + {"quh", HB_TAG('Q','U','Z',' ')}, /* South Bolivian Quechua -> Quechua */ {"quk", HB_TAG('Q','U','Z',' ')}, /* Chachapoyas Quechua -> Quechua */ + {"qul", HB_TAG('Q','U','H',' ')}, /* North Bolivian Quechua -> Quechua (Bolivia) */ {"qul", HB_TAG('Q','U','Z',' ')}, /* North Bolivian Quechua -> Quechua */ + {"qum", HB_TAG('M','Y','N',' ')}, /* Sipacapense -> Mayan */ {"qup", HB_TAG('Q','V','I',' ')}, /* Southern Pastaza Quechua -> Quechua (Ecuador) */ + {"qup", HB_TAG('Q','U','Z',' ')}, /* Southern Pastaza Quechua -> Quechua */ {"qur", HB_TAG('Q','W','H',' ')}, /* Yanahuanca Pasco Quechua -> Quechua (Peru) */ + {"qur", HB_TAG('Q','U','Z',' ')}, /* Yanahuanca Pasco Quechua -> Quechua */ {"qus", HB_TAG('Q','U','H',' ')}, /* Santiago del Estero Quichua -> Quechua (Bolivia) */ + {"qus", HB_TAG('Q','U','Z',' ')}, /* Santiago del Estero Quichua -> Quechua */ + {"quv", HB_TAG('M','Y','N',' ')}, /* Sacapulteco -> Mayan */ {"quw", HB_TAG('Q','V','I',' ')}, /* Tena Lowland Quichua -> Quechua (Ecuador) */ + {"quw", HB_TAG('Q','U','Z',' ')}, /* Tena Lowland Quichua -> Quechua */ {"qux", HB_TAG('Q','W','H',' ')}, /* Yauyos Quechua -> Quechua (Peru) */ + {"qux", HB_TAG('Q','U','Z',' ')}, /* Yauyos Quechua -> Quechua */ {"quy", HB_TAG('Q','U','Z',' ')}, /* Ayacucho Quechua -> Quechua */ /*{"quz", HB_TAG('Q','U','Z',' ')},*/ /* Cusco Quechua -> Quechua */ {"qva", HB_TAG('Q','W','H',' ')}, /* Ambo-Pasco Quechua -> Quechua (Peru) */ + {"qva", HB_TAG('Q','U','Z',' ')}, /* Ambo-Pasco Quechua -> Quechua */ {"qvc", HB_TAG('Q','U','Z',' ')}, /* Cajamarca Quechua -> Quechua */ {"qve", HB_TAG('Q','U','Z',' ')}, /* Eastern Apurímac Quechua -> Quechua */ {"qvh", HB_TAG('Q','W','H',' ')}, /* Huamalíes-Dos de Mayo Huánuco Quechua -> Quechua (Peru) */ -/*{"qvi", HB_TAG('Q','V','I',' ')},*/ /* Imbabura Highland Quichua -> Quechua (Ecuador) */ + {"qvh", HB_TAG('Q','U','Z',' ')}, /* Huamalíes-Dos de Mayo Huánuco Quechua -> Quechua */ + {"qvi", HB_TAG('Q','V','I',' ')}, /* Imbabura Highland Quichua -> Quechua (Ecuador) */ + {"qvi", HB_TAG('Q','U','Z',' ')}, /* Imbabura Highland Quichua -> Quechua */ {"qvj", HB_TAG('Q','V','I',' ')}, /* Loja Highland Quichua -> Quechua (Ecuador) */ + {"qvj", HB_TAG('Q','U','Z',' ')}, /* Loja Highland Quichua -> Quechua */ {"qvl", HB_TAG('Q','W','H',' ')}, /* Cajatambo North Lima Quechua -> Quechua (Peru) */ + {"qvl", HB_TAG('Q','U','Z',' ')}, /* Cajatambo North Lima Quechua -> Quechua */ {"qvm", HB_TAG('Q','W','H',' ')}, /* Margos-Yarowilca-Lauricocha Quechua -> Quechua (Peru) */ + {"qvm", HB_TAG('Q','U','Z',' ')}, /* Margos-Yarowilca-Lauricocha Quechua -> Quechua */ {"qvn", HB_TAG('Q','W','H',' ')}, /* North Junín Quechua -> Quechua (Peru) */ + {"qvn", HB_TAG('Q','U','Z',' ')}, /* North Junín Quechua -> Quechua */ {"qvo", HB_TAG('Q','V','I',' ')}, /* Napo Lowland Quechua -> Quechua (Ecuador) */ + {"qvo", HB_TAG('Q','U','Z',' ')}, /* Napo Lowland Quechua -> Quechua */ {"qvp", HB_TAG('Q','W','H',' ')}, /* Pacaraos Quechua -> Quechua (Peru) */ + {"qvp", HB_TAG('Q','U','Z',' ')}, /* Pacaraos Quechua -> Quechua */ {"qvs", HB_TAG('Q','U','Z',' ')}, /* San Martín Quechua -> Quechua */ {"qvw", HB_TAG('Q','W','H',' ')}, /* Huaylla Wanca Quechua -> Quechua (Peru) */ + {"qvw", HB_TAG('Q','U','Z',' ')}, /* Huaylla Wanca Quechua -> Quechua */ {"qvz", HB_TAG('Q','V','I',' ')}, /* Northern Pastaza Quichua -> Quechua (Ecuador) */ + {"qvz", HB_TAG('Q','U','Z',' ')}, /* Northern Pastaza Quichua -> Quechua */ {"qwa", HB_TAG('Q','W','H',' ')}, /* Corongo Ancash Quechua -> Quechua (Peru) */ + {"qwa", HB_TAG('Q','U','Z',' ')}, /* Corongo Ancash Quechua -> Quechua */ {"qwc", HB_TAG('Q','U','Z',' ')}, /* Classical Quechua -> Quechua */ -/*{"qwh", HB_TAG('Q','W','H',' ')},*/ /* Huaylas Ancash Quechua -> Quechua (Peru) */ + {"qwh", HB_TAG('Q','W','H',' ')}, /* Huaylas Ancash Quechua -> Quechua (Peru) */ + {"qwh", HB_TAG('Q','U','Z',' ')}, /* Huaylas Ancash Quechua -> Quechua */ {"qws", HB_TAG('Q','W','H',' ')}, /* Sihuas Ancash Quechua -> Quechua (Peru) */ + {"qws", HB_TAG('Q','U','Z',' ')}, /* Sihuas Ancash Quechua -> Quechua */ + {"qwt", HB_TAG('A','T','H',' ')}, /* Kwalhioqua-Tlatskanai -> Athapaskan */ {"qxa", HB_TAG('Q','W','H',' ')}, /* Chiquián Ancash Quechua -> Quechua (Peru) */ + {"qxa", HB_TAG('Q','U','Z',' ')}, /* Chiquián Ancash Quechua -> Quechua */ {"qxc", HB_TAG('Q','W','H',' ')}, /* Chincha Quechua -> Quechua (Peru) */ + {"qxc", HB_TAG('Q','U','Z',' ')}, /* Chincha Quechua -> Quechua */ {"qxh", HB_TAG('Q','W','H',' ')}, /* Panao Huánuco Quechua -> Quechua (Peru) */ + {"qxh", HB_TAG('Q','U','Z',' ')}, /* Panao Huánuco Quechua -> Quechua */ {"qxl", HB_TAG('Q','V','I',' ')}, /* Salasaca Highland Quichua -> Quechua (Ecuador) */ + {"qxl", HB_TAG('Q','U','Z',' ')}, /* Salasaca Highland Quichua -> Quechua */ {"qxn", HB_TAG('Q','W','H',' ')}, /* Northern Conchucos Ancash Quechua -> Quechua (Peru) */ + {"qxn", HB_TAG('Q','U','Z',' ')}, /* Northern Conchucos Ancash Quechua -> Quechua */ {"qxo", HB_TAG('Q','W','H',' ')}, /* Southern Conchucos Ancash Quechua -> Quechua (Peru) */ + {"qxo", HB_TAG('Q','U','Z',' ')}, /* Southern Conchucos Ancash Quechua -> Quechua */ {"qxp", HB_TAG('Q','U','Z',' ')}, /* Puno Quechua -> Quechua */ {"qxr", HB_TAG('Q','V','I',' ')}, /* Cañar Highland Quichua -> Quechua (Ecuador) */ + {"qxr", HB_TAG('Q','U','Z',' ')}, /* Cañar Highland Quichua -> Quechua */ {"qxt", HB_TAG('Q','W','H',' ')}, /* Santa Ana de Tusi Pasco Quechua -> Quechua (Peru) */ + {"qxt", HB_TAG('Q','U','Z',' ')}, /* Santa Ana de Tusi Pasco Quechua -> Quechua */ {"qxu", HB_TAG('Q','U','Z',' ')}, /* Arequipa-La Unión Quechua -> Quechua */ {"qxw", HB_TAG('Q','W','H',' ')}, /* Jauja Wanca Quechua -> Quechua (Peru) */ + {"qxw", HB_TAG('Q','U','Z',' ')}, /* Jauja Wanca Quechua -> Quechua */ {"rag", HB_TAG('L','U','H',' ')}, /* Logooli -> Luyia */ /*{"raj", HB_TAG('R','A','J',' ')},*/ /* Rajasthani [macrolanguage] */ + {"ral", HB_TAG('Q','I','N',' ')}, /* Ralte -> Chin */ /*{"rar", HB_TAG('R','A','R',' ')},*/ /* Rarotongan */ {"rbb", HB_TAG('P','L','G',' ')}, /* Rumai Palaung -> Palaung */ {"rbl", HB_TAG('B','I','K',' ')}, /* Miraya Bikol -> Bikol */ + {"rcf", HB_TAG('C','P','P',' ')}, /* Réunion Creole French -> Creoles */ /*{"rej", HB_TAG('R','E','J',' ')},*/ /* Rejang */ /*{"ria", HB_TAG('R','I','A',' ')},*/ /* Riang (India) */ -/*{"rif", HB_TAG('R','I','F',' ')},*/ /* Tarifit */ -/*{"rit", HB_TAG('R','I','T',' ')},*/ /* Ritarungo */ + {"rif", HB_TAG('R','I','F',' ')}, /* Tarifit */ + {"rif", HB_TAG('B','B','R',' ')}, /* Tarifit -> Berber */ +/*{"rit", HB_TAG('R','I','T',' ')},*/ /* Ritharrngu -> Ritarungo */ {"rki", HB_TAG('A','R','K',' ')}, /* Rakhine */ /*{"rkw", HB_TAG('R','K','W',' ')},*/ /* Arakwal */ {"rm", HB_TAG('R','M','S',' ')}, /* Romansh */ @@ -812,13 +1243,16 @@ static const LangTag ot_languages[] = { {"rml", HB_TAG('R','O','Y',' ')}, /* Baltic Romani -> Romany */ {"rmn", HB_TAG('R','O','Y',' ')}, /* Balkan Romani -> Romany */ {"rmo", HB_TAG('R','O','Y',' ')}, /* Sinte Romani -> Romany */ + {"rms", HB_TAG_NONE }, /* Romanian Sign Language != Romansh */ {"rmw", HB_TAG('R','O','Y',' ')}, /* Welsh Romani -> Romany */ -/*{"rmy", HB_TAG('R','M','Y',' ')},*/ /* Vlax Romani */ + {"rmy", HB_TAG('R','M','Y',' ')}, /* Vlax Romani */ + {"rmy", HB_TAG('R','O','Y',' ')}, /* Vlax Romani -> Romany */ {"rmz", HB_TAG('A','R','K',' ')}, /* Marma -> Rakhine */ {"rn", HB_TAG('R','U','N',' ')}, /* Rundi */ - {"rnl", HB_TAG('H','A','L',' ')}, /* Ranglong -> Halam (Falam Chin) */ {"ro", HB_TAG('R','O','M',' ')}, /* Romanian */ {"rom", HB_TAG('R','O','Y',' ')}, /* Romany [macrolanguage] */ + {"rop", HB_TAG('C','P','P',' ')}, /* Kriol -> Creoles */ + {"rtc", HB_TAG('Q','I','N',' ')}, /* Rungtu Chin -> Chin */ /*{"rtm", HB_TAG('R','T','M',' ')},*/ /* Rotuman */ {"ru", HB_TAG('R','U','S',' ')}, /* Russian */ {"rue", HB_TAG('R','S','Y',' ')}, /* Rusyn */ @@ -826,11 +1260,16 @@ static const LangTag ot_languages[] = { {"rw", HB_TAG('R','U','A',' ')}, /* Kinyarwanda */ {"rwr", HB_TAG('M','A','W',' ')}, /* Marwari (India) */ {"sa", HB_TAG('S','A','N',' ')}, /* Sanskrit */ + {"sad", HB_TAG_NONE }, /* Sandawe != Sadri */ {"sah", HB_TAG('Y','A','K',' ')}, /* Yakut -> Sakha */ {"sam", HB_TAG('P','A','A',' ')}, /* Samaritan Aramaic -> Palestinian Aramaic */ /*{"sas", HB_TAG('S','A','S',' ')},*/ /* Sasak */ /*{"sat", HB_TAG('S','A','T',' ')},*/ /* Santali */ + {"say", HB_TAG_NONE }, /* Saya != Sayisi */ {"sc", HB_TAG('S','R','D',' ')}, /* Sardinian [macrolanguage] */ + {"scf", HB_TAG('C','P','P',' ')}, /* San Miguel Creole French -> Creoles */ + {"sch", HB_TAG('Q','I','N',' ')}, /* Sakachep -> Chin */ + {"sci", HB_TAG('C','P','P',' ')}, /* Sri Lankan Creole Malay -> Creoles */ {"sck", HB_TAG('S','A','D',' ')}, /* Sadri */ /*{"scn", HB_TAG('S','C','N',' ')},*/ /* Sicilian */ /*{"sco", HB_TAG('S','C','O',' ')},*/ /* Scots */ @@ -841,6 +1280,7 @@ static const LangTag ot_languages[] = { {"sdc", HB_TAG('S','R','D',' ')}, /* Sassarese Sardinian -> Sardinian */ {"sdh", HB_TAG('K','U','R',' ')}, /* Southern Kurdish -> Kurdish */ {"sdn", HB_TAG('S','R','D',' ')}, /* Gallurese Sardinian -> Sardinian */ + {"sds", HB_TAG('B','B','R',' ')}, /* Sened -> Berber */ {"se", HB_TAG('N','S','M',' ')}, /* Northern Sami */ {"seh", HB_TAG('S','N','A',' ')}, /* Sena */ {"sek", HB_TAG('A','T','H',' ')}, /* Sekani -> Athapaskan */ @@ -850,51 +1290,78 @@ static const LangTag ot_languages[] = { {"sg", HB_TAG('S','G','O',' ')}, /* Sango */ /*{"sga", HB_TAG('S','G','A',' ')},*/ /* Old Irish (to 900) */ {"sgc", HB_TAG('K','A','L',' ')}, /* Kipsigis -> Kalenjin */ + {"sgo", HB_TAG_NONE }, /* Songa (retired code) != Sango */ /*{"sgs", HB_TAG('S','G','S',' ')},*/ /* Samogitian */ {"sgw", HB_TAG('C','H','G',' ')}, /* Sebat Bet Gurage -> Chaha Gurage */ - {"sgw", HB_TAG('S','G','W',' ')}, /* Sebat Bet Gurage -> Chaha Gurage (SIL fonts) */ -/*{"shi", HB_TAG('S','H','I',' ')},*/ /* Tachelhit */ + {"shi", HB_TAG('S','H','I',' ')}, /* Tachelhit */ + {"shi", HB_TAG('B','B','R',' ')}, /* Tachelhit -> Berber */ + {"shl", HB_TAG('Q','I','N',' ')}, /* Shendu -> Chin */ /*{"shn", HB_TAG('S','H','N',' ')},*/ /* Shan */ {"shu", HB_TAG('A','R','A',' ')}, /* Chadian Arabic -> Arabic */ + {"shy", HB_TAG('B','B','R',' ')}, /* Tachawit -> Berber */ {"si", HB_TAG('S','N','H',' ')}, /* Sinhala (Sinhalese) */ + {"sib", HB_TAG_NONE }, /* Sebop != Sibe */ /*{"sid", HB_TAG('S','I','D',' ')},*/ /* Sidamo */ + {"sig", HB_TAG_NONE }, /* Paasaal != Silte Gurage */ + {"siz", HB_TAG('B','B','R',' ')}, /* Siwi -> Berber */ {"sjd", HB_TAG('K','S','M',' ')}, /* Kildin Sami */ {"sjo", HB_TAG('S','I','B',' ')}, /* Xibe -> Sibe */ + {"sjs", HB_TAG('B','B','R',' ')}, /* Senhaja De Srair -> Berber */ {"sk", HB_TAG('S','K','Y',' ')}, /* Slovak */ {"skg", HB_TAG('M','L','G',' ')}, /* Sakalava Malagasy -> Malagasy */ {"skr", HB_TAG('S','R','K',' ')}, /* Saraiki */ + {"sks", HB_TAG_NONE }, /* Maia != Skolt Sami */ + {"skw", HB_TAG('C','P','P',' ')}, /* Skepi Creole Dutch -> Creoles */ + {"sky", HB_TAG_NONE }, /* Sikaiana != Slovak */ {"sl", HB_TAG('S','L','V',' ')}, /* Slovenian */ + {"sla", HB_TAG_NONE }, /* Slavic [family] != Slavey */ {"sm", HB_TAG('S','M','O',' ')}, /* Samoan */ {"sma", HB_TAG('S','S','M',' ')}, /* Southern Sami */ {"smj", HB_TAG('L','S','M',' ')}, /* Lule Sami */ + {"sml", HB_TAG_NONE }, /* Central Sama != Somali */ {"smn", HB_TAG('I','S','M',' ')}, /* Inari Sami */ {"sms", HB_TAG('S','K','S',' ')}, /* Skolt Sami */ + {"smt", HB_TAG('Q','I','N',' ')}, /* Simte -> Chin */ {"sn", HB_TAG('S','N','A','0')}, /* Shona */ + {"snh", HB_TAG_NONE }, /* Shinabo (retired code) != Sinhala (Sinhalese) */ /*{"snk", HB_TAG('S','N','K',' ')},*/ /* Soninke */ {"so", HB_TAG('S','M','L',' ')}, /* Somali */ + {"sog", HB_TAG_NONE }, /* Sogdian != Sodo Gurage */ /*{"sop", HB_TAG('S','O','P',' ')},*/ /* Songe */ {"spv", HB_TAG('O','R','I',' ')}, /* Sambalpuri -> Odia (formerly Oriya) */ {"spy", HB_TAG('K','A','L',' ')}, /* Sabaot -> Kalenjin */ {"sq", HB_TAG('S','Q','I',' ')}, /* Albanian [macrolanguage] */ {"sr", HB_TAG('S','R','B',' ')}, /* Serbian */ + {"srb", HB_TAG_NONE }, /* Sora != Serbian */ {"src", HB_TAG('S','R','D',' ')}, /* Logudorese Sardinian -> Sardinian */ + {"srk", HB_TAG_NONE }, /* Serudung Murut != Saraiki */ + {"srm", HB_TAG('C','P','P',' ')}, /* Saramaccan -> Creoles */ + {"srn", HB_TAG('C','P','P',' ')}, /* Sranan Tongo -> Creoles */ {"sro", HB_TAG('S','R','D',' ')}, /* Campidanese Sardinian -> Sardinian */ /*{"srr", HB_TAG('S','R','R',' ')},*/ /* Serer */ {"srs", HB_TAG('A','T','H',' ')}, /* Sarsi -> Athapaskan */ {"ss", HB_TAG('S','W','Z',' ')}, /* Swati */ {"ssh", HB_TAG('A','R','A',' ')}, /* Shihhi Arabic -> Arabic */ - {"st", HB_TAG('S','O','T',' ')}, /* Southern Sotho -> Sotho, Southern */ + {"ssl", HB_TAG_NONE }, /* Western Sisaala != South Slavey */ + {"ssm", HB_TAG_NONE }, /* Semnam != Southern Sami */ + {"st", HB_TAG('S','O','T',' ')}, /* Southern Sotho */ + {"sta", HB_TAG('C','P','P',' ')}, /* Settla -> Creoles */ /*{"stq", HB_TAG('S','T','Q',' ')},*/ /* Saterfriesisch -> Saterland Frisian */ {"stv", HB_TAG('S','I','G',' ')}, /* Silt'e -> Silte Gurage */ {"su", HB_TAG('S','U','N',' ')}, /* Sundanese */ /*{"suk", HB_TAG('S','U','K',' ')},*/ /* Sukuma */ {"suq", HB_TAG('S','U','R',' ')}, /* Suri */ + {"sur", HB_TAG_NONE }, /* Mwaghavul != Suri */ {"sv", HB_TAG('S','V','E',' ')}, /* Swedish */ /*{"sva", HB_TAG('S','V','A',' ')},*/ /* Svan */ + {"svc", HB_TAG('C','P','P',' ')}, /* Vincentian Creole English -> Creoles */ + {"sve", HB_TAG_NONE }, /* Serili != Swedish */ {"sw", HB_TAG('S','W','K',' ')}, /* Swahili [macrolanguage] */ {"swb", HB_TAG('C','M','R',' ')}, /* Maore Comorian -> Comorian */ {"swc", HB_TAG('S','W','K',' ')}, /* Congo Swahili -> Swahili */ {"swh", HB_TAG('S','W','K',' ')}, /* Swahili */ + {"swk", HB_TAG_NONE }, /* Malawi Sena != Swahili */ + {"swn", HB_TAG('B','B','R',' ')}, /* Sawknah -> Berber */ {"swv", HB_TAG('M','A','W',' ')}, /* Shekhawati -> Marwari */ /*{"sxu", HB_TAG('S','X','U',' ')},*/ /* Upper Saxon */ {"syc", HB_TAG('S','Y','R',' ')}, /* Classical Syriac -> Syriac */ @@ -904,11 +1371,16 @@ static const LangTag ot_languages[] = { {"ta", HB_TAG('T','A','M',' ')}, /* Tamil */ {"taa", HB_TAG('A','T','H',' ')}, /* Lower Tanana -> Athapaskan */ /*{"tab", HB_TAG('T','A','B',' ')},*/ /* Tabassaran -> Tabasaran */ + {"taj", HB_TAG_NONE }, /* Eastern Tamang != Tajiki */ {"taq", HB_TAG('T','M','H',' ')}, /* Tamasheq -> Tamashek */ + {"taq", HB_TAG('B','B','R',' ')}, /* Tamasheq -> Berber */ + {"tas", HB_TAG('C','P','P',' ')}, /* Tay Boi -> Creoles */ {"tau", HB_TAG('A','T','H',' ')}, /* Upper Tanana -> Athapaskan */ {"tcb", HB_TAG('A','T','H',' ')}, /* Tanacross -> Athapaskan */ {"tce", HB_TAG('A','T','H',' ')}, /* Southern Tutchone -> Athapaskan */ + {"tch", HB_TAG('C','P','P',' ')}, /* Turks And Caicos Creole English -> Creoles */ {"tcp", HB_TAG('Q','I','N',' ')}, /* Tawr Chin -> Chin */ + {"tcs", HB_TAG('C','P','P',' ')}, /* Torres Strait Creole -> Creoles */ {"tcy", HB_TAG('T','U','L',' ')}, /* Tulu -> Tumbuka */ {"tcz", HB_TAG('Q','I','N',' ')}, /* Thado Chin -> Chin */ /*{"tdd", HB_TAG('T','D','D',' ')},*/ /* Tai Nüa -> Dehong Dai */ @@ -917,41 +1389,70 @@ static const LangTag ot_languages[] = { {"tec", HB_TAG('K','A','L',' ')}, /* Terik -> Kalenjin */ {"tem", HB_TAG('T','M','N',' ')}, /* Timne -> Temne */ /*{"tet", HB_TAG('T','E','T',' ')},*/ /* Tetum */ + {"tez", HB_TAG('B','B','R',' ')}, /* Tetserret -> Berber */ {"tfn", HB_TAG('A','T','H',' ')}, /* Tanaina -> Athapaskan */ {"tg", HB_TAG('T','A','J',' ')}, /* Tajik -> Tajiki */ + {"tgh", HB_TAG('C','P','P',' ')}, /* Tobagonian Creole English -> Creoles */ {"tgj", HB_TAG('N','I','S',' ')}, /* Tagin -> Nisi */ + {"tgn", HB_TAG_NONE }, /* Tandaganon != Tongan */ + {"tgr", HB_TAG_NONE }, /* Tareng != Tigre */ {"tgx", HB_TAG('A','T','H',' ')}, /* Tagish -> Athapaskan */ + {"tgy", HB_TAG_NONE }, /* Togoyo != Tigrinya */ {"th", HB_TAG('T','H','A',' ')}, /* Thai */ {"tht", HB_TAG('A','T','H',' ')}, /* Tahltan -> Athapaskan */ {"thv", HB_TAG('T','M','H',' ')}, /* Tahaggart Tamahaq -> Tamashek */ + {"thv", HB_TAG('B','B','R',' ')}, /* Tahaggart Tamahaq -> Berber */ {"thz", HB_TAG('T','M','H',' ')}, /* Tayart Tamajeq -> Tamashek */ + {"thz", HB_TAG('B','B','R',' ')}, /* Tayart Tamajeq -> Berber */ {"ti", HB_TAG('T','G','Y',' ')}, /* Tigrinya */ + {"tia", HB_TAG('B','B','R',' ')}, /* Tidikelt Tamazight -> Berber */ {"tig", HB_TAG('T','G','R',' ')}, /* Tigre */ /*{"tiv", HB_TAG('T','I','V',' ')},*/ /* Tiv */ + {"tjo", HB_TAG('B','B','R',' ')}, /* Temacine Tamazight -> Berber */ {"tk", HB_TAG('T','K','M',' ')}, /* Turkmen */ {"tkg", HB_TAG('M','L','G',' ')}, /* Tesaka Malagasy -> Malagasy */ + {"tkm", HB_TAG_NONE }, /* Takelma != Turkmen */ {"tl", HB_TAG('T','G','L',' ')}, /* Tagalog */ -/*{"tmh", HB_TAG('T','M','H',' ')},*/ /* Tamashek [macrolanguage] */ + {"tmg", HB_TAG('C','P','P',' ')}, /* Ternateño -> Creoles */ + {"tmh", HB_TAG('T','M','H',' ')}, /* Tamashek [macrolanguage] */ + {"tmh", HB_TAG('B','B','R',' ')}, /* Tamashek [macrolanguage] -> Berber */ + {"tmn", HB_TAG_NONE }, /* Taman (Indonesia) != Temne */ {"tmw", HB_TAG('M','L','Y',' ')}, /* Temuan -> Malay */ {"tn", HB_TAG('T','N','A',' ')}, /* Tswana */ + {"tna", HB_TAG_NONE }, /* Tacana != Tswana */ + {"tne", HB_TAG_NONE }, /* Tinoc Kallahan (retired code) != Tundra Enets */ {"tnf", HB_TAG('D','R','I',' ')}, /* Tangshewi (retired code) -> Dari */ + {"tnf", HB_TAG('F','A','R',' ')}, /* Tangshewi (retired code) -> Persian */ + {"tng", HB_TAG_NONE }, /* Tobanga != Tonga */ {"to", HB_TAG('T','G','N',' ')}, /* Tonga (Tonga Islands) -> Tongan */ {"tod", HB_TAG('T','O','D','0')}, /* Toma */ {"toi", HB_TAG('T','N','G',' ')}, /* Tonga (Zambia) */ + {"toj", HB_TAG('M','Y','N',' ')}, /* Tojolabal -> Mayan */ {"tol", HB_TAG('A','T','H',' ')}, /* Tolowa -> Athapaskan */ -/*{"tpi", HB_TAG('T','P','I',' ')},*/ /* Tok Pisin */ + {"tor", HB_TAG('B','A','D','0')}, /* Togbo-Vara Banda -> Banda */ + {"tpi", HB_TAG('T','P','I',' ')}, /* Tok Pisin */ + {"tpi", HB_TAG('C','P','P',' ')}, /* Tok Pisin -> Creoles */ {"tr", HB_TAG('T','R','K',' ')}, /* Turkish */ + {"trf", HB_TAG('C','P','P',' ')}, /* Trinidadian Creole English -> Creoles */ + {"trk", HB_TAG_NONE }, /* Turkic [family] != Turkish */ {"tru", HB_TAG('T','U','A',' ')}, /* Turoyo -> Turoyo Aramaic */ {"tru", HB_TAG('S','Y','R',' ')}, /* Turoyo -> Syriac */ {"ts", HB_TAG('T','S','G',' ')}, /* Tsonga */ + {"tsg", HB_TAG_NONE }, /* Tausug != Tsonga */ /*{"tsj", HB_TAG('T','S','J',' ')},*/ /* Tshangla */ {"tt", HB_TAG('T','A','T',' ')}, /* Tatar */ + {"ttc", HB_TAG('M','Y','N',' ')}, /* Tektiteko -> Mayan */ {"ttm", HB_TAG('A','T','H',' ')}, /* Northern Tutchone -> Athapaskan */ {"ttq", HB_TAG('T','M','H',' ')}, /* Tawallammat Tamajaq -> Tamashek */ + {"ttq", HB_TAG('B','B','R',' ')}, /* Tawallammat Tamajaq -> Berber */ + {"tua", HB_TAG_NONE }, /* Wiarumus != Turoyo Aramaic */ + {"tul", HB_TAG_NONE }, /* Tula != Tumbuka */ /*{"tum", HB_TAG('T','U','M',' ')},*/ /* Tumbuka -> Tulu */ {"tuu", HB_TAG('A','T','H',' ')}, /* Tututni -> Athapaskan */ + {"tuv", HB_TAG_NONE }, /* Turkana != Tuvin */ {"tuy", HB_TAG('K','A','L',' ')}, /* Tugen -> Kalenjin */ /*{"tvl", HB_TAG('T','V','L',' ')},*/ /* Tuvalu */ + {"tvy", HB_TAG('C','P','P',' ')}, /* Timor Pidgin -> Creoles */ {"tw", HB_TAG('T','W','I',' ')}, /* Twi */ {"tw", HB_TAG('A','K','A',' ')}, /* Twi -> Akan */ {"txc", HB_TAG('A','T','H',' ')}, /* Tsetsaut -> Athapaskan */ @@ -959,32 +1460,48 @@ static const LangTag ot_languages[] = { {"ty", HB_TAG('T','H','T',' ')}, /* Tahitian */ {"tyv", HB_TAG('T','U','V',' ')}, /* Tuvinian -> Tuvin */ /*{"tyz", HB_TAG('T','Y','Z',' ')},*/ /* Tày */ -/*{"tzm", HB_TAG('T','Z','M',' ')},*/ /* Central Atlas Tamazight -> Tamazight */ -/*{"tzo", HB_TAG('T','Z','O',' ')},*/ /* Tzotzil */ + {"tzh", HB_TAG('M','Y','N',' ')}, /* Tzeltal -> Mayan */ + {"tzj", HB_TAG('M','Y','N',' ')}, /* Tz'utujil -> Mayan */ + {"tzm", HB_TAG('T','Z','M',' ')}, /* Central Atlas Tamazight -> Tamazight */ + {"tzm", HB_TAG('B','B','R',' ')}, /* Central Atlas Tamazight -> Berber */ + {"tzo", HB_TAG('T','Z','O',' ')}, /* Tzotzil */ + {"tzo", HB_TAG('M','Y','N',' ')}, /* Tzotzil -> Mayan */ {"ubl", HB_TAG('B','I','K',' ')}, /* Buhi'non Bikol -> Bikol */ /*{"udm", HB_TAG('U','D','M',' ')},*/ /* Udmurt */ {"ug", HB_TAG('U','Y','G',' ')}, /* Uyghur */ {"uk", HB_TAG('U','K','R',' ')}, /* Ukrainian */ + {"uki", HB_TAG('K','U','I',' ')}, /* Kui (India) */ + {"uln", HB_TAG('C','P','P',' ')}, /* Unserdeutsch -> Creoles */ /*{"umb", HB_TAG('U','M','B',' ')},*/ /* Umbundu */ {"unr", HB_TAG('M','U','N',' ')}, /* Mundari */ {"ur", HB_TAG('U','R','D',' ')}, /* Urdu */ {"urk", HB_TAG('M','L','Y',' ')}, /* Urak Lawoi' -> Malay */ + {"usp", HB_TAG('M','Y','N',' ')}, /* Uspanteco -> Mayan */ {"uz", HB_TAG('U','Z','B',' ')}, /* Uzbek [macrolanguage] */ {"uzn", HB_TAG('U','Z','B',' ')}, /* Northern Uzbek -> Uzbek */ {"uzs", HB_TAG('U','Z','B',' ')}, /* Southern Uzbek -> Uzbek */ + {"vap", HB_TAG('Q','I','N',' ')}, /* Vaiphei -> Chin */ {"ve", HB_TAG('V','E','N',' ')}, /* Venda */ /*{"vec", HB_TAG('V','E','C',' ')},*/ /* Venetian */ {"vi", HB_TAG('V','I','T',' ')}, /* Vietnamese */ + {"vic", HB_TAG('C','P','P',' ')}, /* Virgin Islands Creole English -> Creoles */ + {"vit", HB_TAG_NONE }, /* Viti != Vietnamese */ {"vkk", HB_TAG('M','L','Y',' ')}, /* Kaur -> Malay */ + {"vkp", HB_TAG('C','P','P',' ')}, /* Korlai Creole Portuguese -> Creoles */ {"vkt", HB_TAG('M','L','Y',' ')}, /* Tenggarong Kutai Malay -> Malay */ {"vls", HB_TAG('F','L','E',' ')}, /* Vlaams -> Dutch (Flemish) */ {"vmw", HB_TAG('M','A','K',' ')}, /* Makhuwa */ {"vo", HB_TAG('V','O','L',' ')}, /* Volapük */ /*{"vro", HB_TAG('V','R','O',' ')},*/ /* Võro */ {"wa", HB_TAG('W','L','N',' ')}, /* Walloon */ + {"wag", HB_TAG_NONE }, /* Wa'ema != Wagdi */ /*{"war", HB_TAG('W','A','R',' ')},*/ /* Waray (Philippines) -> Waray-Waray */ {"wbm", HB_TAG('W','A',' ',' ')}, /* Wa */ {"wbr", HB_TAG('W','A','G',' ')}, /* Wagdi */ + {"wbr", HB_TAG('R','A','J',' ')}, /* Wagdi -> Rajasthani */ + {"wea", HB_TAG('K','R','N',' ')}, /* Wewaw -> Karen */ + {"wes", HB_TAG('C','P','P',' ')}, /* Cameroon Pidgin -> Creoles */ + {"weu", HB_TAG('Q','I','N',' ')}, /* Rawngtu Chin -> Chin */ {"wlc", HB_TAG('C','M','R',' ')}, /* Mwali Comorian -> Comorian */ {"wle", HB_TAG('S','I','G',' ')}, /* Wolane -> Silte Gurage */ {"wlk", HB_TAG('A','T','H',' ')}, /* Wailaki -> Athapaskan */ @@ -993,45 +1510,58 @@ static const LangTag ot_languages[] = { {"wry", HB_TAG('M','A','W',' ')}, /* Merwari -> Marwari */ {"wsg", HB_TAG('G','O','N',' ')}, /* Adilabad Gondi -> Gondi */ /*{"wtm", HB_TAG('W','T','M',' ')},*/ /* Mewati */ - {"wuu", HB_TAG('Z','H','S',' ')}, /* Wu Chinese -> Chinese Simplified */ + {"wuu", HB_TAG('Z','H','S',' ')}, /* Wu Chinese -> Chinese, Simplified */ {"xal", HB_TAG('K','L','M',' ')}, /* Kalmyk */ {"xal", HB_TAG('T','O','D',' ')}, /* Kalmyk -> Todo */ {"xan", HB_TAG('S','E','K',' ')}, /* Xamtanga -> Sekota */ + {"xbd", HB_TAG_NONE }, /* Bindal != Lü */ {"xh", HB_TAG('X','H','S',' ')}, /* Xhosa */ /*{"xjb", HB_TAG('X','J','B',' ')},*/ /* Minjungbal -> Minjangbal */ /*{"xkf", HB_TAG('X','K','F',' ')},*/ /* Khengkha */ + {"xmg", HB_TAG('B','M','L',' ')}, /* Mengaka -> Bamileke */ {"xmm", HB_TAG('M','L','Y',' ')}, /* Manado Malay -> Malay */ + {"xmm", HB_TAG('C','P','P',' ')}, /* Manado Malay -> Creoles */ {"xmv", HB_TAG('M','L','G',' ')}, /* Antankarana Malagasy -> Malagasy */ {"xmw", HB_TAG('M','L','G',' ')}, /* Tsimihety Malagasy -> Malagasy */ - {"xnr", HB_TAG('D','G','R',' ')}, /* Kangri -> Dogri */ + {"xnj", HB_TAG('S','X','T',' ')}, /* Ngoni (Tanzania) -> Sutu */ + {"xnq", HB_TAG('S','X','T',' ')}, /* Ngoni (Mozambique) -> Sutu */ + {"xnr", HB_TAG('D','G','R',' ')}, /* Kangri -> Dogri (macrolanguage) */ /*{"xog", HB_TAG('X','O','G',' ')},*/ /* Soga */ -/*{"xpe", HB_TAG('X','P','E',' ')},*/ /* Liberia Kpelle -> Kpelle (Liberia) */ + {"xpe", HB_TAG('X','P','E',' ')}, /* Liberia Kpelle -> Kpelle (Liberia) */ + {"xpe", HB_TAG('K','P','L',' ')}, /* Liberia Kpelle -> Kpelle */ {"xsl", HB_TAG('S','S','L',' ')}, /* South Slavey */ {"xsl", HB_TAG('S','L','A',' ')}, /* South Slavey -> Slavey */ {"xsl", HB_TAG('A','T','H',' ')}, /* South Slavey -> Athapaskan */ {"xst", HB_TAG('S','I','G',' ')}, /* Silt'e (retired code) -> Silte Gurage */ + {"xup", HB_TAG('A','T','H',' ')}, /* Upper Umpqua -> Athapaskan */ {"xwo", HB_TAG('T','O','D',' ')}, /* Written Oirat -> Todo */ + {"yaj", HB_TAG('B','A','D','0')}, /* Banda-Yangere -> Banda */ + {"yak", HB_TAG_NONE }, /* Yakama != Sakha */ /*{"yao", HB_TAG('Y','A','O',' ')},*/ /* Yao */ /*{"yap", HB_TAG('Y','A','P',' ')},*/ /* Yapese */ + {"yba", HB_TAG_NONE }, /* Yala != Yoruba */ + {"ybb", HB_TAG('B','M','L',' ')}, /* Yemba -> Bamileke */ {"ybd", HB_TAG('A','R','K',' ')}, /* Yangbye (retired code) -> Rakhine */ {"ydd", HB_TAG('J','I','I',' ')}, /* Eastern Yiddish -> Yiddish */ {"yi", HB_TAG('J','I','I',' ')}, /* Yiddish [macrolanguage] */ {"yih", HB_TAG('J','I','I',' ')}, /* Western Yiddish -> Yiddish */ + {"yim", HB_TAG_NONE }, /* Yimchungru Naga != Yi Modern */ {"yo", HB_TAG('Y','B','A',' ')}, /* Yoruba */ {"yos", HB_TAG('Q','I','N',' ')}, /* Yos (retired code) -> Chin */ - {"yrk", HB_TAG('T','N','E',' ')}, /* Nenets -> Tundra Nenets */ - {"yrk", HB_TAG('F','N','E',' ')}, /* Nenets -> Forest Nenets */ - {"yue", HB_TAG('Z','H','H',' ')}, /* Yue Chinese -> Chinese, Hong Kong SAR */ + {"yua", HB_TAG('M','Y','N',' ')}, /* Yucateco -> Mayan */ + {"yue", HB_TAG('Z','H','H',' ')}, /* Yue Chinese -> Chinese, Traditional, Hong Kong SAR */ {"za", HB_TAG('Z','H','A',' ')}, /* Zhuang [macrolanguage] */ {"zch", HB_TAG('Z','H','A',' ')}, /* Central Hongshuihe Zhuang -> Zhuang */ {"zdj", HB_TAG('C','M','R',' ')}, /* Ngazidja Comorian -> Comorian */ /*{"zea", HB_TAG('Z','E','A',' ')},*/ /* Zeeuws -> Zealandic */ {"zeh", HB_TAG('Z','H','A',' ')}, /* Eastern Hongshuihe Zhuang -> Zhuang */ + {"zen", HB_TAG('B','B','R',' ')}, /* Zenaga -> Berber */ {"zgb", HB_TAG('Z','H','A',' ')}, /* Guibei Zhuang -> Zhuang */ -/*{"zgh", HB_TAG('Z','G','H',' ')},*/ /* Standard Moroccan Tamazight */ + {"zgh", HB_TAG('Z','G','H',' ')}, /* Standard Moroccan Tamazight */ + {"zgh", HB_TAG('B','B','R',' ')}, /* Standard Moroccan Tamazight -> Berber */ {"zgm", HB_TAG('Z','H','A',' ')}, /* Minz Zhuang -> Zhuang */ {"zgn", HB_TAG('Z','H','A',' ')}, /* Guibian Zhuang -> Zhuang */ - {"zh", HB_TAG('Z','H','S',' ')}, /* Chinese [macrolanguage] -> Chinese Simplified */ + {"zh", HB_TAG('Z','H','S',' ')}, /* Chinese, Simplified [macrolanguage] */ {"zhd", HB_TAG('Z','H','A',' ')}, /* Dai Zhuang -> Zhuang */ {"zhn", HB_TAG('Z','H','A',' ')}, /* Nong Zhuang -> Zhuang */ {"zlj", HB_TAG('Z','H','A',' ')}, /* Liujiang Zhuang -> Zhuang */ @@ -1039,6 +1569,8 @@ static const LangTag ot_languages[] = { {"zln", HB_TAG('Z','H','A',' ')}, /* Lianshan Zhuang -> Zhuang */ {"zlq", HB_TAG('Z','H','A',' ')}, /* Liuqian Zhuang -> Zhuang */ {"zmi", HB_TAG('M','L','Y',' ')}, /* Negeri Sembilan Malay -> Malay */ + {"zmz", HB_TAG('B','A','D','0')}, /* Mbandja -> Banda */ + {"znd", HB_TAG_NONE }, /* Zande [family] != Zande */ {"zne", HB_TAG('Z','N','D',' ')}, /* Zande */ {"zom", HB_TAG('Q','I','N',' ')}, /* Zou -> Chin */ {"zqe", HB_TAG('Z','H','A',' ')}, /* Qiubei Zhuang -> Zhuang */ @@ -1049,6 +1581,7 @@ static const LangTag ot_languages[] = { {"zyg", HB_TAG('Z','H','A',' ')}, /* Yang Zhuang -> Zhuang */ {"zyj", HB_TAG('Z','H','A',' ')}, /* Youjiang Zhuang -> Zhuang */ {"zyn", HB_TAG('Z','H','A',' ')}, /* Yongnan Zhuang -> Zhuang */ + {"zyp", HB_TAG('Q','I','N',' ')}, /* Zyphe Chin -> Chin */ /*{"zza", HB_TAG('Z','Z','A',' ')},*/ /* Zazaki [macrolanguage] */ {"zzj", HB_TAG('Z','H','A',' ')}, /* Zuojiang Zhuang -> Zhuang */ }; @@ -1087,6 +1620,13 @@ hb_ot_tags_from_complex_language (const char *lang_str, *count = 1; return true; } + if (subtag_matches (lang_str, limit, "-arevmda")) + { + /* Armenian; Western Armenian (retired code) */ + tags[0] = HB_TAG('H','Y','E',' '); /* Armenian */ + *count = 1; + return true; + } if (subtag_matches (lang_str, limit, "-provenc")) { /* Occitan (post 1500); Provençal */ @@ -1134,7 +1674,7 @@ hb_ot_tags_from_complex_language (const char *lang_str, case 'a': if (0 == strcmp (&lang_str[1], "rt-lojban")) { - /* Lojban */ + /* Lojban (retired code) */ tags[0] = HB_TAG('J','B','O',' '); /* Lojban */ *count = 1; return true; @@ -1143,169 +1683,273 @@ hb_ot_tags_from_complex_language (const char *lang_str, case 'c': if (lang_matches (&lang_str[1], "do-hant-hk")) { - /* Min Dong Chinese */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + /* Min Dong Chinese; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } if (lang_matches (&lang_str[1], "do-hant-mo")) { - /* Min Dong Chinese */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; + /* Min Dong Chinese; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; return true; } if (lang_matches (&lang_str[1], "jy-hant-hk")) { - /* Jinyu Chinese */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + /* Jinyu Chinese; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } if (lang_matches (&lang_str[1], "jy-hant-mo")) { - /* Jinyu Chinese */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; + /* Jinyu Chinese; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; return true; } if (lang_matches (&lang_str[1], "mn-hant-hk")) { - /* Mandarin Chinese */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + /* Mandarin Chinese; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } if (lang_matches (&lang_str[1], "mn-hant-mo")) { - /* Mandarin Chinese */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + /* Mandarin Chinese; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } + if (lang_matches (&lang_str[1], "np-hant-hk")) + { + /* Northern Ping Chinese; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } + if (lang_matches (&lang_str[1], "np-hant-mo")) + { + /* Northern Ping Chinese; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } if (lang_matches (&lang_str[1], "px-hant-hk")) { - /* Pu-Xian Chinese */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + /* Pu-Xian Chinese; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } if (lang_matches (&lang_str[1], "px-hant-mo")) { - /* Pu-Xian Chinese */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + /* Pu-Xian Chinese; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } + if (lang_matches (&lang_str[1], "sp-hant-hk")) + { + /* Southern Ping Chinese; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } + if (lang_matches (&lang_str[1], "sp-hant-mo")) + { + /* Southern Ping Chinese; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } if (lang_matches (&lang_str[1], "zh-hant-hk")) { - /* Huizhou Chinese */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + /* Huizhou Chinese; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } if (lang_matches (&lang_str[1], "zh-hant-mo")) { - /* Huizhou Chinese */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; + /* Huizhou Chinese; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; return true; } if (lang_matches (&lang_str[1], "zo-hant-hk")) { - /* Min Zhong Chinese */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + /* Min Zhong Chinese; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } if (lang_matches (&lang_str[1], "zo-hant-mo")) { - /* Min Zhong Chinese */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; + /* Min Zhong Chinese; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; return true; } if (lang_matches (&lang_str[1], "do-hans")) { - /* Min Dong Chinese */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + /* Min Dong Chinese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ *count = 1; return true; } if (lang_matches (&lang_str[1], "do-hant")) { - /* Min Dong Chinese */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + /* Min Dong Chinese; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ *count = 1; return true; } if (lang_matches (&lang_str[1], "jy-hans")) { - /* Jinyu Chinese */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + /* Jinyu Chinese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ *count = 1; return true; } if (lang_matches (&lang_str[1], "jy-hant")) { - /* Jinyu Chinese */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + /* Jinyu Chinese; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ *count = 1; return true; } if (lang_matches (&lang_str[1], "mn-hans")) { - /* Mandarin Chinese */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + /* Mandarin Chinese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ *count = 1; return true; } if (lang_matches (&lang_str[1], "mn-hant")) { - /* Mandarin Chinese */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + /* Mandarin Chinese; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "np-hans")) + { + /* Northern Ping Chinese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "np-hant")) + { + /* Northern Ping Chinese; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ *count = 1; return true; } if (lang_matches (&lang_str[1], "px-hans")) { - /* Pu-Xian Chinese */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + /* Pu-Xian Chinese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ *count = 1; return true; } if (lang_matches (&lang_str[1], "px-hant")) { - /* Pu-Xian Chinese */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + /* Pu-Xian Chinese; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "sp-hans")) + { + /* Southern Ping Chinese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], "sp-hant")) + { + /* Southern Ping Chinese; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ *count = 1; return true; } if (lang_matches (&lang_str[1], "zh-hans")) { - /* Huizhou Chinese */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + /* Huizhou Chinese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ *count = 1; return true; } if (lang_matches (&lang_str[1], "zh-hant")) { - /* Huizhou Chinese */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + /* Huizhou Chinese; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ *count = 1; return true; } if (lang_matches (&lang_str[1], "zo-hans")) { - /* Min Zhong Chinese */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + /* Min Zhong Chinese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ *count = 1; return true; } if (lang_matches (&lang_str[1], "zo-hant")) { - /* Min Zhong Chinese */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + /* Min Zhong Chinese; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ *count = 1; return true; } @@ -1313,7 +1957,7 @@ hb_ot_tags_from_complex_language (const char *lang_str, && subtag_matches (lang_str, limit, "-hk")) { /* Min Dong Chinese; Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } @@ -1321,15 +1965,21 @@ hb_ot_tags_from_complex_language (const char *lang_str, && subtag_matches (lang_str, limit, "-mo")) { /* Min Dong Chinese; Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; return true; } if (0 == strncmp (&lang_str[1], "do-", 3) && subtag_matches (lang_str, limit, "-tw")) { /* Min Dong Chinese; Taiwan, Province of China */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ *count = 1; return true; } @@ -1337,7 +1987,7 @@ hb_ot_tags_from_complex_language (const char *lang_str, && subtag_matches (lang_str, limit, "-hk")) { /* Jinyu Chinese; Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } @@ -1345,15 +1995,21 @@ hb_ot_tags_from_complex_language (const char *lang_str, && subtag_matches (lang_str, limit, "-mo")) { /* Jinyu Chinese; Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; return true; } if (0 == strncmp (&lang_str[1], "jy-", 3) && subtag_matches (lang_str, limit, "-tw")) { /* Jinyu Chinese; Taiwan, Province of China */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ *count = 1; return true; } @@ -1361,7 +2017,7 @@ hb_ot_tags_from_complex_language (const char *lang_str, && subtag_matches (lang_str, limit, "-hk")) { /* Mandarin Chinese; Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } @@ -1369,15 +2025,51 @@ hb_ot_tags_from_complex_language (const char *lang_str, && subtag_matches (lang_str, limit, "-mo")) { /* Mandarin Chinese; Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; return true; } if (0 == strncmp (&lang_str[1], "mn-", 3) && subtag_matches (lang_str, limit, "-tw")) { /* Mandarin Chinese; Taiwan, Province of China */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "np-", 3) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Northern Ping Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "np-", 3) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Northern Ping Chinese; Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } + if (0 == strncmp (&lang_str[1], "np-", 3) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Northern Ping Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ *count = 1; return true; } @@ -1385,7 +2077,7 @@ hb_ot_tags_from_complex_language (const char *lang_str, && subtag_matches (lang_str, limit, "-hk")) { /* Pu-Xian Chinese; Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } @@ -1393,15 +2085,51 @@ hb_ot_tags_from_complex_language (const char *lang_str, && subtag_matches (lang_str, limit, "-mo")) { /* Pu-Xian Chinese; Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; return true; } if (0 == strncmp (&lang_str[1], "px-", 3) && subtag_matches (lang_str, limit, "-tw")) { /* Pu-Xian Chinese; Taiwan, Province of China */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "sp-", 3) + && subtag_matches (lang_str, limit, "-hk")) + { + /* Southern Ping Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "sp-", 3) + && subtag_matches (lang_str, limit, "-mo")) + { + /* Southern Ping Chinese; Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } + if (0 == strncmp (&lang_str[1], "sp-", 3) + && subtag_matches (lang_str, limit, "-tw")) + { + /* Southern Ping Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ *count = 1; return true; } @@ -1409,7 +2137,7 @@ hb_ot_tags_from_complex_language (const char *lang_str, && subtag_matches (lang_str, limit, "-hk")) { /* Huizhou Chinese; Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } @@ -1417,15 +2145,21 @@ hb_ot_tags_from_complex_language (const char *lang_str, && subtag_matches (lang_str, limit, "-mo")) { /* Huizhou Chinese; Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; return true; } if (0 == strncmp (&lang_str[1], "zh-", 3) && subtag_matches (lang_str, limit, "-tw")) { /* Huizhou Chinese; Taiwan, Province of China */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ *count = 1; return true; } @@ -1433,7 +2167,7 @@ hb_ot_tags_from_complex_language (const char *lang_str, && subtag_matches (lang_str, limit, "-hk")) { /* Min Zhong Chinese; Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } @@ -1441,15 +2175,21 @@ hb_ot_tags_from_complex_language (const char *lang_str, && subtag_matches (lang_str, limit, "-mo")) { /* Min Zhong Chinese; Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; return true; } if (0 == strncmp (&lang_str[1], "zo-", 3) && subtag_matches (lang_str, limit, "-tw")) { /* Min Zhong Chinese; Taiwan, Province of China */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ *count = 1; return true; } @@ -1457,35 +2197,41 @@ hb_ot_tags_from_complex_language (const char *lang_str, case 'g': if (lang_matches (&lang_str[1], "an-hant-hk")) { - /* Gan Chinese */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + /* Gan Chinese; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } if (lang_matches (&lang_str[1], "an-hant-mo")) { - /* Gan Chinese */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; + /* Gan Chinese; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; return true; } if (lang_matches (&lang_str[1], "an-hans")) { - /* Gan Chinese */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + /* Gan Chinese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ *count = 1; return true; } if (lang_matches (&lang_str[1], "an-hant")) { - /* Gan Chinese */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + /* Gan Chinese; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ *count = 1; return true; } if (lang_matches (&lang_str[1], "a-latg")) { - /* Irish */ + /* Irish; Latin (Gaelic variant) */ tags[0] = HB_TAG('I','R','T',' '); /* Irish Traditional */ *count = 1; return true; @@ -1494,7 +2240,7 @@ hb_ot_tags_from_complex_language (const char *lang_str, && subtag_matches (lang_str, limit, "-hk")) { /* Gan Chinese; Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } @@ -1502,15 +2248,21 @@ hb_ot_tags_from_complex_language (const char *lang_str, && subtag_matches (lang_str, limit, "-mo")) { /* Gan Chinese; Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; return true; } if (0 == strncmp (&lang_str[1], "an-", 3) && subtag_matches (lang_str, limit, "-tw")) { /* Gan Chinese; Taiwan, Province of China */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ *count = 1; return true; } @@ -1518,57 +2270,69 @@ hb_ot_tags_from_complex_language (const char *lang_str, case 'h': if (lang_matches (&lang_str[1], "ak-hant-hk")) { - /* Hakka Chinese */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + /* Hakka Chinese; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } if (lang_matches (&lang_str[1], "ak-hant-mo")) { - /* Hakka Chinese */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; + /* Hakka Chinese; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; return true; } if (lang_matches (&lang_str[1], "sn-hant-hk")) { - /* Xiang Chinese */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + /* Xiang Chinese; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } if (lang_matches (&lang_str[1], "sn-hant-mo")) { - /* Xiang Chinese */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; + /* Xiang Chinese; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; return true; } if (lang_matches (&lang_str[1], "ak-hans")) { - /* Hakka Chinese */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + /* Hakka Chinese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ *count = 1; return true; } if (lang_matches (&lang_str[1], "ak-hant")) { - /* Hakka Chinese */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + /* Hakka Chinese; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ *count = 1; return true; } if (lang_matches (&lang_str[1], "sn-hans")) { - /* Xiang Chinese */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + /* Xiang Chinese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ *count = 1; return true; } if (lang_matches (&lang_str[1], "sn-hant")) { - /* Xiang Chinese */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + /* Xiang Chinese; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ *count = 1; return true; } @@ -1576,7 +2340,7 @@ hb_ot_tags_from_complex_language (const char *lang_str, && subtag_matches (lang_str, limit, "-hk")) { /* Hakka Chinese; Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } @@ -1584,15 +2348,21 @@ hb_ot_tags_from_complex_language (const char *lang_str, && subtag_matches (lang_str, limit, "-mo")) { /* Hakka Chinese; Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; return true; } if (0 == strncmp (&lang_str[1], "ak-", 3) && subtag_matches (lang_str, limit, "-tw")) { /* Hakka Chinese; Taiwan, Province of China */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ *count = 1; return true; } @@ -1600,7 +2370,7 @@ hb_ot_tags_from_complex_language (const char *lang_str, && subtag_matches (lang_str, limit, "-hk")) { /* Xiang Chinese; Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } @@ -1608,15 +2378,21 @@ hb_ot_tags_from_complex_language (const char *lang_str, && subtag_matches (lang_str, limit, "-mo")) { /* Xiang Chinese; Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; return true; } if (0 == strncmp (&lang_str[1], "sn-", 3) && subtag_matches (lang_str, limit, "-tw")) { /* Xiang Chinese; Taiwan, Province of China */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ *count = 1; return true; } @@ -1624,7 +2400,7 @@ hb_ot_tags_from_complex_language (const char *lang_str, case 'i': if (0 == strcmp (&lang_str[1], "-navajo")) { - /* Navajo */ + /* Navajo (retired code) */ unsigned int i; hb_tag_t possible_tags[] = { HB_TAG('N','A','V',' '), /* Navajo */ @@ -1637,14 +2413,14 @@ hb_ot_tags_from_complex_language (const char *lang_str, } if (0 == strcmp (&lang_str[1], "-hak")) { - /* Hakka */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + /* Hakka (retired code) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ *count = 1; return true; } if (0 == strcmp (&lang_str[1], "-lux")) { - /* Luxembourgish */ + /* Luxembourgish (retired code) */ tags[0] = HB_TAG('L','T','Z',' '); /* Luxembourgish */ *count = 1; return true; @@ -1653,8 +2429,8 @@ hb_ot_tags_from_complex_language (const char *lang_str, case 'l': if (lang_matches (&lang_str[1], "zh-hans")) { - /* Literary Chinese */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + /* Literary Chinese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ *count = 1; return true; } @@ -1662,29 +2438,35 @@ hb_ot_tags_from_complex_language (const char *lang_str, case 'm': if (lang_matches (&lang_str[1], "np-hant-hk")) { - /* Min Bei Chinese */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + /* Min Bei Chinese; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } if (lang_matches (&lang_str[1], "np-hant-mo")) { - /* Min Bei Chinese */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; + /* Min Bei Chinese; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; return true; } if (lang_matches (&lang_str[1], "np-hans")) { - /* Min Bei Chinese */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + /* Min Bei Chinese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ *count = 1; return true; } if (lang_matches (&lang_str[1], "np-hant")) { - /* Min Bei Chinese */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + /* Min Bei Chinese; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ *count = 1; return true; } @@ -1692,7 +2474,7 @@ hb_ot_tags_from_complex_language (const char *lang_str, && subtag_matches (lang_str, limit, "-hk")) { /* Min Bei Chinese; Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } @@ -1700,15 +2482,21 @@ hb_ot_tags_from_complex_language (const char *lang_str, && subtag_matches (lang_str, limit, "-mo")) { /* Min Bei Chinese; Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; return true; } if (0 == strncmp (&lang_str[1], "np-", 3) && subtag_matches (lang_str, limit, "-tw")) { /* Min Bei Chinese; Taiwan, Province of China */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ *count = 1; return true; } @@ -1716,29 +2504,35 @@ hb_ot_tags_from_complex_language (const char *lang_str, case 'n': if (lang_matches (&lang_str[1], "an-hant-hk")) { - /* Min Nan Chinese */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + /* Min Nan Chinese; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } if (lang_matches (&lang_str[1], "an-hant-mo")) { - /* Min Nan Chinese */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; + /* Min Nan Chinese; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; return true; } if (lang_matches (&lang_str[1], "an-hans")) { - /* Min Nan Chinese */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + /* Min Nan Chinese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ *count = 1; return true; } if (lang_matches (&lang_str[1], "an-hant")) { - /* Min Nan Chinese */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + /* Min Nan Chinese; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ *count = 1; return true; } @@ -1746,7 +2540,7 @@ hb_ot_tags_from_complex_language (const char *lang_str, && subtag_matches (lang_str, limit, "-hk")) { /* Min Nan Chinese; Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } @@ -1754,30 +2548,42 @@ hb_ot_tags_from_complex_language (const char *lang_str, && subtag_matches (lang_str, limit, "-mo")) { /* Min Nan Chinese; Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; return true; } if (0 == strncmp (&lang_str[1], "an-", 3) && subtag_matches (lang_str, limit, "-tw")) { /* Min Nan Chinese; Taiwan, Province of China */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ *count = 1; return true; } if (0 == strcmp (&lang_str[1], "o-bok")) { - /* Norwegian Bokmal */ + /* Norwegian Bokmal (retired code) */ tags[0] = HB_TAG('N','O','R',' '); /* Norwegian */ *count = 1; return true; } if (0 == strcmp (&lang_str[1], "o-nyn")) { - /* Norwegian Nynorsk */ - tags[0] = HB_TAG('N','Y','N',' '); /* Norwegian Nynorsk (Nynorsk, Norwegian) */ - *count = 1; + /* Norwegian Nynorsk (retired code) */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('N','Y','N',' '), /* Norwegian Nynorsk (Nynorsk, Norwegian) */ + HB_TAG('N','O','R',' '), /* Norwegian */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; return true; } break; @@ -1794,29 +2600,35 @@ hb_ot_tags_from_complex_language (const char *lang_str, case 'w': if (lang_matches (&lang_str[1], "uu-hant-hk")) { - /* Wu Chinese */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + /* Wu Chinese; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } if (lang_matches (&lang_str[1], "uu-hant-mo")) { - /* Wu Chinese */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; + /* Wu Chinese; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; return true; } if (lang_matches (&lang_str[1], "uu-hans")) { - /* Wu Chinese */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + /* Wu Chinese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ *count = 1; return true; } if (lang_matches (&lang_str[1], "uu-hant")) { - /* Wu Chinese */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + /* Wu Chinese; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ *count = 1; return true; } @@ -1824,7 +2636,7 @@ hb_ot_tags_from_complex_language (const char *lang_str, && subtag_matches (lang_str, limit, "-hk")) { /* Wu Chinese; Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } @@ -1832,15 +2644,21 @@ hb_ot_tags_from_complex_language (const char *lang_str, && subtag_matches (lang_str, limit, "-mo")) { /* Wu Chinese; Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; return true; } if (0 == strncmp (&lang_str[1], "uu-", 3) && subtag_matches (lang_str, limit, "-tw")) { /* Wu Chinese; Taiwan, Province of China */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ *count = 1; return true; } @@ -1848,8 +2666,8 @@ hb_ot_tags_from_complex_language (const char *lang_str, case 'y': if (lang_matches (&lang_str[1], "ue-hans")) { - /* Yue Chinese */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + /* Yue Chinese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ *count = 1; return true; } @@ -1857,67 +2675,79 @@ hb_ot_tags_from_complex_language (const char *lang_str, case 'z': if (lang_matches (&lang_str[1], "h-hant-hk")) { - /* Chinese */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + /* Chinese [macrolanguage]; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } if (lang_matches (&lang_str[1], "h-hant-mo")) { - /* Chinese */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; + /* Chinese [macrolanguage]; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; return true; } if (0 == strcmp (&lang_str[1], "h-min-nan")) { - /* Minnan, Hokkien, Amoy, Taiwanese, Southern Min, Southern Fujian, Hoklo, Southern Fukien, Ho-lo */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + /* Minnan, Hokkien, Amoy, Taiwanese, Southern Min, Southern Fujian, Hoklo, Southern Fukien, Ho-lo (retired code) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ *count = 1; return true; } if (lang_matches (&lang_str[1], "h-hans")) { - /* Chinese */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + /* Chinese [macrolanguage]; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ *count = 1; return true; } if (lang_matches (&lang_str[1], "h-hant")) { - /* Chinese */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + /* Chinese [macrolanguage]; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ *count = 1; return true; } if (0 == strcmp (&lang_str[1], "h-min")) { - /* Min, Fuzhou, Hokkien, Amoy, or Taiwanese */ - tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */ + /* Min, Fuzhou, Hokkien, Amoy, or Taiwanese (retired code) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ *count = 1; return true; } if (0 == strncmp (&lang_str[1], "h-", 2) && subtag_matches (lang_str, limit, "-hk")) { - /* Chinese; Hong Kong */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ + /* Chinese [macrolanguage]; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ *count = 1; return true; } if (0 == strncmp (&lang_str[1], "h-", 2) && subtag_matches (lang_str, limit, "-mo")) { - /* Chinese; Macao */ - tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */ - *count = 1; + /* Chinese [macrolanguage]; Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; return true; } if (0 == strncmp (&lang_str[1], "h-", 2) && subtag_matches (lang_str, limit, "-tw")) { - /* Chinese; Taiwan, Province of China */ - tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */ + /* Chinese [macrolanguage]; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ *count = 1; return true; } @@ -1948,97 +2778,131 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag) case HB_TAG('A','P','P','H'): /* Phonetic transcription—Americanist conventions */ return hb_language_from_string ("und-fonnapa", -1); /* Undetermined; North American Phonetic Alphabet */ case HB_TAG('A','R','A',' '): /* Arabic */ - return hb_language_from_string ("ar", -1); /* Arabic */ + return hb_language_from_string ("ar", -1); /* Arabic [macrolanguage] */ case HB_TAG('A','R','K',' '): /* Rakhine */ return hb_language_from_string ("rki", -1); /* Rakhine */ case HB_TAG('A','T','H',' '): /* Athapaskan */ - return hb_language_from_string ("ath", -1); /* Athapascan */ + return hb_language_from_string ("ath", -1); /* Athapascan [family] */ + case HB_TAG('B','B','R',' '): /* Berber */ + return hb_language_from_string ("ber", -1); /* Berber [family] */ case HB_TAG('B','I','K',' '): /* Bikol */ - return hb_language_from_string ("bik", -1); /* Bikol */ + return hb_language_from_string ("bik", -1); /* Bikol [macrolanguage] */ + case HB_TAG('B','T','K',' '): /* Batak */ + return hb_language_from_string ("btk", -1); /* Batak [family] */ case HB_TAG('C','P','P',' '): /* Creoles */ - return hb_language_from_string ("crp", -1); /* Creoles and pidgins */ + return hb_language_from_string ("crp", -1); /* Creoles and pidgins [family] */ case HB_TAG('C','R','R',' '): /* Carrier */ return hb_language_from_string ("crx", -1); /* Carrier */ + case HB_TAG('D','G','R',' '): /* Dogri (macrolanguage) */ + return hb_language_from_string ("doi", -1); /* Dogri [macrolanguage] */ case HB_TAG('D','N','K',' '): /* Dinka */ - return hb_language_from_string ("din", -1); /* Dinka */ + return hb_language_from_string ("din", -1); /* Dinka [macrolanguage] */ case HB_TAG('D','R','I',' '): /* Dari */ return hb_language_from_string ("prs", -1); /* Dari */ case HB_TAG('D','Z','N',' '): /* Dzongkha */ return hb_language_from_string ("dz", -1); /* Dzongkha */ case HB_TAG('E','T','I',' '): /* Estonian */ - return hb_language_from_string ("et", -1); /* Estonian */ + return hb_language_from_string ("et", -1); /* Estonian [macrolanguage] */ + case HB_TAG('F','A','R',' '): /* Persian */ + return hb_language_from_string ("fa", -1); /* Persian [macrolanguage] */ case HB_TAG('G','O','N',' '): /* Gondi */ - return hb_language_from_string ("gon", -1); /* Gondi */ + return hb_language_from_string ("gon", -1); /* Gondi [macrolanguage] */ case HB_TAG('H','M','N',' '): /* Hmong */ - return hb_language_from_string ("hmn", -1); /* Hmong */ + return hb_language_from_string ("hmn", -1); /* Hmong [macrolanguage] */ case HB_TAG('H','N','D',' '): /* Hindko */ return hb_language_from_string ("hnd", -1); /* Southern Hindko */ + case HB_TAG('H','Y','E',' '): /* Armenian */ + return hb_language_from_string ("hyw", -1); /* Western Armenian */ + case HB_TAG('I','B','A',' '): /* Iban */ + return hb_language_from_string ("iba", -1); /* Iban */ case HB_TAG('I','J','O',' '): /* Ijo */ - return hb_language_from_string ("ijo", -1); /* Ijo */ + return hb_language_from_string ("ijo", -1); /* Ijo [family] */ case HB_TAG('I','N','U',' '): /* Inuktitut */ - return hb_language_from_string ("iu", -1); /* Inuktitut */ + return hb_language_from_string ("iu", -1); /* Inuktitut [macrolanguage] */ case HB_TAG('I','P','K',' '): /* Inupiat */ - return hb_language_from_string ("ik", -1); /* Inupiaq */ + return hb_language_from_string ("ik", -1); /* Inupiaq [macrolanguage] */ case HB_TAG('I','P','P','H'): /* Phonetic transcription—IPA conventions */ return hb_language_from_string ("und-fonipa", -1); /* Undetermined; International Phonetic Alphabet */ case HB_TAG('I','R','T',' '): /* Irish Traditional */ return hb_language_from_string ("ga-Latg", -1); /* Irish; Latin (Gaelic variant) */ case HB_TAG('J','I','I',' '): /* Yiddish */ - return hb_language_from_string ("yi", -1); /* Yiddish */ + return hb_language_from_string ("yi", -1); /* Yiddish [macrolanguage] */ case HB_TAG('K','A','L',' '): /* Kalenjin */ - return hb_language_from_string ("kln", -1); /* Kalenjin */ + return hb_language_from_string ("kln", -1); /* Kalenjin [macrolanguage] */ case HB_TAG('K','G','E',' '): /* Khutsuri Georgian */ return hb_language_from_string ("und-Geok", -1); /* Undetermined; Khutsuri (Asomtavruli and Nuskhuri) */ case HB_TAG('K','N','R',' '): /* Kanuri */ - return hb_language_from_string ("kr", -1); /* Kanuri */ + return hb_language_from_string ("kr", -1); /* Kanuri [macrolanguage] */ + case HB_TAG('K','O','H',' '): /* Korean Old Hangul */ + return hb_language_from_string ("okm", -1); /* Middle Korean (10th-16th cent.) */ case HB_TAG('K','O','K',' '): /* Konkani */ - return hb_language_from_string ("kok", -1); /* Konkani */ + return hb_language_from_string ("kok", -1); /* Konkani [macrolanguage] */ + case HB_TAG('K','O','M',' '): /* Komi */ + return hb_language_from_string ("kv", -1); /* Komi [macrolanguage] */ + case HB_TAG('K','P','L',' '): /* Kpelle */ + return hb_language_from_string ("kpe", -1); /* Kpelle [macrolanguage] */ + case HB_TAG('K','R','N',' '): /* Karen */ + return hb_language_from_string ("kar", -1); /* Karen [family] */ + case HB_TAG('K','U','I',' '): /* Kui */ + return hb_language_from_string ("uki", -1); /* Kui (India) */ case HB_TAG('K','U','R',' '): /* Kurdish */ - return hb_language_from_string ("ku", -1); /* Kurdish */ + return hb_language_from_string ("ku", -1); /* Kurdish [macrolanguage] */ case HB_TAG('L','U','H',' '): /* Luyia */ - return hb_language_from_string ("luy", -1); /* Luyia */ + return hb_language_from_string ("luy", -1); /* Luyia [macrolanguage] */ case HB_TAG('L','V','I',' '): /* Latvian */ - return hb_language_from_string ("lv", -1); /* Latvian */ + return hb_language_from_string ("lv", -1); /* Latvian [macrolanguage] */ case HB_TAG('M','A','W',' '): /* Marwari */ - return hb_language_from_string ("mwr", -1); /* Marwari */ + return hb_language_from_string ("mwr", -1); /* Marwari [macrolanguage] */ case HB_TAG('M','L','G',' '): /* Malagasy */ - return hb_language_from_string ("mg", -1); /* Malagasy */ + return hb_language_from_string ("mg", -1); /* Malagasy [macrolanguage] */ case HB_TAG('M','L','Y',' '): /* Malay */ - return hb_language_from_string ("ms", -1); /* Malay */ + return hb_language_from_string ("ms", -1); /* Malay [macrolanguage] */ case HB_TAG('M','N','G',' '): /* Mongolian */ - return hb_language_from_string ("mn", -1); /* Mongolian */ + 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 */ return hb_language_from_string ("ro-MD", -1); /* Romanian; Moldova */ + case HB_TAG('M','Y','N',' '): /* Mayan */ + return hb_language_from_string ("myn", -1); /* Mayan [family] */ + case HB_TAG('N','A','H',' '): /* Nahuatl */ + return hb_language_from_string ("nah", -1); /* Nahuatl [family] */ case HB_TAG('N','E','P',' '): /* Nepali */ - return hb_language_from_string ("ne", -1); /* Nepali */ + return hb_language_from_string ("ne", -1); /* Nepali [macrolanguage] */ case HB_TAG('N','I','S',' '): /* Nisi */ return hb_language_from_string ("njz", -1); /* Nyishi */ case HB_TAG('N','O','R',' '): /* Norwegian */ - return hb_language_from_string ("no", -1); /* Norwegian */ + return hb_language_from_string ("no", -1); /* Norwegian [macrolanguage] */ case HB_TAG('O','J','B',' '): /* Ojibway */ - return hb_language_from_string ("oj", -1); /* Ojibwa */ + return hb_language_from_string ("oj", -1); /* Ojibwa [macrolanguage] */ case HB_TAG('O','R','O',' '): /* Oromo */ - return hb_language_from_string ("om", -1); /* Oromo */ + return hb_language_from_string ("om", -1); /* Oromo [macrolanguage] */ case HB_TAG('P','A','S',' '): /* Pashto */ - return hb_language_from_string ("ps", -1); /* Pashto */ + return hb_language_from_string ("ps", -1); /* Pashto [macrolanguage] */ case HB_TAG('P','G','R',' '): /* Polytonic Greek */ return hb_language_from_string ("el-polyton", -1); /* Modern Greek (1453-); Polytonic Greek */ case HB_TAG('P','R','O',' '): /* Provençal / Old Provençal */ return hb_language_from_string ("pro", -1); /* Old Provençal (to 1500) */ case HB_TAG('Q','U','H',' '): /* Quechua (Bolivia) */ return hb_language_from_string ("quh", -1); /* South Bolivian Quechua */ + case HB_TAG('Q','U','Z',' '): /* Quechua */ + return hb_language_from_string ("qu", -1); /* Quechua [macrolanguage] */ case HB_TAG('Q','V','I',' '): /* Quechua (Ecuador) */ return hb_language_from_string ("qvi", -1); /* Imbabura Highland Quichua */ case HB_TAG('Q','W','H',' '): /* Quechua (Peru) */ return hb_language_from_string ("qwh", -1); /* Huaylas Ancash Quechua */ case HB_TAG('R','A','J',' '): /* Rajasthani */ - return hb_language_from_string ("raj", -1); /* Rajasthani */ + return hb_language_from_string ("raj", -1); /* Rajasthani [macrolanguage] */ case HB_TAG('R','O','Y',' '): /* Romany */ - return hb_language_from_string ("rom", -1); /* Romany */ + return hb_language_from_string ("rom", -1); /* Romany [macrolanguage] */ case HB_TAG('S','Q','I',' '): /* Albanian */ - return hb_language_from_string ("sq", -1); /* Albanian */ + return hb_language_from_string ("sq", -1); /* Albanian [macrolanguage] */ + case HB_TAG('S','R','B',' '): /* Serbian */ + return hb_language_from_string ("sr", -1); /* Serbian */ + case HB_TAG('S','X','T',' '): /* Sutu */ + return hb_language_from_string ("xnj", -1); /* Ngoni (Tanzania) */ case HB_TAG('S','Y','R',' '): /* Syriac */ - return hb_language_from_string ("syr", -1); /* Syriac */ + return hb_language_from_string ("syr", -1); /* Syriac [macrolanguage] */ case HB_TAG('S','Y','R','E'): /* Syriac, Estrangela script-variant (equivalent to ISO 15924 'Syre') */ return hb_language_from_string ("und-Syre", -1); /* Undetermined; Syriac (Estrangelo variant) */ case HB_TAG('S','Y','R','J'): /* Syriac, Western script-variant (equivalent to ISO 15924 'Syrj') */ @@ -2046,15 +2910,19 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag) case HB_TAG('S','Y','R','N'): /* Syriac, Eastern script-variant (equivalent to ISO 15924 'Syrn') */ return hb_language_from_string ("und-Syrn", -1); /* Undetermined; Syriac (Eastern variant) */ case HB_TAG('T','M','H',' '): /* Tamashek */ - return hb_language_from_string ("tmh", -1); /* Tamashek */ - case HB_TAG('T','N','E',' '): /* Tundra Nenets */ - return hb_language_from_string ("yrk", -1); /* Nenets */ - case HB_TAG('Z','H','H',' '): /* Chinese, Hong Kong SAR */ - return hb_language_from_string ("zh-HK", -1); /* Chinese; Hong Kong */ - case HB_TAG('Z','H','S',' '): /* Chinese Simplified */ - return hb_language_from_string ("zh-Hans", -1); /* Chinese; Han (Simplified variant) */ - case HB_TAG('Z','H','T',' '): /* Chinese Traditional */ - return hb_language_from_string ("zh-Hant", -1); /* Chinese; Han (Traditional variant) */ + return hb_language_from_string ("tmh", -1); /* Tamashek [macrolanguage] */ + case HB_TAG('T','O','D',' '): /* Todo */ + return hb_language_from_string ("xwo", -1); /* Written Oirat */ + case HB_TAG('Z','H','H',' '): /* Chinese, Traditional, Hong Kong SAR */ + return hb_language_from_string ("zh-HK", -1); /* Chinese [macrolanguage]; Hong Kong */ + case HB_TAG('Z','H','S',' '): /* Chinese, Simplified */ + return hb_language_from_string ("zh-Hans", -1); /* Chinese [macrolanguage]; Han (Simplified variant) */ + case HB_TAG('Z','H','T',' '): /* Chinese, Traditional */ + return hb_language_from_string ("zh-Hant", -1); /* Chinese [macrolanguage]; Han (Traditional variant) */ + case HB_TAG('Z','H','T','M'): /* Chinese, Traditional, Macao SAR */ + return hb_language_from_string ("zh-MO", -1); /* Chinese [macrolanguage]; Macao */ + case HB_TAG('Z','Z','A',' '): /* Zazaki */ + return hb_language_from_string ("zza", -1); /* Zazaki [macrolanguage] */ default: return HB_LANGUAGE_INVALID; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc index 8ad917ae7f..fc145a41f7 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc @@ -164,6 +164,15 @@ hb_ot_all_tags_from_script (hb_script_t script, *count = i; } +/** + * hb_ot_tag_to_script: + * @tag: a script tag + * + * Converts a script tag to an #hb_script_t. + * + * Return value: The #hb_script_t corresponding to @tag. + * + **/ hb_script_t hb_ot_tag_to_script (hb_tag_t tag) { @@ -280,6 +289,7 @@ hb_ot_tags_from_language (const char *lang_str, for (i = 0; i < *count && tag_idx + i < ARRAY_LENGTH (ot_languages) && + ot_languages[tag_idx + i].tag != HB_TAG_NONE && 0 == strcmp (ot_languages[tag_idx + i].language, ot_languages[tag_idx].language); i++) tags[i] = ot_languages[tag_idx + i].tag; @@ -319,12 +329,26 @@ parse_private_use_subtag (const char *private_use_subtag, char tag[4]; int i; s += strlen (prefix); - for (i = 0; i < 4 && ISALNUM (s[i]); i++) - tag[i] = normalize (s[i]); - if (!i) return false; - - for (; i < 4; i++) - tag[i] = ' '; + if (s[0] == '-') { + s += 1; + char c; + for (i = 0; i < 8 && ISHEX (s[i]); i++) + { + c = FROMHEX (s[i]); + if (i % 2 == 0) + tag[i / 2] = c << 4; + else + tag[i / 2] += c; + } + if (i != 8) return false; + } else { + for (i = 0; i < 4 && ISALNUM (s[i]); i++) + tag[i] = normalize (s[i]); + if (!i) return false; + + for (; i < 4; i++) + tag[i] = ' '; + } tags[0] = HB_TAG (tag[0], tag[1], tag[2], tag[3]); if ((tags[0] & 0xDFDFDFDF) == HB_OT_TAG_DEFAULT_SCRIPT) tags[0] ^= ~0xDFDFDFDF; @@ -336,13 +360,13 @@ parse_private_use_subtag (const char *private_use_subtag, * hb_ot_tags_from_script_and_language: * @script: an #hb_script_t to convert. * @language: an #hb_language_t to convert. - * @script_count: (allow-none): maximum number of script tags to retrieve (IN) + * @script_count: (inout) (optional): maximum number of script tags to retrieve (IN) * and actual number of script tags retrieved (OUT) - * @script_tags: (out) (allow-none): array of size at least @script_count to store the + * @script_tags: (out) (optional): array of size at least @script_count to store the * script tag results - * @language_count: (allow-none): maximum number of language tags to retrieve + * @language_count: (inout) (optional): maximum number of language tags to retrieve * (IN) and actual number of language tags retrieved (OUT) - * @language_tags: (out) (allow-none): array of size at least @language_count to store + * @language_tags: (out) (optional): array of size at least @language_count to store * the language tag results * * Converts an #hb_script_t and an #hb_language_t to script and language tags. @@ -409,10 +433,12 @@ hb_ot_tags_from_script_and_language (hb_script_t script, /** * hb_ot_tag_to_language: + * @tag: an language tag * + * Converts a language tag to an #hb_language_t. * - * - * Return value: (transfer none): + * Return value: (transfer none) (nullable): + * The #hb_language_t corresponding to @tag. * * Since: 0.9.2 **/ @@ -434,30 +460,28 @@ hb_ot_tag_to_language (hb_tag_t tag) if (ot_languages[i].tag == tag) return hb_language_from_string (ot_languages[i].language, -1); - /* If it's three letters long, assume it's ISO 639-3 and lower-case and use it - * (if it's not a registered tag, calling hb_ot_tag_from_language on the - * result might not return the same tag as the original tag). - * Else return a custom language in the form of "x-hbotABCD". */ + /* Return a custom language in the form of "x-hbot-AABBCCDD". + * If it's three letters long, also guess it's ISO 639-3 and lower-case and + * prepend it (if it's not a registered tag, the private use subtags will + * ensure that calling hb_ot_tag_from_language on the result will still return + * the same tag as the original tag). + */ { - char buf[11] = "x-hbot"; + char buf[20]; char *str = buf; - buf[6] = tag >> 24; - buf[7] = (tag >> 16) & 0xFF; - buf[8] = (tag >> 8) & 0xFF; - buf[9] = tag & 0xFF; - if (buf[9] == 0x20) + if (ISALPHA (tag >> 24) + && ISALPHA ((tag >> 16) & 0xFF) + && ISALPHA ((tag >> 8) & 0xFF) + && (tag & 0xFF) == ' ') { - buf[9] = '\0'; - if (ISALPHA (buf[6]) && ISALPHA (buf[7]) && ISALPHA (buf[8])) - { - buf[6] = TOLOWER (buf[6]); - buf[7] = TOLOWER (buf[7]); - buf[8] = TOLOWER (buf[8]); - str += 6; - } + buf[0] = TOLOWER (tag >> 24); + buf[1] = TOLOWER ((tag >> 16) & 0xFF); + buf[2] = TOLOWER ((tag >> 8) & 0xFF); + buf[3] = '-'; + str += 4; } - buf[10] = '\0'; - return hb_language_from_string (str, -1); + snprintf (str, 16, "x-hbot-%08x", tag); + return hb_language_from_string (&*buf, -1); } } @@ -465,9 +489,9 @@ hb_ot_tag_to_language (hb_tag_t tag) * hb_ot_tags_to_script_and_language: * @script_tag: a script tag * @language_tag: a language tag - * @script: (allow-none): the #hb_script_t corresponding to @script_tag (OUT). - * @language: (allow-none): the #hb_language_t corresponding to @script_tag and - * @language_tag (OUT). + * @script: (out) (optional): the #hb_script_t corresponding to @script_tag. + * @language: (out) (optional): the #hb_language_t corresponding to @script_tag and + * @language_tag. * * Converts a script tag and a language tag to an #hb_script_t and an * #hb_language_t. @@ -498,13 +522,14 @@ hb_ot_tags_to_script_and_language (hb_tag_t script_tag, unsigned char *buf; const char *lang_str = hb_language_to_string (*language); size_t len = strlen (lang_str); - buf = (unsigned char *) malloc (len + 11); + buf = (unsigned char *) malloc (len + 16); if (unlikely (!buf)) { *language = nullptr; } else { + int shift; memcpy (buf, lang_str, len); if (lang_str[0] != 'x' || lang_str[1] != '-') { buf[len++] = '-'; @@ -515,10 +540,9 @@ hb_ot_tags_to_script_and_language (hb_tag_t script_tag, buf[len++] = 'b'; buf[len++] = 's'; buf[len++] = 'c'; - buf[len++] = script_tag >> 24; - buf[len++] = (script_tag >> 16) & 0xFF; - buf[len++] = (script_tag >> 8) & 0xFF; - buf[len++] = script_tag & 0xFF; + buf[len++] = '-'; + for (shift = 28; shift >= 0; shift -= 4) + buf[len++] = TOHEX (script_tag >> shift); *language = hb_language_from_string ((char *) buf, len); free (buf); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-avar-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-avar-table.hh index ef8ba3f5a2..29219adb0a 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-avar-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-avar-table.hh @@ -51,7 +51,7 @@ struct AxisValueMap public: F2DOT14 coords[2]; // F2DOT14 fromCoord; /* A normalized coordinate value obtained using -// * default normalization. */ +// * default normalization. */ // F2DOT14 toCoord; /* The modified, normalized coordinate value. */ public: @@ -79,7 +79,7 @@ struct SegmentMaps : ArrayOf<AxisValueMap> return value - arrayZ[0].fromCoord + arrayZ[0].toCoord; unsigned int i; - unsigned int count = len; + unsigned int count = len - 1; for (i = 1; i < count && value > arrayZ[i].fromCoord; i++) ; @@ -90,9 +90,8 @@ struct SegmentMaps : ArrayOf<AxisValueMap> return arrayZ[i-1].toCoord; int denom = arrayZ[i].fromCoord - arrayZ[i-1].fromCoord; - return arrayZ[i-1].toCoord + - ((arrayZ[i].toCoord - arrayZ[i-1].toCoord) * - (value - arrayZ[i-1].fromCoord) + denom/2) / denom; + return roundf (arrayZ[i-1].toCoord + ((float) (arrayZ[i].toCoord - arrayZ[i-1].toCoord) * + (value - arrayZ[i-1].fromCoord)) / denom); #undef toCoord #undef fromCoord } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-fvar-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-fvar-table.hh index 7ce3123819..f9e933fb2b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-fvar-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-fvar-table.hh @@ -70,22 +70,83 @@ struct InstanceRecord struct AxisRecord { + int cmp (hb_tag_t key) const { return axisTag.cmp (key); } + enum { AXIS_FLAG_HIDDEN = 0x0001, }; +#ifndef HB_DISABLE_DEPRECATED + void get_axis_deprecated (hb_ot_var_axis_t *info) const + { + info->tag = axisTag; + info->name_id = axisNameID; + get_coordinates (info->min_value, info->default_value, info->max_value); + } +#endif + + void get_axis_info (unsigned axis_index, hb_ot_var_axis_info_t *info) const + { + info->axis_index = axis_index; + info->tag = axisTag; + info->name_id = axisNameID; + info->flags = (hb_ot_var_axis_flags_t) (unsigned int) flags; + get_coordinates (info->min_value, info->default_value, info->max_value); + info->reserved = 0; + } + + int normalize_axis_value (float v) const + { + float min_value, default_value, max_value; + get_coordinates (min_value, default_value, max_value); + + v = hb_clamp (v, min_value, max_value); + + if (v == default_value) + return 0; + else if (v < default_value) + v = (v - default_value) / (default_value - min_value); + else + v = (v - default_value) / (max_value - default_value); + return roundf (v * 16384.f); + } + + float unnormalize_axis_value (int v) const + { + float min_value, default_value, max_value; + get_coordinates (min_value, default_value, max_value); + + if (v == 0) + return default_value; + else if (v < 0) + return v * (default_value - min_value) / 16384.f + default_value; + else + return v * (max_value - default_value) / 16384.f + default_value; + } + + hb_ot_name_id_t get_name_id () const { return axisNameID; } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this)); } - public: + protected: + void get_coordinates (float &min, float &default_, float &max) const + { + default_ = defaultValue / 65536.f; + /* Ensure order, to simplify client math. */ + min = hb_min (default_, minValue / 65536.f); + max = hb_max (default_, maxValue / 65536.f); + } + + protected: Tag axisTag; /* Tag identifying the design variation for the axis. */ - HBFixed minValue; /* The minimum coordinate value for the axis. */ - HBFixed defaultValue; /* The default coordinate value for the axis. */ - HBFixed maxValue; /* The maximum coordinate value for the axis. */ + HBFixed minValue; /* The minimum coordinate value for the axis. */ + HBFixed defaultValue; /* The default coordinate value for the axis. */ + HBFixed maxValue; /* The maximum coordinate value for the axis. */ HBUINT16 flags; /* Axis flags. */ NameID axisNameID; /* The name ID for entries in the 'name' table that * provide a display name for this axis. */ @@ -115,53 +176,15 @@ struct fvar unsigned int get_axis_count () const { return axisCount; } #ifndef HB_DISABLE_DEPRECATED - void get_axis_deprecated (unsigned int axis_index, - hb_ot_var_axis_t *info) const - { - const AxisRecord &axis = get_axes ()[axis_index]; - info->tag = axis.axisTag; - info->name_id = axis.axisNameID; - info->default_value = axis.defaultValue / 65536.f; - /* Ensure order, to simplify client math. */ - info->min_value = hb_min (info->default_value, axis.minValue / 65536.f); - info->max_value = hb_max (info->default_value, axis.maxValue / 65536.f); - } -#endif - - void get_axis_info (unsigned int axis_index, - hb_ot_var_axis_info_t *info) const - { - const AxisRecord &axis = get_axes ()[axis_index]; - info->axis_index = axis_index; - info->tag = axis.axisTag; - info->name_id = axis.axisNameID; - info->flags = (hb_ot_var_axis_flags_t) (unsigned int) axis.flags; - info->default_value = axis.defaultValue / 65536.f; - /* Ensure order, to simplify client math. */ - info->min_value = hb_min (info->default_value, axis.minValue / 65536.f); - info->max_value = hb_max (info->default_value, axis.maxValue / 65536.f); - info->reserved = 0; - } - -#ifndef HB_DISABLE_DEPRECATED unsigned int get_axes_deprecated (unsigned int start_offset, unsigned int *axes_count /* IN/OUT */, hb_ot_var_axis_t *axes_array /* OUT */) const { if (axes_count) { - /* TODO Rewrite as hb_array_t<>::sub-array() */ - unsigned int count = axisCount; - start_offset = hb_min (start_offset, count); - - count -= start_offset; - axes_array += start_offset; - - count = hb_min (count, *axes_count); - *axes_count = count; - - for (unsigned int i = 0; i < count; i++) - get_axis_deprecated (start_offset + i, axes_array + i); + hb_array_t<const AxisRecord> arr = get_axes ().sub_array (start_offset, axes_count); + for (unsigned i = 0; i < arr.length; ++i) + arr[i].get_axis_deprecated (&axes_array[i]); } return axisCount; } @@ -173,86 +196,38 @@ struct fvar { if (axes_count) { - /* TODO Rewrite as hb_array_t<>::sub-array() */ - unsigned int count = axisCount; - start_offset = hb_min (start_offset, count); - - count -= start_offset; - axes_array += start_offset; - - count = hb_min (count, *axes_count); - *axes_count = count; - - for (unsigned int i = 0; i < count; i++) - get_axis_info (start_offset + i, axes_array + i); + hb_array_t<const AxisRecord> arr = get_axes ().sub_array (start_offset, axes_count); + for (unsigned i = 0; i < arr.length; ++i) + arr[i].get_axis_info (start_offset + i, &axes_array[i]); } return axisCount; } #ifndef HB_DISABLE_DEPRECATED - bool find_axis_deprecated (hb_tag_t tag, - unsigned int *axis_index, - hb_ot_var_axis_t *info) const + bool + find_axis_deprecated (hb_tag_t tag, unsigned *axis_index, hb_ot_var_axis_t *info) const { - const AxisRecord *axes = get_axes (); - unsigned int count = get_axis_count (); - for (unsigned int i = 0; i < count; i++) - if (axes[i].axisTag == tag) - { - if (axis_index) - *axis_index = i; - get_axis_deprecated (i, info); - return true; - } - if (axis_index) - *axis_index = HB_OT_VAR_NO_AXIS_INDEX; - return false; + unsigned i; + if (!axis_index) axis_index = &i; + *axis_index = HB_OT_VAR_NO_AXIS_INDEX; + auto axes = get_axes (); + return axes.lfind (tag, axis_index) && (axes[*axis_index].get_axis_deprecated (info), true); } #endif - bool find_axis_info (hb_tag_t tag, - hb_ot_var_axis_info_t *info) const + bool + find_axis_info (hb_tag_t tag, hb_ot_var_axis_info_t *info) const { - const AxisRecord *axes = get_axes (); - unsigned int count = get_axis_count (); - for (unsigned int i = 0; i < count; i++) - if (axes[i].axisTag == tag) - { - get_axis_info (i, info); - return true; - } - return false; + unsigned i; + auto axes = get_axes (); + return axes.lfind (tag, &i) && (axes[i].get_axis_info (i, info), true); } int normalize_axis_value (unsigned int axis_index, float v) const - { - hb_ot_var_axis_info_t axis; - get_axis_info (axis_index, &axis); - - v = hb_max (hb_min (v, axis.max_value), axis.min_value); /* Clamp. */ - - if (v == axis.default_value) - return 0; - else if (v < axis.default_value) - v = (v - axis.default_value) / (axis.default_value - axis.min_value); - else - v = (v - axis.default_value) / (axis.max_value - axis.default_value); - return roundf (v * 16384.f); - } - - float unnormalize_axis_value (unsigned int axis_index, float v) const - { - hb_ot_var_axis_info_t axis; - get_axis_info (axis_index, &axis); + { return get_axes ()[axis_index].normalize_axis_value (v); } - if (v == 0) - return axis.default_value; - else if (v < 0) - v = v * (axis.default_value - axis.min_value) / 16384.f + axis.default_value; - else - v = v * (axis.max_value - axis.default_value) / 16384.f + axis.default_value; - return v; - } + float unnormalize_axis_value (unsigned int axis_index, int v) const + { return get_axes ()[axis_index].unnormalize_axis_value (v); } unsigned int get_instance_count () const { return instanceCount; } @@ -299,7 +274,7 @@ struct fvar if (!has_data ()) return; + get_axes () - | hb_map (&AxisRecord::axisNameID) + | hb_map (&AxisRecord::get_name_id) | hb_sink (nameids) ; @@ -314,7 +289,6 @@ struct fvar ; } - protected: hb_array_t<const AxisRecord> get_axes () const { return hb_array (&(this+firstAxis), axisCount); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-gvar-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-gvar-table.hh index a76121d860..7e4eaaad95 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-gvar-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-gvar-table.hh @@ -29,8 +29,6 @@ #define HB_OT_VAR_GVAR_TABLE_HH #include "hb-open-type.hh" -#include "hb-ot-glyf-table.hh" -#include "hb-ot-var-fvar-table.hh" /* * gvar -- Glyph Variation Table @@ -42,12 +40,14 @@ namespace OT { struct contour_point_t { - void init (float x_=0.f, float y_=0.f) { flag = 0; x = x_; y = y_; } + void init (float x_ = 0.f, float y_ = 0.f, bool is_end_point_ = false) + { flag = 0; x = x_; y = y_; is_end_point = is_end_point_; } void translate (const contour_point_t &p) { x += p.x; y += p.y; } uint8_t flag; float x, y; + bool is_end_point; }; struct contour_point_vector_t : hb_vector_t<contour_point_t> @@ -78,50 +78,34 @@ struct contour_point_vector_t : hb_vector_t<contour_point_t> } }; -struct Tuple : UnsizedArrayOf<F2DOT14> {}; - -struct TuppleIndex : HBUINT16 +/* https://docs.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuplevariationheader */ +struct TupleVariationHeader { - enum Flags { - EmbeddedPeakTuple = 0x8000u, - IntermediateRegion = 0x4000u, - PrivatePointNumbers = 0x2000u, - TupleIndexMask = 0x0FFFu - }; - - DEFINE_SIZE_STATIC (2); -}; + unsigned get_size (unsigned axis_count) const + { return min_size + get_all_tuples (axis_count).get_size (); } -struct TupleVarHeader -{ - unsigned int get_size (unsigned int axis_count) const - { - return min_size + - (has_peak () ? get_peak_tuple ().get_size (axis_count) : 0) + - (has_intermediate () ? (get_start_tuple (axis_count).get_size (axis_count) + - get_end_tuple (axis_count).get_size (axis_count)) : 0); - } + unsigned get_data_size () const { return varDataSize; } - const TupleVarHeader &get_next (unsigned int axis_count) const - { return StructAtOffset<TupleVarHeader> (this, get_size (axis_count)); } + const TupleVariationHeader &get_next (unsigned axis_count) const + { return StructAtOffset<TupleVariationHeader> (this, get_size (axis_count)); } float calculate_scalar (const int *coords, unsigned int coord_count, - const hb_array_t<const F2DOT14> shared_tuples) const + const hb_array_t<const F2DOT14> shared_tuples) const { - const F2DOT14 *peak_tuple; + hb_array_t<const F2DOT14> peak_tuple; if (has_peak ()) - peak_tuple = &(get_peak_tuple ()[0]); + peak_tuple = get_peak_tuple (coord_count); else { unsigned int index = get_index (); if (unlikely (index * coord_count >= shared_tuples.length)) return 0.f; - peak_tuple = &shared_tuples[coord_count * index]; + peak_tuple = shared_tuples.sub_array (coord_count * index, coord_count); } - const F2DOT14 *start_tuple = nullptr; - const F2DOT14 *end_tuple = nullptr; + hb_array_t<const F2DOT14> start_tuple; + hb_array_t<const F2DOT14> end_tuple; if (has_intermediate ()) { start_tuple = get_start_tuple (coord_count); @@ -154,58 +138,64 @@ struct TupleVarHeader return scalar; } - unsigned int get_data_size () const { return varDataSize; } - - bool has_peak () const { return (tupleIndex & TuppleIndex::EmbeddedPeakTuple); } - bool has_intermediate () const { return (tupleIndex & TuppleIndex::IntermediateRegion); } - bool has_private_points () const { return (tupleIndex & TuppleIndex::PrivatePointNumbers); } - unsigned int get_index () const { return (tupleIndex & TuppleIndex::TupleIndexMask); } + bool has_peak () const { return tupleIndex & TuppleIndex::EmbeddedPeakTuple; } + bool has_intermediate () const { return tupleIndex & TuppleIndex::IntermediateRegion; } + bool has_private_points () const { return tupleIndex & TuppleIndex::PrivatePointNumbers; } + unsigned get_index () const { return tupleIndex & TuppleIndex::TupleIndexMask; } protected: - const Tuple &get_peak_tuple () const - { return StructAfter<Tuple> (tupleIndex); } - const Tuple &get_start_tuple (unsigned int axis_count) const - { return *(const Tuple *) &get_peak_tuple ()[has_peak () ? axis_count : 0]; } - const Tuple &get_end_tuple (unsigned int axis_count) const - { return *(const Tuple *) &get_peak_tuple ()[has_peak () ? (axis_count * 2) : axis_count]; } - - HBUINT16 varDataSize; - TuppleIndex tupleIndex; + struct TuppleIndex : HBUINT16 + { + enum Flags { + EmbeddedPeakTuple = 0x8000u, + IntermediateRegion = 0x4000u, + PrivatePointNumbers = 0x2000u, + TupleIndexMask = 0x0FFFu + }; + + DEFINE_SIZE_STATIC (2); + }; + + hb_array_t<const F2DOT14> get_all_tuples (unsigned axis_count) const + { return StructAfter<UnsizedArrayOf<F2DOT14>> (tupleIndex).as_array ((has_peak () + has_intermediate () * 2) * axis_count); } + hb_array_t<const F2DOT14> get_peak_tuple (unsigned axis_count) const + { return get_all_tuples (axis_count).sub_array (0, axis_count); } + hb_array_t<const F2DOT14> get_start_tuple (unsigned axis_count) const + { return get_all_tuples (axis_count).sub_array (has_peak () * axis_count, axis_count); } + hb_array_t<const F2DOT14> get_end_tuple (unsigned axis_count) const + { return get_all_tuples (axis_count).sub_array (has_peak () * axis_count + axis_count, axis_count); } + + HBUINT16 varDataSize; /* The size in bytes of the serialized + * data for this tuple variation table. */ + TuppleIndex tupleIndex; /* A packed field. The high 4 bits are flags (see below). + The low 12 bits are an index into a shared tuple + records array. */ /* UnsizedArrayOf<F2DOT14> peakTuple - optional */ + /* Peak tuple record for this tuple variation table — optional, + * determined by flags in the tupleIndex value. + * + * Note that this must always be included in the 'cvar' table. */ /* UnsizedArrayOf<F2DOT14> intermediateStartTuple - optional */ + /* Intermediate start tuple record for this tuple variation table — optional, + determined by flags in the tupleIndex value. */ /* UnsizedArrayOf<F2DOT14> intermediateEndTuple - optional */ - + /* Intermediate end tuple record for this tuple variation table — optional, + * determined by flags in the tupleIndex value. */ public: DEFINE_SIZE_MIN (4); }; -struct TupleVarCount : HBUINT16 +struct GlyphVariationData { - bool has_shared_point_numbers () const { return ((*this) & SharedPointNumbers); } - unsigned int get_count () const { return (*this) & CountMask; } - - protected: - enum Flags - { - SharedPointNumbers = 0x8000u, - CountMask = 0x0FFFu - }; - - public: - DEFINE_SIZE_STATIC (2); -}; - -struct GlyphVarData -{ - const TupleVarHeader &get_tuple_var_header (void) const - { return StructAfter<TupleVarHeader> (data); } + const TupleVariationHeader &get_tuple_var_header (void) const + { return StructAfter<TupleVariationHeader> (data); } struct tuple_iterator_t { - void init (const GlyphVarData *var_data_, unsigned int length_, unsigned int axis_count_) + void init (hb_bytes_t var_data_bytes_, unsigned int axis_count_) { - var_data = var_data_; - length = length_; + var_data_bytes = var_data_bytes_; + var_data = var_data_bytes_.as<GlyphVariationData> (); index = 0; axis_count = axis_count_; current_tuple = &var_data->get_tuple_var_header (); @@ -216,10 +206,9 @@ struct GlyphVarData { if (var_data->has_shared_point_numbers ()) { - hb_bytes_t bytes ((const char *) var_data, length); const HBUINT8 *base = &(var_data+var_data->data); const HBUINT8 *p = base; - if (!unpack_points (p, shared_indices, bytes)) return false; + if (!unpack_points (p, shared_indices, var_data_bytes)) return false; data_offset = p - base; } return true; @@ -228,7 +217,8 @@ struct GlyphVarData bool is_valid () const { return (index < var_data->tupleVarCount.get_count ()) && - in_range (current_tuple) && + var_data_bytes.check_range (current_tuple, TupleVariationHeader::min_size) && + var_data_bytes.check_range (current_tuple, hb_max (current_tuple->get_data_size (), current_tuple->get_size (axis_count))) && current_tuple->get_size (axis_count); } @@ -240,32 +230,25 @@ struct GlyphVarData return is_valid (); } - bool in_range (const void *p, unsigned int l) const - { return (const char*) p >= (const char*) var_data && (const char*) p+l <= (const char*) var_data + length; } - - template <typename T> bool in_range (const T *p) const { return in_range (p, sizeof (*p)); } - const HBUINT8 *get_serialized_data () const { return &(var_data+var_data->data) + data_offset; } private: - const GlyphVarData *var_data; - unsigned int length; + const GlyphVariationData *var_data; unsigned int index; unsigned int axis_count; unsigned int data_offset; public: - const TupleVarHeader *current_tuple; + hb_bytes_t var_data_bytes; + const TupleVariationHeader *current_tuple; }; - static bool get_tuple_iterator (const GlyphVarData *var_data, - unsigned int length, - unsigned int axis_count, - hb_vector_t<unsigned int> &shared_indices /* OUT */, - tuple_iterator_t *iterator /* OUT */) + static bool get_tuple_iterator (hb_bytes_t var_data_bytes, unsigned axis_count, + hb_vector_t<unsigned int> &shared_indices /* OUT */, + tuple_iterator_t *iterator /* OUT */) { - iterator->init (var_data, length, axis_count); + iterator->init (var_data_bytes, axis_count); if (!iterator->get_shared_indices (shared_indices)) return false; return iterator->is_valid (); @@ -283,12 +266,12 @@ struct GlyphVarData POINT_RUN_COUNT_MASK = 0x7F }; - if (unlikely (!bytes.in_range (p))) return false; + if (unlikely (!bytes.check_range (p))) return false; uint16_t count = *p++; if (count & POINTS_ARE_WORDS) { - if (unlikely (!bytes.in_range (p))) return false; + if (unlikely (!bytes.check_range (p))) return false; count = ((count & POINT_RUN_COUNT_MASK) << 8) | *p++; } points.resize (count); @@ -297,7 +280,7 @@ struct GlyphVarData uint16_t i = 0; while (i < count) { - if (unlikely (!bytes.in_range (p))) return false; + if (unlikely (!bytes.check_range (p))) return false; uint16_t j; uint8_t control = *p++; uint16_t run_count = (control & POINT_RUN_COUNT_MASK) + 1; @@ -305,7 +288,7 @@ struct GlyphVarData { for (j = 0; j < run_count && i < count; j++, i++) { - if (unlikely (!bytes.in_range ((const HBUINT16 *) p))) + if (unlikely (!bytes.check_range ((const HBUINT16 *) p))) return false; n += *(const HBUINT16 *)p; points[i] = n; @@ -316,7 +299,7 @@ struct GlyphVarData { for (j = 0; j < run_count && i < count; j++, i++) { - if (unlikely (!bytes.in_range (p))) return false; + if (unlikely (!bytes.check_range (p))) return false; n += *p++; points[i] = n; } @@ -341,7 +324,7 @@ struct GlyphVarData unsigned int count = deltas.length; while (i < count) { - if (unlikely (!bytes.in_range (p))) return false; + if (unlikely (!bytes.check_range (p))) return false; uint8_t control = *p++; unsigned int run_count = (control & DELTA_RUN_COUNT_MASK) + 1; unsigned int j; @@ -351,7 +334,7 @@ struct GlyphVarData else if (control & DELTAS_ARE_WORDS) for (j = 0; j < run_count && i < count; j++, i++) { - if (unlikely (!bytes.in_range ((const HBUINT16 *) p))) + if (unlikely (!bytes.check_range ((const HBUINT16 *) p))) return false; deltas[i] = *(const HBINT16 *) p; p += HBUINT16::static_size; @@ -359,7 +342,7 @@ struct GlyphVarData else for (j = 0; j < run_count && i < count; j++, i++) { - if (unlikely (!bytes.in_range (p))) + if (unlikely (!bytes.check_range (p))) return false; deltas[i] = *(const HBINT8 *) p++; } @@ -369,10 +352,32 @@ struct GlyphVarData return true; } + bool has_data () const { return tupleVarCount; } + protected: - TupleVarCount tupleVarCount; - OffsetTo<HBUINT8> data; - /* TupleVarHeader tupleVarHeaders[] */ + struct TupleVarCount : HBUINT16 + { + bool has_shared_point_numbers () const { return ((*this) & SharedPointNumbers); } + unsigned int get_count () const { return (*this) & CountMask; } + + protected: + enum Flags + { + SharedPointNumbers= 0x8000u, + CountMask = 0x0FFFu + }; + public: + DEFINE_SIZE_STATIC (2); + }; + + TupleVarCount tupleVarCount; /* A packed field. The high 4 bits are flags, and the + * low 12 bits are the number of tuple variation tables + * for this glyph. The number of tuple variation tables + * can be any number between 1 and 4095. */ + OffsetTo<HBUINT8> + data; /* Offset from the start of the GlyphVariationData table + * to the serialized data. */ + /* TupleVariationHeader tupleVariationHeaders[] *//* Array of tuple variation headers. */ public: DEFINE_SIZE_MIN (4); }; @@ -386,7 +391,7 @@ struct gvar TRACE_SANITIZE (this); return_trace (c->check_struct (this) && (version.major == 1) && (glyphCount == c->get_num_glyphs ()) && - c->check_array (&(this+sharedTuples), axisCount * sharedTupleCount) && + sharedTuples.sanitize (c, this, axisCount * sharedTupleCount) && (is_long_offset () ? c->check_array (get_long_offset_array (), glyphCount+1) : c->check_array (get_short_offset_array (), glyphCount+1)) && @@ -394,7 +399,7 @@ struct gvar get_offset (glyphCount) - get_offset (0))); } - /* GlyphVarData not sanitized here; must be checked while accessing each glyph varation data */ + /* GlyphVariationData not sanitized here; must be checked while accessing each glyph varation data */ bool sanitize (hb_sanitize_context_t *c) const { return sanitize_shallow (c); } @@ -418,7 +423,7 @@ struct gvar { hb_codepoint_t old_gid; if (!c->plan->old_gid_for_new_gid (gid, &old_gid)) continue; - subset_data_size += get_glyph_var_data_length (old_gid); + subset_data_size += get_glyph_var_data_bytes (c->source_blob, old_gid).length; } bool long_offset = subset_data_size & ~0xFFFFu; @@ -436,27 +441,30 @@ struct gvar F2DOT14 *tuples = c->serializer->allocate_size<F2DOT14> (shared_tuple_size); if (!tuples) return_trace (false); out->sharedTuples = (char *) tuples - (char *) out; - memcpy (tuples, &(this+sharedTuples), shared_tuple_size); + memcpy (tuples, this+sharedTuples, shared_tuple_size); } char *subset_data = c->serializer->allocate_size<char> (subset_data_size); if (!subset_data) return_trace (false); - out->dataZ = subset_data - (char *)out; + out->dataZ = subset_data - (char *) out; unsigned int glyph_offset = 0; for (hb_codepoint_t gid = 0; gid < num_glyphs; gid++) { hb_codepoint_t old_gid; - unsigned int length = c->plan->old_gid_for_new_gid (gid, &old_gid) ? get_glyph_var_data_length (old_gid) : 0; + hb_bytes_t var_data_bytes = c->plan->old_gid_for_new_gid (gid, &old_gid) + ? get_glyph_var_data_bytes (c->source_blob, old_gid) + : hb_bytes_t (); if (long_offset) ((HBUINT32 *) subset_offsets)[gid] = glyph_offset; else ((HBUINT16 *) subset_offsets)[gid] = glyph_offset / 2; - if (length > 0) memcpy (subset_data, get_glyph_var_data (old_gid), length); - subset_data += length; - glyph_offset += length; + if (var_data_bytes.length > 0) + memcpy (subset_data, var_data_bytes.arrayZ, var_data_bytes.length); + subset_data += var_data_bytes.length; + glyph_offset += var_data_bytes.length; } if (long_offset) ((HBUINT32 *) subset_offsets)[num_glyphs] = glyph_offset; @@ -467,36 +475,18 @@ struct gvar } protected: - const GlyphVarData *get_glyph_var_data (hb_codepoint_t glyph) const + const hb_bytes_t get_glyph_var_data_bytes (hb_blob_t *blob, hb_codepoint_t glyph) const { - unsigned int start_offset = get_offset (glyph); - unsigned int end_offset = get_offset (glyph+1); - - if ((start_offset == end_offset) || - unlikely ((start_offset > get_offset (glyphCount)) || - (start_offset + GlyphVarData::min_size > end_offset))) - return &Null (GlyphVarData); - return &(((unsigned char *) this + start_offset) + dataZ); + unsigned start_offset = get_offset (glyph); + unsigned length = get_offset (glyph+1) - start_offset; + hb_bytes_t var_data = blob->as_bytes ().sub_array (((unsigned) dataZ) + start_offset, length); + return likely (var_data.length >= GlyphVariationData::min_size) ? var_data : hb_bytes_t (); } - bool is_long_offset () const { return (flags & 1) != 0; } + bool is_long_offset () const { return flags & 1; } - unsigned int get_offset (unsigned int i) const - { - if (is_long_offset ()) - return get_long_offset_array ()[i]; - else - return get_short_offset_array ()[i] * 2; - } - - unsigned int get_glyph_var_data_length (unsigned int glyph) const - { - unsigned int end_offset = get_offset (glyph + 1); - unsigned int start_offset = get_offset (glyph); - if (unlikely (start_offset > end_offset || end_offset > get_offset (glyphCount))) - return 0; - return end_offset - start_offset; - } + unsigned get_offset (unsigned i) const + { return is_long_offset () ? get_long_offset_array ()[i] : get_short_offset_array ()[i] * 2; } const HBUINT32 * get_long_offset_array () const { return (const HBUINT32 *) &offsetZ; } const HBUINT16 *get_short_offset_array () const { return (const HBUINT16 *) &offsetZ; } @@ -505,27 +495,8 @@ struct gvar struct accelerator_t { void init (hb_face_t *face) - { - gvar_table = hb_sanitize_context_t ().reference_table<gvar> (face); - hb_blob_ptr_t<fvar> fvar_table = hb_sanitize_context_t ().reference_table<fvar> (face); - unsigned int axis_count = fvar_table->get_axis_count (); - fvar_table.destroy (); - - if (unlikely ((gvar_table->glyphCount != face->get_num_glyphs ()) || - (gvar_table->axisCount != axis_count))) - fini (); - - unsigned int num_shared_coord = gvar_table->sharedTupleCount * gvar_table->axisCount; - shared_tuples.resize (num_shared_coord); - for (unsigned int i = 0; i < num_shared_coord; i++) - shared_tuples[i] = (&(gvar_table + gvar_table->sharedTuples))[i]; - } - - void fini () - { - gvar_table.destroy (); - shared_tuples.fini (); - } + { table = hb_sanitize_context_t ().reference_table<gvar> (face); } + void fini () { table.destroy (); } private: struct x_getter { static float get (const contour_point_t &p) { return p.x; } }; @@ -543,11 +514,11 @@ struct gvar float next_delta = T::get (deltas[next]); if (prev_val == next_val) - return (prev_delta == next_delta) ? prev_delta : 0.f; + return (prev_delta == next_delta) ? prev_delta : 0.f; else if (target_val <= hb_min (prev_val, next_val)) - return (prev_val < next_val) ? prev_delta : next_delta; + return (prev_val < next_val) ? prev_delta : next_delta; else if (target_val >= hb_max (prev_val, next_val)) - return (prev_val > next_val) ? prev_delta : next_delta; + return (prev_val > next_val) ? prev_delta : next_delta; /* linear interpolation */ float r = (target_val - prev_val) / (next_val - prev_val); @@ -558,23 +529,21 @@ struct gvar { return (i >= end) ? start : (i + 1); } public: - bool apply_deltas_to_points (hb_codepoint_t glyph, - const int *coords, unsigned int coord_count, - const hb_array_t<contour_point_t> points, - const hb_array_t<unsigned int> end_points) const + bool apply_deltas_to_points (hb_codepoint_t glyph, hb_font_t *font, + const hb_array_t<contour_point_t> points) const { - if (unlikely (coord_count != gvar_table->axisCount)) return false; + /* num_coords should exactly match gvar's axisCount due to how GlyphVariationData tuples are aligned */ + if (!font->num_coords || font->num_coords != table->axisCount) return true; - const GlyphVarData *var_data = gvar_table->get_glyph_var_data (glyph); - if (var_data == &Null (GlyphVarData)) return true; + if (unlikely (glyph >= table->glyphCount)) return true; + + hb_bytes_t var_data_bytes = table->get_glyph_var_data_bytes (table.get_blob (), glyph); + if (!var_data_bytes.as<GlyphVariationData> ()->has_data ()) return true; hb_vector_t<unsigned int> shared_indices; - GlyphVarData::tuple_iterator_t iterator; - if (!GlyphVarData::get_tuple_iterator (var_data, - gvar_table->get_glyph_var_data_length (glyph), - gvar_table->axisCount, - shared_indices, - &iterator)) - return false; + GlyphVariationData::tuple_iterator_t iterator; + if (!GlyphVariationData::get_tuple_iterator (var_data_bytes, table->axisCount, + shared_indices, &iterator)) + return true; /* so isn't applied at all */ /* Save original points for inferred delta calculation */ contour_point_vector_t orig_points; @@ -585,19 +554,27 @@ struct gvar contour_point_vector_t deltas; /* flag is used to indicate referenced point */ deltas.resize (points.length); + hb_vector_t<unsigned> end_points; + for (unsigned i = 0; i < points.length; ++i) + if (points[i].is_end_point) + end_points.push (i); + + int *coords = font->coords; + unsigned num_coords = font->num_coords; + hb_array_t<const F2DOT14> shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * table->axisCount); do { - float scalar = iterator.current_tuple->calculate_scalar (coords, coord_count, shared_tuples.as_array ()); + float scalar = iterator.current_tuple->calculate_scalar (coords, num_coords, shared_tuples); if (scalar == 0.f) continue; const HBUINT8 *p = iterator.get_serialized_data (); unsigned int length = iterator.current_tuple->get_data_size (); - if (unlikely (!iterator.in_range (p, length))) + if (unlikely (!iterator.var_data_bytes.check_range (p, length))) return false; hb_bytes_t bytes ((const char *) p, length); hb_vector_t<unsigned int> private_indices; if (iterator.current_tuple->has_private_points () && - !GlyphVarData::unpack_points (p, private_indices, bytes)) + !GlyphVariationData::unpack_points (p, private_indices, bytes)) return false; const hb_array_t<unsigned int> &indices = private_indices.length ? private_indices : shared_indices; @@ -605,11 +582,11 @@ struct gvar unsigned int num_deltas = apply_to_all ? points.length : indices.length; hb_vector_t<int> x_deltas; x_deltas.resize (num_deltas); - if (!GlyphVarData::unpack_deltas (p, x_deltas, bytes)) + if (!GlyphVariationData::unpack_deltas (p, x_deltas, bytes)) return false; hb_vector_t<int> y_deltas; y_deltas.resize (num_deltas); - if (!GlyphVarData::unpack_deltas (p, y_deltas, bytes)) + if (!GlyphVariationData::unpack_deltas (p, y_deltas, bytes)) return false; for (unsigned int i = 0; i < deltas.length; i++) @@ -623,26 +600,26 @@ struct gvar } /* infer deltas for unreferenced points */ - unsigned int start_point = 0; - for (unsigned int c = 0; c < end_points.length; c++) + unsigned start_point = 0; + for (unsigned c = 0; c < end_points.length; c++) { - unsigned int end_point = end_points[c]; - unsigned int i, j; + unsigned end_point = end_points[c]; /* Check the number of unreferenced points in a contour. If no unref points or no ref points, nothing to do. */ - unsigned int unref_count = 0; - for (i = start_point; i <= end_point; i++) + unsigned unref_count = 0; + for (unsigned i = start_point; i <= end_point; i++) if (!deltas[i].flag) unref_count++; + + unsigned j = start_point; if (unref_count == 0 || unref_count > end_point - start_point) goto no_more_gaps; - j = start_point; for (;;) { /* Locate the next gap of unreferenced points between two referenced points prev and next. * Note that a gap may wrap around at left (start_point) and/or at right (end_point). */ - unsigned int prev, next; + unsigned int prev, next, i; for (;;) { i = j; @@ -675,37 +652,44 @@ no_more_gaps: /* apply specified / inferred deltas to points */ for (unsigned int i = 0; i < points.length; i++) { - points[i].x += (float) roundf (deltas[i].x); - points[i].y += (float) roundf (deltas[i].y); + points[i].x += deltas[i].x; + points[i].y += deltas[i].y; } } while (iterator.move_to_next ()); return true; } - unsigned int get_axis_count () const { return gvar_table->axisCount; } - - protected: - const GlyphVarData *get_glyph_var_data (hb_codepoint_t glyph) const - { return gvar_table->get_glyph_var_data (glyph); } + unsigned int get_axis_count () const { return table->axisCount; } private: - hb_blob_ptr_t<gvar> gvar_table; - hb_vector_t<F2DOT14> shared_tuples; + hb_blob_ptr_t<gvar> table; }; protected: - FixedVersion<>version; /* Version of gvar table. Set to 0x00010000u. */ - HBUINT16 axisCount; + FixedVersion<>version; /* Version number of the glyph variations table + * Set to 0x00010000u. */ + HBUINT16 axisCount; /* The number of variation axes for this font. This must be + * the same number as axisCount in the 'fvar' table. */ HBUINT16 sharedTupleCount; - LOffsetTo<F2DOT14> - sharedTuples; /* LOffsetTo<UnsizedArrayOf<Tupple>> */ - HBUINT16 glyphCount; - HBUINT16 flags; - LOffsetTo<GlyphVarData> - dataZ; /* Array of GlyphVarData */ + /* The number of shared tuple records. Shared tuple records + * can be referenced within glyph variation data tables for + * multiple glyphs, as opposed to other tuple records stored + * directly within a glyph variation data table. */ + LNNOffsetTo<UnsizedArrayOf<F2DOT14>> + sharedTuples; /* Offset from the start of this table to the shared tuple records. + * Array of tuple records shared across all glyph variation data tables. */ + HBUINT16 glyphCount; /* The number of glyphs in this font. This must match the number of + * glyphs stored elsewhere in the font. */ + HBUINT16 flags; /* Bit-field that gives the format of the offset array that follows. + * If bit 0 is clear, the offsets are uint16; if bit 0 is set, the + * offsets are uint32. */ + LOffsetTo<GlyphVariationData> + dataZ; /* Offset from the start of this table to the array of + * GlyphVariationData tables. */ UnsizedArrayOf<HBUINT8> - offsetZ; /* Array of 16-bit or 32-bit (glyphCount+1) offsets */ + offsetZ; /* Offsets from the start of the GlyphVariationData array + * to each GlyphVariationData table. */ public: DEFINE_SIZE_MIN (20); }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-hvar-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-hvar-table.hh index 223430fb82..fdcc88d674 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-hvar-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-hvar-table.hh @@ -44,6 +44,38 @@ struct DeltaSetIndexMap get_width ())); } + template <typename T> + bool serialize (hb_serialize_context_t *c, const T &plan) + { + unsigned int width = plan.get_width (); + unsigned int inner_bit_count = plan.get_inner_bit_count (); + const hb_array_t<const unsigned int> output_map = plan.get_output_map (); + + TRACE_SERIALIZE (this); + if (unlikely (output_map.length && ((((inner_bit_count-1)&~0xF)!=0) || (((width-1)&~0x3)!=0)))) + return_trace (false); + if (unlikely (!c->extend_min (*this))) return_trace (false); + + format = ((width-1)<<4)|(inner_bit_count-1); + mapCount = output_map.length; + HBUINT8 *p = c->allocate_size<HBUINT8> (width * output_map.length); + if (unlikely (!p)) return_trace (false); + for (unsigned int i = 0; i < output_map.length; i++) + { + unsigned int v = output_map[i]; + unsigned int outer = v >> 16; + unsigned int inner = v & 0xFFFF; + unsigned int u = (outer << inner_bit_count) | inner; + for (unsigned int w = width; w > 0;) + { + p[--w] = u; + u >>= 8; + } + p += width; + } + return_trace (true); + } + unsigned int map (unsigned int v) const /* Returns 16.16 outer.inner. */ { /* If count is zero, pass value unchanged. This takes @@ -63,7 +95,7 @@ struct DeltaSetIndexMap } { /* Repack it. */ - unsigned int n = get_inner_bitcount (); + unsigned int n = get_inner_bit_count (); unsigned int outer = u >> n; unsigned int inner = u & ((1 << n) - 1); u = (outer<<16) | inner; @@ -72,22 +104,230 @@ struct DeltaSetIndexMap return u; } - protected: - unsigned int get_width () const { return ((format >> 4) & 3) + 1; } - - unsigned int get_inner_bitcount () const { return (format & 0xF) + 1; } + unsigned int get_map_count () const { return mapCount; } + unsigned int get_width () const { return ((format >> 4) & 3) + 1; } + unsigned int get_inner_bit_count () const { return (format & 0xF) + 1; } protected: HBUINT16 format; /* A packed field that describes the compressed * representation of delta-set indices. */ HBUINT16 mapCount; /* The number of mapping entries. */ UnsizedArrayOf<HBUINT8> - mapDataZ; /* The delta-set index mapping data. */ + mapDataZ; /* The delta-set index mapping data. */ public: DEFINE_SIZE_ARRAY (4, mapDataZ); }; +struct index_map_subset_plan_t +{ + enum index_map_index_t { + ADV_INDEX, + LSB_INDEX, /* dual as TSB */ + RSB_INDEX, /* dual as BSB */ + VORG_INDEX + }; + + void init (const DeltaSetIndexMap &index_map, + hb_inc_bimap_t &outer_map, + hb_vector_t<hb_set_t *> &inner_sets, + const hb_subset_plan_t *plan) + { + map_count = 0; + outer_bit_count = 0; + inner_bit_count = 1; + max_inners.init (); + output_map.init (); + + if (&index_map == &Null (DeltaSetIndexMap)) return; + + unsigned int last_val = (unsigned int)-1; + hb_codepoint_t last_gid = (hb_codepoint_t)-1; + hb_codepoint_t gid = (hb_codepoint_t) hb_min (index_map.get_map_count (), plan->num_output_glyphs ()); + + outer_bit_count = (index_map.get_width () * 8) - index_map.get_inner_bit_count (); + max_inners.resize (inner_sets.length); + for (unsigned i = 0; i < inner_sets.length; i++) max_inners[i] = 0; + + /* Search backwards for a map value different from the last map value */ + for (; gid > 0; gid--) + { + hb_codepoint_t old_gid; + if (!plan->old_gid_for_new_gid (gid - 1, &old_gid)) + { + if (last_gid == (hb_codepoint_t) -1) + continue; + else + break; + } + + unsigned int v = index_map.map (old_gid); + if (last_gid == (hb_codepoint_t) -1) + { + last_val = v; + last_gid = gid; + continue; + } + if (v != last_val) break; + + last_gid = gid; + } + + if (unlikely (last_gid == (hb_codepoint_t)-1)) return; + map_count = last_gid; + for (gid = 0; gid < map_count; gid++) + { + hb_codepoint_t old_gid; + if (plan->old_gid_for_new_gid (gid, &old_gid)) + { + unsigned int v = index_map.map (old_gid); + unsigned int outer = v >> 16; + unsigned int inner = v & 0xFFFF; + outer_map.add (outer); + if (inner > max_inners[outer]) max_inners[outer] = inner; + if (outer >= inner_sets.length) return; + inner_sets[outer]->add (inner); + } + } + } + + void fini () + { + max_inners.fini (); + output_map.fini (); + } + + void remap (const DeltaSetIndexMap *input_map, + const hb_inc_bimap_t &outer_map, + const hb_vector_t<hb_inc_bimap_t> &inner_maps, + const hb_subset_plan_t *plan) + { + if (input_map == &Null (DeltaSetIndexMap)) return; + + for (unsigned int i = 0; i < max_inners.length; i++) + { + if (inner_maps[i].get_population () == 0) continue; + unsigned int bit_count = (max_inners[i]==0)? 1: hb_bit_storage (inner_maps[i][max_inners[i]]); + if (bit_count > inner_bit_count) inner_bit_count = bit_count; + } + + output_map.resize (map_count); + for (hb_codepoint_t gid = 0; gid < output_map.length; gid++) + { + hb_codepoint_t old_gid; + if (plan->old_gid_for_new_gid (gid, &old_gid)) + { + unsigned int v = input_map->map (old_gid); + unsigned int outer = v >> 16; + output_map[gid] = (outer_map[outer] << 16) | (inner_maps[outer][v & 0xFFFF]); + } + else + output_map[gid] = 0; /* Map unused glyph to outer/inner=0/0 */ + } + } + + unsigned int get_inner_bit_count () const { return inner_bit_count; } + unsigned int get_width () const { return ((outer_bit_count + inner_bit_count + 7) / 8); } + unsigned int get_map_count () const { return map_count; } + + unsigned int get_size () const + { return (map_count? (DeltaSetIndexMap::min_size + get_width () * map_count): 0); } + + bool is_identity () const { return get_output_map ().length == 0; } + hb_array_t<const unsigned int> get_output_map () const { return output_map.as_array (); } + + protected: + unsigned int map_count; + hb_vector_t<unsigned int> max_inners; + unsigned int outer_bit_count; + unsigned int inner_bit_count; + hb_vector_t<unsigned int> output_map; +}; + +struct hvarvvar_subset_plan_t +{ + hvarvvar_subset_plan_t() : inner_maps (), index_map_plans () {} + ~hvarvvar_subset_plan_t() { fini (); } + + void init (const hb_array_t<const DeltaSetIndexMap *> &index_maps, + const VariationStore &_var_store, + const hb_subset_plan_t *plan) + { + index_map_plans.resize (index_maps.length); + + var_store = &_var_store; + inner_sets.resize (var_store->get_sub_table_count ()); + for (unsigned int i = 0; i < inner_sets.length; i++) + inner_sets[i] = hb_set_create (); + adv_set = hb_set_create (); + + inner_maps.resize (var_store->get_sub_table_count ()); + + for (unsigned int i = 0; i < inner_maps.length; i++) + inner_maps[i].init (); + + if (unlikely (!index_map_plans.length || !inner_sets.length || !inner_maps.length)) return; + + bool retain_adv_map = false; + index_map_plans[0].init (*index_maps[0], outer_map, inner_sets, plan); + if (index_maps[0] == &Null (DeltaSetIndexMap)) + { + retain_adv_map = plan->retain_gids; + outer_map.add (0); + for (hb_codepoint_t gid = 0; gid < plan->num_output_glyphs (); gid++) + { + hb_codepoint_t old_gid; + if (plan->old_gid_for_new_gid (gid, &old_gid)) + inner_sets[0]->add (old_gid); + } + hb_set_union (adv_set, inner_sets[0]); + } + + for (unsigned int i = 1; i < index_maps.length; i++) + index_map_plans[i].init (*index_maps[i], outer_map, inner_sets, plan); + + outer_map.sort (); + + if (retain_adv_map) + { + for (hb_codepoint_t gid = 0; gid < plan->num_output_glyphs (); gid++) + if (inner_sets[0]->has (gid)) + inner_maps[0].add (gid); + else + inner_maps[0].skip (); + } + else + { + inner_maps[0].add_set (adv_set); + hb_set_subtract (inner_sets[0], adv_set); + inner_maps[0].add_set (inner_sets[0]); + } + + for (unsigned int i = 1; i < inner_maps.length; i++) + inner_maps[i].add_set (inner_sets[i]); + + for (unsigned int i = 0; i < index_maps.length; i++) + index_map_plans[i].remap (index_maps[i], outer_map, inner_maps, plan); + } + + void fini () + { + for (unsigned int i = 0; i < inner_sets.length; i++) + hb_set_destroy (inner_sets[i]); + hb_set_destroy (adv_set); + inner_maps.fini_deep (); + index_map_plans.fini_deep (); + } + + 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; + + protected: + hb_vector_t<hb_set_t *> inner_sets; + hb_set_t *adv_set; +}; /* * HVAR -- Horizontal Metrics Variations @@ -114,7 +354,59 @@ struct HVARVVAR rsbMap.sanitize (c, this)); } - float get_advance_var (hb_font_t *font, hb_codepoint_t glyph) const + void listup_index_maps (hb_vector_t<const DeltaSetIndexMap *> &index_maps) const + { + index_maps.push (&(this+advMap)); + index_maps.push (&(this+lsbMap)); + index_maps.push (&(this+rsbMap)); + } + + bool serialize_index_maps (hb_serialize_context_t *c, + const hb_array_t<index_map_subset_plan_t> &im_plans) + { + TRACE_SERIALIZE (this); + if (im_plans[index_map_subset_plan_t::ADV_INDEX].is_identity ()) + advMap = 0; + else if (unlikely (!advMap.serialize (c, this).serialize (c, im_plans[index_map_subset_plan_t::ADV_INDEX]))) + return_trace (false); + if (im_plans[index_map_subset_plan_t::LSB_INDEX].is_identity ()) + lsbMap = 0; + else if (unlikely (!lsbMap.serialize (c, this).serialize (c, im_plans[index_map_subset_plan_t::LSB_INDEX]))) + return_trace (false); + if (im_plans[index_map_subset_plan_t::RSB_INDEX].is_identity ()) + rsbMap = 0; + else if (unlikely (!rsbMap.serialize (c, this).serialize (c, im_plans[index_map_subset_plan_t::RSB_INDEX]))) + return_trace (false); + + return_trace (true); + } + + template <typename T> + bool _subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + hvarvvar_subset_plan_t hvar_plan; + hb_vector_t<const DeltaSetIndexMap *> + index_maps; + + ((T*)this)->listup_index_maps (index_maps); + hvar_plan.init (index_maps.as_array (), this+varStore, c->plan); + + T *out = c->serializer->allocate_min<T> (); + if (unlikely (!out)) return_trace (false); + + out->version.major = 1; + out->version.minor = 0; + + if (unlikely (!out->varStore.serialize (c->serializer, out) + .serialize (c->serializer, hvar_plan.var_store, hvar_plan.inner_maps.as_array ()))) + return_trace (false); + + return_trace (out->T::serialize_index_maps (c->serializer, + hvar_plan.index_map_plans.as_array ())); + } + + float get_advance_var (hb_codepoint_t glyph, hb_font_t *font) const { unsigned int varidx = (this+advMap).map (glyph); return (this+varStore).get_delta (varidx, font->coords, font->num_coords); @@ -148,6 +440,7 @@ struct HVARVVAR struct HVAR : HVARVVAR { static constexpr hb_tag_t tableTag = HB_OT_TAG_HVAR; + bool subset (hb_subset_context_t *c) const { return HVARVVAR::_subset<HVAR> (c); } }; struct VVAR : HVARVVAR { static constexpr hb_tag_t tableTag = HB_OT_TAG_VVAR; @@ -159,6 +452,28 @@ struct VVAR : HVARVVAR { vorgMap.sanitize (c, this)); } + void listup_index_maps (hb_vector_t<const DeltaSetIndexMap *> &index_maps) const + { + HVARVVAR::listup_index_maps (index_maps); + index_maps.push (&(this+vorgMap)); + } + + bool serialize_index_maps (hb_serialize_context_t *c, + const hb_array_t<index_map_subset_plan_t> &im_plans) + { + TRACE_SERIALIZE (this); + if (unlikely (!HVARVVAR::serialize_index_maps (c, im_plans))) + return_trace (false); + if (!im_plans[index_map_subset_plan_t::VORG_INDEX].get_map_count ()) + vorgMap = 0; + else if (unlikely (!vorgMap.serialize (c, this).serialize (c, im_plans[index_map_subset_plan_t::VORG_INDEX]))) + return_trace (false); + + return_trace (true); + } + + bool subset (hb_subset_context_t *c) const { return HVARVVAR::_subset<VVAR> (c); } + protected: LOffsetTo<DeltaSetIndexMap> vorgMap; /* Offset to vertical-origin var-idx mapping. */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-mvar-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-mvar-table.hh index 5a9d2afb7c..1b7fad9cec 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-mvar-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-mvar-table.hh @@ -77,7 +77,9 @@ struct MVAR const int *coords, unsigned int coord_count) const { const VariationValueRecord *record; - record = (VariationValueRecord *) hb_bsearch (&tag, valuesZ.arrayZ, + record = (VariationValueRecord *) hb_bsearch (tag, + (const VariationValueRecord *) + (const HBUINT8 *) valuesZ, valueRecordCount, valueRecordSize, tag_compare); if (!record) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-var.cc index 6b8b09b6ba..6b42b45cd9 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var.cc @@ -52,11 +52,11 @@ /** * hb_ot_var_has_data: - * @face: #hb_face_t to test + * @face: The #hb_face_t to work on * - * This function allows to verify the presence of OpenType variation data on the face. + * Tests whether a face includes any OpenType variation data in the `fvar` table. * - * Return value: true if face has a `fvar' table and false otherwise + * Return value: %true if data found, %false otherwise * * Since: 1.4.2 **/ @@ -68,6 +68,11 @@ hb_ot_var_has_data (hb_face_t *face) /** * hb_ot_var_get_axis_count: + * @face: The #hb_face_t to work on + * + * Fetches the number of OpenType variation axes included in the face. + * + * Return value: the number of variation axes defined * * Since: 1.4.2 **/ @@ -80,9 +85,17 @@ hb_ot_var_get_axis_count (hb_face_t *face) #ifndef HB_DISABLE_DEPRECATED /** * hb_ot_var_get_axes: + * @face: #hb_face_t to work upon + * @start_offset: offset of the first lookup to retrieve + * @axes_count: (inout) (optional): Input = the maximum number of variation axes to return; + * Output = the actual number of variation axes returned (may be zero) + * @axes_array: (out caller-allocates) (array length=axes_count): The array of variation axes found + * + * Fetches a list of all variation axes in the specified face. The list returned will begin + * at the offset provided. * * Since: 1.4.2 - * Deprecated: 2.2.0 + * Deprecated: 2.2.0: use hb_ot_var_get_axis_infos() instead **/ unsigned int hb_ot_var_get_axes (hb_face_t *face, @@ -95,9 +108,16 @@ hb_ot_var_get_axes (hb_face_t *face, /** * hb_ot_var_find_axis: + * @face: #hb_face_t to work upon + * @axis_tag: The #hb_tag_t of the variation axis to query + * @axis_index: The index of the variation axis + * @axis_info: (out): The #hb_ot_var_axis_info_t of the axis tag queried + * + * Fetches the variation-axis information corresponding to the specified axis tag + * in the specified face. * * Since: 1.4.2 - * Deprecated: 2.2.0 + * Deprecated: 2.2.0 - use hb_ot_var_find_axis_info() instead **/ hb_bool_t hb_ot_var_find_axis (hb_face_t *face, @@ -111,6 +131,16 @@ hb_ot_var_find_axis (hb_face_t *face, /** * hb_ot_var_get_axis_infos: + * @face: #hb_face_t to work upon + * @start_offset: offset of the first lookup to retrieve + * @axes_count: (inout) (optional): Input = the maximum number of variation axes to return; + * Output = the actual number of variation axes returned (may be zero) + * @axes_array: (out caller-allocates) (array length=axes_count): The array of variation axes found + * + * Fetches a list of all variation axes in the specified face. The list returned will begin + * at the offset provided. + * + * Return value: the number of variation axes in the face * * Since: 2.2.0 **/ @@ -125,6 +155,14 @@ hb_ot_var_get_axis_infos (hb_face_t *face, /** * hb_ot_var_find_axis_info: + * @face: #hb_face_t to work upon + * @axis_tag: The #hb_tag_t of the variation axis to query + * @axis_info: (out): The #hb_ot_var_axis_info_t of the axis tag queried + * + * Fetches the variation-axis information corresponding to the specified axis tag + * in the specified face. + * + * Return value: %true if data found, %false otherwise * * Since: 2.2.0 **/ @@ -141,12 +179,34 @@ hb_ot_var_find_axis_info (hb_face_t *face, * Named instances. */ +/** + * hb_ot_var_get_named_instance_count: + * @face: The #hb_face_t to work on + * + * Fetches the number of named instances included in the face. + * + * Return value: the number of named instances defined + * + * Since: 2.2.0 + **/ unsigned int hb_ot_var_get_named_instance_count (hb_face_t *face) { return face->table.fvar->get_instance_count (); } +/** + * hb_ot_var_named_instance_get_subfamily_name_id: + * @face: The #hb_face_t to work on + * @instance_index: The index of the named instance to query + * + * Fetches the `name` table Name ID that provides display names for + * the "Subfamily name" defined for the given named instance in the face. + * + * Return value: the Name ID found for the Subfamily name + * + * Since: 2.2.0 + **/ hb_ot_name_id_t hb_ot_var_named_instance_get_subfamily_name_id (hb_face_t *face, unsigned int instance_index) @@ -154,6 +214,18 @@ hb_ot_var_named_instance_get_subfamily_name_id (hb_face_t *face, return face->table.fvar->get_instance_subfamily_name_id (instance_index); } +/** + * hb_ot_var_named_instance_get_postscript_name_id: + * @face: The #hb_face_t to work on + * @instance_index: The index of the named instance to query + * + * Fetches the `name` table Name ID that provides display names for + * the "PostScript name" defined for the given named instance in the face. + * + * Return value: the Name ID found for the PostScript name + * + * Since: 2.2.0 + **/ hb_ot_name_id_t hb_ot_var_named_instance_get_postscript_name_id (hb_face_t *face, unsigned int instance_index) @@ -161,6 +233,21 @@ hb_ot_var_named_instance_get_postscript_name_id (hb_face_t *face, return face->table.fvar->get_instance_postscript_name_id (instance_index); } +/** + * hb_ot_var_named_instance_get_design_coords: + * @face: The #hb_face_t to work on + * @instance_index: The index of the named instance to query + * @coords_length: (inout) (optional): Input = the maximum number of coordinates to return; + * Output = the actual number of coordinates returned (may be zero) + * @coords: (out) (array length=coords_length): The array of coordinates found for the query + * + * Fetches the design-space coordinates corresponding to the given + * named instance in the face. + * + * Return value: the number of variation axes in the face + * + * Since: 2.2.0 + **/ unsigned int hb_ot_var_named_instance_get_design_coords (hb_face_t *face, unsigned int instance_index, @@ -173,6 +260,13 @@ hb_ot_var_named_instance_get_design_coords (hb_face_t *face, /** * hb_ot_var_normalize_variations: + * @face: The #hb_face_t to work on + * @variations: The array of variations to normalize + * @variations_length: The number of variations to normalize + * @coords: (out) (array length=coords_length): The array of normalized coordinates + * @coords_length: The length of the coordinate array + * + * Normalizes all of the coordinates in the given list of variation axes. * * Since: 1.4.2 **/ @@ -200,6 +294,17 @@ hb_ot_var_normalize_variations (hb_face_t *face, /** * hb_ot_var_normalize_coords: + * @face: The #hb_face_t to work on + * @coords_length: The length of the coordinate array + * @design_coords: The design-space coordinates to normalize + * @normalized_coords: (out): The normalized coordinates + * + * Normalizes the given design-space coordinates. The minimum and maximum + * values for the axis are mapped to the interval [-1,1], with the default + * axis value mapped to 0. + * + * Any additional scaling defined in the face's `avar` table is also + * applied, as described at https://docs.microsoft.com/en-us/typography/opentype/spec/avar * * Since: 1.4.2 **/ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-var.h index df89bc5a23..ce201d3b4f 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var.h @@ -24,7 +24,7 @@ * Red Hat Author(s): Behdad Esfahbod */ -#ifndef HB_OT_H_IN +#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb-ot.h> instead." #endif @@ -35,11 +35,40 @@ HB_BEGIN_DECLS - +/** + * HB_OT_TAG_VAR_AXIS_ITALIC: + * + * Registered tag for the roman/italic axis. + */ #define HB_OT_TAG_VAR_AXIS_ITALIC HB_TAG('i','t','a','l') + +/** + * HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE: + * + * Registered tag for the optical-size axis. + * <note>Note: The optical-size axis supersedes the OpenType `size` feature.</note> + */ #define HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE HB_TAG('o','p','s','z') + +/** + * HB_OT_TAG_VAR_AXIS_SLANT: + * + * Registered tag for the slant axis + */ #define HB_OT_TAG_VAR_AXIS_SLANT HB_TAG('s','l','n','t') + +/** + * HB_OT_TAG_VAR_AXIS_WIDTH: + * + * Registered tag for the width axis. + */ #define HB_OT_TAG_VAR_AXIS_WIDTH HB_TAG('w','d','t','h') + +/** + * HB_OT_TAG_VAR_AXIS_WEIGHT: + * + * Registered tag for the weight axis. + */ #define HB_OT_TAG_VAR_AXIS_WEIGHT HB_TAG('w','g','h','t') @@ -63,21 +92,37 @@ hb_ot_var_get_axis_count (hb_face_t *face); * hb_ot_var_axis_flags_t: * @HB_OT_VAR_AXIS_FLAG_HIDDEN: The axis should not be exposed directly in user interfaces. * + * Flags for #hb_ot_var_axis_info_t. + * * Since: 2.2.0 */ typedef enum { /*< flags >*/ HB_OT_VAR_AXIS_FLAG_HIDDEN = 0x00000001u, + /*< private >*/ _HB_OT_VAR_AXIS_FLAG_MAX_VALUE= HB_TAG_MAX_SIGNED /*< skip >*/ } hb_ot_var_axis_flags_t; /** * hb_ot_var_axis_info_t: + * @axis_index: Index of the axis in the variation-axis array + * @tag: The #hb_tag_t tag identifying the design variation of the axis + * @name_id: The `name` table Name ID that provides display names for the axis + * @flags: The #hb_ot_var_axis_flags_t flags for the axis + * @min_value: The mininum value on the variation axis that the font covers + * @default_value: The position on the variation axis corresponding to the font's defaults + * @max_value: The maximum value on the variation axis that the font covers + * + * Data type for holding variation-axis values. + * + * The minimum, default, and maximum values are in un-normalized, user scales. + * + * <note>Note: at present, the only flag defined for @flags is + * #HB_OT_VAR_AXIS_FLAG_HIDDEN.</note> * * Since: 2.2.0 */ -typedef struct hb_ot_var_axis_info_t -{ +typedef struct hb_ot_var_axis_info_t { unsigned int axis_index; hb_tag_t tag; hb_ot_name_id_t name_id; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-vorg-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-vorg-table.hh index a4d6b0622b..c6803200f9 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-vorg-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-vorg-table.hh @@ -84,7 +84,7 @@ struct VORG this->defaultVertOriginY = defaultVertOriginY; this->vertYOrigins.len = it.len (); - for (const auto _ : it) c->copy (_); + c->copy_all (it); } bool subset (hb_subset_context_t *c) const @@ -122,10 +122,11 @@ struct VORG } protected: - FixedVersion<> version; /* Version of VORG table. Set to 0x00010000u. */ - FWORD defaultVertOriginY; /* The default vertical origin. */ + FixedVersion<>version; /* Version of VORG table. Set to 0x00010000u. */ + FWORD defaultVertOriginY; + /* The default vertical origin. */ SortedArrayOf<VertOriginMetric> - vertYOrigins; /* The array of vertical origins. */ + vertYOrigins; /* The array of vertical origins. */ public: DEFINE_SIZE_ARRAY(8, vertYOrigins); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-pool.hh b/src/3rdparty/harfbuzz-ng/src/hb-pool.hh index 83875dbe13..dcf0faf2a9 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-pool.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-pool.hh @@ -41,9 +41,7 @@ struct hb_pool_t { next = nullptr; - + hb_iter (chunks) - | hb_apply ([] (chunk_t *_) { ::free (_); }) - ; + for (chunk_t *_ : chunks) ::free (_); chunks.fini (); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-sanitize.hh b/src/3rdparty/harfbuzz-ng/src/hb-sanitize.hh index 7859c6a2c6..1675e8448a 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-sanitize.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-sanitize.hh @@ -73,7 +73,7 @@ * === The sanitize() contract === * * The sanitize() method of each object type shall return true if it's safe to - * call other methods of the object, and false otherwise. + * call other methods of the object, and %false otherwise. * * Note that what sanitize() checks for might align with what the specification * describes as valid table data, but does not have to be. In particular, we @@ -113,14 +113,16 @@ #ifndef HB_SANITIZE_MAX_OPS_MAX #define HB_SANITIZE_MAX_OPS_MAX 0x3FFFFFFF #endif +#ifndef HB_SANITIZE_MAX_SUBTABLES +#define HB_SANITIZE_MAX_SUBTABLES 0x4000 +#endif struct hb_sanitize_context_t : hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE> { hb_sanitize_context_t () : - debug_depth (0), start (nullptr), end (nullptr), - max_ops (0), + max_ops (0), max_subtables (0), writable (false), edit_count (0), blob (nullptr), num_glyphs (65536), @@ -134,6 +136,12 @@ struct hb_sanitize_context_t : static return_t no_dispatch_return_value () { return false; } bool stop_sublookup_iteration (const return_t r) const { return !r; } + bool visit_subtables (unsigned count) + { + max_subtables += count; + return max_subtables < HB_SANITIZE_MAX_SUBTABLES; + } + private: template <typename T, typename ...Ts> auto _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN @@ -189,8 +197,12 @@ struct hb_sanitize_context_t : void start_processing () { reset_object (); - this->max_ops = hb_max ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR, - (unsigned) HB_SANITIZE_MAX_OPS_MIN); + if (unlikely (hb_unsigned_mul_overflows (this->end - this->start, HB_SANITIZE_MAX_OPS_FACTOR))) + this->max_ops = HB_SANITIZE_MAX_OPS_MAX; + else + this->max_ops = hb_clamp ((unsigned) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR, + (unsigned) HB_SANITIZE_MAX_OPS_MIN, + (unsigned) HB_SANITIZE_MAX_OPS_MAX); this->edit_count = 0; this->debug_depth = 0; @@ -374,9 +386,8 @@ struct hb_sanitize_context_t : return sanitize_blob<Type> (hb_face_reference_table (face, tableTag)); } - mutable unsigned int debug_depth; const char *start, *end; - mutable int max_ops; + mutable int max_ops, max_subtables; private: bool writable; unsigned int edit_count; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-serialize.hh b/src/3rdparty/harfbuzz-ng/src/hb-serialize.hh index 4c674b1b1a..fe29bdf96e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-serialize.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-serialize.hh @@ -45,12 +45,13 @@ struct hb_serialize_context_t { typedef unsigned objidx_t; - struct range_t - { - char *head, *tail; - }; + enum whence_t { + Head, /* Relative to the current object head (default). */ + Tail, /* Relative to the current object tail after packed. */ + Absolute /* Absolute: from the start of the serialize buffer. */ + }; - struct object_t : range_t + struct object_t { void fini () { links.fini (); } @@ -70,17 +71,29 @@ struct hb_serialize_context_t struct link_t { bool is_wide: 1; - unsigned position : 31; + bool is_signed: 1; + unsigned whence: 2; + unsigned position: 28; unsigned bias; objidx_t objidx; }; + char *head; + char *tail; hb_vector_t<link_t> links; object_t *next; }; - range_t snapshot () { range_t s = {head, tail} ; return s; } + struct snapshot_t + { + char *head; + char *tail; + object_t *current; // Just for sanity check + unsigned num_links; + }; + snapshot_t snapshot () + { return snapshot_t { head, tail, current, current->links.length }; } hb_serialize_context_t (void *start_, unsigned int size) : start ((char *) start_), @@ -123,7 +136,7 @@ struct hb_serialize_context_t template <typename T1, typename T2> bool check_equal (T1 &&v1, T2 &&v2) - { return check_success (v1 == v2); } + { return check_success ((long long) v1 == (long long) v2); } template <typename T1, typename T2> bool check_assign (T1 &v1, T2 &&v2) @@ -159,6 +172,8 @@ struct hb_serialize_context_t propagate_error (packed, packed_map); if (unlikely (!current)) return; + if (unlikely (in_error())) return; + assert (!current->next); /* Only "pack" if there exist other objects... Otherwise, don't bother. @@ -166,7 +181,7 @@ struct hb_serialize_context_t if (packed.length <= 1) return; - pop_pack (); + pop_pack (false); resolve_links (); } @@ -174,6 +189,8 @@ struct hb_serialize_context_t template <typename Type = void> Type *push () { + if (unlikely (in_error ())) return start_embed<Type> (); + object_t *obj = object_pool.alloc (); if (unlikely (!obj)) check_success (false); @@ -190,15 +207,24 @@ struct hb_serialize_context_t { object_t *obj = current; if (unlikely (!obj)) return; + if (unlikely (in_error())) return; + current = current->next; - revert (*obj); + revert (obj->head, obj->tail); obj->fini (); object_pool.free (obj); } - objidx_t pop_pack () + + /* Set share to false when an object is unlikely sharable with others + * so not worth an attempt, or a contiguous table is serialized as + * multiple consecutive objects in the reverse order so can't be shared. + */ + objidx_t pop_pack (bool share=true) { object_t *obj = current; if (unlikely (!obj)) return 0; + if (unlikely (in_error())) return 0; + current = current->next; obj->tail = head; obj->next = nullptr; @@ -211,11 +237,15 @@ struct hb_serialize_context_t return 0; } - objidx_t objidx = packed_map.get (obj); - if (objidx) + objidx_t objidx; + if (share) { - obj->fini (); - return objidx; + objidx = packed_map.get (obj); + if (objidx) + { + obj->fini (); + return objidx; + } } tail -= len; @@ -226,27 +256,45 @@ struct hb_serialize_context_t packed.push (obj); - if (unlikely (packed.in_error ())) + if (unlikely (!propagate_error (packed))) + { + /* Obj wasn't successfully added to packed, so clean it up otherwise its + * links will be leaked. When we use constructor/destructors properly, we + * can remove these. */ + obj->fini (); return 0; + } objidx = packed.length - 1; - packed_map.set (obj, objidx); + if (share) packed_map.set (obj, objidx); + propagate_error (packed_map); return objidx; } - void revert (range_t snap) + void revert (snapshot_t snap) { - assert (snap.head <= head); - assert (tail <= snap.tail); - head = snap.head; - tail = snap.tail; + if (unlikely (in_error ())) return; + assert (snap.current == current); + current->links.shrink (snap.num_links); + revert (snap.head, snap.tail); + } + + void revert (char *snap_head, + char *snap_tail) + { + if (unlikely (in_error ())) return; + assert (snap_head <= head); + assert (tail <= snap_tail); + head = snap_head; + tail = snap_tail; discard_stale_objects (); } void discard_stale_objects () { + if (unlikely (in_error ())) return; while (packed.length > 1 && packed.tail ()->head < tail) { @@ -260,9 +308,12 @@ struct hb_serialize_context_t } template <typename T> - void add_link (T &ofs, objidx_t objidx, const void *base = nullptr) + void add_link (T &ofs, objidx_t objidx, + whence_t whence = Head, + unsigned bias = 0) { static_assert (sizeof (T) == 2 || sizeof (T) == 4, ""); + if (unlikely (in_error ())) return; if (!objidx) return; @@ -270,18 +321,25 @@ struct hb_serialize_context_t assert (current); assert (current->head <= (const char *) &ofs); - if (!base) - base = current->head; - else - assert (current->head <= (const char *) base); - auto& link = *current->links.push (); + link.is_wide = sizeof (T) == 4; + link.is_signed = hb_is_signed (hb_unwrap_type (T)); + link.whence = (unsigned) whence; link.position = (const char *) &ofs - current->head; - link.bias = (const char *) base - current->head; + link.bias = bias; link.objidx = objidx; } + unsigned to_bias (const void *base) const + { + if (unlikely (in_error ())) return 0; + if (!base) return 0; + assert (current); + assert (current->head <= (const char *) base); + return (const char *) base - current->head; + } + void resolve_links () { if (unlikely (in_error ())) return; @@ -293,25 +351,38 @@ struct hb_serialize_context_t for (const object_t::link_t &link : parent->links) { const object_t* child = packed[link.objidx]; - assert (link.bias <= (size_t) (parent->tail - parent->head)); - unsigned offset = (child->head - parent->head) - link.bias; + if (unlikely (!child)) { err_other_error(); return; } + unsigned offset = 0; + switch ((whence_t) link.whence) { + case Head: offset = child->head - parent->head; break; + case Tail: offset = child->head - parent->tail; break; + case Absolute: offset = (head - start) + (child->head - tail); break; + } - if (link.is_wide) + assert (offset >= link.bias); + offset -= link.bias; + if (link.is_signed) { - auto &off = * ((BEInt<uint32_t, 4> *) (parent->head + link.position)); - assert (0 == off); - check_assign (off, offset); + if (link.is_wide) + assign_offset<int32_t> (parent, link, offset); + else + assign_offset<int16_t> (parent, link, offset); } else { - auto &off = * ((BEInt<uint16_t, 2> *) (parent->head + link.position)); - assert (0 == off); - check_assign (off, offset); + if (link.is_wide) + assign_offset<uint32_t> (parent, link, offset); + else + assign_offset<uint16_t> (parent, link, offset); } } } - unsigned int length () const { return this->head - current->head; } + unsigned int length () const + { + if (unlikely (!current)) return 0; + return this->head - current->head; + } void align (unsigned int alignment) { @@ -387,12 +458,20 @@ struct hb_serialize_context_t Type *copy (const Type *src, Ts&&... ds) { return copy (*src, hb_forward<Ts> (ds)...); } + template<typename Iterator, + hb_requires (hb_is_iterator (Iterator)), + typename ...Ts> + void copy_all (Iterator it, Ts&&... ds) + { for (decltype (*it) _ : it) copy (_, hb_forward<Ts> (ds)...); } + template <typename Type> hb_serialize_context_t& operator << (const Type &obj) & { embed (obj); return *this; } template <typename Type> Type *extend_size (Type *obj, unsigned int size) { + if (unlikely (in_error ())) return nullptr; + assert (this->start <= (char *) obj); assert ((char *) obj <= this->head); assert ((char *) obj + size >= this->head); @@ -441,6 +520,15 @@ struct hb_serialize_context_t (char *) b.arrayZ, free); } + private: + template <typename T> + void assign_offset (const object_t* parent, const object_t::link_t &link, unsigned offset) + { + auto &off = * ((BEInt<T> *) (parent->head + link.position)); + assert (0 == off); + check_assign (off, offset); + } + public: /* TODO Make private. */ char *start, *head, *tail, *end; unsigned int debug_depth; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set.cc b/src/3rdparty/harfbuzz-ng/src/hb-set.cc index 10638a7e6d..86bf70034c 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-set.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-set.cc @@ -30,11 +30,11 @@ /** * SECTION:hb-set * @title: hb-set - * @short_description: Object representing a set of integers + * @short_description: Objects representing a set of integers * @include: hb.h * * Set objects represent a mathematical set of integer values. They are - * used in non-shaping API to query certain set of characters or glyphs, + * used in non-shaping APIs to query certain sets of characters or glyphs, * or other integer values. **/ @@ -42,7 +42,9 @@ /** * hb_set_create: (Xconstructor) * - * Return value: (transfer full): + * Creates a new, initially empty set. + * + * Return value: (transfer full): The new #hb_set_t * * Since: 0.9.2 **/ @@ -62,21 +64,25 @@ hb_set_create () /** * hb_set_get_empty: * - * Return value: (transfer full): + * Fetches the singleton empty #hb_set_t. + * + * Return value: (transfer full): The empty #hb_set_t * * Since: 0.9.2 **/ hb_set_t * hb_set_get_empty () { - return const_cast<hb_set_t *> (&Null(hb_set_t)); + return const_cast<hb_set_t *> (&Null (hb_set_t)); } /** * hb_set_reference: (skip) - * @set: a set. + * @set: A set * - * Return value: (transfer full): + * Increases the reference count on a set. + * + * Return value: (transfer full): The set * * Since: 0.9.2 **/ @@ -88,7 +94,11 @@ hb_set_reference (hb_set_t *set) /** * hb_set_destroy: (skip) - * @set: a set. + * @set: A set + * + * Decreases the reference count on a set. When + * the reference count reaches zero, the set is + * destroyed, freeing all memory. * * Since: 0.9.2 **/ @@ -104,13 +114,15 @@ hb_set_destroy (hb_set_t *set) /** * hb_set_set_user_data: (skip) - * @set: a set. - * @key: - * @data: - * @destroy: - * @replace: + * @set: A set + * @key: The user-data key to set + * @data: A pointer to the user data to set + * @destroy: (nullable): A callback to call when @data is not needed anymore + * @replace: Whether to replace an existing data with the same key * - * Return value: + * Attaches a user-data key/data pair to the specified set. + * + * Return value: %true if success, %false otherwise * * Since: 0.9.2 **/ @@ -126,10 +138,13 @@ hb_set_set_user_data (hb_set_t *set, /** * hb_set_get_user_data: (skip) - * @set: a set. - * @key: + * @set: A set + * @key: The user-data key to query * - * Return value: (transfer none): + * Fetches the user data associated with the specified key, + * attached to the specified set. + * + * Return value: (transfer none): A pointer to the user data * * Since: 0.9.2 **/ @@ -143,11 +158,11 @@ hb_set_get_user_data (hb_set_t *set, /** * hb_set_allocation_successful: - * @set: a set. + * @set: A set * - * + * Tests whether memory allocation for a set was successful. * - * Return value: + * Return value: %true if allocation succeeded, %false otherwise * * Since: 0.9.2 **/ @@ -159,15 +174,18 @@ hb_set_allocation_successful (const hb_set_t *set) /** * hb_set_clear: - * @set: a set. + * @set: A set * - * + * Clears out the contents of a set. * * Since: 0.9.2 **/ void hb_set_clear (hb_set_t *set) { + if (unlikely (hb_object_is_immutable (set))) + return; + set->clear (); } @@ -175,9 +193,9 @@ hb_set_clear (hb_set_t *set) * hb_set_is_empty: * @set: a set. * - * + * Tests whether a set is empty (contains no elements). * - * Return value: + * Return value: %true if @set is empty * * Since: 0.9.7 **/ @@ -189,12 +207,12 @@ hb_set_is_empty (const hb_set_t *set) /** * hb_set_has: - * @set: a set. - * @codepoint: + * @set: A set + * @codepoint: The element to query * - * + * Tests whether @codepoint belongs to @set. * - * Return value: + * Return value: %true if @codepoint is in @set, %false otherwise * * Since: 0.9.2 **/ @@ -207,10 +225,10 @@ hb_set_has (const hb_set_t *set, /** * hb_set_add: - * @set: a set. - * @codepoint: + * @set: A set + * @codepoint: The element to add to @set * - * + * Adds @codepoint to @set. * * Since: 0.9.2 **/ @@ -223,11 +241,12 @@ hb_set_add (hb_set_t *set, /** * hb_set_add_range: - * @set: a set. - * @first: - * @last: + * @set: A set + * @first: The first element to add to @set + * @last: The final element to add to @set * - * + * Adds all of the elements from @first to @last + * (inclusive) to @set. * * Since: 0.9.7 **/ @@ -241,10 +260,10 @@ hb_set_add_range (hb_set_t *set, /** * hb_set_del: - * @set: a set. - * @codepoint: + * @set: A set + * @codepoint: Removes @codepoint from @set * - * + * Removes @codepoint from @set. * * Since: 0.9.2 **/ @@ -257,11 +276,12 @@ hb_set_del (hb_set_t *set, /** * hb_set_del_range: - * @set: a set. - * @first: - * @last: + * @set: A set + * @first: The first element to remove from @set + * @last: The final element to remove from @set * - * + * Removes all of the elements from @first to @last + * (inclusive) from @set. * * Since: 0.9.7 **/ @@ -275,12 +295,13 @@ hb_set_del_range (hb_set_t *set, /** * hb_set_is_equal: - * @set: a set. - * @other: other set. + * @set: A set + * @other: Another set * - * + * Tests whether @set and @other are equal (contain the same + * elements). * - * Return value: %TRUE if the two sets are equal, %FALSE otherwise. + * Return value: %true if the two sets are equal, %false otherwise. * * Since: 0.9.7 **/ @@ -293,12 +314,12 @@ hb_set_is_equal (const hb_set_t *set, /** * hb_set_is_subset: - * @set: a set. - * @larger_set: other set. - * + * @set: A set + * @larger_set: Another set * + * Tests whether @set is a subset of @larger_set. * - * Return value: %TRUE if the @set is a subset of (or equal to) @larger_set, %FALSE otherwise. + * Return value: %true if the @set is a subset of (or equal to) @larger_set, %false otherwise. * * Since: 1.8.1 **/ @@ -311,10 +332,10 @@ hb_set_is_subset (const hb_set_t *set, /** * hb_set_set: - * @set: a set. - * @other: + * @set: A set + * @other: Another set * - * + * Makes the contents of @set equal to the contents of @other. * * Since: 0.9.2 **/ @@ -327,10 +348,10 @@ hb_set_set (hb_set_t *set, /** * hb_set_union: - * @set: a set. - * @other: + * @set: A set + * @other: Another set * - * + * Makes @set the union of @set and @other. * * Since: 0.9.2 **/ @@ -343,10 +364,10 @@ hb_set_union (hb_set_t *set, /** * hb_set_intersect: - * @set: a set. - * @other: + * @set: A set + * @other: Another set * - * + * Makes @set the intersection of @set and @other. * * Since: 0.9.2 **/ @@ -359,10 +380,10 @@ hb_set_intersect (hb_set_t *set, /** * hb_set_subtract: - * @set: a set. - * @other: + * @set: A set + * @other: Another set * - * + * Subtracts the contents of @other from @set. * * Since: 0.9.2 **/ @@ -375,10 +396,11 @@ hb_set_subtract (hb_set_t *set, /** * hb_set_symmetric_difference: - * @set: a set. - * @other: + * @set: A set + * @other: Another set * - * + * Makes @set the symmetric difference of @set + * and @other. * * Since: 0.9.2 **/ @@ -392,9 +414,9 @@ hb_set_symmetric_difference (hb_set_t *set, #ifndef HB_DISABLE_DEPRECATED /** * hb_set_invert: - * @set: a set. + * @set: A set * - * + * Inverts the contents of @set. * * Since: 0.9.10 * @@ -408,11 +430,11 @@ hb_set_invert (hb_set_t *set HB_UNUSED) /** * hb_set_get_population: - * @set: a set. + * @set: A set * - * Returns the number of numbers in the set. + * Returns the number of elements in the set. * - * Return value: set population. + * Return value: The population of @set * * Since: 0.9.7 **/ @@ -424,11 +446,11 @@ hb_set_get_population (const hb_set_t *set) /** * hb_set_get_min: - * @set: a set. + * @set: A set * - * Finds the minimum number in the set. + * Finds the smallest element in the set. * - * Return value: minimum of the set, or %HB_SET_VALUE_INVALID if set is empty. + * Return value: minimum of @set, or #HB_SET_VALUE_INVALID if @set is empty. * * Since: 0.9.7 **/ @@ -440,11 +462,11 @@ hb_set_get_min (const hb_set_t *set) /** * hb_set_get_max: - * @set: a set. + * @set: A set * - * Finds the maximum number in the set. + * Finds the largest element in the set. * - * Return value: minimum of the set, or %HB_SET_VALUE_INVALID if set is empty. + * Return value: maximum of @set, or #HB_SET_VALUE_INVALID if @set is empty. * * Since: 0.9.7 **/ @@ -456,14 +478,15 @@ hb_set_get_max (const hb_set_t *set) /** * hb_set_next: - * @set: a set. - * @codepoint: (inout): + * @set: A set + * @codepoint: (inout): Input = Code point to query + * Output = Code point retrieved * - * Gets the next number in @set that is greater than current value of @codepoint. + * Fetches the next element in @set that is greater than current value of @codepoint. * - * Set @codepoint to %HB_SET_VALUE_INVALID to get started. + * Set @codepoint to #HB_SET_VALUE_INVALID to get started. * - * Return value: whether there was a next value. + * Return value: %true if there was a next value, %false otherwise * * Since: 0.9.2 **/ @@ -476,14 +499,15 @@ hb_set_next (const hb_set_t *set, /** * hb_set_previous: - * @set: a set. - * @codepoint: (inout): + * @set: A set + * @codepoint: (inout): Input = Code point to query + * Output = Code point retrieved * - * Gets the previous number in @set that is lower than current value of @codepoint. + * Fetches the previous element in @set that is lower than current value of @codepoint. * - * Set @codepoint to %HB_SET_VALUE_INVALID to get started. + * Set @codepoint to #HB_SET_VALUE_INVALID to get started. * - * Return value: whether there was a previous value. + * Return value: %true if there was a previous value, %false otherwise * * Since: 1.8.0 **/ @@ -496,16 +520,17 @@ hb_set_previous (const hb_set_t *set, /** * hb_set_next_range: - * @set: a set. - * @first: (out): output first codepoint in the range. - * @last: (inout): input current last and output last codepoint in the range. + * @set: A set + * @first: (out): The first code point in the range + * @last: (inout): Input = The current last code point in the range + * Output = The last code point in the range * - * Gets the next consecutive range of numbers in @set that + * Fetches the next consecutive range of elements in @set that * are greater than current value of @last. * - * Set @last to %HB_SET_VALUE_INVALID to get started. + * Set @last to #HB_SET_VALUE_INVALID to get started. * - * Return value: whether there was a next range. + * Return value: %true if there was a next range, %false otherwise * * Since: 0.9.7 **/ @@ -519,16 +544,17 @@ hb_set_next_range (const hb_set_t *set, /** * hb_set_previous_range: - * @set: a set. - * @first: (inout): input current first and output first codepoint in the range. - * @last: (out): output last codepoint in the range. + * @set: A set + * @first: (inout): Input = The current first code point in the range + * Output = The first code point in the range + * @last: (out): The last code point in the range * - * Gets the previous consecutive range of numbers in @set that - * are less than current value of @first. + * Fetches the previous consecutive range of elements in @set that + * are greater than current value of @last. * - * Set @first to %HB_SET_VALUE_INVALID to get started. + * Set @first to #HB_SET_VALUE_INVALID to get started. * - * Return value: whether there was a previous range. + * Return value: %true if there was a previous range, %false otherwise * * Since: 1.8.0 **/ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set.h b/src/3rdparty/harfbuzz-ng/src/hb-set.h index ed0e05db2e..0ad27f4bbd 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-set.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-set.h @@ -24,7 +24,7 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_H_IN +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb.h> instead." #endif @@ -36,11 +36,24 @@ HB_BEGIN_DECLS -/* +/** + * HB_SET_VALUE_INVALID: + * + * Unset #hb_set_t value. + * * Since: 0.9.21 */ #define HB_SET_VALUE_INVALID ((hb_codepoint_t) -1) +/** + * hb_set_t: + * + * Data type for holding a set of integers. #hb_set_t's are + * used to gather and contain glyph IDs, Unicode code + * points, and various other collections of discrete + * values. + * + **/ typedef struct hb_set_t hb_set_t; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set.hh b/src/3rdparty/harfbuzz-ng/src/hb-set.hh index 36d11c0319..ae8b5eb10f 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-set.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-set.hh @@ -89,6 +89,23 @@ struct hb_set_t } } + void del_range (hb_codepoint_t a, hb_codepoint_t b) + { + elt_t *la = &elt (a); + elt_t *lb = &elt (b); + if (la == lb) + *la &= ~((mask (b) << 1) - mask(a)); + else + { + *la &= mask (a) - 1; + la++; + + memset (la, 0, (char *) lb - (char *) la); + + *lb &= ~((mask (b) << 1) - 1); + } + } + bool is_equal (const page_t *other) const { return 0 == hb_memcmp (&v, &other->v, sizeof (v)); @@ -135,7 +152,11 @@ struct hb_set_t unsigned int i = m / ELT_BITS; unsigned int j = m & ELT_MASK; - const elt_t vv = v[i] & ((elt_t (1) << (j + 1)) - 1); + /* Fancy mask to avoid shifting by elt_t bitsize, which is undefined. */ + const elt_t mask = j < 8 * sizeof (elt_t) - 1 ? + ((elt_t (1) << (j + 1)) - 1) : + (elt_t) -1; + const elt_t vv = v[i] & mask; const elt_t *p = &vv; while (true) { @@ -223,7 +244,7 @@ struct hb_set_t bool resize (unsigned int count) { - if (unlikely (!successful)) return false; + if (unlikely (count > pages.length && !successful)) return false; if (!pages.resize (count) || !page_map.resize (count)) { pages.resize (page_map.length); @@ -235,19 +256,14 @@ struct hb_set_t void reset () { - if (unlikely (hb_object_is_immutable (this))) - return; - clear (); successful = true; + clear (); } void clear () { - if (unlikely (hb_object_is_immutable (this))) - return; - population = 0; - page_map.resize (0); - pages.resize (0); + if (resize (0)) + population = 0; } bool is_empty () const { @@ -257,8 +273,9 @@ struct hb_set_t return false; return true; } + explicit operator bool () const { return !is_empty (); } - void dirty () { population = (unsigned int) -1; } + void dirty () { population = UINT_MAX; } void add (hb_codepoint_t g) { @@ -362,14 +379,62 @@ struct hb_set_t dirty (); page->del (g); } + + private: + void del_pages (int ds, int de) + { + if (ds <= de) + { + // Pre-allocate the workspace that compact() will need so we can bail on allocation failure + // before attempting to rewrite the page map. + hb_vector_t<unsigned> compact_workspace; + if (unlikely (!allocate_compact_workspace (compact_workspace))) return; + + unsigned int write_index = 0; + for (unsigned int i = 0; i < page_map.length; i++) + { + int m = (int) page_map[i].major; + if (m < ds || de < m) + page_map[write_index++] = page_map[i]; + } + compact (compact_workspace, write_index); + resize (write_index); + } + } + + + public: void del_range (hb_codepoint_t a, hb_codepoint_t b) { /* TODO perform op even if !successful. */ - /* TODO Optimize, like add_range(). */ if (unlikely (!successful)) return; - for (unsigned int i = a; i < b + 1; i++) - del (i); + if (unlikely (a > b || a == INVALID || b == INVALID)) return; + dirty (); + unsigned int ma = get_major (a); + unsigned int mb = get_major (b); + /* Delete pages from ds through de if ds <= de. */ + int ds = (a == major_start (ma))? (int) ma: (int) (ma + 1); + int de = (b + 1 == major_start (mb + 1))? (int) mb: ((int) mb - 1); + if (ds > de || (int) ma < ds) + { + page_t *page = page_for (a); + if (page) + { + if (ma == mb) + page->del_range (a, b); + else + page->del_range (a, major_start (ma + 1) - 1); + } + } + if (de < (int) mb && ma != mb) + { + page_t *page = page_for (b); + if (page) + page->del_range (major_start (mb), b); + } + del_pages (ds, de); } + bool get (hb_codepoint_t g) const { const page_t *page = page_for (g); @@ -387,7 +452,10 @@ struct hb_set_t bool operator () (hb_codepoint_t k) const { return has (k); } /* Sink interface. */ - hb_set_t& operator << (hb_codepoint_t v) { add (v); return *this; } + hb_set_t& operator << (hb_codepoint_t v) + { add (v); return *this; } + hb_set_t& operator << (const hb_pair_t<hb_codepoint_t, hb_codepoint_t>& range) + { add_range (range.first, range.second); return *this; } bool intersects (hb_codepoint_t first, hb_codepoint_t last) const { @@ -446,9 +514,57 @@ struct hb_set_t return true; } + bool allocate_compact_workspace(hb_vector_t<unsigned>& workspace) + { + if (unlikely(!workspace.resize (pages.length))) + { + successful = false; + return false; + } + + return true; + } + + + /* + * workspace should be a pre-sized vector allocated to hold at exactly pages.length + * elements. + */ + void compact (hb_vector_t<unsigned>& workspace, + unsigned int length) + { + assert(workspace.length == pages.length); + hb_vector_t<unsigned>& old_index_to_page_map_index = workspace; + + hb_fill (old_index_to_page_map_index.writer(), 0xFFFFFFFF); + /* TODO(iter) Rewrite as dagger? */ + for (unsigned i = 0; i < length; i++) + old_index_to_page_map_index[page_map[i].index] = i; + + compact_pages (old_index_to_page_map_index); + } + + void compact_pages (const hb_vector_t<unsigned>& old_index_to_page_map_index) + { + unsigned int write_index = 0; + for (unsigned int i = 0; i < pages.length; i++) + { + if (old_index_to_page_map_index[i] == 0xFFFFFFFF) continue; + + if (write_index < i) + pages[write_index] = pages[i]; + + page_map[old_index_to_page_map_index[i]].index = write_index; + write_index++; + } + } + template <typename Op> void process (const Op& op, const hb_set_t *other) { + const bool passthru_left = op (1, 0); + const bool passthru_right = op (0, 1); + if (unlikely (!successful)) return; dirty (); @@ -459,35 +575,60 @@ struct hb_set_t unsigned int count = 0, newCount = 0; unsigned int a = 0, b = 0; + unsigned int write_index = 0; + + // Pre-allocate the workspace that compact() will need so we can bail on allocation failure + // before attempting to rewrite the page map. + hb_vector_t<unsigned> compact_workspace; + if (!passthru_left && unlikely (!allocate_compact_workspace (compact_workspace))) return; + for (; a < na && b < nb; ) { if (page_map[a].major == other->page_map[b].major) { + if (!passthru_left) + { + // Move page_map entries that we're keeping from the left side set + // to the front of the page_map vector. This isn't necessary if + // passthru_left is set since no left side pages will be removed + // in that case. + if (write_index < a) + page_map[write_index] = page_map[a]; + write_index++; + } + count++; a++; b++; } else if (page_map[a].major < other->page_map[b].major) { - if (Op::passthru_left) + if (passthru_left) count++; a++; } else { - if (Op::passthru_right) + if (passthru_right) count++; b++; } } - if (Op::passthru_left) + if (passthru_left) count += na - a; - if (Op::passthru_right) + if (passthru_right) count += nb - b; - if (count > pages.length) - if (!resize (count)) - return; + if (!passthru_left) + { + na = write_index; + next_page = write_index; + compact (compact_workspace, write_index); + } + + if (!resize (count)) + return; + newCount = count; /* Process in-place backward. */ @@ -506,7 +647,7 @@ struct hb_set_t else if (page_map[a - 1].major > other->page_map[b - 1].major) { a--; - if (Op::passthru_left) + if (passthru_left) { count--; page_map[count] = page_map[a]; @@ -515,7 +656,7 @@ struct hb_set_t else { b--; - if (Op::passthru_right) + if (passthru_right) { count--; page_map[count].major = other->page_map[b].major; @@ -524,14 +665,14 @@ struct hb_set_t } } } - if (Op::passthru_left) + if (passthru_left) while (a) { a--; count--; page_map[count] = page_map [a]; } - if (Op::passthru_right) + if (passthru_right) while (b) { b--; @@ -542,6 +683,9 @@ struct hb_set_t } assert (!count); if (pages.length > newCount) + // This resize() doesn't need to be checked because we can't get here + // if the set is currently in_error() and this only resizes downwards + // which will always succeed if the set is not in_error(). resize (newCount); } @@ -662,7 +806,7 @@ struct hb_set_t unsigned int get_population () const { - if (population != (unsigned int) -1) + if (population != UINT_MAX) return population; unsigned int pop = 0; @@ -698,8 +842,15 @@ struct hb_set_t struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t> { static constexpr bool is_sorted_iterator = true; - iter_t (const hb_set_t &s_ = Null(hb_set_t)) : - s (&s_), v (INVALID), l (s->get_population () + 1) { __next__ (); } + iter_t (const hb_set_t &s_ = Null (hb_set_t), + bool init = true) : s (&s_), v (INVALID), l(0) + { + if (init) + { + l = s->get_population () + 1; + __next__ (); + } + } typedef hb_codepoint_t __item_t__; hb_codepoint_t __item__ () const { return v; } @@ -707,7 +858,7 @@ struct hb_set_t void __next__ () { s->next (&v); if (l) l--; } void __prev__ () { s->previous (&v); } unsigned __len__ () const { return l; } - iter_t end () const { return iter_t (*s); } + iter_t end () const { return iter_t (*s, false); } bool operator != (const iter_t& o) const { return s != o.s || v != o.v; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc index ffd723d083..0d9eaddaa6 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc @@ -37,10 +37,17 @@ * @short_description: Object representing a shaping plan * @include: hb.h * - * Shape plans are not used for shaping directly, but can be access to query - * certain information about how shaping will perform given a set of input - * parameters (script, language, direction, features, etc.) - * Most client would not need to deal with shape plans directly. + * Shape plans are an internal mechanism. Each plan contains state + * describing how HarfBuzz will shape a particular text segment, based on + * the combination of segment properties and the capabilities in the + * font face in use. + * + * Shape plans are not used for shaping directly, but can be queried to + * access certain information about how shaping will perform, given a set + * of specific input parameters (script, language, direction, features, + * etc.). + * + * Most client programs will not need to deal with shape plans directly. **/ @@ -164,15 +171,16 @@ hb_shape_plan_key_t::equal (const hb_shape_plan_key_t *other) /** * hb_shape_plan_create: (Xconstructor) - * @face: - * @props: - * @user_features: (array length=num_user_features): - * @num_user_features: - * @shaper_list: (array zero-terminated=1): - * + * @face: #hb_face_t to use + * @props: The #hb_segment_properties_t of the segment + * @user_features: (array length=num_user_features): The list of user-selected features + * @num_user_features: The number of user-selected features + * @shaper_list: (array zero-terminated=1): List of shapers to try * + * Constructs a shaping plan for a combination of @face, @user_features, @props, + * and @shaper_list. * - * Return value: (transfer full): + * Return value: (transfer full): The shaping plan * * Since: 0.9.7 **/ @@ -189,6 +197,24 @@ hb_shape_plan_create (hb_face_t *face, shaper_list); } +/** + * hb_shape_plan_create2: (Xconstructor) + * @face: #hb_face_t to use + * @props: The #hb_segment_properties_t of the segment + * @user_features: (array length=num_user_features): The list of user-selected features + * @num_user_features: The number of user-selected features + * @coords: (array length=num_coords): The list of variation-space coordinates + * @num_coords: The number of variation-space coordinates + * @shaper_list: (array zero-terminated=1): List of shapers to try + * + * The variable-font version of #hb_shape_plan_create. + * Constructs a shaping plan for a combination of @face, @user_features, @props, + * and @shaper_list, plus the variation-space coordinates @coords. + * + * Return value: (transfer full): The shaping plan + * + * Since: 1.4.0 + **/ hb_shape_plan_t * hb_shape_plan_create2 (hb_face_t *face, const hb_segment_properties_t *props, @@ -248,25 +274,25 @@ bail: /** * hb_shape_plan_get_empty: * + * Fetches the singleton empty shaping plan. * - * - * Return value: (transfer full): + * Return value: (transfer full): The empty shaping plan * * Since: 0.9.7 **/ hb_shape_plan_t * hb_shape_plan_get_empty () { - return const_cast<hb_shape_plan_t *> (&Null(hb_shape_plan_t)); + return const_cast<hb_shape_plan_t *> (&Null (hb_shape_plan_t)); } /** * hb_shape_plan_reference: (skip) - * @shape_plan: a shape plan. + * @shape_plan: A shaping plan * + * Increases the reference count on the given shaping plan. * - * - * Return value: (transfer full): + * Return value: (transfer full): @shape_plan * * Since: 0.9.7 **/ @@ -278,9 +304,11 @@ hb_shape_plan_reference (hb_shape_plan_t *shape_plan) /** * hb_shape_plan_destroy: (skip) - * @shape_plan: a shape plan. - * + * @shape_plan: A shaping plan * + * Decreases the reference count on the given shaping plan. When the + * reference count reaches zero, the shaping plan is destroyed, + * freeing all memory. * * Since: 0.9.7 **/ @@ -298,15 +326,15 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan) /** * hb_shape_plan_set_user_data: (skip) - * @shape_plan: a shape plan. - * @key: - * @data: - * @destroy: - * @replace: - * + * @shape_plan: A shaping plan + * @key: The user-data key to set + * @data: A pointer to the user data + * @destroy: (nullable): A callback to call when @data is not needed anymore + * @replace: Whether to replace an existing data with the same key * + * Attaches a user-data key/data pair to the given shaping plan. * - * Return value: + * Return value: %true if success, %false otherwise. * * Since: 0.9.7 **/ @@ -322,12 +350,13 @@ hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan, /** * hb_shape_plan_get_user_data: (skip) - * @shape_plan: a shape plan. - * @key: + * @shape_plan: A shaping plan + * @key: The user-data key to query * + * Fetches the user data associated with the specified key, + * attached to the specified shaping plan. * - * - * Return value: (transfer none): + * Return value: (transfer none): A pointer to the user data * * Since: 0.9.7 **/ @@ -340,11 +369,11 @@ hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan, /** * hb_shape_plan_get_shaper: - * @shape_plan: a shape plan. - * + * @shape_plan: A shaping plan * + * Fetches the shaper from a given shaping plan. * - * Return value: (transfer none): + * Return value: (transfer none): The shaper * * Since: 0.9.7 **/ @@ -355,26 +384,12 @@ hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan) } -/** - * hb_shape_plan_execute: - * @shape_plan: a shape plan. - * @font: a font. - * @buffer: a buffer. - * @features: (array length=num_features): - * @num_features: - * - * - * - * Return value: - * - * Since: 0.9.7 - **/ -hb_bool_t -hb_shape_plan_execute (hb_shape_plan_t *shape_plan, - hb_font_t *font, - hb_buffer_t *buffer, - const hb_feature_t *features, - unsigned int num_features) +static bool +_hb_shape_plan_execute_internal (hb_shape_plan_t *shape_plan, + hb_font_t *font, + hb_buffer_t *buffer, + const hb_feature_t *features, + unsigned int num_features) { DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan, "num_features=%d shaper_func=%p, shaper_name=%s", @@ -386,7 +401,8 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan, return true; assert (!hb_object_is_immutable (buffer)); - assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE); + + buffer->assert_unicode (); if (unlikely (hb_object_is_inert (shape_plan))) return false; @@ -412,6 +428,36 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan, return false; } +/** + * hb_shape_plan_execute: + * @shape_plan: A shaping plan + * @font: The #hb_font_t to use + * @buffer: The #hb_buffer_t to work upon + * @features: (array length=num_features): Features to enable + * @num_features: The number of features to enable + * + * Executes the given shaping plan on the specified buffer, using + * the given @font and @features. + * + * Return value: %true if success, %false otherwise. + * + * Since: 0.9.7 + **/ +hb_bool_t +hb_shape_plan_execute (hb_shape_plan_t *shape_plan, + hb_font_t *font, + hb_buffer_t *buffer, + const hb_feature_t *features, + unsigned int num_features) +{ + bool ret = _hb_shape_plan_execute_internal (shape_plan, font, buffer, + features, num_features); + + if (ret && buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE) + buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS; + + return ret; +} /* @@ -420,15 +466,16 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan, /** * hb_shape_plan_create_cached: - * @face: - * @props: - * @user_features: (array length=num_user_features): - * @num_user_features: - * @shaper_list: (array zero-terminated=1): - * + * @face: #hb_face_t to use + * @props: The #hb_segment_properties_t of the segment + * @user_features: (array length=num_user_features): The list of user-selected features + * @num_user_features: The number of user-selected features + * @shaper_list: (array zero-terminated=1): List of shapers to try * + * Creates a cached shaping plan suitable for reuse, for a combination + * of @face, @user_features, @props, and @shaper_list. * - * Return value: (transfer full): + * Return value: (transfer full): The shaping plan * * Since: 0.9.7 **/ @@ -445,6 +492,25 @@ hb_shape_plan_create_cached (hb_face_t *face, shaper_list); } +/** + * hb_shape_plan_create_cached2: + * @face: #hb_face_t to use + * @props: The #hb_segment_properties_t of the segment + * @user_features: (array length=num_user_features): The list of user-selected features + * @num_user_features: The number of user-selected features + * @coords: (array length=num_coords): The list of variation-space coordinates + * @num_coords: The number of variation-space coordinates + * @shaper_list: (array zero-terminated=1): List of shapers to try + * + * The variable-font version of #hb_shape_plan_create_cached. + * Creates a cached shaping plan suitable for reuse, for a combination + * of @face, @user_features, @props, and @shaper_list, plus the + * variation-space coordinates @coords. + * + * Return value: (transfer full): The shaping plan + * + * Since: 1.4.0 + **/ hb_shape_plan_t * hb_shape_plan_create_cached2 (hb_face_t *face, const hb_segment_properties_t *props, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.h b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.h index b62ae7ca35..fc7c041899 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.h @@ -24,7 +24,7 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_H_IN +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb.h> instead." #endif @@ -36,6 +36,20 @@ HB_BEGIN_DECLS +/** + * hb_shape_plan_t: + * + * Data type for holding a shaping plan. + * + * Shape plans contain information about how HarfBuzz will shape a + * particular text segment, based on the segment's properties and the + * capabilities in the font face in use. + * + * Shape plans can be queried about how shaping will perform, given a set + * of specific input parameters (script, language, direction, features, + * etc.). + * + **/ typedef struct hb_shape_plan_t hb_shape_plan_t; HB_EXTERN hb_shape_plan_t * diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-shape.cc index cf4e1525a2..c442f4403b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-shape.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-shape.cc @@ -111,10 +111,10 @@ hb_shape_list_shapers () * hb_shape_full: * @font: an #hb_font_t to use for shaping * @buffer: an #hb_buffer_t to shape - * @features: (array length=num_features) (allow-none): an array of user + * @features: (array length=num_features) (nullable): an array of user * specified #hb_feature_t or %NULL * @num_features: the length of @features array - * @shaper_list: (array zero-terminated=1) (allow-none): a %NULL-terminated + * @shaper_list: (array zero-terminated=1) (nullable): a %NULL-terminated * array of shapers to use or %NULL * * See hb_shape() for details. If @shaper_list is not %NULL, the specified @@ -139,8 +139,6 @@ hb_shape_full (hb_font_t *font, hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features); hb_shape_plan_destroy (shape_plan); - if (res) - buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS; return res; } @@ -148,7 +146,7 @@ hb_shape_full (hb_font_t *font, * hb_shape: * @font: an #hb_font_t to use for shaping * @buffer: an #hb_buffer_t to shape - * @features: (array length=num_features) (allow-none): an array of user + * @features: (array length=num_features) (nullable): an array of user * specified #hb_feature_t or %NULL * @num_features: the length of @features array * diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape.h b/src/3rdparty/harfbuzz-ng/src/hb-shape.h index 39507ff744..922f8c011e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-shape.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-shape.h @@ -26,7 +26,7 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_H_IN +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb.h> instead." #endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shaper.hh b/src/3rdparty/harfbuzz-ng/src/hb-shaper.hh index 79dc5d07e0..b4138a324f 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-shaper.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-shaper.hh @@ -102,7 +102,7 @@ template <enum hb_shaper_order_t order, typename Object> struct hb_shaper_object static void destroy (Type *p) { HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (p); } \ }; \ \ - static_assert (true, "") /* Require semicolon. */ + static_assert (true, "") /* Require semicolon after. */ template <typename Object> diff --git a/src/3rdparty/harfbuzz-ng/src/hb-static.cc b/src/3rdparty/harfbuzz-ng/src/hb-static.cc index 08a2f21363..f5b7fa50a0 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-static.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-static.cc @@ -51,6 +51,9 @@ DEFINE_NULL_NAMESPACE_BYTES (AAT, SettingName) = {0xFF,0xFF, 0xFF,0xFF}; const unsigned char _hb_Null_AAT_Lookup[2] = {0xFF, 0xFF}; + +/* hb_face_t */ + unsigned int hb_face_t::load_num_glyphs () const { @@ -73,4 +76,37 @@ hb_face_t::load_upem () const return ret; } + +/* hb_user_data_array_t */ + +bool +hb_user_data_array_t::set (hb_user_data_key_t *key, + void * data, + hb_destroy_func_t destroy, + hb_bool_t replace) +{ + if (!key) + return false; + + if (replace) { + if (!data && !destroy) { + items.remove (key, lock); + return true; + } + } + hb_user_data_item_t item = {key, data, destroy}; + bool ret = !!items.replace_or_insert (item, lock, (bool) replace); + + return ret; +} + +void * +hb_user_data_array_t::get (hb_user_data_key_t *key) +{ + hb_user_data_item_t item = {nullptr, nullptr, nullptr}; + + return items.find (key, &item, lock) ? item.data : nullptr; +} + + #endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-string-array.hh b/src/3rdparty/harfbuzz-ng/src/hb-string-array.hh index 1c67ab4d7c..e7ac119232 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-string-array.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-string-array.hh @@ -37,6 +37,7 @@ #define HB_STRING_ARRAY_TYPE_NAME HB_PASTE(HB_STRING_ARRAY_NAME, _msgstr_t) #define HB_STRING_ARRAY_POOL_NAME HB_PASTE(HB_STRING_ARRAY_NAME, _msgstr) #define HB_STRING_ARRAY_OFFS_NAME HB_PASTE(HB_STRING_ARRAY_NAME, _msgidx) +#define HB_STRING_ARRAY_LENG_NAME HB_PASTE(HB_STRING_ARRAY_NAME, _length) static const union HB_STRING_ARRAY_TYPE_NAME { struct { @@ -66,6 +67,8 @@ static const unsigned int HB_STRING_ARRAY_OFFS_NAME[] = sizeof (HB_STRING_ARRAY_TYPE_NAME) }; +static const unsigned int HB_STRING_ARRAY_LENG_NAME = ARRAY_LENGTH_CONST (HB_STRING_ARRAY_OFFS_NAME) - 1; + static inline hb_bytes_t HB_STRING_ARRAY_NAME (unsigned int i) { @@ -77,5 +80,6 @@ HB_STRING_ARRAY_NAME (unsigned int i) #undef HB_STRING_ARRAY_TYPE_NAME #undef HB_STRING_ARRAY_POOL_NAME #undef HB_STRING_ARRAY_OFFS_NAME +#undef HB_STRING_ARRAY_LENG_NAME #endif /* HB_STRING_ARRAY_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-style.cc b/src/3rdparty/harfbuzz-ng/src/hb-style.cc new file mode 100644 index 0000000000..2f45d119f9 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-style.cc @@ -0,0 +1,136 @@ +/* + * Copyright © 2019 Ebrahim Byagowi + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#include "hb.hh" + +#ifndef HB_NO_STYLE +#ifdef HB_EXPERIMENTAL_API + +#include "hb-ot-var-avar-table.hh" +#include "hb-ot-var-fvar-table.hh" +#include "hb-ot-stat-table.hh" +#include "hb-ot-os2-table.hh" +#include "hb-ot-head-table.hh" +#include "hb-ot-post-table.hh" +#include "hb-ot-face.hh" + +/** + * hb_style_tag_t: + * @HB_STYLE_TAG_ITALIC: Used to vary between non-italic and italic. + * A value of 0 can be interpreted as "Roman" (non-italic); a value of 1 can + * be interpreted as (fully) italic. + * @HB_STYLE_TAG_OPTICAL_SIZE: Used to vary design to suit different text sizes. + * Non-zero. Values can be interpreted as text size, in points. + * @HB_STYLE_TAG_SLANT: Used to vary between upright and slanted text. Values + * must be greater than -90 and less than +90. Values can be interpreted as + * the angle, in counter-clockwise degrees, of oblique slant from whatever the + * designer considers to be upright for that font design. + * @HB_STYLE_TAG_WIDTH: Used to vary width of text from narrower to wider. + * Non-zero. Values can be interpreted as a percentage of whatever the font + * designer considers “normal width” for that font design. + * @HB_STYLE_TAG_WEIGHT: Used to vary stroke thicknesses or other design details + * to give variation from lighter to blacker. Values can be interpreted in direct + * comparison to values for usWeightClass in the OS/2 table, + * or the CSS font-weight property. + * + * Defined by https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxisreg + * + * Since: EXPERIMENTAL + **/ +typedef enum { + HB_STYLE_TAG_ITALIC = HB_TAG ('i','t','a','l'), + HB_STYLE_TAG_OPTICAL_SIZE = HB_TAG ('o','p','s','z'), + HB_STYLE_TAG_SLANT = HB_TAG ('s','l','n','t'), + HB_STYLE_TAG_WIDTH = HB_TAG ('w','d','t','h'), + HB_STYLE_TAG_WEIGHT = HB_TAG ('w','g','h','t'), + + /*< private >*/ + _HB_STYLE_TAG_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/ +} hb_style_tag_t; + +/** + * hb_style_get_value: + * @font: a #hb_font_t object. + * @style_tag: a style tag. + * + * Searches variation axes of a hb_font_t object for a specific axis first, + * if not set, then tries to get default style values from different + * tables of the font. + * + * Returns: Corresponding axis or default value to a style tag. + * + * Since: EXPERIMENTAL + **/ +float +hb_style_get_value (hb_font_t *font, hb_tag_t tag) +{ + hb_style_tag_t style_tag = (hb_style_tag_t) tag; + hb_face_t *face = font->face; + +#ifndef HB_NO_VAR + hb_ot_var_axis_info_t axis; + if (hb_ot_var_find_axis_info (face, style_tag, &axis)) + { + if (axis.axis_index < font->num_coords) return font->design_coords[axis.axis_index]; + /* If a face is variable, fvar's default_value is better than STAT records */ + return axis.default_value; + } +#endif + + if (style_tag == HB_STYLE_TAG_OPTICAL_SIZE && font->ptem) + return font->ptem; + + /* STAT */ + float value; + if (face->table.STAT->get_value (style_tag, &value)) + return value; + + switch ((unsigned) style_tag) + { + case HB_STYLE_TAG_ITALIC: + return face->table.OS2->is_italic () || face->table.head->is_italic () ? 1 : 0; + case HB_STYLE_TAG_OPTICAL_SIZE: + { + unsigned int lower, upper; + return face->table.OS2->v5 ().get_optical_size (&lower, &upper) + ? (float) (lower + upper) / 2.f + : 12.f; + } + case HB_STYLE_TAG_SLANT: + return face->table.post->table->italicAngle.to_float (); + case HB_STYLE_TAG_WIDTH: + return face->table.OS2->has_data () + ? face->table.OS2->get_width () + : (face->table.head->is_condensed () ? 75 : 100); + case HB_STYLE_TAG_WEIGHT: + return face->table.OS2->has_data () + ? face->table.OS2->usWeightClass + : (face->table.head->is_bold () ? 700 : 400); + default: + return 0; + } +} + +#endif +#endif diff --git a/src/3rdparty/harfbuzz-ng/src/dump-use-data.cc b/src/3rdparty/harfbuzz-ng/src/hb-style.h index d639426b73..f5776cee58 100644 --- a/src/3rdparty/harfbuzz-ng/src/dump-use-data.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-style.h @@ -1,5 +1,5 @@ /* - * Copyright © 2018 Google, Inc. + * Copyright © 2019 Ebrahim Byagowi * * This is part of HarfBuzz, a text shaping library. * @@ -20,19 +20,24 @@ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod */ -#include "hb-ot-shape-complex-use.hh" +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) +#error "Include <hb.h> instead." +#endif + +#ifndef HB_STYLE_H +#define HB_STYLE_H + +#include "hb.h" + +HB_BEGIN_DECLS + +#ifdef HB_EXPERIMENTAL_API +HB_EXTERN float +hb_style_get_value (hb_font_t *font, hb_tag_t style_tag); +#endif + +HB_END_DECLS -int -main () -{ - for (hb_codepoint_t u = 0; u <= 0x10FFFF; u++) - { - unsigned int category = hb_use_get_category (u); - if (category != USE_O) - printf("U+%04X %u\n", u, category); - } -} +#endif /* HB_STYLE_H */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff-common.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-cff-common.cc index c9a880ad50..04e1db24ac 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff-common.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-cff-common.cc @@ -108,7 +108,7 @@ hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan, fdmap.add (fd); hb_set_destroy (set); if (unlikely (fdmap.get_population () != subset_fd_count)) - return false; + return false; } /* update each font dict index stored as "code" in fdselect_ranges */ @@ -158,7 +158,7 @@ serialize_fdselect_3_4 (hb_serialize_context_t *c, { TRACE_SERIALIZE (this); FDSELECT3_4 *p = c->allocate_size<FDSELECT3_4> (size); - if (unlikely (p == nullptr)) return_trace (false); + if (unlikely (!p)) return_trace (false); p->nRanges () = fdselect_ranges.length; for (unsigned int i = 0; i < fdselect_ranges.length; i++) { @@ -184,7 +184,7 @@ hb_serialize_cff_fdselect (hb_serialize_context_t *c, { TRACE_SERIALIZE (this); FDSelect *p = c->allocate_min<FDSelect> (); - if (unlikely (p == nullptr)) return_trace (false); + if (unlikely (!p)) return_trace (false); p->format = fdselect_format; size -= FDSelect::min_size; @@ -194,7 +194,7 @@ hb_serialize_cff_fdselect (hb_serialize_context_t *c, case 0: { FDSelect0 *p = c->allocate_size<FDSelect0> (size); - if (unlikely (p == nullptr)) return_trace (false); + if (unlikely (!p)) return_trace (false); unsigned int range_index = 0; unsigned int fd = fdselect_ranges[range_index++].code; for (unsigned int i = 0; i < num_glyphs; i++) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-subset-cff-common.hh index 3c66119603..422b20b8d0 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff-common.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-cff-common.hh @@ -44,7 +44,7 @@ struct str_encoder_t void encode_byte (unsigned char b) { - if (unlikely (buff.push (b) == &Crap(unsigned char))) + if (unlikely (buff.push (b) == &Crap (unsigned char))) set_error (); } @@ -110,7 +110,11 @@ struct str_encoder_t void copy_str (const byte_str_t &str) { unsigned int offset = buff.length; - buff.resize (offset + str.length); + if (unlikely (!buff.resize (offset + str.length))) + { + set_error (); + return; + } if (unlikely (buff.length < offset + str.length)) { set_error (); @@ -128,26 +132,17 @@ struct str_encoder_t bool error; }; -struct cff_sub_table_offsets_t { - cff_sub_table_offsets_t () : privateDictsOffset (0) +struct cff_sub_table_info_t { + cff_sub_table_info_t () + : fd_array_link (0), + char_strings_link (0) { - topDictInfo.init (); - FDSelectInfo.init (); - FDArrayInfo.init (); - charStringsInfo.init (); - globalSubrsInfo.init (); - localSubrsInfos.init (); + fd_select.init (); } - ~cff_sub_table_offsets_t () { localSubrsInfos.fini (); } - - table_info_t topDictInfo; - table_info_t FDSelectInfo; - table_info_t FDArrayInfo; - table_info_t charStringsInfo; - unsigned int privateDictsOffset; - table_info_t globalSubrsInfo; - hb_vector_t<table_info_t> localSubrsInfos; + table_info_t fd_select; + objidx_t fd_array_link; + objidx_t char_strings_link; }; template <typename OPSTR=op_str_t> @@ -155,40 +150,26 @@ struct cff_top_dict_op_serializer_t : op_serializer_t { bool serialize (hb_serialize_context_t *c, const OPSTR &opstr, - const cff_sub_table_offsets_t &offsets) const + const cff_sub_table_info_t &info) const { TRACE_SERIALIZE (this); switch (opstr.op) { case OpCode_CharStrings: - return_trace (FontDict::serialize_offset4_op(c, opstr.op, offsets.charStringsInfo.offset)); + return_trace (FontDict::serialize_link4_op(c, opstr.op, info.char_strings_link, whence_t::Absolute)); case OpCode_FDArray: - return_trace (FontDict::serialize_offset4_op(c, opstr.op, offsets.FDArrayInfo.offset)); + return_trace (FontDict::serialize_link4_op(c, opstr.op, info.fd_array_link, whence_t::Absolute)); case OpCode_FDSelect: - return_trace (FontDict::serialize_offset4_op(c, opstr.op, offsets.FDSelectInfo.offset)); + return_trace (FontDict::serialize_link4_op(c, opstr.op, info.fd_select.link, whence_t::Absolute)); default: return_trace (copy_opstr (c, opstr)); } return_trace (true); } - - unsigned int calculate_serialized_size (const OPSTR &opstr) const - { - switch (opstr.op) - { - case OpCode_CharStrings: - case OpCode_FDArray: - case OpCode_FDSelect: - return OpCode_Size (OpCode_longintdict) + 4 + OpCode_Size (opstr.op); - - default: - return opstr.str.length; - } - } }; struct cff_font_dict_op_serializer_t : op_serializer_t @@ -202,33 +183,17 @@ struct cff_font_dict_op_serializer_t : op_serializer_t if (opstr.op == OpCode_Private) { /* serialize the private dict size & offset as 2-byte & 4-byte integers */ - if (unlikely (!UnsizedByteStr::serialize_int2 (c, privateDictInfo.size) || - !UnsizedByteStr::serialize_int4 (c, privateDictInfo.offset))) - return_trace (false); - - /* serialize the opcode */ - HBUINT8 *p = c->allocate_size<HBUINT8> (1); - if (unlikely (p == nullptr)) return_trace (false); - *p = OpCode_Private; - - return_trace (true); + return_trace (UnsizedByteStr::serialize_int2 (c, privateDictInfo.size) && + Dict::serialize_link4_op (c, opstr.op, privateDictInfo.link, whence_t::Absolute)); } else { HBUINT8 *d = c->allocate_size<HBUINT8> (opstr.str.length); - if (unlikely (d == nullptr)) return_trace (false); + if (unlikely (!d)) return_trace (false); memcpy (d, &opstr.str[0], opstr.str.length); } return_trace (true); } - - unsigned int calculate_serialized_size (const op_str_t &opstr) const - { - if (opstr.op == OpCode_Private) - return OpCode_Size (OpCode_longintdict) + 4 + OpCode_Size (OpCode_shortint) + 2 + OpCode_Size (OpCode_Private); - else - return opstr.str.length; - } }; struct cff_private_dict_op_serializer_t : op_serializer_t @@ -238,7 +203,7 @@ struct cff_private_dict_op_serializer_t : op_serializer_t bool serialize (hb_serialize_context_t *c, const op_str_t &opstr, - const unsigned int subrsOffset) const + objidx_t subrs_link) const { TRACE_SERIALIZE (this); @@ -246,31 +211,15 @@ struct cff_private_dict_op_serializer_t : op_serializer_t return true; if (opstr.op == OpCode_Subrs) { - if (desubroutinize || (subrsOffset == 0)) + if (desubroutinize || !subrs_link) return_trace (true); else - return_trace (FontDict::serialize_offset2_op (c, opstr.op, subrsOffset)); + return_trace (FontDict::serialize_link2_op (c, opstr.op, subrs_link)); } else return_trace (copy_opstr (c, opstr)); } - unsigned int calculate_serialized_size (const op_str_t &opstr, - bool has_localsubr=true) const - { - if (drop_hints && dict_opset_t::is_hint_op (opstr.op)) - return 0; - if (opstr.op == OpCode_Subrs) - { - if (desubroutinize || !has_localsubr) - return 0; - else - return OpCode_Size (OpCode_shortint) + 2 + OpCode_Size (opstr.op); - } - else - return opstr.str.length; - } - protected: const bool desubroutinize; const bool drop_hints; @@ -300,14 +249,14 @@ struct subr_flattener_t hb_codepoint_t glyph; if (!plan->old_gid_for_new_gid (i, &glyph)) { - /* add an endchar only charstring for a missing glyph if CFF1 */ - if (endchar_op != OpCode_Invalid) flat_charstrings[i].push (endchar_op); - continue; + /* add an endchar only charstring for a missing glyph if CFF1 */ + if (endchar_op != OpCode_Invalid) flat_charstrings[i].push (endchar_op); + continue; } const byte_str_t str = (*acc.charStrings)[glyph]; unsigned int fd = acc.fdSelect->get_fd (glyph); if (unlikely (fd >= acc.fdCount)) - return false; + return false; cs_interpreter_t<ENV, OPSET, flatten_param_t> interp; interp.env.init (str, acc, fd); flatten_param_t param = { flat_charstrings[i], plan->drop_hints }; @@ -456,7 +405,7 @@ struct parsed_cs_str_t : parsed_values_t<parsed_cs_op_t> bool vsindex_dropped; bool has_prefix_; op_code_t prefix_op_; - number_t prefix_num_; + number_t prefix_num_; private: typedef parsed_values_t<parsed_cs_op_t> SUPER; @@ -467,7 +416,8 @@ struct parsed_cs_str_vec_t : hb_vector_t<parsed_cs_str_t> void init (unsigned int len_ = 0) { SUPER::init (); - resize (len_); + if (unlikely (!resize (len_))) + return; for (unsigned int i = 0; i < length; i++) (*this)[i].init (); } @@ -516,19 +466,19 @@ struct subr_subset_param_t template <typename ENV> void set_current_str (ENV &env, bool calling) { - parsed_cs_str_t *parsed_str = get_parsed_str_for_context (env.context); - if (likely (parsed_str != nullptr)) + parsed_cs_str_t *parsed_str = get_parsed_str_for_context (env.context); + if (unlikely (!parsed_str)) { - /* If the called subroutine is parsed partially but not completely yet, - * it must be because we are calling it recursively. - * Handle it as an error. */ - if (unlikely (calling && !parsed_str->is_parsed () && (parsed_str->values.length > 0))) - env.set_error (); - else - current_parsed_str = parsed_str; + env.set_error (); + return; } - else + /* If the called subroutine is parsed partially but not completely yet, + * it must be because we are calling it recursively. + * Handle it as an error. */ + if (unlikely (calling && !parsed_str->is_parsed () && (parsed_str->values.length > 0))) env.set_error (); + else + current_parsed_str = parsed_str; } parsed_cs_str_t *current_parsed_str; @@ -583,11 +533,16 @@ struct subr_remaps_t void init (unsigned int fdCount) { - local_remaps.resize (fdCount); + if (unlikely (!local_remaps.resize (fdCount))) return; for (unsigned int i = 0; i < fdCount; i++) local_remaps[i].init (); } + bool in_error() + { + return local_remaps.in_error (); + } + void create (subr_closures_t& closures) { global_remap.create (closures.global_closure); @@ -646,10 +601,19 @@ struct subr_subsetter_t parsed_charstrings.init (plan->num_output_glyphs ()); parsed_global_subrs.init (acc.globalSubrs->count); - parsed_local_subrs.resize (acc.fdCount); + + if (unlikely (remaps.in_error() + || parsed_charstrings.in_error () + || parsed_global_subrs.in_error ())) { + return false; + } + + if (unlikely (!parsed_local_subrs.resize (acc.fdCount))) return false; + for (unsigned int i = 0; i < acc.fdCount; i++) { parsed_local_subrs[i].init (acc.privateDicts[i].localSubrs->count); + if (unlikely (parsed_local_subrs[i].in_error ())) return false; } if (unlikely (!closures.valid)) return false; @@ -659,11 +623,11 @@ struct subr_subsetter_t { hb_codepoint_t glyph; if (!plan->old_gid_for_new_gid (i, &glyph)) - continue; + continue; const byte_str_t str = (*acc.charStrings)[glyph]; unsigned int fd = acc.fdSelect->get_fd (glyph); if (unlikely (fd >= acc.fdCount)) - return false; + return false; cs_interpreter_t<ENV, OPSET, subr_subset_param_t> interp; interp.env.init (str, acc, fd); @@ -677,8 +641,8 @@ struct subr_subsetter_t if (unlikely (!interp.interpret (param))) return false; - /* finalize parsed string esp. copy CFF1 width or CFF2 vsindex to the parsed charstring for encoding */ - SUBSETTER::finalize_parsed_str (interp.env, param, parsed_charstrings[i]); + /* complete parsed string esp. copy CFF1 width or CFF2 vsindex to the parsed charstring for encoding */ + SUBSETTER::complete_parsed_str (interp.env, param, parsed_charstrings[i]); } if (plan->drop_hints) @@ -740,13 +704,13 @@ struct subr_subsetter_t hb_codepoint_t glyph; if (!plan->old_gid_for_new_gid (i, &glyph)) { - /* add an endchar only charstring for a missing glyph if CFF1 */ - if (endchar_op != OpCode_Invalid) buffArray[i].push (endchar_op); - continue; + /* add an endchar only charstring for a missing glyph if CFF1 */ + if (endchar_op != OpCode_Invalid) buffArray[i].push (endchar_op); + continue; } unsigned int fd = acc.fdSelect->get_fd (glyph); if (unlikely (fd >= acc.fdCount)) - return false; + return false; if (unlikely (!encode_str (parsed_charstrings[i], fd, buffArray[i]))) return false; } @@ -900,11 +864,11 @@ struct subr_subsetter_t { parsed_cs_op_t &csop = str.values[pos]; if (csop.op == OpCode_return) - break; + break; if (!csop.for_drop ()) { - drop.all_dropped = false; - break; + drop.all_dropped = false; + break; } } @@ -986,7 +950,7 @@ struct subr_subsetter_t } protected: - const ACC &acc; + const ACC &acc; const hb_subset_plan_t *plan; subr_closures_t closures; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff1.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-cff1.cc index e9e075749e..df322f8451 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff1.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-cff1.cc @@ -64,29 +64,25 @@ struct remap_sid_t : hb_inc_bimap_t static unsigned int unoffset_sid (unsigned int sid) { return sid - num_std_strings; } }; -struct cff1_sub_table_offsets_t : cff_sub_table_offsets_t +struct cff1_sub_table_info_t : cff_sub_table_info_t { - cff1_sub_table_offsets_t () - : cff_sub_table_offsets_t (), - nameIndexOffset (0), - encodingOffset (0) - { - stringIndexInfo.init (); - charsetInfo.init (); + cff1_sub_table_info_t () + : cff_sub_table_info_t (), + encoding_link (0), + charset_link (0) + { privateDictInfo.init (); } - unsigned int nameIndexOffset; - table_info_t stringIndexInfo; - unsigned int encodingOffset; - table_info_t charsetInfo; + objidx_t encoding_link; + objidx_t charset_link; table_info_t privateDictInfo; }; /* a copy of a parsed out cff1_top_dict_values_t augmented with additional operators */ struct cff1_top_dict_values_mod_t : cff1_top_dict_values_t { - void init (const cff1_top_dict_values_t *base_= &Null(cff1_top_dict_values_t)) + void init (const cff1_top_dict_values_t *base_= &Null (cff1_top_dict_values_t)) { SUPER::init (); base = base_; @@ -117,13 +113,13 @@ struct cff1_top_dict_values_mod_t : cff1_top_dict_values_t struct top_dict_modifiers_t { - top_dict_modifiers_t (const cff1_sub_table_offsets_t &offsets_, - const unsigned int (&nameSIDs_)[name_dict_values_t::ValCount]) - : offsets (offsets_), + top_dict_modifiers_t (const cff1_sub_table_info_t &info_, + const unsigned int (&nameSIDs_)[name_dict_values_t::ValCount]) + : info (info_), nameSIDs (nameSIDs_) {} - const cff1_sub_table_offsets_t &offsets; + const cff1_sub_table_info_t &info; const unsigned int (&nameSIDs)[name_dict_values_t::ValCount]; }; @@ -139,22 +135,20 @@ struct cff1_top_dict_op_serializer_t : cff_top_dict_op_serializer_t<cff1_top_dic switch (op) { case OpCode_charset: - return_trace (FontDict::serialize_offset4_op(c, op, mod.offsets.charsetInfo.offset)); + if (mod.info.charset_link) + return_trace (FontDict::serialize_link4_op(c, op, mod.info.charset_link, whence_t::Absolute)); + else + goto fall_back; case OpCode_Encoding: - return_trace (FontDict::serialize_offset4_op(c, op, mod.offsets.encodingOffset)); + if (mod.info.encoding_link) + return_trace (FontDict::serialize_link4_op(c, op, mod.info.encoding_link, whence_t::Absolute)); + else + goto fall_back; case OpCode_Private: - { - if (unlikely (!UnsizedByteStr::serialize_int2 (c, mod.offsets.privateDictInfo.size))) - return_trace (false); - if (unlikely (!UnsizedByteStr::serialize_int4 (c, mod.offsets.privateDictInfo.offset))) - return_trace (false); - HBUINT8 *p = c->allocate_size<HBUINT8> (1); - if (unlikely (p == nullptr)) return_trace (false); - *p = OpCode_Private; - } - break; + return_trace (UnsizedByteStr::serialize_int2 (c, mod.info.privateDictInfo.size) && + Dict::serialize_link4_op (c, op, mod.info.privateDictInfo.link, whence_t::Absolute)); case OpCode_version: case OpCode_Notice: @@ -165,7 +159,7 @@ struct cff1_top_dict_op_serializer_t : cff_top_dict_op_serializer_t<cff1_top_dic case OpCode_PostScript: case OpCode_BaseFontName: case OpCode_FontName: - return_trace (FontDict::serialize_offset2_op(c, op, mod.nameSIDs[name_dict_values_t::name_op_to_index (op)])); + return_trace (FontDict::serialize_int2_op (c, op, mod.nameSIDs[name_dict_values_t::name_op_to_index (op)])); case OpCode_ROS: { @@ -180,86 +174,29 @@ struct cff1_top_dict_op_serializer_t : cff_top_dict_op_serializer_t<cff1_top_dic UnsizedByteStr::serialize_int2 (c, mod.nameSIDs[name_dict_values_t::ordering]) && copy_opstr (c, supp_op)); } + fall_back: default: - return_trace (cff_top_dict_op_serializer_t<cff1_top_dict_val_t>::serialize (c, opstr, mod.offsets)); + return_trace (cff_top_dict_op_serializer_t<cff1_top_dict_val_t>::serialize (c, opstr, mod.info)); } return_trace (true); } - unsigned int calculate_serialized_size (const cff1_top_dict_val_t &opstr) const - { - op_code_t op = opstr.op; - switch (op) - { - case OpCode_charset: - case OpCode_Encoding: - return OpCode_Size (OpCode_longintdict) + 4 + OpCode_Size (op); - - case OpCode_Private: - return OpCode_Size (OpCode_longintdict) + 4 + OpCode_Size (OpCode_shortint) + 2 + OpCode_Size (OpCode_Private); - - case OpCode_version: - case OpCode_Notice: - case OpCode_Copyright: - case OpCode_FullName: - case OpCode_FamilyName: - case OpCode_Weight: - case OpCode_PostScript: - case OpCode_BaseFontName: - case OpCode_FontName: - return OpCode_Size (OpCode_shortint) + 2 + OpCode_Size (op); - - case OpCode_ROS: - return ((OpCode_Size (OpCode_shortint) + 2) * 2) + (opstr.str.length - opstr.last_arg_offset)/* supplement + op */; - - default: - return cff_top_dict_op_serializer_t<cff1_top_dict_val_t>::calculate_serialized_size (opstr); - } - } -}; - -struct font_dict_values_mod_t -{ - void init (const cff1_font_dict_values_t *base_, - unsigned int fontName_, - const table_info_t &privateDictInfo_) - { - base = base_; - fontName = fontName_; - privateDictInfo = privateDictInfo_; - } - - unsigned get_count () const { return base->get_count (); } - - const op_str_t &operator [] (unsigned int i) const { return (*base)[i]; } - - const cff1_font_dict_values_t *base; - table_info_t privateDictInfo; - unsigned int fontName; }; struct cff1_font_dict_op_serializer_t : cff_font_dict_op_serializer_t { bool serialize (hb_serialize_context_t *c, const op_str_t &opstr, - const font_dict_values_mod_t &mod) const + const cff1_font_dict_values_mod_t &mod) const { TRACE_SERIALIZE (this); if (opstr.op == OpCode_FontName) - return_trace (FontDict::serialize_uint2_op (c, opstr.op, mod.fontName)); + return_trace (FontDict::serialize_int2_op (c, opstr.op, mod.fontName)); else return_trace (SUPER::serialize (c, opstr, mod.privateDictInfo)); } - unsigned int calculate_serialized_size (const op_str_t &opstr) const - { - if (opstr.op == OpCode_FontName) - return OpCode_Size (OpCode_shortint) + 2 + OpCode_Size (OpCode_FontName); - else - return SUPER::calculate_serialized_size (opstr); - } - private: typedef cff_font_dict_op_serializer_t SUPER; }; @@ -331,7 +268,7 @@ struct cff1_cs_opset_flatten_t : cff1_cs_opset_t<cff1_cs_opset_flatten_t, flatte struct range_list_t : hb_vector_t<code_pair_t> { /* replace the first glyph ID in the "glyph" field each range with a nLeft value */ - bool finalize (unsigned int last_glyph) + bool complete (unsigned int last_glyph) { bool two_byte = false; for (unsigned int i = (*this).length; i > 0; i--) @@ -402,7 +339,7 @@ struct cff1_subr_subsetter_t : subr_subsetter_t<cff1_subr_subsetter_t, CFF1Subrs cff1_subr_subsetter_t (const OT::cff1::accelerator_subset_t &acc_, const hb_subset_plan_t *plan_) : subr_subsetter_t (acc_, plan_) {} - static void finalize_parsed_str (cff1_cs_interp_env_t &env, subr_subset_param_t& param, parsed_cs_str_t &charstring) + static void complete_parsed_str (cff1_cs_interp_env_t &env, subr_subset_param_t& param, parsed_cs_str_t &charstring) { /* insert width at the beginning of the charstring as necessary */ if (env.has_width) @@ -414,8 +351,8 @@ struct cff1_subr_subsetter_t : subr_subsetter_t<cff1_subr_subsetter_t, CFF1Subrs param.current_parsed_str->set_parsed (); for (unsigned int i = 0; i < env.callStack.get_count (); i++) { - parsed_cs_str_t *parsed_str = param.get_parsed_str_for_context (env.callStack[i]); - if (likely (parsed_str != nullptr)) + parsed_cs_str_t *parsed_str = param.get_parsed_str_for_context (env.callStack[i]); + if (likely (parsed_str)) parsed_str->set_parsed (); else env.set_error (); @@ -425,16 +362,13 @@ struct cff1_subr_subsetter_t : subr_subsetter_t<cff1_subr_subsetter_t, CFF1Subrs struct cff_subset_plan { cff_subset_plan () - : final_size (0), - offsets (), + : info (), orig_fdcount (0), subset_fdcount (1), subset_fdselect_format (0), drop_hints (false), desubroutinize(false) { - topdict_sizes.init (); - topdict_sizes.resize (1); topdict_mod.init (); subset_fdselect_ranges.init (); fdmap.init (); @@ -452,7 +386,6 @@ struct cff_subset_plan { ~cff_subset_plan () { - topdict_sizes.fini (); topdict_mod.fini (); subset_fdselect_ranges.fini (); fdmap.fini (); @@ -466,14 +399,19 @@ struct cff_subset_plan { sidmap.fini (); } - unsigned int plan_subset_encoding (const OT::cff1::accelerator_subset_t &acc, hb_subset_plan_t *plan) + void plan_subset_encoding (const OT::cff1::accelerator_subset_t &acc, hb_subset_plan_t *plan) { const Encoding *encoding = acc.encoding; unsigned int size0, size1, supp_size; hb_codepoint_t code, last_code = CFF_UNDEF_CODE; hb_vector_t<hb_codepoint_t> supp_codes; - subset_enc_code_ranges.resize (0); + if (unlikely (!subset_enc_code_ranges.resize (0))) + { + plan->check_success (false); + return; + } + supp_size = 0; supp_codes.init (); @@ -484,7 +422,7 @@ struct cff_subset_plan { hb_codepoint_t old_glyph; if (!plan->old_gid_for_new_gid (glyph, &old_glyph)) { - /* Retain the code for the old missing glyph ID */ + /* Retain the code for the old missing glyph ID */ old_glyph = glyph; } code = acc.glyph_to_code (old_glyph); @@ -501,7 +439,7 @@ struct cff_subset_plan { } last_code = code; - if (encoding != &Null(Encoding)) + if (encoding != &Null (Encoding)) { hb_codepoint_t sid = acc.glyph_to_sid (old_glyph); encoding->get_supplement_codes (sid, supp_codes); @@ -515,7 +453,7 @@ struct cff_subset_plan { } supp_codes.fini (); - subset_enc_code_ranges.finalize (glyph); + subset_enc_code_ranges.complete (glyph); assert (subset_enc_num_codes <= 0xFF); size0 = Encoding0::min_size + HBUINT8::static_size * subset_enc_num_codes; @@ -525,26 +463,26 @@ struct cff_subset_plan { subset_enc_format = 0; else subset_enc_format = 1; - - return Encoding::calculate_serialized_size ( - subset_enc_format, - subset_enc_format? subset_enc_code_ranges.length: subset_enc_num_codes, - subset_enc_supp_codes.length); } - unsigned int plan_subset_charset (const OT::cff1::accelerator_subset_t &acc, hb_subset_plan_t *plan) + void plan_subset_charset (const OT::cff1::accelerator_subset_t &acc, hb_subset_plan_t *plan) { unsigned int size0, size_ranges; hb_codepoint_t sid, last_sid = CFF_UNDEF_CODE; - subset_charset_ranges.resize (0); + if (unlikely (!subset_charset_ranges.resize (0))) + { + plan->check_success (false); + return; + } + unsigned int glyph; for (glyph = 1; glyph < plan->num_output_glyphs (); glyph++) { hb_codepoint_t old_glyph; if (!plan->old_gid_for_new_gid (glyph, &old_glyph)) { - /* Retain the SID for the old missing glyph ID */ + /* Retain the SID for the old missing glyph ID */ old_glyph = glyph; } sid = acc.glyph_to_sid (old_glyph); @@ -560,7 +498,7 @@ struct cff_subset_plan { last_sid = sid; } - bool two_byte = subset_charset_ranges.finalize (glyph); + bool two_byte = subset_charset_ranges.complete (glyph); size0 = Charset0::min_size + HBUINT16::static_size * (plan->num_output_glyphs () - 1); if (!two_byte) @@ -574,10 +512,6 @@ struct cff_subset_plan { subset_charset_format = 1; else subset_charset_format = 2; - - return Charset::calculate_serialized_size ( - subset_charset_format, - subset_charset_format? subset_charset_ranges.length: plan->num_output_glyphs ()); } bool collect_sids_in_dicts (const OT::cff1::accelerator_subset_t &acc) @@ -594,7 +528,7 @@ struct cff_subset_plan { } } - if (acc.fdArray != &Null(CFF1FDArray)) + if (acc.fdArray != &Null (CFF1FDArray)) for (unsigned int i = 0; i < orig_fdcount; i++) if (fdmap.has (i)) (void)sidmap.add (acc.fontDicts[i].fontName); @@ -609,7 +543,6 @@ struct cff_subset_plan { hb_codepoint_t old_glyph; if (!plan->old_gid_for_new_gid (0, &old_glyph) || (old_glyph != 0)) return false; - final_size = 0; num_glyphs = plan->num_output_glyphs (); orig_fdcount = acc.fdCount; drop_hints = plan->drop_hints; @@ -620,7 +553,7 @@ struct cff_subset_plan { for (hb_codepoint_t new_glyph = 0; new_glyph < plan->num_output_glyphs (); new_glyph++) { if (!plan->old_gid_for_new_gid(new_glyph, &old_glyph)) - continue; + continue; if (new_glyph != old_glyph) { gid_renum = true; break; @@ -630,13 +563,6 @@ struct cff_subset_plan { subset_charset = gid_renum || !acc.is_predef_charset (); subset_encoding = !acc.is_CID() && !acc.is_predef_encoding (); - /* CFF header */ - final_size += OT::cff1::static_size; - - /* Name INDEX */ - offsets.nameIndexOffset = final_size; - final_size += acc.nameIndex->get_size (); - /* top dict INDEX */ { /* Add encoding/charset to a (copy of) top dict as necessary */ @@ -650,25 +576,16 @@ struct cff_subset_plan { if (need_to_add_set) topdict_mod.add_op (OpCode_charset); } - offsets.topDictInfo.offset = final_size; - cff1_top_dict_op_serializer_t topSzr; - unsigned int topDictSize = TopDict::calculate_serialized_size (topdict_mod, topSzr); - offsets.topDictInfo.offSize = calcOffSize(topDictSize); - if (unlikely (offsets.topDictInfo.offSize > 4)) - return false; - final_size += CFF1IndexOf<TopDict>::calculate_serialized_size<cff1_top_dict_values_mod_t> - (offsets.topDictInfo.offSize, - &topdict_mod, 1, topdict_sizes, topSzr); } /* Determine re-mapping of font index as fdmap among other info */ - if (acc.fdSelect != &Null(CFF1FDSelect)) + if (acc.fdSelect != &Null (CFF1FDSelect)) { if (unlikely (!hb_plan_subset_cff_fdselect (plan, orig_fdcount, *acc.fdSelect, subset_fdcount, - offsets.FDSelectInfo.size, + info.fd_select.size, subset_fdselect_format, subset_fdselect_ranges, fdmap))) @@ -683,18 +600,11 @@ struct cff_subset_plan { if (unlikely (!collect_sids_in_dicts (acc))) return false; if (unlikely (sidmap.get_population () > 0x8000)) /* assumption: a dict won't reference that many strings */ - return false; - if (subset_charset) - offsets.charsetInfo.size = plan_subset_charset (acc, plan); + return false; - topdict_mod.reassignSIDs (sidmap); - } + if (subset_charset) plan_subset_charset (acc, plan); - /* String INDEX */ - { - offsets.stringIndexInfo.offset = final_size; - offsets.stringIndexInfo.size = acc.stringIndex->calculate_serialized_size (offsets.stringIndexInfo.offSize, sidmap); - final_size += offsets.stringIndexInfo.size; + topdict_mod.reassignSIDs (sidmap); } if (desubroutinize) @@ -704,9 +614,6 @@ struct cff_subset_plan { flattener(acc, plan); if (!flattener.flatten (subset_charstrings)) return false; - - /* no global/local subroutines */ - offsets.globalSubrsInfo.size = CFF1Subrs::calculate_serialized_size (1, 0, 0); } else { @@ -723,131 +630,48 @@ struct cff_subset_plan { if (!subr_subsetter.encode_globalsubrs (subset_globalsubrs)) return false; - /* global subrs */ - unsigned int dataSize = subset_globalsubrs.total_size (); - offsets.globalSubrsInfo.offSize = calcOffSize (dataSize); - if (unlikely (offsets.globalSubrsInfo.offSize > 4)) - return false; - offsets.globalSubrsInfo.size = CFF1Subrs::calculate_serialized_size (offsets.globalSubrsInfo.offSize, subset_globalsubrs.length, dataSize); - /* local subrs */ - if (!offsets.localSubrsInfos.resize (orig_fdcount)) - return false; if (!subset_localsubrs.resize (orig_fdcount)) return false; for (unsigned int fd = 0; fd < orig_fdcount; fd++) { subset_localsubrs[fd].init (); - offsets.localSubrsInfos[fd].init (); if (fdmap.has (fd)) { if (!subr_subsetter.encode_localsubrs (fd, subset_localsubrs[fd])) return false; - - unsigned int dataSize = subset_localsubrs[fd].total_size (); - if (dataSize > 0) - { - offsets.localSubrsInfos[fd].offset = final_size; - offsets.localSubrsInfos[fd].offSize = calcOffSize (dataSize); - if (unlikely (offsets.localSubrsInfos[fd].offSize > 4)) - return false; - offsets.localSubrsInfos[fd].size = CFF1Subrs::calculate_serialized_size (offsets.localSubrsInfos[fd].offSize, subset_localsubrs[fd].length, dataSize); - } } } } - /* global subrs */ - offsets.globalSubrsInfo.offset = final_size; - final_size += offsets.globalSubrsInfo.size; - /* Encoding */ - if (!subset_encoding) - offsets.encodingOffset = acc.topDict.EncodingOffset; - else - { - offsets.encodingOffset = final_size; - final_size += plan_subset_encoding (acc, plan); - } - - /* Charset */ - if (!subset_charset && acc.is_predef_charset ()) - offsets.charsetInfo.offset = acc.topDict.CharsetOffset; - else - offsets.charsetInfo.offset = final_size; - final_size += offsets.charsetInfo.size; - - /* FDSelect */ - if (acc.fdSelect != &Null(CFF1FDSelect)) - { - offsets.FDSelectInfo.offset = final_size; - final_size += offsets.FDSelectInfo.size; - } - - /* FDArray (FDIndex) */ - if (acc.fdArray != &Null(CFF1FDArray)) { - offsets.FDArrayInfo.offset = final_size; - cff1_font_dict_op_serializer_t fontSzr; - unsigned int dictsSize = 0; - for (unsigned int i = 0; i < acc.fontDicts.length; i++) - if (fdmap.has (i)) - dictsSize += FontDict::calculate_serialized_size (acc.fontDicts[i], fontSzr); - - offsets.FDArrayInfo.offSize = calcOffSize (dictsSize); - if (unlikely (offsets.FDArrayInfo.offSize > 4)) - return false; - final_size += CFF1Index::calculate_serialized_size (offsets.FDArrayInfo.offSize, subset_fdcount, dictsSize); - } - - /* CharStrings */ - { - offsets.charStringsInfo.offset = final_size; - unsigned int dataSize = subset_charstrings.total_size (); - offsets.charStringsInfo.offSize = calcOffSize (dataSize); - if (unlikely (offsets.charStringsInfo.offSize > 4)) - return false; - final_size += CFF1CharStrings::calculate_serialized_size (offsets.charStringsInfo.offSize, plan->num_output_glyphs (), dataSize); - } + if (subset_encoding) + plan_subset_encoding (acc, plan); /* private dicts & local subrs */ - offsets.privateDictInfo.offset = final_size; - for (unsigned int i = 0; i < orig_fdcount; i++) + if (!acc.is_CID ()) + fontdicts_mod.push (cff1_font_dict_values_mod_t ()); + else { - if (fdmap.has (i)) - { - bool has_localsubrs = offsets.localSubrsInfos[i].size > 0; - cff_private_dict_op_serializer_t privSzr (desubroutinize, plan->drop_hints); - unsigned int priv_size = PrivateDict::calculate_serialized_size (acc.privateDicts[i], privSzr, has_localsubrs); - table_info_t privInfo = { final_size, priv_size, 0 }; - font_dict_values_mod_t fontdict_mod; - if (!acc.is_CID ()) - fontdict_mod.init ( &Null(cff1_font_dict_values_t), CFF_UNDEF_SID, privInfo ); - else - fontdict_mod.init ( &acc.fontDicts[i], sidmap[acc.fontDicts[i].fontName], privInfo ); - fontdicts_mod.push (fontdict_mod); - final_size += privInfo.size; - - if (!plan->desubroutinize && has_localsubrs) + + hb_iter (acc.fontDicts) + | hb_filter ([&] (const cff1_font_dict_values_t &_) + { return fdmap.has (&_ - &acc.fontDicts[0]); } ) + | hb_map ([&] (const cff1_font_dict_values_t &_) { - offsets.localSubrsInfos[i].offset = final_size; - final_size += offsets.localSubrsInfos[i].size; - } - } + cff1_font_dict_values_mod_t mod; + mod.init (&_, sidmap[_.fontName]); + return mod; + }) + | hb_sink (fontdicts_mod) + ; } - if (!acc.is_CID ()) - offsets.privateDictInfo = fontdicts_mod[0].privateDictInfo; - return ((subset_charstrings.length == plan->num_output_glyphs ()) && (fontdicts_mod.length == subset_fdcount)); } - unsigned int get_final_size () const { return final_size; } - - unsigned int final_size; - hb_vector_t<unsigned int> topdict_sizes; cff1_top_dict_values_mod_t topdict_mod; - cff1_sub_table_offsets_t offsets; + cff1_sub_table_info_t info; unsigned int num_glyphs; unsigned int orig_fdcount; @@ -862,7 +686,7 @@ struct cff_subset_plan { str_buff_vec_t subset_charstrings; str_buff_vec_t subset_globalsubrs; hb_vector_t<str_buff_vec_t> subset_localsubrs; - hb_vector_t<font_dict_values_mod_t> fontdicts_mod; + hb_vector_t<cff1_font_dict_values_mod_t> fontdicts_mod; bool drop_hints; @@ -883,91 +707,95 @@ struct cff_subset_plan { bool desubroutinize; }; -static inline bool _write_cff1 (const cff_subset_plan &plan, - const OT::cff1::accelerator_subset_t &acc, - unsigned int num_glyphs, - unsigned int dest_sz, - void *dest) +static bool _serialize_cff1 (hb_serialize_context_t *c, + cff_subset_plan &plan, + const OT::cff1::accelerator_subset_t &acc, + unsigned int num_glyphs) { - hb_serialize_context_t c (dest, dest_sz); - - OT::cff1 *cff = c.start_serialize<OT::cff1> (); - if (unlikely (!c.extend_min (*cff))) - return false; - - /* header */ - cff->version.major = 0x01; - cff->version.minor = 0x00; - cff->nameIndex = cff->min_size; - cff->offSize = 4; /* unused? */ - - /* name INDEX */ + /* private dicts & local subrs */ + for (int i = (int)acc.privateDicts.length; --i >= 0 ;) { - assert (cff->nameIndex == (unsigned) (c.head - c.start)); - CFF1NameIndex *dest = c.start_embed<CFF1NameIndex> (); - if (unlikely (dest == nullptr)) return false; - if (unlikely (!dest->serialize (&c, *acc.nameIndex))) + if (plan.fdmap.has (i)) { - DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF name INDEX"); - return false; - } - } + objidx_t subrs_link = 0; + if (plan.subset_localsubrs[i].length > 0) + { + CFF1Subrs *dest = c->start_embed <CFF1Subrs> (); + if (unlikely (!dest)) return false; + c->push (); + if (likely (dest && dest->serialize (c, plan.subset_localsubrs[i]))) + subrs_link = c->pop_pack (); + else + { + c->pop_discard (); + return false; + } + } - /* top dict INDEX */ - { - assert (plan.offsets.topDictInfo.offset == (unsigned) (c.head - c.start)); - CFF1IndexOf<TopDict> *dest = c.start_embed< CFF1IndexOf<TopDict>> (); - if (dest == nullptr) return false; - cff1_top_dict_op_serializer_t topSzr; - top_dict_modifiers_t modifier (plan.offsets, plan.topDictModSIDs); - if (unlikely (!dest->serialize (&c, plan.offsets.topDictInfo.offSize, - &plan.topdict_mod, 1, - plan.topdict_sizes, topSzr, modifier))) - { - DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF top dict"); - return false; + PrivateDict *pd = c->start_embed<PrivateDict> (); + if (unlikely (!pd)) return false; + c->push (); + cff_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints); + /* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */ + if (likely (pd->serialize (c, acc.privateDicts[i], privSzr, subrs_link))) + { + unsigned fd = plan.fdmap[i]; + plan.fontdicts_mod[fd].privateDictInfo.size = c->length (); + plan.fontdicts_mod[fd].privateDictInfo.link = c->pop_pack (); + } + else + { + c->pop_discard (); + return false; + } } } - /* String INDEX */ + if (!acc.is_CID ()) + plan.info.privateDictInfo = plan.fontdicts_mod[0].privateDictInfo; + + /* CharStrings */ { - assert (plan.offsets.stringIndexInfo.offset == (unsigned) (c.head - c.start)); - CFF1StringIndex *dest = c.start_embed<CFF1StringIndex> (); - if (unlikely (dest == nullptr)) return false; - if (unlikely (!dest->serialize (&c, *acc.stringIndex, plan.offsets.stringIndexInfo.offSize, plan.sidmap))) + CFF1CharStrings *cs = c->start_embed<CFF1CharStrings> (); + if (unlikely (!cs)) return false; + c->push (); + if (likely (cs->serialize (c, plan.subset_charstrings))) + plan.info.char_strings_link = c->pop_pack (); + else { - DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF string INDEX"); + c->pop_discard (); return false; } } - /* global subrs */ + /* FDArray (FD Index) */ + if (acc.fdArray != &Null (CFF1FDArray)) { - assert (plan.offsets.globalSubrsInfo.offset != 0); - assert (plan.offsets.globalSubrsInfo.offset == (unsigned) (c.head - c.start)); - - CFF1Subrs *dest = c.start_embed <CFF1Subrs> (); - if (unlikely (dest == nullptr)) return false; - if (unlikely (!dest->serialize (&c, plan.offsets.globalSubrsInfo.offSize, plan.subset_globalsubrs))) + CFF1FDArray *fda = c->start_embed<CFF1FDArray> (); + if (unlikely (!fda)) return false; + c->push (); + cff1_font_dict_op_serializer_t fontSzr; + auto it = + hb_zip (+ hb_iter (plan.fontdicts_mod), + hb_iter (plan.fontdicts_mod)); + if (likely (fda->serialize (c, it, fontSzr))) + plan.info.fd_array_link = c->pop_pack (false); + else { - DEBUG_MSG (SUBSET, nullptr, "failed to serialize global subroutines"); + c->pop_discard (); return false; } } - /* Encoding */ - if (plan.subset_encoding) + /* FDSelect */ + if (acc.fdSelect != &Null (CFF1FDSelect)) { - assert (plan.offsets.encodingOffset == (unsigned) (c.head - c.start)); - Encoding *dest = c.start_embed<Encoding> (); - if (unlikely (dest == nullptr)) return false; - if (unlikely (!dest->serialize (&c, - plan.subset_enc_format, - plan.subset_enc_num_codes, - plan.subset_enc_code_ranges, - plan.subset_enc_supp_codes))) + c->push (); + if (likely (hb_serialize_cff_fdselect (c, num_glyphs, *acc.fdSelect, acc.fdCount, + plan.subset_fdselect_format, plan.info.fd_select.size, + plan.subset_fdselect_ranges))) + plan.info.fd_select.link = c->pop_pack (); + else { - DEBUG_MSG (SUBSET, nullptr, "failed to serialize Encoding"); + c->pop_discard (); return false; } } @@ -975,129 +803,120 @@ static inline bool _write_cff1 (const cff_subset_plan &plan, /* Charset */ if (plan.subset_charset) { - assert (plan.offsets.charsetInfo.offset == (unsigned) (c.head - c.start)); - Charset *dest = c.start_embed<Charset> (); - if (unlikely (dest == nullptr)) return false; - if (unlikely (!dest->serialize (&c, - plan.subset_charset_format, - plan.num_glyphs, - plan.subset_charset_ranges))) + Charset *dest = c->start_embed<Charset> (); + if (unlikely (!dest)) return false; + c->push (); + if (likely (dest->serialize (c, + plan.subset_charset_format, + plan.num_glyphs, + plan.subset_charset_ranges))) + plan.info.charset_link = c->pop_pack (); + else { - DEBUG_MSG (SUBSET, nullptr, "failed to serialize Charset"); + c->pop_discard (); return false; } } - /* FDSelect */ - if (acc.fdSelect != &Null(CFF1FDSelect)) + /* Encoding */ + if (plan.subset_encoding) { - assert (plan.offsets.FDSelectInfo.offset == (unsigned) (c.head - c.start)); - - if (unlikely (!hb_serialize_cff_fdselect (&c, num_glyphs, *acc.fdSelect, acc.fdCount, - plan.subset_fdselect_format, plan.offsets.FDSelectInfo.size, - plan.subset_fdselect_ranges))) + Encoding *dest = c->start_embed<Encoding> (); + if (unlikely (!dest)) return false; + c->push (); + if (likely (dest->serialize (c, + plan.subset_enc_format, + plan.subset_enc_num_codes, + plan.subset_enc_code_ranges, + plan.subset_enc_supp_codes))) + plan.info.encoding_link = c->pop_pack (); + else { - DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF subset FDSelect"); + c->pop_discard (); return false; } } - /* FDArray (FD Index) */ - if (acc.fdArray != &Null(CFF1FDArray)) + /* global subrs */ { - assert (plan.offsets.FDArrayInfo.offset == (unsigned) (c.head - c.start)); - CFF1FDArray *fda = c.start_embed<CFF1FDArray> (); - if (unlikely (fda == nullptr)) return false; - cff1_font_dict_op_serializer_t fontSzr; - if (unlikely (!fda->serialize (&c, plan.offsets.FDArrayInfo.offSize, - plan.fontdicts_mod, - fontSzr))) + c->push (); + CFF1Subrs *dest = c->start_embed <CFF1Subrs> (); + if (unlikely (!dest)) return false; + if (likely (dest->serialize (c, plan.subset_globalsubrs))) + c->pop_pack (); + else { - DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF FDArray"); + c->pop_discard (); return false; } } - /* CharStrings */ + /* String INDEX */ { - assert (plan.offsets.charStringsInfo.offset == (unsigned) (c.head - c.start)); - CFF1CharStrings *cs = c.start_embed<CFF1CharStrings> (); - if (unlikely (cs == nullptr)) return false; - if (unlikely (!cs->serialize (&c, plan.offsets.charStringsInfo.offSize, plan.subset_charstrings))) + CFF1StringIndex *dest = c->start_embed<CFF1StringIndex> (); + if (unlikely (!dest)) return false; + c->push (); + if (likely (dest->serialize (c, *acc.stringIndex, plan.sidmap))) + c->pop_pack (); + else { - DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF CharStrings"); + c->pop_discard (); return false; } } - /* private dicts & local subrs */ - assert (plan.offsets.privateDictInfo.offset == (unsigned) (c.head - c.start)); - for (unsigned int i = 0; i < acc.privateDicts.length; i++) + OT::cff1 *cff = c->allocate_min<OT::cff1> (); + if (unlikely (!cff)) + return false; + + /* header */ + cff->version.major = 0x01; + cff->version.minor = 0x00; + cff->nameIndex = cff->min_size; + cff->offSize = 4; /* unused? */ + + /* name INDEX */ + if (unlikely (!(*acc.nameIndex).copy (c))) return false; + + /* top dict INDEX */ { - if (plan.fdmap.has (i)) + /* serialize singleton TopDict */ + TopDict *top = c->start_embed<TopDict> (); + if (!top) return false; + c->push (); + cff1_top_dict_op_serializer_t topSzr; + unsigned top_size = 0; + top_dict_modifiers_t modifier (plan.info, plan.topDictModSIDs); + if (likely (top->serialize (c, plan.topdict_mod, topSzr, modifier))) { - PrivateDict *pd = c.start_embed<PrivateDict> (); - if (unlikely (pd == nullptr)) return false; - unsigned int priv_size = plan.fontdicts_mod[plan.fdmap[i]].privateDictInfo.size; - bool result; - cff_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints); - /* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */ - unsigned int subroffset = (plan.offsets.localSubrsInfos[i].size > 0) ? priv_size : 0; - result = pd->serialize (&c, acc.privateDicts[i], privSzr, subroffset); - if (unlikely (!result)) - { - DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF Private Dict[%d]", i); - return false; - } - if (plan.offsets.localSubrsInfos[i].size > 0) - { - CFF1Subrs *dest = c.start_embed <CFF1Subrs> (); - if (unlikely (dest == nullptr)) return false; - if (unlikely (!dest->serialize (&c, plan.offsets.localSubrsInfos[i].offSize, plan.subset_localsubrs[i]))) - { - DEBUG_MSG (SUBSET, nullptr, "failed to serialize local subroutines"); - return false; - } - } + top_size = c->length (); + c->pop_pack (false); } + else + { + c->pop_discard (); + return false; + } + /* serialize INDEX header for above */ + CFF1Index *dest = c->start_embed<CFF1Index> (); + if (!dest) return false; + return dest->serialize_header (c, hb_iter (hb_array_t<unsigned> (&top_size, 1))); } - - assert (c.head == c.end); - c.end_serialize (); - - return true; } -static inline bool +static bool _hb_subset_cff1 (const OT::cff1::accelerator_subset_t &acc, - const char *data, - hb_subset_plan_t *plan, - hb_blob_t **prime /* OUT */) + hb_subset_context_t *c) { cff_subset_plan cff_plan; - if (unlikely (!cff_plan.create (acc, plan))) + if (unlikely (!cff_plan.create (acc, c->plan))) { DEBUG_MSG(SUBSET, nullptr, "Failed to generate a cff subsetting plan."); return false; } - unsigned int cff_prime_size = cff_plan.get_final_size (); - char *cff_prime_data = (char *) calloc (1, cff_prime_size); - - if (unlikely (!_write_cff1 (cff_plan, acc, plan->num_output_glyphs (), - cff_prime_size, cff_prime_data))) { - DEBUG_MSG(SUBSET, nullptr, "Failed to write a subset cff."); - free (cff_prime_data); - return false; - } - - *prime = hb_blob_create (cff_prime_data, - cff_prime_size, - HB_MEMORY_MODE_READONLY, - cff_prime_data, - free); - return true; + return _serialize_cff1 (c->serializer, cff_plan, acc, c->plan->num_output_glyphs ()); } /** @@ -1107,17 +926,11 @@ _hb_subset_cff1 (const OT::cff1::accelerator_subset_t &acc, * Return value: subsetted cff table. **/ bool -hb_subset_cff1 (hb_subset_plan_t *plan, - hb_blob_t **prime /* OUT */) +hb_subset_cff1 (hb_subset_context_t *c) { - hb_blob_t *cff_blob = hb_sanitize_context_t().reference_table<CFF::cff1> (plan->source); - const char *data = hb_blob_get_data(cff_blob, nullptr); - OT::cff1::accelerator_subset_t acc; - acc.init(plan->source); - bool result = likely (acc.is_valid ()) && - _hb_subset_cff1 (acc, data, plan, prime); - hb_blob_destroy (cff_blob); + acc.init (c->plan->source); + bool result = likely (acc.is_valid ()) && _hb_subset_cff1 (acc, c); acc.fini (); return result; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff1.hh b/src/3rdparty/harfbuzz-ng/src/hb-subset-cff1.hh index 1ec8678845..aaf5def1ed 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff1.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-cff1.hh @@ -32,7 +32,6 @@ #include "hb-subset-plan.hh" HB_INTERNAL bool -hb_subset_cff1 (hb_subset_plan_t *plan, - hb_blob_t **cff_prime /* OUT */); +hb_subset_cff1 (hb_subset_context_t *c); #endif /* HB_SUBSET_CFF1_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff2.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-cff2.cc index 7edc3f5153..17ee040deb 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff2.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-cff2.cc @@ -38,43 +38,31 @@ using namespace CFF; -struct cff2_sub_table_offsets_t : cff_sub_table_offsets_t +struct cff2_sub_table_info_t : cff_sub_table_info_t { - cff2_sub_table_offsets_t () - : cff_sub_table_offsets_t (), - varStoreOffset (0) + cff2_sub_table_info_t () + : cff_sub_table_info_t (), + var_store_link (0) {} - unsigned int varStoreOffset; + objidx_t var_store_link; }; struct cff2_top_dict_op_serializer_t : cff_top_dict_op_serializer_t<> { bool serialize (hb_serialize_context_t *c, const op_str_t &opstr, - const cff2_sub_table_offsets_t &offsets) const + const cff2_sub_table_info_t &info) const { TRACE_SERIALIZE (this); switch (opstr.op) { case OpCode_vstore: - return_trace (FontDict::serialize_offset4_op(c, opstr.op, offsets.varStoreOffset)); + return_trace (FontDict::serialize_link4_op(c, opstr.op, info.var_store_link)); default: - return_trace (cff_top_dict_op_serializer_t<>::serialize (c, opstr, offsets)); - } - } - - unsigned int calculate_serialized_size (const op_str_t &opstr) const - { - switch (opstr.op) - { - case OpCode_vstore: - return OpCode_Size (OpCode_longintdict) + 4 + OpCode_Size (opstr.op); - - default: - return cff_top_dict_op_serializer_t<>::calculate_serialized_size (opstr); + return_trace (cff_top_dict_op_serializer_t<>::serialize (c, opstr, info)); } } }; @@ -116,8 +104,8 @@ struct cff2_cs_opset_flatten_t : cff2_cs_opset_t<cff2_cs_opset_flatten_t, flatte const blend_arg_t &arg = env.argStack[i]; if (arg.blending ()) { - if (unlikely (!((arg.numValues > 0) && (env.argStack.get_count () >= arg.numValues)))) - { + if (unlikely (!((arg.numValues > 0) && (env.argStack.get_count () >= arg.numValues)))) + { env.set_error (); return; } @@ -144,8 +132,8 @@ struct cff2_cs_opset_flatten_t : cff2_cs_opset_t<cff2_cs_opset_flatten_t, flatte if (unlikely (!((arg1.blending () && (arg.numValues == arg1.numValues) && (arg1.valueIndex == j) && (arg1.deltas.length == env.get_region_count ()))))) { - env.set_error (); - return; + env.set_error (); + return; } encoder.encode_num (arg1); } @@ -232,7 +220,7 @@ struct cff2_subr_subsetter_t : subr_subsetter_t<cff2_subr_subsetter_t, CFF2Subrs cff2_subr_subsetter_t (const OT::cff2::accelerator_subset_t &acc_, const hb_subset_plan_t *plan_) : subr_subsetter_t (acc_, plan_) {} - static void finalize_parsed_str (cff2_cs_interp_env_t &env, subr_subset_param_t& param, parsed_cs_str_t &charstring) + static void complete_parsed_str (cff2_cs_interp_env_t &env, subr_subset_param_t& param, parsed_cs_str_t &charstring) { /* vsindex is inserted at the beginning of the charstring as necessary */ if (env.seen_vsindex ()) @@ -246,9 +234,9 @@ struct cff2_subr_subsetter_t : subr_subsetter_t<cff2_subr_subsetter_t, CFF2Subrs struct cff2_subset_plan { cff2_subset_plan () - : final_size (0), - orig_fdcount (0), + : orig_fdcount (0), subset_fdcount(1), + subset_fdselect_size (0), subset_fdselect_format (0), drop_hints (false), desubroutinize (false) @@ -258,7 +246,6 @@ struct cff2_subset_plan { subset_charstrings.init (); subset_globalsubrs.init (); subset_localsubrs.init (); - privateDictInfos.init (); } ~cff2_subset_plan () @@ -268,28 +255,16 @@ struct cff2_subset_plan { subset_charstrings.fini_deep (); subset_globalsubrs.fini_deep (); subset_localsubrs.fini_deep (); - privateDictInfos.fini (); } bool create (const OT::cff2::accelerator_subset_t &acc, hb_subset_plan_t *plan) { - final_size = 0; orig_fdcount = acc.fdArray->count; drop_hints = plan->drop_hints; desubroutinize = plan->desubroutinize; - /* CFF2 header */ - final_size += OT::cff2::static_size; - - /* top dict */ - { - cff2_top_dict_op_serializer_t topSzr; - offsets.topDictInfo.size = TopDict::calculate_serialized_size (acc.topDict, topSzr); - final_size += offsets.topDictInfo.size; - } - if (desubroutinize) { /* Flatten global & local subrs */ @@ -297,9 +272,6 @@ struct cff2_subset_plan { flattener(acc, plan); if (!flattener.flatten (subset_charstrings)) return false; - - /* no global/local subroutines */ - offsets.globalSubrsInfo.size = CFF2Subrs::calculate_serialized_size (1, 0, 0); } else { @@ -316,115 +288,41 @@ struct cff2_subset_plan { if (!subr_subsetter.encode_globalsubrs (subset_globalsubrs)) return false; - /* global subrs */ - unsigned int dataSize = subset_globalsubrs.total_size (); - offsets.globalSubrsInfo.offSize = calcOffSize (dataSize); - offsets.globalSubrsInfo.size = CFF2Subrs::calculate_serialized_size (offsets.globalSubrsInfo.offSize, subset_globalsubrs.length, dataSize); - /* local subrs */ - if (!offsets.localSubrsInfos.resize (orig_fdcount)) - return false; if (!subset_localsubrs.resize (orig_fdcount)) return false; for (unsigned int fd = 0; fd < orig_fdcount; fd++) { subset_localsubrs[fd].init (); - offsets.localSubrsInfos[fd].init (); if (!subr_subsetter.encode_localsubrs (fd, subset_localsubrs[fd])) return false; - - unsigned int dataSize = subset_localsubrs[fd].total_size (); - if (dataSize > 0) - { - offsets.localSubrsInfos[fd].offset = final_size; - offsets.localSubrsInfos[fd].offSize = calcOffSize (dataSize); - offsets.localSubrsInfos[fd].size = CFF2Subrs::calculate_serialized_size (offsets.localSubrsInfos[fd].offSize, subset_localsubrs[fd].length, dataSize); - } } } - /* global subrs */ - offsets.globalSubrsInfo.offset = final_size; - final_size += offsets.globalSubrsInfo.size; - - /* variation store */ - if (acc.varStore != &Null(CFF2VariationStore)) - { - offsets.varStoreOffset = final_size; - final_size += acc.varStore->get_size (); - } - /* FDSelect */ - if (acc.fdSelect != &Null(CFF2FDSelect)) + if (acc.fdSelect != &Null (CFF2FDSelect)) { - offsets.FDSelectInfo.offset = final_size; if (unlikely (!hb_plan_subset_cff_fdselect (plan, - orig_fdcount, - *(const FDSelect *)acc.fdSelect, - subset_fdcount, - offsets.FDSelectInfo.size, - subset_fdselect_format, - subset_fdselect_ranges, - fdmap))) + orig_fdcount, + *(const FDSelect *)acc.fdSelect, + subset_fdcount, + subset_fdselect_size, + subset_fdselect_format, + subset_fdselect_ranges, + fdmap))) return false; - - final_size += offsets.FDSelectInfo.size; } else fdmap.identity (1); - /* FDArray (FDIndex) */ - { - offsets.FDArrayInfo.offset = final_size; - cff_font_dict_op_serializer_t fontSzr; - unsigned int dictsSize = 0; - for (unsigned int i = 0; i < acc.fontDicts.length; i++) - if (fdmap.has (i)) - dictsSize += FontDict::calculate_serialized_size (acc.fontDicts[i], fontSzr); - - offsets.FDArrayInfo.offSize = calcOffSize (dictsSize); - final_size += CFF2Index::calculate_serialized_size (offsets.FDArrayInfo.offSize, subset_fdcount, dictsSize); - } - - /* CharStrings */ - { - offsets.charStringsInfo.offset = final_size; - unsigned int dataSize = subset_charstrings.total_size (); - offsets.charStringsInfo.offSize = calcOffSize (dataSize); - final_size += CFF2CharStrings::calculate_serialized_size (offsets.charStringsInfo.offSize, plan->num_output_glyphs (), dataSize); - } - - /* private dicts & local subrs */ - offsets.privateDictsOffset = final_size; - for (unsigned int i = 0; i < orig_fdcount; i++) - { - if (fdmap.has (i)) - { - bool has_localsubrs = offsets.localSubrsInfos[i].size > 0; - cff_private_dict_op_serializer_t privSzr (desubroutinize, drop_hints); - unsigned int priv_size = PrivateDict::calculate_serialized_size (acc.privateDicts[i], privSzr, has_localsubrs); - table_info_t privInfo = { final_size, priv_size, 0 }; - privateDictInfos.push (privInfo); - final_size += privInfo.size; - - if (!plan->desubroutinize && has_localsubrs) - { - offsets.localSubrsInfos[i].offset = final_size; - final_size += offsets.localSubrsInfos[i].size; - } - } - } - return true; } - unsigned int get_final_size () const { return final_size; } - - unsigned int final_size; - cff2_sub_table_offsets_t offsets; + cff2_sub_table_info_t info; unsigned int orig_fdcount; unsigned int subset_fdcount; + unsigned int subset_fdselect_size; unsigned int subset_fdselect_format; hb_vector_t<code_pair_t> subset_fdselect_ranges; @@ -433,200 +331,158 @@ struct cff2_subset_plan { str_buff_vec_t subset_charstrings; str_buff_vec_t subset_globalsubrs; hb_vector_t<str_buff_vec_t> subset_localsubrs; - hb_vector_t<table_info_t> privateDictInfos; bool drop_hints; bool desubroutinize; }; -static inline bool _write_cff2 (const cff2_subset_plan &plan, - const OT::cff2::accelerator_subset_t &acc, - unsigned int num_glyphs, - unsigned int dest_sz, - void *dest) +static bool _serialize_cff2 (hb_serialize_context_t *c, + cff2_subset_plan &plan, + const OT::cff2::accelerator_subset_t &acc, + unsigned int num_glyphs) { - hb_serialize_context_t c (dest, dest_sz); - - OT::cff2 *cff2 = c.start_serialize<OT::cff2> (); - if (unlikely (!c.extend_min (*cff2))) - return false; - - /* header */ - cff2->version.major = 0x02; - cff2->version.minor = 0x00; - cff2->topDict = OT::cff2::static_size; + /* private dicts & local subrs */ + hb_vector_t<table_info_t> private_dict_infos; + if (unlikely (!private_dict_infos.resize (plan.subset_fdcount))) return false; - /* top dict */ + for (int i = (int)acc.privateDicts.length; --i >= 0 ;) { - assert (cff2->topDict == (unsigned) (c.head - c.start)); - cff2->topDictSize = plan.offsets.topDictInfo.size; - TopDict &dict = cff2 + cff2->topDict; - cff2_top_dict_op_serializer_t topSzr; - if (unlikely (!dict.serialize (&c, acc.topDict, topSzr, plan.offsets))) + if (plan.fdmap.has (i)) { - DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF2 top dict"); - return false; - } - } + objidx_t subrs_link = 0; - /* global subrs */ - { - assert (cff2->topDict + plan.offsets.topDictInfo.size == (unsigned) (c.head - c.start)); - CFF2Subrs *dest = c.start_embed <CFF2Subrs> (); - if (unlikely (dest == nullptr)) return false; - if (unlikely (!dest->serialize (&c, plan.offsets.globalSubrsInfo.offSize, plan.subset_globalsubrs))) - { - DEBUG_MSG (SUBSET, nullptr, "failed to serialize global subroutines"); - return false; + if (plan.subset_localsubrs[i].length > 0) + { + CFF2Subrs *dest = c->start_embed <CFF2Subrs> (); + if (unlikely (!dest)) return false; + c->push (); + if (likely (dest->serialize (c, plan.subset_localsubrs[i]))) + subrs_link = c->pop_pack (); + else + { + c->pop_discard (); + return false; + } + } + PrivateDict *pd = c->start_embed<PrivateDict> (); + if (unlikely (!pd)) return false; + c->push (); + cff_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints); + if (likely (pd->serialize (c, acc.privateDicts[i], privSzr, subrs_link))) + { + unsigned fd = plan.fdmap[i]; + private_dict_infos[fd].size = c->length (); + private_dict_infos[fd].link = c->pop_pack (); + } + else + { + c->pop_discard (); + return false; + } } } - /* variation store */ - if (acc.varStore != &Null(CFF2VariationStore)) + /* CharStrings */ { - assert (plan.offsets.varStoreOffset == (unsigned) (c.head - c.start)); - CFF2VariationStore *dest = c.start_embed<CFF2VariationStore> (); - if (unlikely (!dest->serialize (&c, acc.varStore))) + CFF2CharStrings *cs = c->start_embed<CFF2CharStrings> (); + if (unlikely (!cs)) return false; + c->push (); + if (likely (cs->serialize (c, plan.subset_charstrings))) + plan.info.char_strings_link = c->pop_pack (); + else { - DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF2 Variation Store"); + c->pop_discard (); return false; } } /* FDSelect */ - if (acc.fdSelect != &Null(CFF2FDSelect)) + if (acc.fdSelect != &Null (CFF2FDSelect)) { - assert (plan.offsets.FDSelectInfo.offset == (unsigned) (c.head - c.start)); - - if (unlikely (!hb_serialize_cff_fdselect (&c, num_glyphs, *(const FDSelect *)acc.fdSelect, acc.fdArray->count, - plan.subset_fdselect_format, plan.offsets.FDSelectInfo.size, - plan.subset_fdselect_ranges))) + c->push (); + if (likely (hb_serialize_cff_fdselect (c, num_glyphs, *(const FDSelect *)acc.fdSelect, plan.orig_fdcount, + plan.subset_fdselect_format, plan.subset_fdselect_size, + plan.subset_fdselect_ranges))) + plan.info.fd_select.link = c->pop_pack (); + else { - DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF2 subset FDSelect"); + c->pop_discard (); return false; } } /* FDArray (FD Index) */ { - assert (plan.offsets.FDArrayInfo.offset == (unsigned) (c.head - c.start)); - CFF2FDArray *fda = c.start_embed<CFF2FDArray> (); - if (unlikely (fda == nullptr)) return false; - cff_font_dict_op_serializer_t fontSzr; - if (unlikely (!fda->serialize (&c, plan.offsets.FDArrayInfo.offSize, - acc.fontDicts, plan.subset_fdcount, plan.fdmap, - fontSzr, plan.privateDictInfos))) - { - DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF2 FDArray"); - return false; - } + c->push (); + CFF2FDArray *fda = c->start_embed<CFF2FDArray> (); + if (unlikely (!fda)) return false; + cff_font_dict_op_serializer_t fontSzr; + auto it = + + hb_zip (+ hb_iter (acc.fontDicts) + | hb_filter ([&] (const cff2_font_dict_values_t &_) + { return plan.fdmap.has (&_ - &acc.fontDicts[0]); }), + hb_iter (private_dict_infos)) + ; + if (unlikely (!fda->serialize (c, it, fontSzr))) return false; + plan.info.fd_array_link = c->pop_pack (); } - /* CharStrings */ + /* variation store */ + if (acc.varStore != &Null (CFF2VariationStore)) { - assert (plan.offsets.charStringsInfo.offset == (unsigned) (c.head - c.start)); - CFF2CharStrings *cs = c.start_embed<CFF2CharStrings> (); - if (unlikely (cs == nullptr)) return false; - if (unlikely (!cs->serialize (&c, plan.offsets.charStringsInfo.offSize, plan.subset_charstrings))) - { - DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF2 CharStrings"); - return false; - } + c->push (); + CFF2VariationStore *dest = c->start_embed<CFF2VariationStore> (); + if (unlikely (!dest || !dest->serialize (c, acc.varStore))) return false; + plan.info.var_store_link = c->pop_pack (); } - /* private dicts & local subrs */ - assert (plan.offsets.privateDictsOffset == (unsigned) (c.head - c.start)); - for (unsigned int i = 0; i < acc.privateDicts.length; i++) + OT::cff2 *cff2 = c->allocate_min<OT::cff2> (); + if (unlikely (!cff2)) return false; + + /* header */ + cff2->version.major = 0x02; + cff2->version.minor = 0x00; + cff2->topDict = OT::cff2::static_size; + + /* top dict */ { - if (plan.fdmap.has (i)) - { - PrivateDict *pd = c.start_embed<PrivateDict> (); - if (unlikely (pd == nullptr)) return false; - unsigned int priv_size = plan.privateDictInfos[plan.fdmap[i]].size; - bool result; - cff_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints); - /* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */ - unsigned int subroffset = (plan.offsets.localSubrsInfos[i].size > 0) ? priv_size : 0; - result = pd->serialize (&c, acc.privateDicts[i], privSzr, subroffset); - if (unlikely (!result)) - { - DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF Private Dict[%d]", i); - return false; - } - if (plan.offsets.localSubrsInfos[i].size > 0) - { - CFF2Subrs *dest = c.start_embed <CFF2Subrs> (); - if (unlikely (dest == nullptr)) return false; - if (unlikely (!dest->serialize (&c, plan.offsets.localSubrsInfos[i].offSize, plan.subset_localsubrs[i]))) - { - DEBUG_MSG (SUBSET, nullptr, "failed to serialize local subroutines"); - return false; - } - } - } + TopDict &dict = cff2 + cff2->topDict; + cff2_top_dict_op_serializer_t topSzr; + if (unlikely (!dict.serialize (c, acc.topDict, topSzr, plan.info))) return false; + cff2->topDictSize = c->head - (const char *)&dict; } - assert (c.head == c.end); - c.end_serialize (); - - return true; + /* global subrs */ + { + CFF2Subrs *dest = c->start_embed <CFF2Subrs> (); + if (unlikely (!dest)) return false; + return dest->serialize (c, plan.subset_globalsubrs); + } } -static inline bool +static bool _hb_subset_cff2 (const OT::cff2::accelerator_subset_t &acc, - const char *data, - hb_subset_plan_t *plan, - hb_blob_t **prime /* OUT */) + hb_subset_context_t *c) { cff2_subset_plan cff2_plan; - if (unlikely (!cff2_plan.create (acc, plan))) - { - DEBUG_MSG(SUBSET, nullptr, "Failed to generate a cff2 subsetting plan."); - return false; - } - - unsigned int cff2_prime_size = cff2_plan.get_final_size (); - char *cff2_prime_data = (char *) calloc (1, cff2_prime_size); - - if (unlikely (!_write_cff2 (cff2_plan, acc, plan->num_output_glyphs (), - cff2_prime_size, cff2_prime_data))) { - DEBUG_MSG(SUBSET, nullptr, "Failed to write a subset cff2."); - free (cff2_prime_data); - return false; - } - - *prime = hb_blob_create (cff2_prime_data, - cff2_prime_size, - HB_MEMORY_MODE_READONLY, - cff2_prime_data, - free); - return true; + if (unlikely (!cff2_plan.create (acc, c->plan))) return false; + return _serialize_cff2 (c->serializer, cff2_plan, acc, c->plan->num_output_glyphs ()); } /** * hb_subset_cff2: - * Subsets the CFF2 table according to a provided plan. - * - * Return value: subsetted cff2 table. + * Subsets the CFF2 table according to a provided subset context. **/ bool -hb_subset_cff2 (hb_subset_plan_t *plan, - hb_blob_t **prime /* OUT */) +hb_subset_cff2 (hb_subset_context_t *c) { - hb_blob_t *cff2_blob = hb_sanitize_context_t().reference_table<CFF::cff2> (plan->source); - const char *data = hb_blob_get_data(cff2_blob, nullptr); - OT::cff2::accelerator_subset_t acc; - acc.init(plan->source); - bool result = likely (acc.is_valid ()) && - _hb_subset_cff2 (acc, data, plan, prime); - - hb_blob_destroy (cff2_blob); + acc.init (c->plan->source); + bool result = likely (acc.is_valid ()) && _hb_subset_cff2 (acc, c); acc.fini (); return result; } - #endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff2.hh b/src/3rdparty/harfbuzz-ng/src/hb-subset-cff2.hh index a07dc290e5..f10556ddd7 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff2.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-cff2.hh @@ -32,7 +32,6 @@ #include "hb-subset-plan.hh" HB_INTERNAL bool -hb_subset_cff2 (hb_subset_plan_t *plan, - hb_blob_t **cff2_prime /* OUT */); +hb_subset_cff2 (hb_subset_context_t *c); #endif /* HB_SUBSET_CFF2_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc index d92f33ffed..fe9be3ce02 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc @@ -46,10 +46,13 @@ hb_subset_input_create_or_fail () input->glyphs = hb_set_create (); input->name_ids = hb_set_create (); hb_set_add_range (input->name_ids, 0, 6); + input->name_languages = hb_set_create (); + hb_set_add (input->name_languages, 0x0409); input->drop_tables = hb_set_create (); input->drop_hints = false; input->desubroutinize = false; input->retain_gids = false; + input->name_legacy = false; hb_tag_t default_drop_tables[] = { // Layout disabled by default @@ -77,8 +80,6 @@ hb_subset_input_create_or_fail () HB_TAG ('G', 'l', 'o', 'c'), HB_TAG ('S', 'i', 'l', 'f'), HB_TAG ('S', 'i', 'l', 'l'), - // Colour - HB_TAG ('s', 'b', 'i', 'x') }; input->drop_tables->add_array (default_drop_tables, ARRAY_LENGTH (default_drop_tables)); @@ -116,6 +117,7 @@ hb_subset_input_destroy (hb_subset_input_t *subset_input) hb_set_destroy (subset_input->unicodes); hb_set_destroy (subset_input->glyphs); hb_set_destroy (subset_input->name_ids); + hb_set_destroy (subset_input->name_languages); hb_set_destroy (subset_input->drop_tables); free (subset_input); @@ -152,6 +154,12 @@ hb_subset_input_nameid_set (hb_subset_input_t *subset_input) } HB_EXTERN hb_set_t * +hb_subset_input_namelangid_set (hb_subset_input_t *subset_input) +{ + return subset_input->name_languages; +} + +HB_EXTERN hb_set_t * hb_subset_input_drop_tables_set (hb_subset_input_t *subset_input) { return subset_input->drop_tables; @@ -206,3 +214,16 @@ hb_subset_input_get_retain_gids (hb_subset_input_t *subset_input) { return subset_input->retain_gids; } + +HB_EXTERN void +hb_subset_input_set_name_legacy (hb_subset_input_t *subset_input, + hb_bool_t name_legacy) +{ + subset_input->name_legacy = name_legacy; +} + +HB_EXTERN hb_bool_t +hb_subset_input_get_name_legacy (hb_subset_input_t *subset_input) +{ + return subset_input->name_legacy; +} diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-input.hh b/src/3rdparty/harfbuzz-ng/src/hb-subset-input.hh index f6dd4ac319..0aeb96695b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset-input.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-input.hh @@ -41,11 +41,13 @@ struct hb_subset_input_t hb_set_t *unicodes; hb_set_t *glyphs; hb_set_t *name_ids; + hb_set_t *name_languages; hb_set_t *drop_tables; bool drop_hints; bool desubroutinize; bool retain_gids; + bool name_legacy; /* TODO * * features diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.cc index f4912f86ba..d055783a4d 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.cc @@ -30,10 +30,15 @@ #include "hb-ot-cmap-table.hh" #include "hb-ot-glyf-table.hh" +#include "hb-ot-layout-gdef-table.hh" +#include "hb-ot-layout-gpos-table.hh" +#include "hb-ot-layout-gsub-table.hh" #include "hb-ot-cff1-table.hh" +#include "hb-ot-color-colr-table.hh" #include "hb-ot-var-fvar-table.hh" #include "hb-ot-stat-table.hh" + #ifndef HB_NO_SUBSET_CFF static inline void _add_cff_seac_components (const OT::cff1::accelerator_t &cff, @@ -50,8 +55,22 @@ _add_cff_seac_components (const OT::cff1::accelerator_t &cff, #endif #ifndef HB_NO_SUBSET_LAYOUT +static void +_remap_indexes (const hb_set_t *indexes, + hb_map_t *mapping /* OUT */) +{ + unsigned count = indexes->get_population (); + + for (auto _ : + hb_zip (indexes->iter (), hb_range (count))) + mapping->set (_.first, _.second); + +} + static inline void -_gsub_closure (hb_face_t *face, hb_set_t *gids_to_retain) +_gsub_closure_glyphs_lookups_features (hb_face_t *face, + hb_set_t *gids_to_retain, + hb_map_t *gsub_lookups, + hb_map_t *gsub_features) { hb_set_t lookup_indices; hb_ot_layout_collect_lookups (face, @@ -63,6 +82,86 @@ _gsub_closure (hb_face_t *face, hb_set_t *gids_to_retain) hb_ot_layout_lookups_substitute_closure (face, &lookup_indices, gids_to_retain); + hb_blob_ptr_t<OT::GSUB> gsub = hb_sanitize_context_t ().reference_table<OT::GSUB> (face); + gsub->closure_lookups (face, + gids_to_retain, + &lookup_indices); + _remap_indexes (&lookup_indices, gsub_lookups); + + // Collect and prune features + hb_set_t feature_indices; + hb_ot_layout_collect_features (face, + HB_OT_TAG_GSUB, + nullptr, + nullptr, + nullptr, + &feature_indices); + gsub->prune_features (gsub_lookups, &feature_indices); + _remap_indexes (&feature_indices, gsub_features); + + gsub.destroy (); +} + +static inline void +_gpos_closure_lookups_features (hb_face_t *face, + const hb_set_t *gids_to_retain, + hb_map_t *gpos_lookups, + hb_map_t *gpos_features) +{ + hb_set_t lookup_indices; + hb_ot_layout_collect_lookups (face, + HB_OT_TAG_GPOS, + nullptr, + nullptr, + nullptr, + &lookup_indices); + hb_blob_ptr_t<OT::GPOS> gpos = hb_sanitize_context_t ().reference_table<OT::GPOS> (face); + gpos->closure_lookups (face, + gids_to_retain, + &lookup_indices); + _remap_indexes (&lookup_indices, gpos_lookups); + + // Collect and prune features + hb_set_t feature_indices; + hb_ot_layout_collect_features (face, + HB_OT_TAG_GPOS, + nullptr, + nullptr, + nullptr, + &feature_indices); + gpos->prune_features (gpos_lookups, &feature_indices); + _remap_indexes (&feature_indices, gpos_features); + gpos.destroy (); +} +#endif + +#ifndef HB_NO_VAR +static inline void + _collect_layout_variation_indices (hb_face_t *face, + const hb_set_t *glyphset, + const hb_map_t *gpos_lookups, + hb_set_t *layout_variation_indices, + hb_map_t *layout_variation_idx_map) +{ + hb_blob_ptr_t<OT::GDEF> gdef = hb_sanitize_context_t ().reference_table<OT::GDEF> (face); + hb_blob_ptr_t<OT::GPOS> gpos = hb_sanitize_context_t ().reference_table<OT::GPOS> (face); + + if (!gdef->has_data ()) + { + gdef.destroy (); + gpos.destroy (); + return; + } + OT::hb_collect_variation_indices_context_t c (layout_variation_indices, glyphset, gpos_lookups); + gdef->collect_variation_indices (&c); + + if (hb_ot_layout_has_positioning (face)) + gpos->collect_variation_indices (&c); + + gdef->remap_layout_variation_indices (layout_variation_indices, layout_variation_idx_map); + + gdef.destroy (); + gpos.destroy (); } #endif @@ -93,14 +192,22 @@ static void _populate_gids_to_retain (hb_subset_plan_t* plan, const hb_set_t *unicodes, const hb_set_t *input_glyphs_to_retain, - bool close_over_gsub) + bool close_over_gsub, + bool close_over_gpos, + bool close_over_gdef) { OT::cmap::accelerator_t cmap; OT::glyf::accelerator_t glyf; +#ifndef HB_NO_SUBSET_CFF OT::cff1::accelerator_t cff; +#endif + OT::COLR::accelerator_t colr; cmap.init (plan->source); glyf.init (plan->source); +#ifndef HB_NO_SUBSET_CFF cff.init (plan->source); +#endif + colr.init (plan->source); plan->_glyphset_gsub->add (0); // Not-def hb_set_union (plan->_glyphset_gsub, input_glyphs_to_retain); @@ -123,8 +230,11 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, #ifndef HB_NO_SUBSET_LAYOUT if (close_over_gsub) - // Add all glyphs needed for GSUB substitutions. - _gsub_closure (plan->source, plan->_glyphset_gsub); + // closure all glyphs/lookups/features needed for GSUB substitutions. + _gsub_closure_glyphs_lookups_features (plan->source, plan->_glyphset_gsub, plan->gsub_lookups, plan->gsub_features); + + if (close_over_gpos) + _gpos_closure_lookups_features (plan->source, plan->_glyphset_gsub, plan->gpos_lookups, plan->gpos_features); #endif _remove_invalid_gids (plan->_glyphset_gsub, plan->source->get_num_glyphs ()); @@ -138,11 +248,24 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, if (cff.is_valid ()) _add_cff_seac_components (cff, gid, plan->_glyphset); #endif + if (colr.is_valid ()) + colr.closure_glyphs (gid, plan->_glyphset); } _remove_invalid_gids (plan->_glyphset, plan->source->get_num_glyphs ()); +#ifndef HB_NO_VAR + if (close_over_gdef) + _collect_layout_variation_indices (plan->source, + plan->_glyphset_gsub, + plan->gpos_lookups, + plan->layout_variation_indices, + plan->layout_variation_idx_map); +#endif + +#ifndef HB_NO_SUBSET_CFF cff.fini (); +#endif glyf.fini (); cmap.fini (); } @@ -186,7 +309,7 @@ static void _nameid_closure (hb_face_t *face, hb_set_t *nameids) { -#ifndef HB_NO_STAT +#ifndef HB_NO_STYLE face->table.STAT->collect_name_ids (nameids); #endif #ifndef HB_NO_VAR @@ -208,14 +331,20 @@ hb_subset_plan_t * hb_subset_plan_create (hb_face_t *face, hb_subset_input_t *input) { - hb_subset_plan_t *plan = hb_object_create<hb_subset_plan_t> (); + hb_subset_plan_t *plan; + if (unlikely (!(plan = hb_object_create<hb_subset_plan_t> ()))) + return const_cast<hb_subset_plan_t *> (&Null (hb_subset_plan_t)); + plan->successful = true; plan->drop_hints = input->drop_hints; plan->desubroutinize = input->desubroutinize; plan->retain_gids = input->retain_gids; + plan->name_legacy = input->name_legacy; plan->unicodes = hb_set_create (); plan->name_ids = hb_set_reference (input->name_ids); _nameid_closure (face, plan->name_ids); + plan->name_languages = hb_set_reference (input->name_languages); + plan->glyphs_requested = hb_set_reference (input->glyphs); plan->drop_tables = hb_set_reference (input->drop_tables); plan->source = hb_face_reference (face); plan->dest = hb_face_builder_create (); @@ -225,11 +354,19 @@ hb_subset_plan_create (hb_face_t *face, plan->codepoint_to_glyph = hb_map_create (); plan->glyph_map = hb_map_create (); plan->reverse_glyph_map = hb_map_create (); + plan->gsub_lookups = hb_map_create (); + plan->gpos_lookups = hb_map_create (); + plan->gsub_features = hb_map_create (); + plan->gpos_features = hb_map_create (); + plan->layout_variation_indices = hb_set_create (); + plan->layout_variation_idx_map = hb_map_create (); _populate_gids_to_retain (plan, input->unicodes, input->glyphs, - !input->drop_tables->has (HB_OT_TAG_GSUB)); + !input->drop_tables->has (HB_OT_TAG_GSUB), + !input->drop_tables->has (HB_OT_TAG_GPOS), + !input->drop_tables->has (HB_OT_TAG_GDEF)); _create_old_gid_to_new_gid_map (face, input->retain_gids, @@ -253,6 +390,8 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan) hb_set_destroy (plan->unicodes); hb_set_destroy (plan->name_ids); + hb_set_destroy (plan->name_languages); + hb_set_destroy (plan->glyphs_requested); hb_set_destroy (plan->drop_tables); hb_face_destroy (plan->source); hb_face_destroy (plan->dest); @@ -261,6 +400,13 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan) hb_map_destroy (plan->reverse_glyph_map); hb_set_destroy (plan->_glyphset); hb_set_destroy (plan->_glyphset_gsub); + hb_map_destroy (plan->gsub_lookups); + hb_map_destroy (plan->gpos_lookups); + hb_map_destroy (plan->gsub_features); + hb_map_destroy (plan->gpos_features); + hb_set_destroy (plan->layout_variation_indices); + hb_map_destroy (plan->layout_variation_idx_map); + free (plan); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh index af2337e494..cc9cb7a1a2 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh @@ -39,9 +39,11 @@ struct hb_subset_plan_t { hb_object_header_t header; + bool successful : 1; bool drop_hints : 1; bool desubroutinize : 1; bool retain_gids : 1; + bool name_legacy : 1; // For each cp that we'd like to retain maps to the corresponding gid. hb_set_t *unicodes; @@ -49,6 +51,12 @@ struct hb_subset_plan_t // name_ids we would like to retain hb_set_t *name_ids; + // name_languages we would like to retain + hb_set_t *name_languages; + + //glyph ids requested to retain + hb_set_t *glyphs_requested; + // Tables which should be dropped. hb_set_t *drop_tables; @@ -67,8 +75,29 @@ struct hb_subset_plan_t hb_set_t *_glyphset; hb_set_t *_glyphset_gsub; + //active lookups we'd like to retain + hb_map_t *gsub_lookups; + hb_map_t *gpos_lookups; + + //active features we'd like to retain + hb_map_t *gsub_features; + hb_map_t *gpos_features; + + //The set of layout item variation store delta set indices to be retained + hb_set_t *layout_variation_indices; + //Old -> New layout item variation store delta set index mapping + hb_map_t *layout_variation_idx_map; + public: + bool in_error () const { return !successful; } + + bool check_success(bool success) + { + successful = (successful && success); + return successful; + } + /* * The set of input glyph ids which will be retained in the subset. * Does NOT include ids kept due to retain_gids. You probably want to use @@ -143,12 +172,15 @@ struct hb_subset_plan_t add_table (hb_tag_t tag, hb_blob_t *contents) { - hb_blob_t *source_blob = source->reference_table (tag); - DEBUG_MSG(SUBSET, nullptr, "add table %c%c%c%c, dest %d bytes, source %d bytes", - HB_UNTAG(tag), - hb_blob_get_length (contents), - hb_blob_get_length (source_blob)); - hb_blob_destroy (source_blob); + if (HB_DEBUG_SUBSET) + { + hb_blob_t *source_blob = source->reference_table (tag); + DEBUG_MSG(SUBSET, nullptr, "add table %c%c%c%c, dest %d bytes, source %d bytes", + HB_UNTAG(tag), + hb_blob_get_length (contents), + hb_blob_get_length (source_blob)); + hb_blob_destroy (source_blob); + } return hb_face_builder_add_table (dest, tag, contents); } }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset.cc index ec2f8892fd..8b77ecd45a 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset.cc @@ -37,35 +37,36 @@ #include "hb-ot-hhea-table.hh" #include "hb-ot-hmtx-table.hh" #include "hb-ot-maxp-table.hh" +#include "hb-ot-color-sbix-table.hh" +#include "hb-ot-color-colr-table.hh" #include "hb-ot-os2-table.hh" #include "hb-ot-post-table.hh" #include "hb-ot-cff1-table.hh" #include "hb-ot-cff2-table.hh" #include "hb-ot-vorg-table.hh" #include "hb-ot-name-table.hh" +#include "hb-ot-color-cbdt-table.hh" #include "hb-ot-layout-gsub-table.hh" #include "hb-ot-layout-gpos-table.hh" +#include "hb-ot-var-gvar-table.hh" +#include "hb-ot-var-hvar-table.hh" -HB_UNUSED static inline unsigned int -_plan_estimate_subset_table_size (hb_subset_plan_t *plan, - unsigned int table_len); -static inline unsigned int -_plan_estimate_subset_table_size (hb_subset_plan_t *plan, - unsigned int table_len) +static unsigned +_plan_estimate_subset_table_size (hb_subset_plan_t *plan, unsigned table_len) { - unsigned int src_glyphs = plan->source->get_num_glyphs (); - unsigned int dst_glyphs = plan->glyphset ()->get_population (); + unsigned src_glyphs = plan->source->get_num_glyphs (); + unsigned dst_glyphs = plan->glyphset ()->get_population (); if (unlikely (!src_glyphs)) return 512 + table_len; - return 512 + (unsigned int) (table_len * sqrt ((double) dst_glyphs / src_glyphs)); + return 512 + (unsigned) (table_len * sqrt ((double) dst_glyphs / src_glyphs)); } template<typename TableType> static bool -_subset2 (hb_subset_plan_t *plan) +_subset (hb_subset_plan_t *plan) { bool result = false; hb_blob_t *source_blob = hb_sanitize_context_t ().reference_table<TableType> (plan->source); @@ -77,26 +78,26 @@ _subset2 (hb_subset_plan_t *plan) hb_vector_t<char> buf; /* TODO Not all tables are glyph-related. 'name' table size for example should not be * affected by number of glyphs. Accommodate that. */ - unsigned int buf_size = _plan_estimate_subset_table_size (plan, source_blob->length); - DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size); + unsigned buf_size = _plan_estimate_subset_table_size (plan, source_blob->length); + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size); if (unlikely (!buf.alloc (buf_size))) { - DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG (tag), buf_size); + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG (tag), buf_size); hb_blob_destroy (source_blob); return false; } retry: hb_serialize_context_t serializer ((void *) buf, buf_size); serializer.start_serialize<TableType> (); - hb_subset_context_t c (plan, &serializer); + hb_subset_context_t c (source_blob, plan, &serializer, tag); bool needed = table->subset (&c); if (serializer.ran_out_of_room) { buf_size += (buf_size >> 1) + 32; - DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", HB_UNTAG (tag), buf_size); + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", HB_UNTAG (tag), buf_size); if (unlikely (!buf.alloc (buf_size))) { - DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", HB_UNTAG (tag), buf_size); + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", HB_UNTAG (tag), buf_size); hb_blob_destroy (source_blob); return false; } @@ -111,159 +112,119 @@ _subset2 (hb_subset_plan_t *plan) if (needed) { hb_blob_t *dest_blob = serializer.copy_blob (); - DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c final subset table size: %u bytes.", HB_UNTAG (tag), dest_blob->length); + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c final subset table size: %u bytes.", HB_UNTAG (tag), dest_blob->length); result = c.plan->add_table (tag, dest_blob); hb_blob_destroy (dest_blob); } else { - DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag)); + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag)); } } } else - DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag)); + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag)); hb_blob_destroy (source_blob); - DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG (tag), result ? "success" : "FAILED!"); + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG (tag), result ? "success" : "FAILED!"); return result; } -template<typename TableType> static bool -_subset (hb_subset_plan_t *plan) +_is_table_present (hb_face_t *source, hb_tag_t tag) { - hb_blob_t *source_blob = hb_sanitize_context_t ().reference_table<TableType> (plan->source); - const TableType *table = source_blob->as<TableType> (); - - hb_tag_t tag = TableType::tableTag; - hb_bool_t result = false; - if (source_blob->data) - result = table->subset (plan); - else - DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag)); - - hb_blob_destroy (source_blob); - DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG (tag), result ? "success" : "FAILED!"); - return result; + hb_tag_t table_tags[32]; + unsigned offset = 0, num_tables = ARRAY_LENGTH (table_tags); + while ((hb_face_get_table_tags (source, offset, &num_tables, table_tags), num_tables)) + { + for (unsigned i = 0; i < num_tables; ++i) + if (table_tags[i] == tag) + return true; + offset += num_tables; + } + return false; } - static bool -_subset_table (hb_subset_plan_t *plan, - hb_tag_t tag) +_should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag) { - DEBUG_MSG(SUBSET, nullptr, "begin subset %c%c%c%c", HB_UNTAG (tag)); - bool result = true; - switch (tag) { - case HB_OT_TAG_glyf: - result = _subset2<const OT::glyf> (plan); - break; - case HB_OT_TAG_hdmx: - result = _subset2<const OT::hdmx> (plan); - break; - case HB_OT_TAG_name: - result = _subset2<const OT::name> (plan); - break; - case HB_OT_TAG_head: - // TODO that won't work well if there is no glyf - DEBUG_MSG(SUBSET, nullptr, "skip head, handled by glyf"); - result = true; - break; - case HB_OT_TAG_hhea: - DEBUG_MSG(SUBSET, nullptr, "skip hhea handled by hmtx"); - return true; - case HB_OT_TAG_hmtx: - result = _subset2<const OT::hmtx> (plan); - break; - case HB_OT_TAG_vhea: - DEBUG_MSG(SUBSET, nullptr, "skip vhea handled by vmtx"); - return true; - case HB_OT_TAG_vmtx: - result = _subset2<const OT::vmtx> (plan); - break; - case HB_OT_TAG_maxp: - result = _subset2<const OT::maxp> (plan); - break; - case HB_OT_TAG_loca: - DEBUG_MSG(SUBSET, nullptr, "skip loca handled by glyf"); - return true; - case HB_OT_TAG_cmap: - result = _subset2<const OT::cmap> (plan); - break; - case HB_OT_TAG_OS2: - result = _subset2<const OT::OS2> (plan); - break; - case HB_OT_TAG_post: - result = _subset2<const OT::post> (plan); - break; + if (plan->drop_tables->has (tag)) + return true; -#ifndef HB_NO_SUBSET_CFF - case HB_OT_TAG_cff1: - result = _subset<const OT::cff1> (plan); - break; - case HB_OT_TAG_cff2: - result = _subset<const OT::cff2> (plan); - break; - case HB_OT_TAG_VORG: - result = _subset2<const OT::VORG> (plan); - break; -#endif + switch (tag) + { + case HB_TAG ('c','v','a','r'): /* hint table, fallthrough */ + case HB_TAG ('c','v','t',' '): /* hint table, fallthrough */ + case HB_TAG ('f','p','g','m'): /* hint table, fallthrough */ + case HB_TAG ('p','r','e','p'): /* hint table, fallthrough */ + case HB_TAG ('h','d','m','x'): /* hint table, fallthrough */ + case HB_TAG ('V','D','M','X'): /* hint table, fallthrough */ + return plan->drop_hints; -#ifndef HB_NO_SUBSET_LAYOUT - case HB_OT_TAG_GDEF: - result = _subset2<const OT::GDEF> (plan); - break; - case HB_OT_TAG_GSUB: - result = _subset2<const OT::GSUB> (plan); - break; - case HB_OT_TAG_GPOS: - result = _subset2<const OT::GPOS> (plan); - break; +#ifdef HB_NO_SUBSET_LAYOUT + // Drop Layout Tables if requested. + case HB_OT_TAG_GDEF: + case HB_OT_TAG_GPOS: + case HB_OT_TAG_GSUB: + case HB_TAG ('m','o','r','x'): + case HB_TAG ('m','o','r','t'): + case HB_TAG ('k','e','r','x'): + case HB_TAG ('k','e','r','n'): + return true; #endif - default: - hb_blob_t *source_table = hb_face_reference_table (plan->source, tag); - if (likely (source_table)) - result = plan->add_table (tag, source_table); - else - result = false; - hb_blob_destroy (source_table); - break; + default: + return false; } - DEBUG_MSG(SUBSET, nullptr, "subset %c%c%c%c %s", HB_UNTAG (tag), result ? "ok" : "FAILED"); - return result; } static bool -_should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag) +_subset_table (hb_subset_plan_t *plan, hb_tag_t tag) { - if (plan->drop_tables->has (tag)) - return true; + DEBUG_MSG (SUBSET, nullptr, "subset %c%c%c%c", HB_UNTAG (tag)); + switch (tag) + { + case HB_OT_TAG_glyf: return _subset<const OT::glyf> (plan); + case HB_OT_TAG_hdmx: return _subset<const OT::hdmx> (plan); + case HB_OT_TAG_name: return _subset<const OT::name> (plan); + case HB_OT_TAG_head: + if (_is_table_present (plan->source, HB_OT_TAG_glyf) && !_should_drop_table (plan, HB_OT_TAG_glyf)) + return true; /* skip head, handled by glyf */ + return _subset<const OT::head> (plan); + case HB_OT_TAG_hhea: return true; /* skip hhea, handled by hmtx */ + case HB_OT_TAG_hmtx: return _subset<const OT::hmtx> (plan); + case HB_OT_TAG_vhea: return true; /* skip vhea, handled by vmtx */ + case HB_OT_TAG_vmtx: return _subset<const OT::vmtx> (plan); + case HB_OT_TAG_maxp: return _subset<const OT::maxp> (plan); + case HB_OT_TAG_sbix: return _subset<const OT::sbix> (plan); + case HB_OT_TAG_loca: return true; /* skip loca, handled by glyf */ + case HB_OT_TAG_cmap: return _subset<const OT::cmap> (plan); + case HB_OT_TAG_OS2 : return _subset<const OT::OS2 > (plan); + case HB_OT_TAG_post: return _subset<const OT::post> (plan); + case HB_OT_TAG_COLR: return _subset<const OT::COLR> (plan); + case HB_OT_TAG_CBLC: return _subset<const OT::CBLC> (plan); + case HB_OT_TAG_CBDT: return true; /* skip CBDT, handled by CBLC */ - switch (tag) { - case HB_TAG ('c', 'v', 'a', 'r'): /* hint table, fallthrough */ - case HB_TAG ('c', 'v', 't', ' '): /* hint table, fallthrough */ - case HB_TAG ('f', 'p', 'g', 'm'): /* hint table, fallthrough */ - case HB_TAG ('p', 'r', 'e', 'p'): /* hint table, fallthrough */ - case HB_TAG ('h', 'd', 'm', 'x'): /* hint table, fallthrough */ - case HB_TAG ('V', 'D', 'M', 'X'): /* hint table, fallthrough */ - return plan->drop_hints; +#ifndef HB_NO_SUBSET_CFF + case HB_OT_TAG_cff1: return _subset<const OT::cff1> (plan); + case HB_OT_TAG_cff2: return _subset<const OT::cff2> (plan); + case HB_OT_TAG_VORG: return _subset<const OT::VORG> (plan); +#endif -#ifdef HB_NO_SUBSET_LAYOUT - // Drop Layout Tables if requested. - case HB_OT_TAG_GDEF: - case HB_OT_TAG_GPOS: - case HB_OT_TAG_GSUB: - case HB_TAG ('m', 'o', 'r', 'x'): - case HB_TAG ('m', 'o', 'r', 't'): - case HB_TAG ('k', 'e', 'r', 'x'): - case HB_TAG ('k', 'e', 'r', 'n'): - return true; +#ifndef HB_NO_SUBSET_LAYOUT + case HB_OT_TAG_GDEF: return _subset<const OT::GDEF> (plan); + case HB_OT_TAG_GSUB: return _subset<const OT::GSUB> (plan); + case HB_OT_TAG_GPOS: return _subset<const OT::GPOS> (plan); + case HB_OT_TAG_gvar: return _subset<const OT::gvar> (plan); + case HB_OT_TAG_HVAR: return _subset<const OT::HVAR> (plan); + case HB_OT_TAG_VVAR: return _subset<const OT::VVAR> (plan); #endif - default: - return false; + default: + hb_blob_t *source_table = hb_face_reference_table (plan->source, tag); + bool result = plan->add_table (tag, source_table); + hb_blob_destroy (source_table); + return result; } } @@ -275,35 +236,34 @@ _should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag) * Subsets a font according to provided input. **/ hb_face_t * -hb_subset (hb_face_t *source, - hb_subset_input_t *input) +hb_subset (hb_face_t *source, hb_subset_input_t *input) { if (unlikely (!input || !source)) return hb_face_get_empty (); hb_subset_plan_t *plan = hb_subset_plan_create (source, input); + if (unlikely (plan->in_error ())) + return hb_face_get_empty (); - hb_tag_t table_tags[32]; - unsigned int offset = 0, count; - bool success = true; hb_set_t tags_set; - do { - count = ARRAY_LENGTH (table_tags); - hb_face_get_table_tags (source, offset, &count, table_tags); - for (unsigned int i = 0; i < count; i++) + bool success = true; + hb_tag_t table_tags[32]; + unsigned offset = 0, num_tables = ARRAY_LENGTH (table_tags); + while ((hb_face_get_table_tags (source, offset, &num_tables, table_tags), num_tables)) + { + for (unsigned i = 0; i < num_tables; ++i) { hb_tag_t tag = table_tags[i]; - if (_should_drop_table (plan, tag) && !tags_set.has (tag)) - { - DEBUG_MSG(SUBSET, nullptr, "drop %c%c%c%c", HB_UNTAG (tag)); - continue; - } + if (_should_drop_table (plan, tag) && !tags_set.has (tag)) continue; tags_set.add (tag); - success = success && _subset_table (plan, tag); + success = _subset_table (plan, tag); + if (unlikely (!success)) goto end; } - offset += count; - } while (success && count == ARRAY_LENGTH (table_tags)); + offset += num_tables; + } +end: hb_face_t *result = success ? hb_face_reference (plan->dest) : hb_face_get_empty (); + hb_subset_plan_destroy (plan); return result; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset.h b/src/3rdparty/harfbuzz-ng/src/hb-subset.h index 960afefa5b..ddf4409734 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset.h @@ -58,6 +58,9 @@ HB_EXTERN hb_set_t * hb_subset_input_nameid_set (hb_subset_input_t *subset_input); HB_EXTERN hb_set_t * +hb_subset_input_namelangid_set (hb_subset_input_t *subset_input); + +HB_EXTERN hb_set_t * hb_subset_input_drop_tables_set (hb_subset_input_t *subset_input); HB_EXTERN void @@ -78,6 +81,12 @@ hb_subset_input_set_retain_gids (hb_subset_input_t *subset_input, HB_EXTERN hb_bool_t hb_subset_input_get_retain_gids (hb_subset_input_t *subset_input); +HB_EXTERN void +hb_subset_input_set_name_legacy (hb_subset_input_t *subset_input, + hb_bool_t name_legacy); +HB_EXTERN hb_bool_t +hb_subset_input_get_name_legacy (hb_subset_input_t *subset_input); + /* hb_subset () */ HB_EXTERN hb_face_t * hb_subset (hb_face_t *source, hb_subset_input_t *input); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset.hh b/src/3rdparty/harfbuzz-ng/src/hb-subset.hh index b8dd07ab28..c9b01c67f3 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset.hh @@ -54,15 +54,19 @@ struct hb_subset_context_t : dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN ( _dispatch (obj, hb_prioritize, hb_forward<Ts> (ds)...) ) + hb_blob_t *source_blob; hb_subset_plan_t *plan; hb_serialize_context_t *serializer; - unsigned int debug_depth; + hb_tag_t table_tag; - hb_subset_context_t (hb_subset_plan_t *plan_, - hb_serialize_context_t *serializer_) : + hb_subset_context_t (hb_blob_t *source_blob_, + hb_subset_plan_t *plan_, + hb_serialize_context_t *serializer_, + hb_tag_t table_tag_) : + source_blob (source_blob_), plan (plan_), serializer (serializer_), - debug_depth (0) {} + table_tag (table_tag_) {} }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ucd-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ucd-table.hh index 8b7d648a93..88623db338 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ucd-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ucd-table.hh @@ -4,7 +4,7 @@ * * ./gen-ucd-table.py ucd.nounihan.grouped.xml * - * on file with this description: Unicode 12.1.0 + * on file with this description: Unicode 13.0.0 */ #ifndef HB_UCD_TABLE_HH @@ -13,7 +13,7 @@ #include "hb.hh" static const hb_script_t -_hb_ucd_sc_map[153] = +_hb_ucd_sc_map[157] = { HB_SCRIPT_COMMON, HB_SCRIPT_INHERITED, HB_SCRIPT_UNKNOWN, HB_SCRIPT_ARABIC, @@ -91,7 +91,9 @@ _hb_ucd_sc_map[153] = HB_SCRIPT_MEDEFAIDRIN, HB_SCRIPT_OLD_SOGDIAN, HB_SCRIPT_SOGDIAN, HB_SCRIPT_ELYMAIC, HB_SCRIPT_NANDINAGARI, HB_SCRIPT_NYIAKENG_PUACHUE_HMONG, - HB_SCRIPT_WANCHO, + HB_SCRIPT_WANCHO, HB_SCRIPT_CHORASMIAN, + HB_SCRIPT_DIVES_AKURU, HB_SCRIPT_KHITAN_SMALL_SCRIPT, + HB_SCRIPT_YEZIDI, }; static const uint16_t _hb_ucd_dm1_p0_map[825] = @@ -862,7 +864,7 @@ _hb_ucd_dm2_u32_map[638] = HB_CODEPOINT_ENCODE3_11_7_14 (0x04E9u, 0x0308u, 0x04EBu), }; static const uint64_t -_hb_ucd_dm2_u64_map[387] = +_hb_ucd_dm2_u64_map[388] = { HB_CODEPOINT_ENCODE3 (0x05D0u, 0x05B7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D0u, 0x05B8u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D0u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D1u, 0x05BCu, 0x0000u), @@ -1051,19 +1053,19 @@ _hb_ucd_dm2_u64_map[387] = HB_CODEPOINT_ENCODE3 (0x11347u, 0x11357u, 0x1134Cu),HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114B0u, 0x114BCu), HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114BAu, 0x114BBu),HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114BDu, 0x114BEu), HB_CODEPOINT_ENCODE3 (0x115B8u, 0x115AFu, 0x115BAu),HB_CODEPOINT_ENCODE3 (0x115B9u, 0x115AFu, 0x115BBu), - HB_CODEPOINT_ENCODE3 (0x1D157u, 0x1D165u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D158u, 0x1D165u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D16Eu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D16Fu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D170u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D171u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D172u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D1B9u, 0x1D165u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x1D1BAu, 0x1D165u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D1BBu, 0x1D16Eu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x1D1BBu, 0x1D16Fu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D1BCu, 0x1D16Eu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x1D1BCu, 0x1D16Fu, 0x0000u), + HB_CODEPOINT_ENCODE3 (0x11935u, 0x11930u, 0x11938u), HB_CODEPOINT_ENCODE3 (0x1D157u, 0x1D165u, 0x0000u), + HB_CODEPOINT_ENCODE3 (0x1D158u, 0x1D165u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D16Eu, 0x0000u), + HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D16Fu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D170u, 0x0000u), + HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D171u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D172u, 0x0000u), + HB_CODEPOINT_ENCODE3 (0x1D1B9u, 0x1D165u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D1BAu, 0x1D165u, 0x0000u), + HB_CODEPOINT_ENCODE3 (0x1D1BBu, 0x1D16Eu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D1BBu, 0x1D16Fu, 0x0000u), + HB_CODEPOINT_ENCODE3 (0x1D1BCu, 0x1D16Eu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D1BCu, 0x1D16Fu, 0x0000u), }; #ifndef HB_OPTIMIZE_SIZE static const uint8_t -_hb_ucd_u8[32102] = +_hb_ucd_u8[32480] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 26, 26, 26, 26, 26, @@ -1077,7 +1079,7 @@ _hb_ucd_u8[32102] = 26, 57, 58, 59, 59, 59, 59, 59, 26, 26, 60, 59, 59, 59, 59, 59, 59, 59, 26, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 26, 62, 59, 63, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 64, 26, 65, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 26, 26, 26, 64, 26, 26, 65, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 66, 67, 59, 59, 59, 59, 68, 59, 59, 59, 59, 59, 59, 59, 59, 59, 69, 70, 71, 72, 73, 74, 59, 59, 75, 76, 59, 59, 77, 59, 78, 79, 80, 81, 73, 82, 83, 84, 59, 59, @@ -1089,6 +1091,7 @@ _hb_ucd_u8[32102] = 26, 26, 26, 85, 26, 26, 26, 26, 26, 26, 26, 86, 87, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 88, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 89, 59, 59, 59, 59, 59, 59, 26, 90, 59, 59, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 91, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, @@ -1176,8 +1179,7 @@ _hb_ucd_u8[32102] = 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 91, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 92, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, @@ -1192,7 +1194,7 @@ _hb_ucd_u8[32102] = 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 92, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 93, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, @@ -1200,7 +1202,7 @@ _hb_ucd_u8[32102] = 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 93, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 21, 21, 21, 23, 21, 21, 21, 22, 18, 21, 25, 21, 17, 21, 21, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 21, 21, 25, 25, 25, 21, @@ -1274,7 +1276,8 @@ _hb_ucd_u8[32102] = 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 12, 12, 2, 2, 21, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 2, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, + 7, 7, 7, 7, 7, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 1, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, @@ -1306,7 +1309,7 @@ _hb_ucd_u8[32102] = 2, 12, 10, 10, 2, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 7, 7, 2, 7, 7, 2, 7, 7, 7, 7, 7, 2, 2, 12, 7, 10, 12, 10, 12, 12, 12, 12, 2, 2, 10, 10, 2, 2, 10, 10, 12, 2, 2, - 2, 2, 2, 2, 2, 2, 12, 10, 2, 2, 2, 2, 7, 7, 2, 7, + 2, 2, 2, 2, 2, 12, 12, 10, 2, 2, 2, 2, 7, 7, 2, 7, 26, 7, 15, 15, 15, 15, 15, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 12, 7, 2, 7, 7, 7, 7, 7, 7, 2, 2, 2, 7, 7, 7, 2, 7, 7, 7, 7, 2, 2, 2, 7, 7, 2, 7, 2, 7, 7, @@ -1326,12 +1329,12 @@ _hb_ucd_u8[32102] = 10, 10, 10, 10, 10, 2, 12, 10, 10, 2, 10, 10, 12, 12, 2, 2, 2, 2, 2, 2, 2, 10, 10, 2, 2, 2, 2, 2, 2, 2, 7, 2, 2, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 12, 12, 10, 10, 2, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, + 12, 12, 10, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 12, 7, 10, 10, 10, 12, 12, 12, 12, 2, 10, 10, 10, 2, 10, 10, 10, 12, 7, 26, 2, 2, 2, 2, 7, 7, 7, 10, 15, 15, 15, 15, 15, 15, 15, 7, 15, 15, 15, 15, 15, 15, 15, 15, 15, 26, 7, 7, 7, 7, 7, 7, - 2, 2, 10, 10, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 2, 12, 10, 10, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, 2, 2, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 12, 2, 2, 2, 2, 10, @@ -1415,7 +1418,8 @@ _hb_ucd_u8[32102] = 12, 10, 12, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 10, 10, 10, 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 2, 12, 21, 21, 21, 21, 21, 21, 21, 6, 21, 21, 21, 21, 21, 21, 2, 2, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 2, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 12, + 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 10, 12, 12, 12, 12, 12, 10, 12, 10, 10, 10, 10, 10, 12, 10, 10, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, @@ -1464,7 +1468,6 @@ _hb_ucd_u8[32102] = 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 12, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 9, 26, 26, 26, 26, 9, 26, 26, 5, 9, 9, 9, 5, 5, 9, 9, 9, 5, 26, 9, 26, 26, 25, 9, 9, 9, 9, 9, 26, 26, 26, 26, 26, 26, 9, 26, 9, 26, 9, 26, 9, 9, 9, 9, 26, 5, @@ -1505,7 +1508,7 @@ _hb_ucd_u8[32102] = 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 22, 18, 25, 25, 25, 25, 25, 25, 25, 26, 26, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 9, 5, 9, 9, 9, 5, 5, 9, 5, 9, 5, 9, 5, 9, 9, 9, @@ -1522,6 +1525,7 @@ _hb_ucd_u8[32102] = 20, 19, 22, 18, 22, 18, 22, 18, 22, 18, 21, 21, 21, 21, 21, 6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 17, 17, 21, 21, 21, 21, 17, 21, 22, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 26, 26, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26, 26, 26, 26, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -1554,10 +1558,10 @@ _hb_ucd_u8[32102] = 9, 5, 9, 5, 5, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 9, 9, 9, 9, 5, 9, 9, 9, 9, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, - 2, 2, 9, 5, 9, 9, 9, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 7, 6, 6, 5, 7, 7, 7, 7, 7, + 2, 2, 9, 5, 9, 9, 9, 9, 5, 9, 5, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 9, 5, 7, 6, 6, 5, 7, 7, 7, 7, 7, 7, 7, 12, 7, 7, 7, 12, 7, 7, 7, 7, 12, 7, 7, 7, 7, - 7, 7, 7, 10, 10, 12, 12, 10, 26, 26, 26, 26, 2, 2, 2, 2, + 7, 7, 7, 10, 10, 12, 12, 10, 26, 26, 26, 26, 12, 2, 2, 2, 15, 15, 15, 15, 15, 15, 26, 26, 23, 26, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 21, 21, 21, 21, 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, @@ -1585,7 +1589,7 @@ _hb_ucd_u8[32102] = 2, 7, 7, 7, 7, 7, 7, 2, 2, 7, 7, 7, 7, 7, 7, 2, 2, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 6, 6, 6, 6, - 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 24, 24, 2, 2, 2, 2, 7, 7, 7, 10, 10, 12, 10, 10, 12, 10, 10, 21, 10, 12, 2, 2, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 7, 7, 7, 7, 7, @@ -1601,14 +1605,12 @@ _hb_ucd_u8[32102] = 2, 2, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 18, 22, 2, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 23, 26, 2, 2, 21, 21, 21, 21, 21, 21, 21, 22, 18, 21, 2, 2, 2, 2, 2, 2, 21, 17, 17, 16, 16, 22, 18, 22, 18, 22, 18, 22, 18, 22, 18, 22, 18, 22, 18, 22, 18, 21, 21, 22, 18, 21, 21, 21, 21, 16, 16, 16, 21, 21, 21, 2, 21, 21, 21, 21, 17, 22, 18, 22, 18, 22, 18, 21, 21, 21, 25, 17, 25, 25, 25, 2, 21, 23, 21, 21, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 1, 2, 21, 21, 21, 23, 21, 21, 21, 22, 18, 21, 25, 21, 17, 21, 21, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 22, 25, 18, 25, 22, @@ -1625,6 +1627,7 @@ _hb_ucd_u8[32102] = 15, 15, 15, 15, 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 14, 14, 14, 14, 14, 15, 15, 15, 15, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 15, 15, 26, 26, 26, 2, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, 26, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 12, 2, 2, 12, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, @@ -1668,8 +1671,11 @@ _hb_ucd_u8[32102] = 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, 2, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 12, 12, 17, 2, 2, + 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 15, 15, 15, 15, 15, 15, 15, 7, 2, 2, 2, 2, 2, 2, 2, 2, 12, 15, 15, 15, 15, 21, 21, 21, 21, 21, 2, 2, 2, 2, 2, 2, + 7, 7, 7, 7, 7, 15, 15, 15, 15, 15, 15, 15, 2, 2, 2, 2, 10, 12, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 21, 21, 21, 21, 21, 21, 21, 2, 2, @@ -1680,10 +1686,10 @@ _hb_ucd_u8[32102] = 12, 12, 12, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 12, 12, 12, 12, 10, 12, 12, 12, 12, 12, 12, 12, 12, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 21, 21, 21, 21, 7, 10, 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 21, 21, 21, 21, 7, 10, 10, 7, 2, 2, 2, 2, 2, 2, 2, 2, 7, 7, 7, 12, 21, 21, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 7, 7, 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 10, - 10, 7, 7, 7, 7, 21, 21, 21, 21, 12, 12, 12, 12, 21, 2, 2, + 10, 7, 7, 7, 7, 21, 21, 21, 21, 12, 12, 12, 12, 21, 10, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 7, 21, 7, 21, 21, 21, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -1702,7 +1708,7 @@ _hb_ucd_u8[32102] = 12, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 10, 10, 12, 12, 12, 10, 12, 7, 7, 7, 7, 21, 21, 21, 21, 21, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 21, 2, 21, 12, 7, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 21, 21, 2, 21, 12, 7, 10, 10, 10, 12, 12, 12, 12, 12, 12, 10, 12, 10, 10, 10, 10, 12, 12, 10, 12, 12, 7, 7, 21, 7, 2, 2, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 10, @@ -1718,6 +1724,10 @@ _hb_ucd_u8[32102] = 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 15, 15, 21, 21, 21, 26, 12, 12, 12, 12, 12, 12, 12, 12, 10, 12, 12, 21, 2, 2, 2, 2, 15, 15, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, + 7, 7, 7, 7, 7, 7, 7, 2, 2, 7, 2, 2, 7, 7, 7, 7, + 7, 7, 7, 7, 2, 7, 7, 2, 7, 7, 7, 7, 7, 7, 7, 7, + 10, 10, 10, 10, 10, 10, 2, 10, 10, 2, 2, 12, 12, 10, 12, 7, + 10, 7, 10, 12, 21, 21, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 12, 12, 12, 12, 2, 2, 12, 12, 10, 10, 10, 10, 12, 7, 21, 7, 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -1759,7 +1769,8 @@ _hb_ucd_u8[32102] = 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 21, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 6, 6, 21, 6, 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 10, 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 26, 12, 12, 21, @@ -1832,334 +1843,338 @@ _hb_ucd_u8[32102] = 2, 7, 7, 7, 2, 7, 7, 7, 7, 7, 2, 7, 7, 7, 7, 7, 25, 25, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 24, 24, 24, 24, 24, 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, 2, 2, 2, 2, 2, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 26, 26, 26, - 26, 26, 2, 26, 26, 26, 26, 2, 2, 2, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 2, 2, 26, 26, 26, 26, 26, 26, 2, 2, 2, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, 26, 26, 26, - 26, 26, 26, 26, 2, 2, 2, 2, 26, 26, 26, 2, 2, 2, 2, 2, - 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 26, 26, 26, 26, 26, 2, 2, 2, 26, 26, 26, 2, 2, 2, 2, 2, + 26, 26, 26, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, - 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 0, 0, 15, 0, 0, 0, 16, 17, 18, 19, 20, 21, 22, 0, 0, - 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 25, 0, 0, - 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 12, 12, 13, 14, 12, 15, 16, 17, 18, 19, 20, + 21, 22, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 24, 25, + 0, 26, 27, 0, 28, 29, 30, 31, 32, 33, 0, 34, 0, 0, 0, 0, + 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 37, 38, 0, 0, 0, 0, + 39, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 27, 0, 28, 29, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 33, 0, - 0, 34, 35, 36, 0, 0, 0, 0, 0, 0, 37, 0, 0, 38, 0, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 0, 51, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, + 43, 44, 45, 46, 0, 47, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 56, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 58, 54, 59, 0, 0, 0, 0, 0, 60, 61, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, - 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, 14, 15, - 0, 16, 0, 0, 0, 0, 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 22, 23, 0, 24, 25, 0, 0, 26, - 0, 0, 0, 0, 0, 0, 0, 27, 28, 29, 0, 0, 0, 30, 31, 32, - 0, 0, 0, 0, 0, 30, 31, 0, 0, 33, 0, 0, 0, 30, 31, 0, - 0, 0, 0, 0, 0, 30, 31, 0, 0, 0, 0, 0, 0, 30, 31, 0, - 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 31, 34, - 0, 0, 0, 0, 0, 30, 31, 0, 0, 0, 0, 0, 0, 35, 31, 0, - 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 37, 38, 0, - 0, 0, 0, 0, 0, 39, 40, 0, 0, 0, 0, 41, 0, 42, 0, 0, - 0, 43, 44, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 46, 0, 0, - 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 49, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 0, 0, 0, 0, - 54, 55, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 57, 49, 0, - 58, 59, 0, 0, 60, 0, 0, 0, 61, 62, 0, 0, 0, 63, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 64, 65, 66, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 67, 68, 1, 69, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 70, 71, 72, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 73, 74, 0, 0, 0, 0, 0, 0, - 0, 75, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 76, 0, 0, 0, - 0, 0, 0, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 73, 78, 0, 79, 0, 0, 0, 0, 0, 74, 80, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 49, 0, 1, 74, 0, 0, 81, 0, 0, 82, - 0, 0, 0, 0, 0, 83, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 84, 85, 0, 0, 80, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 86, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, - 0, 89, 0, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 91, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 0, 0, 0, 93, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 88, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, - 0, 75, 0, 0, 0, 95, 0, 0, 0, 0, 96, 0, 0, 97, 0, 0, - 0, 83, 0, 0, 0, 0, 98, 0, 0, 0, 0, 0, 0, 99, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,100, 0, 0, 0, 0,101, 31, 0, - 102,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 33, - 0, 0, 0, 0, 0, 0,105, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 75,106, 0, 0, 0, 0, 0, 0, 75, 0, 0, - 0, 0, 0, 0, 0,107, 0, 0, 0, 0, 0, 0,108, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 49,109, 0, - 0, 0, 0,110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111, 0, - 0, 0, 0,109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,112, 0, 0, 0,113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 115,116,117, 0,118, 0, 0, 0, 0, 0, 0, 0, 0, 0,119, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120,121,122, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 51, 0, 52, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 55, 0, 0, 0, 0, 56, 0, 0, 57, 58, 0, + 59, 60, 61, 62, 63, 64, 65, 0, 66, 67, 0, 68, 69, 70, 71, 0, + 60, 0, 72, 73, 74, 75, 0, 0, 69, 0, 76, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,123, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,124, 0, 0, 0, 0, 0, 0,125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,230,230,230,230,230,230, - 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,232, - 220,220,220,220,232,216,220,220,220,220,220,202,202,220,220,220, - 220,202,202,220,220,220,220,220,220,220,220,220,220,220, 1, 1, - 1, 1, 1,220,220,220,220,230,230,230,230,230,230,230,230,240, - 230,220,220,220,230,230,230,220,220, 0,230,230,230,220,220,220, - 220,230,232,220,220,230,233,234,234,233,234,234,233,230,230,230, - 230,230,230,230,230,230,230,230,230,230, 0, 0, 0,230,230,230, - 230,230, 0, 0, 0, 0, 0, 0, 0, 0, 0,220,230,230,230,230, - 220,230,230,230,222,220,230,230,230,230,230,230,220,220,220,220, - 220,220,230,230,220,230,230,222,228,230, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0,230,220, - 0, 18, 0, 0, 0, 0, 0, 0, 0, 0,230,230,230,230,230,230, - 230,230, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, 34,230,230,220, - 220,230,230,230,230,230,220,230,230,220, 35, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 230,230,230,230,230,230,230, 0, 0,230,230,230,230,220,230, 0, - 0,230,230, 0,220,230,230,220, 0, 0, 0, 36, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,230,220,230,230,220,230, - 230,220,220,220,230,220,220,230,220,230,230,230,220,230,220,230, - 220,230,220,230,230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,230,230,230,230,230,230,230,220,230, 0, 0, - 0, 0, 0, 0, 0, 0, 0,220, 0, 0, 0, 0, 0, 0, 0, 0, - 230,230,230,230, 0,230,230,230,230,230,230,230,230,230, 0,230, - 230,230, 0,230,230,230,230,230, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,220,220,220, 0, 0, 0, 0, 0, 0, 0,220,230,230, - 230,230,230,230,230,230,230,230,230,230,230,230, 0,220,230,230, - 220,230,230,220,230,230,230,220,220,220, 27, 28, 29,230,230,230, - 220,230,230,220,220,230,230,230,230,230, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230,230, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,230, 0, 0, 0, 0, 0, 0, 84, - 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,103,103, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,107,107,107,107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,118,118, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,122,122,122,122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,220,220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,220, - 0,220, 0,216, 0, 0, 0, 0, 0, 0, 0,129,130, 0,132, 0, - 0, 0, 0, 0,130,130,130,130, 0, 0,130, 0,230,230, 9, 0, - 230,230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 7, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,220, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,230,230,230, 0, 0, 0, 0, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,230, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,222,230,220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,230,220, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,230, - 230,230,230,230,230,230,230, 0, 0,220,230,230,230,230,230,220, - 220,220,220,220,220,230,230,220, 0, 0, 0, 0, 0, 0, 7, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,230,220,230,230,230,230,230,230,230, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 7, 0, 0, 0, 0, 0, 0, 0, 0,230,230,230, 0, 1,220, - 220,220,220,220,230,230,220,220,220,220,230, 0, 1, 1, 1, 1, - 1, 1, 1, 0, 0, 0, 0,220, 0, 0, 0, 0, 0, 0,230, 0, - 0, 0,230,230, 0, 0, 0, 0, 0, 0,230,230,220,230,230,230, - 230,230,230,230,220,230,230,234,214,220,202,230,230,230,230,230, - 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, - 232,228,228,220, 0,230,233,220,230,220,230,230, 1, 1,230,230, - 230,230, 1, 1, 1,230,230, 0, 0, 0, 0,230, 0, 0, 0, 1, - 1,230,220,230, 1, 1,220,220,220,220,230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,230,230,230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,218,228,232,222,224,224, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,230,230, - 230,230,230,230,230,230,230,230, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,230,230, 0, 0, 0, 0, 0, 0, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,220,220,220, 0, 0, 0, 0, 0, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,230, 0,230,230,220, 0, - 0,230,230, 0, 0, 0, 0, 0,230,230, 0,230, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 26, 0,230,230,230,230,230,230, - 230,220,220,220,220,220,220,220,230,230,220, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 230,230,230,230,230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,220, 0,230, 0, 0, 0, 0, 0, 0, - 0, 0,230, 1,220, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0,230, - 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,230,230, - 230,230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 220,220,230,230,230,220,230,220,220,220, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 7, 0, 0, 0, 0, 0,230,230,230, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 230,230,230,230,230,230,230, 0, 0, 0,230,230,230,230,230, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, - 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 7, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,230,230,230,230,230,230, - 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,216, - 216, 1, 1, 1, 0, 0, 0,226,216,216,216,216,216, 0, 0, 0, - 0, 0, 0, 0, 0,220,220,220,220,220,220,220,220, 0, 0,230, - 230,230,230,230,220,220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,230,230,230,230, 0, 0, 0, 0,230,230,230, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 78, 79, 0, 0, 0, 0, 0, 0, 0, 0, 80, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 82, 83, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85, 0, 79, 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 87, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 1, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 14, 15, 16, 17, 18, 19, 20, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 21, 0, 0, 0, 0, 0, 22, 23, 24, + 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 27, + 28, 29, 0, 0, 0, 0, 30, 0, 0, 0, 31, 32, 33, 34, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 13, 35, 36, 0, 0, 26, 37, 38, 39, 0, 0, 0, 0, 0, 40, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 1, + 42, 43, 44, 45, 0, 0, 0, 0, 0, 0, 0, 46, 0, 47, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 47, 0, 0, + 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 46, 0, 47, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 50, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 47, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 0, 54, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 56, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 58, 59, 0, 0, 0, 0, + 0, 0, 60, 61, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 65, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, + 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 68, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 71, 72, 0, 0, 0, 0, 0, 0, 0, 0, + 73, 0, 66, 74, 0, 0, 0, 0, 0, 0, 75, 76, 72, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 67, 0, 0, 0, + 0, 77, 78, 0, 0, 0, 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, + 80, 0, 79, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 82, + 83, 84, 85, 86, 0, 0, 0, 0, 0, 0, 0, 0, 87, 88, 89, 1, + 1, 1, 90, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, + 94, 95, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 71, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, 0, 0, 0, 98, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 71,100,101, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 86, 0,102, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, + 1, 1, 86, 0, 0, 0, 0, 0, 0,103, 0, 0, 0, 0,104, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105, 0, 73, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,106,107,108, 0, 0, 0, + 0, 0,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 47, 0, 0, 0, 0, 0,109, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,110,111, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 26,112, 0,113, 0, 0, 0, 0, 0,114, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 115, 0, 0, 0, 0, 0, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117,118, 72, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,102, 0, 0, 0, + 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0,119, 0, 0, 0, 0, + 0, 0, 0, 0,112, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, + 0, 0,105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73,120, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,121, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,122, 0, 0, 0, 0, 0, 0, 0, 0, 0,123, 0, 47, 0, 0, + 26,124,124, 0, 0, 0, 0, 0, 0, 0, 0, 0,125, 0, 0, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97,127, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,129,105, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 97, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,130, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,131, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,132, 0, 0, 0, 0, 0, 0, 0,133, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,134, 0, 0, 0, 0,135, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 136,137,138,139,140,141, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,143, 0, 0, 0, + 0, 0, 0, 0,133, 1, 1,144,145,112, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,146, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100,147, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,230,230,230,230, + 230,230,230,230,230,230,230,230,230,232,220,220,220,220,232,216, + 220,220,220,220,220,202,202,220,220,220,220,202,202,220,220,220, + 220,220,220,220,220,220,220,220, 1, 1, 1, 1, 1,220,220,220, + 220,230,230,230,230,230,230,230,230,240,230,220,220,220,230,230, + 230,220,220, 0,230,230,230,220,220,220,220,230,232,220,220,230, + 233,234,234,233,234,234,233,230,230,230,230,230, 0, 0, 0,230, + 230,230,230,230, 0,220,230,230,230,230,220,230,230,230,222,220, + 230,230,230,230,230,230,220,220,220,220,220,220,230,230,220,230, + 230,222,228,230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, + 21, 22, 0, 23, 0, 24, 25, 0,230,220, 0, 18, 30, 31, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, 34,230, + 230,220,220,230,230,230,230,230,220,230,230,220, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,230,230,230,230,230,230, - 230, 0,230,230,230,230,230,230,230,230,230,230,230,230,230,230, - 230,230,230, 0, 0,230,230,230,230,230,230,230, 0,230,230, 0, - 230,230,230,230,230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,230,230,230,230,220,220,220,220,220,220, - 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,230,230, - 230,230,230,230, 7, 0, 0, 0, 0, 0, 16, 17, 17, 17, 17, 17, - 17, 33, 17, 17, 17, 19, 17, 17, 17, 17, 20,101, 17,113,129,169, - 17, 27, 28, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 230, 0, 0,230,230,230,230,220,230, 0, 0,230,230, 0,220,230, + 230,220, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0,230,220,230,230, + 220,230,230,220,220,220,230,220,220,230,220,230,230,230,220,230, + 220,230,220,230,220,230,230, 0, 0, 0, 0, 0,230,230,220,230, + 0, 0, 0, 0, 0, 0, 0, 0, 0,220, 0, 0,230,230, 0,230, + 230,230,230,230,230,230,230,230, 0,230,230,230, 0,230,230,230, + 230,230, 0, 0, 0,220,220,220, 0, 0, 0, 0, 0, 0, 0,220, + 230,230,230,230,230,230, 0,220,230,230,220,230,230,220,230,230, + 230,220,220,220, 27, 28, 29,230,230,230,220,230,230,220,220,230, + 230,230,230,230, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 0, 0, 0,230,220,230,230, 0, 0, 0, 0, 0, 0, 0, + 0, 0,230, 0, 0, 0, 0, 0, 0, 84, 91, 0, 0, 0, 0, 9, + 9, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0,103,103, 9, 0, + 0, 0, 0, 0,107,107,107,107, 0, 0, 0, 0,118,118, 9, 0, + 0, 0, 0, 0,122,122,122,122, 0, 0, 0, 0,220,220, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,220, 0,220, 0,216, 0, 0, + 0, 0, 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130, + 130,130, 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0, 0, 0, + 0, 0,220, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,230,230,230, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, 0,230, 0, 0, 0,228, 0, 0, + 0, 0, 0, 0, 0,222,230,220, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,230,220, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, + 0, 0, 0, 0,230,230,230,230,230, 0, 0,220,230,230,230,230, + 230,220,220,220,220,220,220,230,230,220, 0,220, 0, 0, 0,230, + 220,230,230,230,230,230,230,230, 0, 0, 0, 0, 0, 0, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0,230,230,230, 0, + 1,220,220,220,220,220,230,230,220,220,220,220,230, 0, 1, 1, + 1, 1, 1, 1, 1, 0, 0, 0, 0,220, 0, 0, 0, 0, 0, 0, + 230, 0, 0, 0,230,230, 0, 0, 0, 0, 0, 0,230,230,220,230, + 230,230,230,230,230,230,220,230,230,234,214,220,202,230,230,230, + 230,230,230,230,230,230,230,230,230,230,232,228,228,220, 0,230, + 233,220,230,220,230,230, 1, 1,230,230,230,230, 1, 1, 1,230, + 230, 0, 0, 0, 0,230, 0, 0, 0, 1, 1,230,220,230, 1, 1, + 220,220,220,220,230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 0, 0,218,228,232,222,224,224, 0, 8, 8, 0, + 0, 0, 0, 0, 0, 0, 0, 0,230,230,230,230,230,230,230,230, + 230,230, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0,220, + 220,220, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 7, + 0, 0, 0, 0,230, 0,230,230,220, 0, 0,230,230, 0, 0, 0, + 0, 0,230,230, 0,230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 26, 0,230,230,230,230,230,230,230,220,220,220,220,220, + 220,220,230,230,230,230,230, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,220, 0,230,230, 1,220, 0, 0, 0, 0, 9, 0, 0, 0, 0, + 0,230,220, 0, 0, 0, 0,230,230, 0, 0, 0, 0, 0, 0, 0, + 0, 0,220,220,230,230,230,220,230,220,220,220, 0, 9, 7, 0, + 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 7, 0, 0, 7, 9, 0, 0, 0, 0, 0, 0, 0, 0, 7, + 7, 0, 0, 0,230,230,230,230,230, 0, 0, 0, 0, 0, 9, 0, + 0, 0, 7, 0, 0, 0, 9, 7, 0, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 7, 0, 0, 0, 0, + 0, 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, + 9, 9, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0,230,230,230,230, + 230,230,230, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0,216,216, 1, 1, 1, 0, 0, + 0,226,216,216,216,216,216, 0, 0, 0, 0, 0, 0, 0, 0,220, + 220,220,220,220,220,220,220, 0, 0,230,230,230,230,230,220,220, + 0, 0, 0, 0, 0, 0,230,230,230,230, 0, 0, 0, 0,230,230, + 230, 0, 0, 0,230, 0, 0,230,230,230,230,230,230,230, 0,230, + 230, 0,230,230,220,220,220,220,220,220,220, 0,230,230, 7, 0, + 0, 0, 0, 0, 16, 17, 17, 17, 17, 17, 17, 33, 17, 17, 17, 19, + 17, 17, 17, 17, 20,101, 17,113,129,169, 17, 27, 28, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17,237, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, - 3, 4, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17,237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, + 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 7, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, + 0, 0, 10, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 0, 13, - 0, 14, 15, 16, 0, 0, 0, 0, 0, 1, 17, 18, 0, 19, 7, 1, - 0, 0, 0, 20, 20, 7, 20, 20, 20, 20, 20, 20, 20, 8, 21, 0, - 22, 0, 7, 23, 24, 0, 20, 20, 25, 0, 0, 0, 26, 27, 1, 7, - 20, 20, 20, 20, 20, 1, 28, 29, 30, 31, 0, 0, 20, 0, 0, 0, - 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 11, 12, 0, 13, 0, 14, 15, 16, 0, 0, + 0, 0, 0, 1, 17, 18, 0, 19, 7, 1, 0, 0, 0, 20, 20, 7, + 20, 20, 20, 20, 20, 20, 20, 8, 21, 0, 22, 0, 7, 23, 24, 0, + 20, 20, 25, 0, 0, 0, 26, 27, 1, 7, 20, 20, 20, 20, 20, 1, + 28, 29, 30, 31, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 20, 20, 20, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 21, 32, 4, 0, 10, - 0, 33, 7, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, + 20, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 8, 21, 32, 4, 0, 10, 0, 33, 7, 20, 20, 20, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 8, 34, 34, 35, 36, 34, 37, 0, 38, 1, 20, 20, + 0, 0, 39, 0, 1, 1, 0, 8, 21, 1, 20, 0, 0, 0, 1, 0, + 0, 40, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 21, + 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 26, 34, 34, 34, 34, 34, 34, 34, 34, 34, 21, 7, 20, 41, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 21, 0, 42, 43, 44, 0, 45, + 0, 8, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 34, 34, 35, 36, 34, - 37, 0, 38, 1, 20, 20, 0, 0, 39, 0, 1, 1, 0, 8, 21, 1, - 20, 0, 0, 0, 1, 0, 0, 40, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 8, 21, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 26, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 21, 7, 20, 41, 34, 34, 34, 34, 34, 34, 34, 34, 34, 21, - 0, 42, 43, 44, 0, 45, 0, 8, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 46, 7, 1, 10, 1, 0, 0, 0, 1, 20, 20, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 7, 1, 10, 1, 0, 0, - 0, 1, 20, 20, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 20, 20, 1, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 1, 20, - 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 21, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 26, 21, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, - 3, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, - 3, 4, 0, 0, 0, 0, 0, 0, 3, 4, 0, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 17, 19, 20, - 21, 22, 23, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 26, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, 3, 47, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, + 0, 0, 3, 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 17, 19, 20, 21, 22, 23, 24, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 27, 28, 28, 29, 30, 31, 32, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 35, 35, 35, - 35, 35, 59, 59, 60, 35, 35, 35, 35, 35, 35, 35, 61, 62, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 63, 64, - 35, 65, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 67, 66, 68, + 25, 25, 25, 27, 28, 28, 29, 30, 31, 32, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 69, 70, 35, 35, 35, 35, 71, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 72, 73, 74, 75, 76, 77, 35, 35, 78, 79, 35, 35, 80, 35, - 81, 82, 83, 84, 17, 85, 86, 87, 35, 35, 25, 25, 25, 25, 25, 25, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 35, 35, 35, 35, 35, 59, 59, 60, 35, + 35, 35, 35, 35, 35, 35, 61, 62, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 63, 64, 35, 65, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 67, 66, 68, 69, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 70, 71, 35, 35, + 35, 35, 72, 35, 35, 35, 35, 35, 35, 35, 35, 35, 73, 74, 75, 76, + 77, 78, 35, 35, 79, 80, 35, 35, 81, 35, 82, 83, 84, 85, 17, 86, + 87, 88, 35, 35, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 88, 25, 25, - 25, 25, 25, 25, 25, 89, 90, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 91, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 92, - 35, 35, 35, 35, 35, 35, 25, 93, 35, 35, 35, 35, 35, 35, 35, 35, + 25, 25, 25, 25, 25, 25, 25, 89, 25, 25, 25, 25, 25, 25, 25, 90, + 91, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 92, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 93, 35, 35, 35, 35, 35, 35, + 25, 94, 35, 35, 25, 25, 25, 25, 25, 25, 25, 25, 25, 95, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, @@ -2247,653 +2262,663 @@ _hb_ucd_u8[32102] = 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 94, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, + 35, 35, 35, 35, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, - 19, 0, 0, 0, 0, 0, 26, 26, 0, 0, 0, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, - 0, 9, 9, 9, 2, 2, 9, 9, 9, 9, 0, 9, 2, 2, 2, 2, - 9, 0, 9, 0, 9, 9, 9, 2, 9, 2, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 4, 4, 4, + 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 19, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, + 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, + 26, 26, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, 2, 2, + 9, 9, 9, 9, 0, 9, 2, 2, 2, 2, 9, 0, 9, 0, 9, 9, + 9, 2, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 0, 4, 2, 2, 4, 4, 4, 2, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 4, 2, 2, 4, 4, 4, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 2, 2, 2, 2, 2, 2, 2, 2, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 2, 2, 2, 2, 14, 14, 14, 14, 14, - 14, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, - 3, 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 0, 3, 2, 3, 0, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 2, + 2, 2, 2, 2, 2, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 2, 2, 2, 2, 14, 14, 14, 14, 14, 14, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, + 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 0, 3, 2, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 2, 37, 37, 37, 37, 37, + 3, 3, 3, 0, 3, 3, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 2, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 2, 2, 37, 37, 37, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 64, 64, 64, 64, + 37, 2, 2, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 2, 2, 64, 64, 64, 90, 90, 90, 90, + 64, 2, 2, 64, 64, 64, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 2, 2, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 2, 95, 95, 95, 95, + 90, 90, 90, 90, 2, 2, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 2, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 2, 2, 95, 2, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, - 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, 1, 1, - 1, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 5, 5, 5, - 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 2, 2, 5, + 95, 95, 2, 2, 95, 2, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 1, 1, 1, 1, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, + 5, 5, 5, 2, 2, 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, + 5, 5, 5, 5, 5, 5, 5, 2, 5, 2, 2, 2, 5, 5, 5, 5, + 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 2, + 2, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, + 2, 2, 5, 5, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 2, 5, 2, - 2, 2, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 2, 2, 5, 5, 2, 2, 5, 5, 5, 5, 2, 2, 2, 2, 2, - 2, 2, 2, 5, 2, 2, 2, 2, 5, 5, 2, 5, 5, 5, 5, 5, - 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 11, 11, 11, - 2, 11, 11, 11, 11, 11, 11, 2, 2, 2, 2, 11, 11, 2, 2, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 2, 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, - 2, 11, 11, 2, 11, 11, 2, 2, 11, 2, 11, 11, 11, 11, 11, 2, - 2, 2, 2, 11, 11, 2, 2, 11, 11, 11, 2, 2, 2, 11, 2, 2, - 2, 2, 2, 2, 2, 11, 11, 11, 11, 2, 11, 2, 2, 2, 2, 2, - 2, 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, - 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, 2, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, - 2, 10, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 2, 10, 10, 10, 2, 10, 10, 10, 2, 2, 10, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, - 2, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, 2, - 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 2, 21, 21, 21, - 2, 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, 2, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, - 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 2, 2, 21, 21, 2, 2, 21, 21, 21, 2, 2, 2, 2, 2, 2, - 2, 2, 21, 21, 2, 2, 2, 2, 21, 21, 2, 21, 21, 21, 21, 21, - 2, 2, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, 22, - 2, 22, 22, 22, 22, 22, 22, 2, 2, 2, 22, 22, 22, 2, 22, 22, - 22, 22, 2, 2, 2, 22, 22, 2, 22, 2, 22, 22, 2, 2, 2, 22, - 22, 2, 2, 2, 22, 22, 22, 2, 2, 2, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 2, 2, 2, 2, 22, 22, 22, 22, 22, 2, - 2, 2, 22, 22, 22, 2, 22, 22, 22, 22, 2, 2, 22, 2, 2, 2, - 2, 2, 2, 22, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 2, 2, 2, 2, 2, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 2, 23, 23, 23, 2, 23, 23, + 5, 5, 5, 5, 5, 2, 2, 11, 11, 11, 2, 11, 11, 11, 11, 11, + 11, 2, 2, 2, 2, 11, 11, 2, 2, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, + 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, 2, 11, 11, 2, 11, 11, + 2, 2, 11, 2, 11, 11, 11, 11, 11, 2, 2, 2, 2, 11, 11, 2, + 2, 11, 11, 11, 2, 2, 2, 11, 2, 2, 2, 2, 2, 2, 2, 11, + 11, 11, 11, 2, 11, 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 2, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 2, 10, 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, + 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 2, 10, 10, 10, 10, 10, + 2, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, + 2, 10, 10, 10, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 2, 2, 2, 2, 2, 2, 2, 10, + 10, 10, 10, 10, 10, 10, 2, 21, 21, 21, 2, 21, 21, 21, 21, 21, + 21, 21, 21, 2, 2, 21, 21, 2, 2, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, + 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 2, 21, 21, 21, 21, 21, + 2, 2, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, + 2, 21, 21, 21, 2, 2, 2, 2, 2, 2, 2, 21, 21, 21, 2, 2, + 2, 2, 21, 21, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 22, 22, 2, 22, 22, 22, 22, 22, + 22, 2, 2, 2, 22, 22, 22, 2, 22, 22, 22, 22, 2, 2, 2, 22, + 22, 2, 22, 2, 22, 22, 2, 2, 2, 22, 22, 2, 2, 2, 22, 22, + 22, 2, 2, 2, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 2, 2, 2, 2, 22, 22, 22, 22, 22, 2, 2, 2, 22, 22, 22, 2, + 22, 22, 22, 22, 2, 2, 22, 2, 2, 2, 2, 2, 2, 22, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 2, 2, 2, 2, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 2, 23, 23, 23, 2, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 2, 2, 2, 23, 23, 23, 23, 23, 23, 23, - 23, 2, 23, 23, 23, 2, 23, 23, 23, 23, 2, 2, 2, 2, 2, 2, - 2, 23, 23, 2, 23, 23, 23, 2, 2, 2, 2, 2, 23, 23, 23, 23, - 2, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 2, 2, 2, 2, - 2, 2, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 2, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 2, 16, 16, 16, 16, 16, 2, 2, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 2, 16, 16, 16, 2, 16, 16, 16, 16, 2, 2, 2, 2, 2, 2, - 2, 16, 16, 2, 2, 2, 2, 2, 2, 2, 16, 2, 16, 16, 16, 16, - 2, 2, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 20, 20, 20, 20, - 2, 20, 20, 20, 20, 20, 20, 20, 20, 2, 20, 20, 20, 2, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 2, 20, 20, 20, 2, 20, 20, 20, 20, 20, 20, 2, 2, 2, 2, + 2, 2, 2, 23, 23, 23, 23, 23, 23, 23, 23, 2, 23, 23, 23, 2, + 23, 23, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 23, 2, 23, 23, + 23, 2, 2, 2, 2, 2, 23, 23, 23, 23, 2, 2, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 2, 16, 16, 16, 2, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 16, + 2, 2, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 2, + 16, 16, 16, 16, 2, 2, 2, 2, 2, 2, 2, 16, 16, 2, 2, 2, + 2, 2, 2, 2, 16, 2, 16, 16, 16, 16, 2, 2, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 2, 16, 16, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 2, 20, 20, 20, 2, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 2, 2, 36, 36, - 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 2, 2, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, 36, 36, 36, 36, - 36, 36, 36, 2, 2, 2, 36, 2, 2, 2, 2, 36, 36, 36, 36, 36, - 36, 2, 36, 2, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2, 2, - 2, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 36, 36, - 36, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 24, 24, 24, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 2, 20, 20, 20, 2, + 20, 20, 20, 20, 20, 20, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 2, 2, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 2, 36, 36, 36, 2, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 2, 36, 2, 2, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2, + 36, 2, 2, 2, 2, 36, 36, 36, 36, 36, 36, 2, 36, 2, 36, 36, + 36, 36, 36, 36, 36, 36, 2, 2, 2, 2, 2, 2, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 2, 2, 36, 36, 36, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 2, 2, 2, 2, 0, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 2, 2, 2, 2, 2, 18, 18, 2, - 18, 2, 18, 18, 18, 18, 18, 2, 18, 18, 18, 18, 18, 18, 18, 18, + 24, 2, 2, 2, 2, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 2, 2, 2, 2, 2, 18, 18, 2, 18, 2, 18, 18, 18, 18, + 18, 2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 2, 18, 2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 2, 2, 18, 18, 18, 18, - 18, 2, 18, 2, 18, 18, 18, 18, 18, 18, 2, 2, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 2, 2, 18, 18, 18, 18, 25, 25, 25, 25, + 18, 18, 18, 18, 2, 2, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, + 18, 18, 18, 18, 2, 2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 2, 2, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 2, 2, 2, 2, 25, 25, 25, + 25, 25, 25, 2, 2, 2, 2, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, - 25, 0, 0, 0, 0, 25, 25, 2, 2, 2, 2, 2, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 2, 8, 2, 2, 2, 2, 2, 8, 2, 2, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 0, 8, 8, 8, 8, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 30, 30, 30, 30, + 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 25, + 25, 2, 2, 2, 2, 2, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 2, 8, 2, 2, + 2, 2, 2, 8, 2, 2, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 0, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 2, + 30, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, 2, 30, 2, + 30, 30, 30, 30, 2, 2, 30, 2, 30, 30, 30, 30, 2, 2, 30, 30, + 30, 30, 30, 30, 30, 2, 30, 2, 30, 30, 30, 30, 2, 2, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 2, 30, 30, 30, 30, 2, 2, 30, 30, 30, 30, - 30, 30, 30, 2, 30, 2, 30, 30, 30, 30, 2, 2, 30, 2, 30, 30, - 30, 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, 2, 30, 2, 30, 30, - 30, 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 2, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 2, 2, 2, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 2, 2, 2, 2, 2, 2, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 2, 2, 29, 29, 29, 29, 29, 29, 2, 2, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 34, 34, 34, 34, + 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 2, 2, 2, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 2, 2, 2, 2, 2, 2, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 2, 2, 29, 29, + 29, 29, 29, 29, 2, 2, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 2, 2, 2, 35, 35, 35, 35, + 34, 34, 34, 2, 2, 2, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 0, 0, 0, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 2, 2, 2, 2, 2, 2, 2, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 2, 45, 45, 45, 45, 45, 45, - 45, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 2, 46, 46, 46, 2, 46, 46, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 31, 31, 31, 31, + 35, 0, 0, 0, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 2, + 2, 2, 2, 2, 2, 2, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 2, 45, 45, 45, 45, 45, 45, 45, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 2, 46, 46, 46, 2, 46, 46, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 2, 2, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 2, 2, 2, 2, 2, 2, 32, 32, 0, 0, - 32, 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 2, 2, 2, 2, 2, 2, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 2, 2, 2, 2, 2, 2, 2, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 2, 2, 2, 2, 2, 28, 28, 28, 28, - 28, 28, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 48, 48, 48, 48, + 31, 31, 31, 31, 2, 2, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 2, 2, 2, 2, 2, 2, 32, 32, 0, 0, 32, 0, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 2, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 2, 2, 2, 2, 2, 2, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2, + 2, 2, 2, 2, 2, 2, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 2, 2, 2, 2, 2, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 2, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 2, 2, 2, 2, 48, 2, 2, 2, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 52, 52, 52, 52, + 48, 48, 48, 48, 48, 2, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 2, 2, 2, 2, 48, 2, 2, 2, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 2, 2, 52, 52, 52, 52, - 52, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 58, 58, 58, 58, + 52, 52, 52, 52, 2, 2, 52, 52, 52, 52, 52, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 2, 2, 2, 2, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 2, 2, 2, 2, 2, 2, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 2, 2, 2, 58, 58, 54, 54, 54, 54, + 58, 58, 2, 2, 2, 2, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 2, 2, 2, 2, 2, 2, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 2, 2, 2, 58, 58, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 2, 2, 54, 54, 91, 91, 91, 91, + 54, 54, 2, 2, 54, 54, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 2, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 2, 2, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 2, 2, 2, 2, 2, 2, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 2, 2, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 62, 62, 62, 62, + 91, 91, 91, 91, 91, 2, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 2, 2, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 2, 2, 2, 2, 2, 2, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 2, 2, 2, 2, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 2, 2, 2, 76, 76, 76, 76, - 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 2, 2, 2, 2, 2, 2, 2, 2, 93, 93, 93, 93, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 2, 2, 8, 8, 8, 76, 76, 76, 76, - 76, 76, 76, 76, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, - 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 1, 1, 0, 2, 2, 2, 2, 2, 19, 19, 19, 19, - 19, 19, 9, 9, 9, 9, 9, 6, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, - 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 9, 9, 9, 9, - 9, 9, 2, 2, 9, 9, 9, 9, 9, 9, 2, 2, 9, 9, 9, 9, - 9, 9, 9, 9, 2, 9, 2, 9, 2, 9, 2, 9, 9, 9, 9, 9, + 62, 62, 2, 2, 2, 2, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 2, 2, 2, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 2, 2, 2, 2, 2, 2, + 2, 2, 93, 93, 93, 93, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 2, 2, + 2, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 2, 2, 2, 70, 70, 70, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, + 2, 2, 2, 2, 2, 2, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 2, 2, 8, 8, 8, 76, 76, 76, 76, 76, 76, 76, 76, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, + 0, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, + 9, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 9, 9, 9, 9, + 9, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 6, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 2, 2, 9, 9, + 9, 9, 9, 9, 2, 2, 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, + 2, 9, 2, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 2, 2, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 2, 9, 9, 9, 9, - 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 2, 2, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 2, 2, 9, 9, - 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 2, 2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 2, 2, 2, 1, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, - 0, 0, 9, 0, 0, 0, 19, 19, 0, 0, 0, 0, 0, 0, 19, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, - 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, - 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 56, 56, 56, 56, + 9, 9, 2, 9, 9, 9, 2, 2, 9, 9, 9, 2, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 19, 2, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 2, 2, 2, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, + 19, 19, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, + 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 2, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 2, 2, 2, 2, 2, 55, 55, 55, 55, 55, 55, 55, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 2, 2, 2, 2, 2, 2, 2, 61, 61, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 61, 30, 30, 30, 30, - 30, 30, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 30, 30, 30, 30, - 30, 30, 30, 2, 30, 30, 30, 30, 30, 30, 30, 2, 13, 13, 13, 13, + 56, 56, 56, 56, 56, 2, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 2, 2, 2, 2, 2, 55, + 55, 55, 55, 55, 55, 55, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 2, 2, + 2, 2, 2, 2, 2, 61, 61, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 61, 30, 30, 30, 30, 30, 30, 30, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, + 30, 30, 30, 30, 30, 2, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, 13, 13, 13, - 13, 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, - 0, 13, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 0, 0, 0, 0, - 0, 0, 0, 0, 13, 13, 13, 13, 0, 0, 0, 0, 2, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 13, 0, 13, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 1, 1, 1, 1, 12, 12, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, + 13, 13, 0, 0, 0, 0, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 2, 2, 1, 1, 0, 0, 15, 15, 15, 0, 17, 17, 17, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 1, + 1, 0, 0, 15, 15, 15, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, 17, 17, 2, 2, 2, 2, - 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 12, 12, 12, + 17, 0, 0, 17, 17, 17, 2, 2, 2, 2, 2, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 2, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, 2, 2, 0, 0, 0, 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 0, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 17, - 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 39, 39, 39, 39, + 12, 12, 12, 12, 12, 2, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 0, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, + 0, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 2, 2, 2, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 2, 2, 2, 39, 39, 39, 39, - 39, 39, 39, 2, 2, 2, 2, 2, 2, 2, 2, 2, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 77, 77, 77, 77, + 39, 39, 39, 2, 2, 2, 39, 39, 39, 39, 39, 39, 39, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, - 77, 77, 77, 77, 77, 77, 77, 77, 2, 2, 2, 2, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 0, 0, 0, 19, 19, 19, 19, 19, 2, 2, 19, 19, - 19, 19, 19, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 19, 19, 19, 19, 19, 19, 19, 19, 19, 60, 60, 60, 60, + 77, 77, 2, 2, 2, 2, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 2, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, + 0, 19, 19, 19, 19, 19, 2, 2, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 2, 2, 2, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 2, 2, 2, 2, 2, 2, 2, 2, 75, 75, 75, 75, - 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, - 75, 75, 2, 2, 2, 2, 2, 2, 2, 2, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 69, 69, 69, 69, + 60, 60, 60, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 2, 2, + 2, 2, 2, 2, 2, 2, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 2, 2, 2, 2, + 2, 2, 2, 2, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 2, 2, 2, 2, 2, 2, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 0, 69, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 74, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 2, 2, 84, 84, 84, 84, + 69, 69, 69, 69, 0, 69, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 74, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 2, 2, 2, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 2, 0, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 2, 2, 2, 2, 84, 84, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 2, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 2, 2, 2, 2, 2, 2, 2, 2, 2, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 2, 2, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 2, 2, 68, 68, 68, 68, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 2, + 84, 84, 84, 84, 2, 0, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, + 2, 2, 2, 2, 84, 84, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 2, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 2, 2, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 2, 2, 68, 68, 68, 68, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 92, 92, 92, 92, 92, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 30, 30, 30, - 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, 30, 2, 2, 30, 30, 30, - 30, 30, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 9, 19, 19, 2, 2, 2, 2, 2, 2, 2, 2, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 2, 2, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, - 12, 12, 12, 2, 2, 2, 2, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 2, 2, 2, 2, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, 2, 19, 19, 19, 19, - 19, 19, 19, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, - 4, 4, 4, 4, 2, 2, 2, 2, 2, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 2, 14, 14, 14, 14, 14, 2, 14, 2, 14, 14, 2, 14, - 14, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 3, 3, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 2, 2, 3, 3, + 2, 92, 92, 92, 92, 92, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 30, 30, 30, 30, 30, 30, 2, 2, 30, + 30, 30, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, 30, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 19, 19, 19, 19, + 0, 0, 2, 2, 2, 2, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 2, 2, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 12, 12, 12, 2, 2, 2, + 2, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 2, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 19, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 2, 2, + 2, 2, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 14, 14, + 14, 14, 14, 2, 14, 2, 14, 14, 2, 14, 14, 2, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 0, 0, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, 0, 0, 0, 2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, 3, 3, - 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 0, 2, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 2, 2, 12, 12, - 12, 12, 12, 12, 2, 2, 12, 12, 12, 12, 12, 12, 2, 2, 12, 12, - 12, 12, 12, 12, 2, 2, 12, 12, 12, 2, 2, 2, 0, 0, 0, 0, - 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, 49, 49, 49, 49, 49, + 3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 6, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 2, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 0, 0, 2, 2, 12, 12, 12, 12, 12, 12, 2, 2, + 12, 12, 12, 12, 12, 12, 2, 2, 12, 12, 12, 12, 12, 12, 2, 2, + 12, 12, 12, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, + 0, 0, 0, 0, 2, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, 2, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 2, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 2, 2, 2, 2, 2, 0, 0, 0, 2, - 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 71, 71, 71, 71, + 49, 2, 49, 49, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 2, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 2, 2, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 2, 2, 2, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 42, 42, 42, 41, 41, 41, 41, + 71, 71, 71, 2, 2, 2, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 42, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, - 41, 41, 41, 41, 41, 41, 41, 2, 2, 2, 2, 2,118,118,118,118, + 41, 2, 2, 2, 2, 2,118,118,118,118,118,118,118,118,118,118, 118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, - 118,118,118,118,118,118,118, 2, 2, 2, 2, 2, 53, 53, 53, 53, + 118, 2, 2, 2, 2, 2, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 2, 53, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 2, 2, 2, 2, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 50, 50, 50, 50, + 53, 53, 53, 53, 2, 53, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 2, 2, 2, 2, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 2, 2, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 2, 2, 2, 2, 2, 2,135,135,135,135, + 50, 50, 50, 50, 2, 2, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 2, 2, 2, 2, 2, 2,135,135,135,135,135,135,135,135,135,135, + 135,135,135,135,135,135,135,135,135,135, 2, 2, 2, 2,135,135, 135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, - 2, 2, 2, 2,135,135,135,135,135,135,135,135,135,135,135,135, - 135,135,135,135,135,135,135,135, 2, 2, 2, 2,106,106,106,106, - 106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, - 106,106,106,106, 2, 2, 2, 2, 2, 2, 2, 2,104,104,104,104, - 104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,104,110,110,110,110, - 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, - 110,110,110, 2, 2, 2, 2, 2, 2, 2, 2, 2,110,110,110,110, - 110,110, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,110,110,110,110, - 110,110,110,110, 2, 2, 2, 2, 2, 2, 2, 2, 47, 47, 47, 47, - 47, 47, 2, 2, 47, 2, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 135,135, 2, 2, 2, 2,106,106,106,106,106,106,106,106,106,106, + 106,106,106,106,106,106,106,106,106,106,106,106,106,106, 2, 2, + 2, 2, 2, 2, 2, 2,104,104,104,104,104,104,104,104,104,104, + 104,104,104,104,104,104,104,104,104,104, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2,104,110,110,110,110,110,110,110,110,110,110, + 110,110,110,110,110,110,110,110,110,110,110,110,110, 2, 2, 2, + 2, 2, 2, 2, 2, 2,110,110,110,110,110,110, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2,110,110,110,110,110,110,110,110, 2, 2, + 2, 2, 2, 2, 2, 2, 47, 47, 47, 47, 47, 47, 2, 2, 47, 2, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 2, 47, 47, 2, 2, 2, 47, 2, 2, 47, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 2, 81, 81, 81, 81, 81, 81, 81, 81, 81,120,120,120,120, - 120,120,120,120,120,120,120,120,120,120,120,120,116,116,116,116, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 2, 47, 47, 2, + 2, 2, 47, 2, 2, 47, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 2, 81, 81, 81, + 81, 81, 81, 81, 81, 81,120,120,120,120,120,120,120,120,120,120, + 120,120,120,120,120,120,116,116,116,116,116,116,116,116,116,116, 116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, - 116,116,116,116,116,116,116,116,116,116,116, 2, 2, 2, 2, 2, - 2, 2, 2,116,116,116,116,116,116,116,116,116,128,128,128,128, - 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 2, - 128,128, 2, 2, 2, 2, 2,128,128,128,128,128, 66, 66, 66, 66, + 116,116,116,116,116, 2, 2, 2, 2, 2, 2, 2, 2,116,116,116, + 116,116,116,116,116,116,128,128,128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128,128, 2,128,128, 2, 2, 2, 2, + 2,128,128,128,128,128, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 2, 2, 2, 66, 72, 72, 72, 72, + 66, 66, 2, 2, 2, 66, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 2, 2, 2, 2, 2, 72, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 97, 97, 97, 97, - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, - 97, 97, 97, 97, 2, 2, 2, 2, 97, 97, 97, 97, 2, 2, 97, 97, - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 57, 57, 57, 57, - 2, 57, 57, 2, 2, 2, 2, 2, 57, 57, 57, 57, 57, 57, 57, 57, - 2, 57, 57, 57, 2, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, + 2, 2, 2, 2, 2, 72, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 2, 2, + 2, 2, 97, 97, 97, 97, 2, 2, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 57, 57, 57, 57, 2, 57, 57, 2, 2, 2, + 2, 2, 57, 57, 57, 57, 57, 57, 57, 57, 2, 57, 57, 57, 2, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 2, 2, 57, 57, 57, 2, 2, 2, 2, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 2, 2, 2, 2, 2, 2, 2, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,117,117,117,117, - 117,117,117,117,117,117,117,117,117,117,117,117,112,112,112,112, - 112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, - 112,112,112, 2, 2, 2, 2,112,112,112,112,112,112,112,112,112, - 112,112,112, 2, 2, 2, 2, 2, 2, 2, 2, 2, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 2, 2, 2, 78, 78, 78, 78, 78, 78, 78, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 2, 2, 83, 83, 83, 83, 83, 83, 83, 83, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 2, - 2, 2, 2, 2, 82, 82, 82, 82, 82, 82, 82, 82,122,122,122,122, - 122,122,122,122,122,122,122,122,122,122,122,122,122,122, 2, 2, - 2, 2, 2, 2, 2,122,122,122,122, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2,122,122,122,122,122,122,122, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 2, 2, 2, 2, 2, 2, 2,130,130,130,130, - 130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,130,130,130, 2, - 2, 2, 2, 2, 2, 2,130,130,130,130,130,130,144,144,144,144, - 144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, - 144,144,144,144, 2, 2, 2, 2, 2, 2, 2, 2,144,144,144,144, - 144,144,144,144,144,144, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2,147,147,147,147, - 147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, - 147,147,147,147, 2, 2, 2, 2, 2, 2, 2, 2,148,148,148,148, + 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 2, 2, 57, 57, + 57, 2, 2, 2, 2, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 2, + 2, 2, 2, 2, 2, 2, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88,117,117,117,117,117,117,117,117,117,117, + 117,117,117,117,117,117,112,112,112,112,112,112,112,112,112,112, + 112,112,112,112,112,112,112,112,112,112,112,112,112, 2, 2, 2, + 2,112,112,112,112,112,112,112,112,112,112,112,112, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 2, 2, 2, 78, + 78, 78, 78, 78, 78, 78, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 2, 2, 83, 83, + 83, 83, 83, 83, 83, 83, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, 82, 2, 2, 2, 2, 2, 82, 82, + 82, 82, 82, 82, 82, 82,122,122,122,122,122,122,122,122,122,122, + 122,122,122,122,122,122,122,122, 2, 2, 2, 2, 2, 2, 2,122, + 122,122,122, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,122, + 122,122,122,122,122,122, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 2, + 2, 2, 2, 2, 2, 2,130,130,130,130,130,130,130,130,130,130, + 130,130,130,130,130,130,130,130,130, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2,130,130,130, 2, 2, 2, 2, 2, 2, 2, + 130,130,130,130,130,130,144,144,144,144,144,144,144,144,144,144, + 144,144,144,144,144,144,144,144,144,144,144,144,144,144, 2, 2, + 2, 2, 2, 2, 2, 2,144,144,144,144,144,144,144,144,144,144, + 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 2,156,156,156,156,156,156,156,156,156,156, + 156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, + 2,156,156,156, 2, 2,156,156, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2,147,147,147,147,147,147,147,147,147,147, + 147,147,147,147,147,147,147,147,147,147,147,147,147,147, 2, 2, + 2, 2, 2, 2, 2, 2,148,148,148,148,148,148,148,148,148,148, 148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, - 148,148,148,148,148,148, 2, 2, 2, 2, 2, 2,149,149,149,149, - 149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, - 149,149,149, 2, 2, 2, 2, 2, 2, 2, 2, 2, 94, 94, 94, 94, + 2, 2, 2, 2, 2, 2,153,153,153,153,153,153,153,153,153,153, + 153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, + 153,153, 2, 2, 2, 2,149,149,149,149,149,149,149,149,149,149, + 149,149,149,149,149,149,149,149,149,149,149,149,149, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 2, 2, 2, 2, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 94, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 85, 2, 2,101,101,101,101, - 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, - 101,101,101,101,101, 2, 2, 2, 2, 2, 2, 2,101,101,101,101, - 101,101,101,101,101,101, 2, 2, 2, 2, 2, 2, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 2, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 2, 2, 2, 2, 2, 2, 2, 2, 2,111,111,111,111, - 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, - 111,111,111, 2, 2, 2, 2, 2, 2, 2, 2, 2,100,100,100,100, - 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, - 100,100,100,100,100,100,100,100,100,100, 2, 2, 2, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,108,108,108,108, - 108,108,108,108,108,108,108,108,108,108,108,108,108,108, 2,108, + 94, 94, 94, 94, 2, 2, 2, 2, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 94, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 85, 2, 2,101,101,101,101,101,101,101,101,101,101, + 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, 2, + 2, 2, 2, 2, 2, 2,101,101,101,101,101,101,101,101,101,101, + 2, 2, 2, 2, 2, 2, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 2, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 2, 2, + 2, 2, 2, 2, 2, 2,111,111,111,111,111,111,111,111,111,111, + 111,111,111,111,111,111,111,111,111,111,111,111,111, 2, 2, 2, + 2, 2, 2, 2, 2, 2,100,100,100,100,100,100,100,100,100,100, + 100,100,100,100,100,100, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2,108,108,108,108,108,108,108,108,108,108, + 108,108,108,108,108,108,108,108, 2,108,108,108,108,108,108,108, 108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, - 108,108,108,108,108,108,108,108,108,108,108, 2,129,129,129,129, - 129,129,129, 2,129, 2,129,129,129,129, 2,129,129,129,129,129, - 129,129,129,129,129,129,129,129,129,129, 2,129,129,129,129,129, - 129,129,129,129,129,129, 2, 2, 2, 2, 2, 2,109,109,109,109, + 108,108,108,108,108, 2,129,129,129,129,129,129,129, 2,129, 2, + 129,129,129,129, 2,129,129,129,129,129,129,129,129,129,129,129, + 129,129,129,129, 2,129,129,129,129,129,129,129,129,129,129,129, + 2, 2, 2, 2, 2, 2,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, - 109,109,109,109,109,109,109, 2, 2, 2, 2, 2,109,109,109,109, - 109,109,109,109,109,109, 2, 2, 2, 2, 2, 2,107,107,107,107, - 2,107,107,107,107,107,107,107,107, 2, 2,107,107, 2, 2,107, - 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, - 107,107,107,107,107, 2,107,107,107,107,107,107,107, 2,107,107, - 2,107,107,107,107,107, 2, 1,107,107,107,107,107,107,107,107, - 107, 2, 2,107,107, 2, 2,107,107,107, 2, 2,107, 2, 2, 2, - 2, 2, 2,107, 2, 2, 2, 2, 2,107,107,107,107,107,107,107, - 2, 2,107,107,107,107,107,107,107, 2, 2, 2,107,107,107,107, - 107, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,137,137,137,137, + 109, 2, 2, 2, 2, 2,109,109,109,109,109,109,109,109,109,109, + 2, 2, 2, 2, 2, 2,107,107,107,107, 2,107,107,107,107,107, + 107,107,107, 2, 2,107,107, 2, 2,107,107,107,107,107,107,107, + 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, 2, + 107,107,107,107,107,107,107, 2,107,107, 2,107,107,107,107,107, + 2, 1,107,107,107,107,107,107,107,107,107, 2, 2,107,107, 2, + 2,107,107,107, 2, 2,107, 2, 2, 2, 2, 2, 2,107, 2, 2, + 2, 2, 2,107,107,107,107,107,107,107, 2, 2,107,107,107,107, + 107,107,107, 2, 2, 2,107,107,107,107,107, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2,137,137,137,137,137,137,137,137,137,137, 137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, - 137,137,137,137,137,137, 2,137, 2,137,137,137,124,124,124,124, - 124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, - 124,124,124,124, 2, 2, 2, 2, 2, 2, 2, 2,124,124,124,124, - 124,124,124,124,124,124, 2, 2, 2, 2, 2, 2,123,123,123,123, + 137,137, 2,137,137,137,137,137, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2,124,124,124,124,124,124,124,124,124,124, + 124,124,124,124,124,124,124,124,124,124,124,124,124,124, 2, 2, + 2, 2, 2, 2, 2, 2,124,124,124,124,124,124,124,124,124,124, + 2, 2, 2, 2, 2, 2,123,123,123,123,123,123,123,123,123,123, + 123,123,123,123,123,123,123,123,123,123,123,123, 2, 2,123,123, 123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, - 123,123, 2, 2,123,123,123,123,123,123,123,123,123,123,123,123, - 123,123,123,123,123,123,123,123,123,123, 2, 2,114,114,114,114, - 114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, - 114, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,114,114,114,114, - 114,114,114,114,114,114, 2, 2, 2, 2, 2, 2, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 2, 2, 2,102,102,102,102, - 102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, - 102,102,102,102,102, 2, 2, 2, 2, 2, 2, 2,102,102,102,102, - 102,102,102,102,102,102, 2, 2, 2, 2, 2, 2,126,126,126,126, + 123,123,123,123, 2, 2,114,114,114,114,114,114,114,114,114,114, + 114,114,114,114,114,114,114,114,114,114,114, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2,114,114,114,114,114,114,114,114,114,114, + 2, 2, 2, 2, 2, 2, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 2, 2, 2,102,102,102,102,102,102,102,102,102,102, + 102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, 2, + 2, 2, 2, 2, 2, 2,102,102,102,102,102,102,102,102,102,102, + 2, 2, 2, 2, 2, 2,126,126,126,126,126,126,126,126,126,126, 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, - 126,126,126,126,126,126,126, 2, 2,126,126,126,126,126,126,126, - 126,126,126,126,126,126,126,126, 2, 2, 2, 2,142,142,142,142, + 126, 2, 2,126,126,126,126,126,126,126,126,126,126,126,126,126, + 126,126, 2, 2, 2, 2,142,142,142,142,142,142,142,142,142,142, 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, - 142,142,142,142,142,142,142,142, 2, 2, 2, 2,125,125,125,125, - 125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,125,150,150,150,150, - 150,150,150,150, 2, 2,150,150,150,150,150,150,150,150,150,150, + 142,142, 2, 2, 2, 2,125,125,125,125,125,125,125,125,125,125, + 125,125,125,125,125,125,125,125,125, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2,125,154,154,154,154,154,154,154, 2, 2,154, + 2, 2,154,154,154,154,154,154,154,154, 2,154,154, 2,154,154, + 154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, + 154,154,154,154,154,154,154,154,154,154,154,154, 2,154,154, 2, + 2,154,154,154,154,154,154,154,154,154,154,154,154, 2, 2, 2, + 2, 2, 2, 2, 2, 2,154,154,154,154,154,154,154,154,154,154, + 2, 2, 2, 2, 2, 2,150,150,150,150,150,150,150,150, 2, 2, 150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, - 150, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,141,141,141,141, - 141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, - 141,141,141,141, 2, 2, 2, 2, 2, 2, 2, 2,140,140,140,140, - 140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,121,121,121,121, - 121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, - 121,121,121,121,121, 2, 2, 2, 2, 2, 2, 2,133,133,133,133, - 133,133,133,133,133, 2,133,133,133,133,133,133,133,133,133,133, + 150,150,150,150,150,150,150,150,150,150,150, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2,141,141,141,141,141,141,141,141,141,141, + 141,141,141,141,141,141,141,141,141,141,141,141,141,141, 2, 2, + 2, 2, 2, 2, 2, 2,140,140,140,140,140,140,140,140,140,140, + 140,140,140,140,140,140,140,140,140, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2,121,121,121,121,121,121,121,121,121,121, + 121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, 2, + 2, 2, 2, 2, 2, 2,133,133,133,133,133,133,133,133,133, 2, 133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, - 133,133,133, 2,133,133,133,133,133,133,133,133,133,133,133,133, - 133,133, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,133,133,133,133, - 133,133,133,133,133,133,133,133,133, 2, 2, 2,134,134,134,134, - 134,134,134,134,134,134,134,134,134,134,134,134, 2, 2,134,134, - 134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, - 134,134,134,134, 2,134,134,134,134,134,134,134,134,134,134,134, - 134,134,134, 2, 2, 2, 2, 2, 2, 2, 2, 2,138,138,138,138, - 138,138,138, 2,138,138, 2,138,138,138,138,138,138,138,138,138, - 138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, - 138,138,138, 2, 2, 2,138, 2,138,138, 2,138,138,138,138,138, - 138,138,138,138, 2, 2, 2, 2, 2, 2, 2, 2,138,138,138,138, - 138,138,138,138,138,138, 2, 2, 2, 2, 2, 2,143,143,143,143, - 143,143, 2,143,143, 2,143,143,143,143,143,143,143,143,143,143, + 133,133,133,133,133,133,133,133,133,133,133,133,133, 2,133,133, + 133,133,133,133,133,133,133,133,133,133,133,133, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2,133,133,133,133,133,133,133,133,133,133, + 133,133,133, 2, 2, 2,134,134,134,134,134,134,134,134,134,134, + 134,134,134,134,134,134, 2, 2,134,134,134,134,134,134,134,134, + 134,134,134,134,134,134,134,134,134,134,134,134,134,134, 2,134, + 134,134,134,134,134,134,134,134,134,134,134,134,134, 2, 2, 2, + 2, 2, 2, 2, 2, 2,138,138,138,138,138,138,138, 2,138,138, + 2,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, + 138,138,138,138,138,138,138,138,138,138,138,138,138, 2, 2, 2, + 138, 2,138,138, 2,138,138,138,138,138,138,138,138,138, 2, 2, + 2, 2, 2, 2, 2, 2,138,138,138,138,138,138,138,138,138,138, + 2, 2, 2, 2, 2, 2,143,143,143,143,143,143, 2,143,143, 2, 143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, - 143,143,143,143,143,143,143,143,143,143,143, 2,143,143, 2,143, - 143,143,143,143,143, 2, 2, 2, 2, 2, 2, 2,143,143,143,143, - 143,143,143,143,143,143, 2, 2, 2, 2, 2, 2,145,145,145,145, - 145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, - 145,145,145,145,145, 2, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, 63, 63, 63, 63, + 143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, + 143,143,143,143,143, 2,143,143, 2,143,143,143,143,143,143, 2, + 2, 2, 2, 2, 2, 2,143,143,143,143,143,143,143,143,143,143, + 2, 2, 2, 2, 2, 2,145,145,145,145,145,145,145,145,145,145, + 145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, 2, + 2, 2, 2, 2, 2, 2, 86, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 22, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 2, 2, 2, 2, 2, 2, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 2, 63, 63, 63, 63, - 63, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 63, 63, 63, 63, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 80, 80, 80, 80, + 2, 2, 2, 2, 2, 2, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 2, 63, 63, 63, 63, 63, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 63, 63, 63, 63, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 2, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 2, 2, 2, 2, 2, 2, 2,127,127,127,127, - 127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, - 127,127,127, 2, 2, 2, 2, 2, 2, 2, 2, 2, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 2, 2, 2, 2, 2, 2, 2,115,115,115,115, + 80, 80, 80, 80, 80, 2, 80, 80, 80, 80, 80, 80, 80, 80, 80, 2, + 2, 2, 2, 2, 2, 2,127,127,127,127,127,127,127,127,127,127, + 127,127,127,127,127,127,127,127,127,127,127,127,127, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 79, 79, 79, 79, 79, 79, 79, 79, 79, 2, + 2, 2, 2, 2, 2, 2,115,115,115,115,115,115,115,115,115,115, 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, - 115,115,115,115,115,115,115,115,115,115,115, 2,115,115,115,115, - 115,115,115,115,115,115, 2, 2, 2, 2,115,115,103,103,103,103, + 115,115,115,115,115, 2,115,115,115,115,115,115,115,115,115,115, + 2, 2, 2, 2,115,115,103,103,103,103,103,103,103,103,103,103, 103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, - 103,103,103,103,103,103,103,103,103,103, 2, 2,103,103,103,103, - 103,103, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,119,119,119,119, - 119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, - 119,119, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,119,119,119,119, - 119,119,119,119,119,119, 2,119,119,119,119,119,119,119, 2,119, - 119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, - 119,119,119,119, 2, 2, 2, 2, 2,119,119,119,146,146,146,146, + 103,103,103,103, 2, 2,103,103,103,103,103,103, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2,119,119,119,119,119,119,119,119,119,119, + 119,119,119,119,119,119,119,119,119,119,119,119, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2,119,119,119,119,119,119,119,119,119,119, + 2,119,119,119,119,119,119,119, 2,119,119,119,119,119,119,119, + 119,119,119,119,119,119,119,119,119,119,119,119,119,119, 2, 2, + 2, 2, 2,119,119,119,146,146,146,146,146,146,146,146,146,146, 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, - 146,146,146,146,146,146,146, 2, 2, 2, 2, 2, 99, 99, 99, 99, + 146, 2, 2, 2, 2, 2, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 2, 2, 2, 2, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 2, 2, 2, 2, 2, 2, 2, 99,136,139, 0, 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,136,136,136,136, - 136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, - 136,136,136,136, 2, 2, 2, 2, 2, 2, 2, 2,136,136,136, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17, 15, 15, 15, + 99, 2, 2, 2, 2, 99, 99, 99, 99, 99, 99, 99, 99, 99, 2, 2, + 2, 2, 2, 2, 2, 99,136,139, 0, 0,155, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 13, 13, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2,136,136,136,136,136,136,136,136,136,136, + 136,136,136,136,136,136,136,136,136,136,136,136,136,136, 2, 2, + 2, 2, 2, 2, 2, 2,155,155,155,155,155,155,155,155,155,155, + 155,155,155,155,155,155,155,155,155,155,155,155, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2,136,136,136,136,136,136,136,136,136, 2, + 2, 2, 2, 2, 2, 2, 17, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 15, 15, 15, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 17, 17, 17, 17, 2, 2, 2, 2, 2, 2, 2, 2,139,139,139,139, + 15, 15, 15, 15, 15, 2, 15, 15, 15, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17, 17, 17, 17, 2, 2, + 2, 2, 2, 2, 2, 2,139,139,139,139,139,139,139,139,139,139, 139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, - 139,139,139,139,139,139,139,139, 2, 2, 2, 2,105,105,105,105, + 139,139, 2, 2, 2, 2,105,105,105,105,105,105,105,105,105,105, 105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, - 105,105,105,105,105,105,105, 2, 2, 2, 2, 2,105,105,105,105, - 105,105,105,105,105,105,105,105,105, 2, 2, 2,105,105,105,105, - 105,105,105,105,105, 2, 2, 2, 2, 2, 2, 2,105,105,105,105, - 105,105,105,105,105,105, 2, 2,105,105,105,105, 0, 0, 0, 0, - 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, - 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 9, 9, 9, 9, - 9, 9, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 2, - 2, 0, 0, 2, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, - 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, - 0, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0,131,131,131,131, + 105, 2, 2, 2, 2, 2,105,105,105,105,105,105,105,105,105,105, + 105,105,105, 2, 2, 2,105,105,105,105,105,105,105,105,105, 2, + 2, 2, 2, 2, 2, 2,105,105,105,105,105,105,105,105,105,105, + 2, 2,105,105,105,105, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 2, 2, 2, 2, 2, 2, 9, 9, 9, 9, 9, 9, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 2, 2, 0, 2, 2, 0, 0, 2, 2, 0, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 2, 2, 2, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 2, 0, 0,131,131,131,131,131,131,131,131,131,131, 131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, - 131,131,131,131,131,131,131,131, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2,131,131,131,131,131, 2,131,131,131, - 131,131,131,131,131,131,131,131,131,131,131,131, 56, 56, 56, 56, - 56, 56, 56, 2, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 2, 2, 56, 56, 56, 56, 56, 56, 56, 2, 56, - 56, 2, 56, 56, 56, 56, 56, 2, 2, 2, 2, 2,151,151,151,151, + 131,131, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2,131,131,131,131,131, 2,131,131,131,131,131,131,131,131,131, + 131,131,131,131,131,131, 56, 56, 56, 56, 56, 56, 56, 2, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 2, + 2, 56, 56, 56, 56, 56, 56, 56, 2, 56, 56, 2, 56, 56, 56, 56, + 56, 2, 2, 2, 2, 2,151,151,151,151,151,151,151,151,151,151, 151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, - 151,151,151,151,151,151,151,151,151, 2, 2, 2,151,151,151,151, - 151,151,151,151,151,151,151,151,151,151, 2, 2,151,151,151,151, - 151,151,151,151,151,151, 2, 2, 2, 2,151,151,152,152,152,152, + 151,151,151, 2, 2, 2,151,151,151,151,151,151,151,151,151,151, + 151,151,151,151, 2, 2,151,151,151,151,151,151,151,151,151,151, + 2, 2, 2, 2,151,151,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, - 152,152,152,152,152,152, 2, 2, 2, 2, 2,152,113,113,113,113, - 113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, - 113, 2, 2,113,113,113,113,113,113,113,113,113,113,113,113,113, - 113,113,113, 2, 2, 2, 2, 2, 2, 2, 2, 2,132,132,132,132, + 2, 2, 2, 2, 2,152,113,113,113,113,113,113,113,113,113,113, + 113,113,113,113,113,113,113,113,113,113,113, 2, 2,113,113,113, + 113,113,113,113,113,113,113,113,113,113,113,113,113, 2, 2, 2, + 2, 2, 2, 2, 2, 2,132,132,132,132,132,132,132,132,132,132, 132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, - 132,132,132,132,132,132,132,132, 2, 2, 2, 2,132,132,132,132, - 132,132,132,132,132,132, 2, 2, 2, 2,132,132, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 3, 3, 3, 3, - 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 2, - 3, 2, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, - 3, 3, 3, 3, 2, 3, 2, 3, 2, 2, 2, 2, 2, 2, 3, 2, - 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 2, 3, 3, 2, - 3, 2, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 2, - 3, 2, 2, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 2, - 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 3, 3, 3, - 2, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, - 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, - 2, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, - 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, 13, 13, 13, - 13, 13, 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, 13, 13, 13, - 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, 13, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 1, - 2, 3, 4, 5, 6, 0, 0, 0, 0, 7, 8, 9, 10, 11, 0, 12, - 0, 0, 0, 0, 13, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, - 15, 16, 0, 17, 18, 19, 0, 0, 0, 20, 21, 22, 0, 23, 0, 24, - 0, 25, 0, 26, 0, 0, 0, 0, 0, 27, 28, 0, 29, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 132,132, 2, 2, 2, 2,132,132,132,132,132,132,132,132,132,132, + 2, 2, 2, 2,132,132, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 2, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 2, 3, 3, 2, 3, 2, 2, 3, 2, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 3, + 2, 3, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 3, 2, 3, + 2, 3, 2, 3, 3, 3, 2, 3, 3, 2, 3, 2, 2, 3, 2, 3, + 2, 3, 2, 3, 2, 3, 2, 3, 3, 2, 3, 2, 2, 3, 3, 3, + 3, 2, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 3, + 3, 3, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 2, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 3, 3, + 2, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 15, 0, 0, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, + 0, 2, 2, 2, 2, 2, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 1, 2, 3, 4, 5, 6, 0, + 0, 0, 0, 7, 8, 9, 10, 11, 0, 12, 0, 0, 0, 0, 13, 0, + 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 15, 16, 0, 17, 18, 19, + 0, 0, 0, 20, 21, 22, 0, 23, 0, 24, 0, 25, 0, 26, 0, 0, + 0, 0, 0, 27, 28, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 32, 33, 34, 35, 36, 37, 38, 39, 40, 0, 0, 0, - 41, 0, 42, 43, 44, 45, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 51, 52, + 0, 0, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 0, 0, 0, 41, 0, 42, 43, 44, 45, + 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 50, 51, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2943,14 +2968,15 @@ _hb_ucd_u8[32102] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, - 64, 0, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 0, 66, 0, - 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 65, 0, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2996,8 +3022,8 @@ _hb_ucd_u8[32102] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 70, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 68, 69, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3070,11 +3096,10 @@ _hb_ucd_u8[32102] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 0, + 0, 0, 0, 0, 0, 0, 72, 73, 74, 75, 76, 77, 78, 79, 80, 0, }; static const uint16_t -_hb_ucd_u16[11168] = +_hb_ucd_u16[11328] = { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, @@ -3084,186 +3109,188 @@ _hb_ucd_u16[11168] = 13, 13, 13, 42, 9, 43, 11, 11, 44, 45, 32, 46, 47, 48, 49, 50, 51, 52, 48, 48, 53, 32, 54, 55, 48, 48, 48, 48, 48, 56, 57, 58, 59, 60, 48, 32, 61, 48, 48, 48, 48, 48, 62, 63, 64, 48, 65, 66, - 48, 67, 68, 69, 48, 70, 71, 72, 72, 72, 48, 73, 72, 74, 75, 32, - 76, 48, 48, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 83, 84, 91, 92, 93, 94, 95, 96, 97, 84, 98, 99, 100, 88, 101, - 102, 83, 84, 103, 104, 105, 88, 106, 107, 108, 109, 110, 111, 112, 94, 113, - 114, 115, 84, 116, 117, 118, 88, 119, 120, 115, 84, 121, 122, 123, 88, 124, - 125, 115, 48, 126, 127, 128, 88, 129, 130, 131, 48, 132, 133, 134, 94, 135, - 136, 48, 48, 137, 138, 139, 72, 72, 140, 48, 141, 142, 143, 144, 72, 72, - 145, 146, 147, 148, 149, 48, 150, 151, 152, 153, 32, 154, 155, 156, 72, 72, - 48, 48, 157, 158, 159, 160, 161, 162, 163, 164, 9, 9, 165, 11, 11, 166, + 48, 67, 68, 69, 48, 70, 71, 72, 72, 72, 48, 73, 74, 75, 76, 32, + 77, 48, 48, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 84, 85, 92, 93, 94, 95, 96, 97, 98, 85, 99, 100, 101, 89, 102, + 103, 84, 85, 104, 105, 106, 89, 107, 108, 109, 110, 111, 112, 113, 95, 114, + 115, 116, 85, 117, 118, 119, 89, 120, 121, 116, 85, 122, 123, 124, 89, 125, + 126, 116, 48, 127, 128, 129, 89, 130, 131, 132, 48, 133, 134, 135, 95, 136, + 137, 48, 48, 138, 139, 140, 72, 72, 141, 48, 142, 143, 144, 145, 72, 72, + 146, 147, 148, 149, 150, 48, 151, 152, 153, 154, 32, 155, 156, 157, 72, 72, + 48, 48, 158, 159, 160, 161, 162, 163, 164, 165, 9, 9, 166, 11, 11, 167, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 167, 168, 48, 48, 167, 48, 48, 169, 170, 171, 48, 48, - 48, 170, 48, 48, 48, 172, 173, 174, 48, 175, 9, 9, 9, 9, 9, 176, - 177, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 168, 169, 48, 48, 168, 48, 48, 170, 171, 172, 48, 48, + 48, 171, 48, 48, 48, 173, 174, 175, 48, 176, 9, 9, 9, 9, 9, 177, + 178, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 178, 48, 179, 180, 48, 48, 48, 48, 181, 182, - 183, 184, 48, 185, 48, 186, 183, 187, 48, 48, 48, 188, 189, 190, 191, 192, - 193, 191, 48, 48, 194, 48, 48, 195, 196, 48, 197, 48, 48, 48, 48, 198, - 48, 199, 200, 201, 202, 48, 203, 204, 48, 48, 205, 48, 206, 207, 208, 208, - 48, 209, 48, 48, 48, 210, 211, 212, 191, 191, 213, 214, 72, 72, 72, 72, - 215, 48, 48, 216, 217, 159, 218, 219, 220, 48, 221, 64, 48, 48, 222, 223, - 48, 48, 224, 225, 226, 64, 48, 227, 228, 9, 9, 229, 230, 231, 232, 233, - 11, 11, 234, 27, 27, 27, 235, 236, 11, 237, 27, 27, 32, 32, 32, 238, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 239, 13, 13, 13, 13, 13, 13, - 240, 241, 240, 240, 241, 242, 240, 243, 244, 244, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 260, 72, 261, 262, 263, - 264, 265, 266, 267, 268, 269, 270, 270, 271, 272, 273, 208, 274, 275, 208, 276, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 278, 208, 279, 208, 208, 208, 208, 280, 208, 281, 277, 282, 208, 283, 284, 208, - 208, 208, 285, 72, 286, 72, 269, 269, 269, 287, 208, 208, 208, 208, 288, 269, - 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 289, 290, 208, 208, 291, - 208, 208, 208, 208, 208, 208, 292, 208, 208, 208, 208, 208, 208, 208, 208, 208, - 208, 208, 208, 208, 208, 208, 293, 294, 269, 295, 208, 208, 296, 277, 297, 277, - 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, - 277, 277, 277, 277, 277, 277, 277, 277, 298, 299, 277, 277, 277, 300, 277, 301, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 208, 208, 208, 277, 302, 208, 208, 303, 208, 304, 208, 208, 208, 208, 208, 208, - 9, 9, 305, 11, 11, 306, 307, 308, 13, 13, 13, 13, 13, 13, 309, 310, - 11, 11, 311, 48, 48, 48, 312, 313, 48, 314, 315, 315, 315, 315, 32, 32, - 316, 317, 318, 319, 320, 72, 72, 72, 208, 321, 208, 208, 208, 208, 208, 322, - 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 323, 72, 324, - 325, 326, 327, 328, 136, 48, 48, 48, 48, 329, 177, 48, 48, 48, 48, 330, - 331, 48, 48, 136, 48, 48, 48, 48, 199, 332, 48, 71, 208, 208, 322, 48, - 208, 333, 334, 208, 335, 336, 208, 208, 334, 208, 208, 336, 208, 208, 208, 208, - 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, + 48, 48, 48, 48, 48, 48, 179, 48, 180, 181, 48, 48, 48, 48, 182, 183, + 184, 185, 48, 186, 48, 187, 184, 188, 48, 48, 48, 189, 190, 191, 192, 193, + 194, 192, 48, 48, 195, 48, 48, 196, 197, 48, 198, 48, 48, 48, 48, 199, + 48, 200, 201, 202, 203, 48, 204, 205, 48, 48, 206, 48, 207, 208, 209, 209, + 48, 210, 48, 48, 48, 211, 212, 213, 192, 192, 214, 215, 216, 72, 72, 72, + 217, 48, 48, 218, 219, 160, 220, 221, 222, 48, 223, 64, 48, 48, 224, 225, + 48, 48, 226, 227, 228, 64, 48, 229, 230, 9, 9, 231, 232, 233, 234, 235, + 11, 11, 236, 27, 27, 27, 237, 238, 11, 239, 27, 27, 32, 32, 32, 240, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 241, 13, 13, 13, 13, 13, 13, + 242, 243, 242, 242, 243, 244, 242, 245, 246, 246, 246, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 262, 72, 263, 264, 216, + 265, 266, 267, 268, 269, 270, 271, 271, 272, 273, 274, 209, 275, 276, 209, 277, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 279, 209, 280, 209, 209, 209, 209, 281, 209, 282, 278, 283, 209, 284, 285, 209, + 209, 209, 286, 72, 287, 72, 270, 270, 270, 288, 209, 209, 209, 209, 289, 270, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 290, 291, 209, 209, 292, + 209, 209, 209, 209, 209, 209, 293, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 209, 209, 209, 294, 295, 270, 296, 209, 209, 297, 278, 298, 278, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 278, 278, 278, 278, 278, 278, 278, 278, 299, 300, 278, 278, 278, 301, 278, 302, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 209, 209, 209, 278, 303, 209, 209, 304, 209, 305, 209, 209, 209, 209, 209, 209, + 9, 9, 306, 11, 11, 307, 308, 309, 13, 13, 13, 13, 13, 13, 310, 311, + 11, 11, 312, 48, 48, 48, 313, 314, 48, 315, 316, 316, 316, 316, 32, 32, + 317, 318, 319, 320, 321, 322, 72, 72, 209, 323, 209, 209, 209, 209, 209, 324, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 325, 72, 326, + 327, 328, 329, 330, 137, 48, 48, 48, 48, 331, 178, 48, 48, 48, 48, 332, + 333, 48, 48, 137, 48, 48, 48, 48, 200, 334, 48, 48, 209, 209, 324, 48, + 209, 335, 336, 209, 337, 338, 209, 209, 336, 209, 209, 338, 209, 209, 209, 209, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 198, 208, 208, 208, 208, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 209, 209, 209, 209, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 72, - 48, 337, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 151, + 48, 339, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 150, 208, 208, 208, 285, 48, 48, 227, + 48, 48, 48, 48, 48, 48, 48, 48, 151, 209, 209, 209, 286, 48, 48, 229, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 338, 48, 339, 72, 13, 13, 340, 341, 13, 342, 48, 48, 48, 48, 343, 344, - 31, 345, 346, 347, 13, 13, 13, 348, 349, 350, 351, 352, 353, 72, 72, 354, - 355, 48, 356, 357, 48, 48, 48, 358, 359, 48, 48, 360, 361, 191, 32, 362, - 64, 48, 363, 48, 364, 365, 48, 150, 76, 48, 48, 366, 367, 368, 369, 370, - 48, 48, 371, 372, 373, 374, 48, 375, 48, 48, 48, 376, 377, 378, 379, 380, - 381, 382, 315, 11, 11, 383, 384, 11, 11, 11, 11, 11, 48, 48, 385, 191, + 340, 48, 341, 72, 13, 13, 342, 343, 13, 344, 48, 48, 48, 48, 345, 346, + 31, 347, 348, 349, 13, 13, 13, 350, 351, 352, 353, 354, 355, 72, 72, 356, + 357, 48, 358, 359, 48, 48, 48, 360, 361, 48, 48, 362, 363, 192, 32, 364, + 64, 48, 365, 48, 366, 367, 48, 151, 77, 48, 48, 368, 369, 370, 371, 372, + 48, 48, 373, 374, 375, 376, 48, 377, 48, 48, 48, 378, 379, 380, 381, 382, + 383, 384, 316, 11, 11, 385, 386, 11, 11, 11, 11, 11, 48, 48, 387, 192, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 386, 48, 387, 48, 48, 205, - 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, - 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, - 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, - 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, - 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 388, 48, 389, 48, 48, 206, + 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, + 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 203, 48, 48, 48, 48, 48, 48, 206, 72, 72, - 390, 391, 392, 393, 394, 48, 48, 48, 48, 48, 48, 395, 396, 397, 48, 48, + 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 207, 72, 72, + 392, 393, 394, 395, 396, 48, 48, 48, 48, 48, 48, 397, 398, 399, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 398, 72, 48, 48, 48, 48, 399, 48, 48, 400, 72, 72, 401, - 32, 402, 32, 403, 404, 405, 406, 407, 48, 48, 48, 48, 48, 48, 48, 408, - 409, 2, 3, 4, 5, 410, 411, 412, 48, 413, 48, 199, 414, 415, 416, 417, - 418, 48, 171, 419, 203, 203, 72, 72, 48, 48, 48, 48, 48, 48, 48, 71, - 420, 269, 269, 421, 270, 270, 270, 422, 423, 324, 424, 72, 72, 208, 208, 425, - 72, 72, 72, 72, 72, 72, 72, 72, 48, 150, 48, 48, 48, 100, 426, 427, - 48, 48, 428, 48, 429, 48, 48, 430, 48, 431, 48, 48, 432, 433, 72, 72, - 9, 9, 434, 11, 11, 48, 48, 48, 48, 203, 191, 9, 9, 435, 11, 436, - 48, 48, 400, 48, 48, 48, 437, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 48, 48, 48, 400, 72, 48, 48, 48, 48, 401, 48, 48, 74, 72, 72, 402, + 32, 403, 32, 404, 405, 406, 407, 73, 48, 48, 48, 48, 48, 48, 48, 408, + 409, 2, 3, 4, 5, 410, 411, 412, 48, 413, 48, 200, 414, 415, 416, 417, + 418, 48, 172, 419, 204, 204, 72, 72, 48, 48, 48, 48, 48, 48, 48, 71, + 420, 270, 270, 421, 271, 271, 271, 422, 423, 424, 425, 72, 72, 209, 209, 426, + 72, 72, 72, 72, 72, 72, 72, 72, 48, 151, 48, 48, 48, 101, 427, 428, + 48, 48, 429, 48, 430, 48, 48, 431, 48, 432, 48, 48, 433, 434, 72, 72, + 9, 9, 435, 11, 11, 48, 48, 48, 48, 204, 192, 9, 9, 436, 11, 437, + 48, 48, 74, 48, 48, 48, 438, 72, 72, 72, 72, 72, 72, 72, 72, 72, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 314, 48, 198, 400, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 438, 48, 48, 439, 48, 440, 48, 441, 48, 199, 442, 72, 72, 72, 48, 443, - 48, 444, 48, 445, 72, 72, 72, 72, 48, 48, 48, 446, 269, 447, 269, 269, - 448, 449, 48, 450, 451, 452, 48, 453, 48, 454, 72, 72, 455, 48, 456, 457, - 48, 48, 48, 458, 48, 459, 48, 460, 48, 461, 462, 72, 72, 72, 72, 72, - 48, 48, 48, 48, 195, 72, 72, 72, 9, 9, 9, 463, 11, 11, 11, 464, - 48, 48, 465, 191, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 269, 466, 72, 72, 72, 72, 72, 72, 72, 72, - 48, 454, 467, 48, 62, 468, 72, 72, 72, 72, 72, 72, 72, 72, 48, 314, - 469, 48, 48, 470, 471, 447, 472, 473, 220, 48, 48, 474, 475, 48, 195, 191, - 476, 48, 477, 478, 479, 48, 48, 480, 220, 48, 48, 481, 482, 483, 484, 485, - 48, 97, 486, 487, 72, 72, 72, 72, 488, 489, 490, 48, 48, 491, 492, 191, - 493, 83, 84, 494, 495, 496, 497, 498, 72, 72, 72, 72, 72, 72, 72, 72, - 48, 48, 48, 499, 500, 501, 72, 72, 48, 48, 48, 502, 503, 191, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 48, 48, 504, 505, 506, 507, 72, 72, - 48, 48, 48, 508, 509, 191, 510, 72, 48, 48, 511, 512, 191, 72, 72, 72, - 48, 172, 513, 514, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 48, 48, 486, 515, 72, 72, 72, 72, 72, 72, 9, 9, 11, 11, 147, 516, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 517, 48, 48, 518, 519, 72, - 520, 48, 48, 521, 522, 523, 48, 48, 524, 525, 526, 72, 48, 48, 48, 195, + 48, 48, 48, 315, 48, 199, 74, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 439, 48, 48, 440, 48, 441, 48, 442, 48, 200, 443, 72, 72, 72, 48, 444, + 48, 445, 48, 446, 72, 72, 72, 72, 48, 48, 48, 447, 270, 448, 270, 270, + 449, 450, 48, 451, 452, 453, 48, 454, 48, 455, 72, 72, 456, 48, 457, 458, + 48, 48, 48, 459, 48, 460, 48, 461, 48, 462, 463, 72, 72, 72, 72, 72, + 48, 48, 48, 48, 196, 72, 72, 72, 9, 9, 9, 464, 11, 11, 11, 465, + 48, 48, 466, 192, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 270, 467, 48, 48, 468, 469, 72, 72, 72, 72, + 48, 455, 470, 48, 62, 471, 72, 72, 72, 72, 72, 48, 472, 72, 48, 315, + 473, 48, 48, 474, 475, 448, 476, 477, 222, 48, 48, 478, 479, 48, 196, 192, + 480, 48, 481, 482, 483, 48, 48, 484, 222, 48, 48, 485, 486, 487, 488, 489, + 48, 98, 490, 491, 72, 72, 72, 72, 492, 493, 494, 48, 48, 495, 496, 192, + 497, 84, 85, 498, 499, 500, 501, 502, 72, 72, 72, 72, 72, 72, 72, 72, + 48, 48, 48, 503, 504, 505, 469, 72, 48, 48, 48, 506, 507, 192, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 48, 48, 508, 509, 510, 511, 72, 72, + 48, 48, 48, 512, 513, 192, 514, 72, 48, 48, 515, 516, 192, 72, 72, 72, + 48, 173, 517, 518, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 48, 48, 490, 519, 72, 72, 72, 72, 72, 72, 9, 9, 11, 11, 148, 520, + 521, 522, 48, 523, 524, 192, 72, 72, 72, 72, 525, 48, 48, 526, 527, 72, + 528, 48, 48, 529, 530, 531, 48, 48, 532, 533, 534, 72, 48, 48, 48, 196, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 84, 48, 504, 527, 528, 147, 174, 529, 48, 530, 531, 532, 72, 72, 72, 72, - 533, 48, 48, 534, 535, 191, 536, 48, 537, 538, 191, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 48, 539, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 269, 540, 541, 542, + 85, 48, 508, 535, 536, 148, 175, 537, 48, 538, 539, 540, 72, 72, 72, 72, + 541, 48, 48, 542, 543, 192, 544, 48, 545, 546, 192, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 48, 547, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 101, 270, 548, 549, 550, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 206, 72, 72, 72, 72, 72, 72, - 270, 270, 270, 270, 270, 270, 543, 544, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 386, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 207, 72, 72, 72, 72, 72, 72, + 271, 271, 271, 271, 271, 271, 551, 552, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 388, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 48, 48, 199, 545, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 48, 48, 200, 553, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 48, 48, 48, 48, 314, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 48, 48, 48, 48, 315, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 48, 48, 48, 195, 48, 199, 368, 72, 72, 72, 72, 72, 72, 48, 203, 546, - 48, 48, 48, 547, 548, 549, 550, 551, 48, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 9, 9, 11, 11, 269, 552, 72, 72, 72, 72, 72, 72, - 48, 48, 48, 48, 553, 554, 555, 555, 556, 557, 72, 72, 72, 72, 558, 72, + 48, 48, 48, 196, 48, 200, 370, 72, 72, 72, 72, 72, 72, 48, 204, 554, + 48, 48, 48, 555, 556, 557, 558, 559, 48, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 9, 9, 11, 11, 270, 560, 72, 72, 72, 72, 72, 72, + 48, 48, 48, 48, 561, 562, 563, 563, 564, 565, 72, 72, 72, 72, 566, 567, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 400, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 559, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 74, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 199, 72, 72, + 196, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 199, 72, 72, 72, 559, 560, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 205, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 48, 48, 48, 48, 48, 48, 71, 150, 195, 561, 562, 72, 72, 72, 72, 72, + 48, 200, 72, 72, 72, 568, 569, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 206, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 323, - 208, 208, 563, 208, 208, 208, 564, 565, 566, 208, 567, 208, 208, 208, 568, 72, - 208, 208, 208, 208, 569, 72, 72, 72, 72, 72, 72, 72, 72, 72, 269, 570, - 208, 208, 208, 208, 208, 285, 269, 451, 72, 72, 72, 72, 72, 72, 72, 72, - 9, 571, 11, 572, 573, 574, 240, 9, 575, 576, 577, 578, 579, 9, 571, 11, - 580, 581, 11, 582, 583, 584, 585, 9, 586, 11, 9, 571, 11, 572, 573, 11, - 240, 9, 575, 585, 9, 586, 11, 9, 571, 11, 587, 9, 588, 589, 590, 591, - 11, 592, 9, 593, 594, 595, 596, 11, 597, 9, 598, 11, 599, 600, 600, 600, - 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, - 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, - 32, 32, 32, 601, 32, 32, 602, 603, 604, 605, 45, 72, 72, 72, 72, 72, + 48, 48, 48, 48, 48, 48, 71, 151, 196, 570, 571, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 606, 607, 608, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 48, 48, 150, 609, 610, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 48, 48, 611, 612, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 325, + 209, 209, 572, 209, 209, 209, 573, 574, 575, 209, 576, 209, 209, 209, 577, 72, + 209, 209, 209, 209, 578, 72, 72, 72, 72, 72, 72, 72, 72, 72, 270, 579, + 209, 209, 209, 209, 209, 286, 270, 452, 72, 72, 72, 72, 72, 72, 72, 72, + 9, 580, 11, 581, 582, 583, 242, 9, 584, 585, 586, 587, 588, 9, 580, 11, + 589, 590, 11, 591, 592, 593, 594, 9, 595, 11, 9, 580, 11, 581, 582, 11, + 242, 9, 584, 594, 9, 595, 11, 9, 580, 11, 596, 9, 597, 598, 599, 600, + 11, 601, 9, 602, 603, 604, 605, 11, 606, 9, 607, 11, 608, 609, 609, 609, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 32, 32, 32, 610, 32, 32, 611, 612, 613, 614, 45, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 613, 614, 72, 72, - 9, 9, 575, 11, 615, 368, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 484, 269, 269, 616, 617, 72, 72, 72, 72, - 484, 269, 618, 619, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 620, 48, 621, 622, 623, 624, 625, 626, 627, 205, 628, 205, 72, 72, 72, 629, + 615, 616, 617, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 48, 48, 151, 618, 619, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 48, 48, 620, 621, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 208, 208, 324, 208, 208, 208, 208, 208, 208, 322, 333, 630, 630, 630, 208, 323, - 174, 208, 208, 208, 208, 208, 631, 208, 208, 208, 631, 72, 72, 72, 632, 208, - 633, 208, 208, 324, 568, 634, 323, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 635, - 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 323, 631, 286, - 208, 208, 208, 208, 208, 208, 208, 322, 208, 208, 208, 208, 208, 568, 324, 72, - 324, 208, 208, 208, 636, 175, 208, 208, 636, 208, 637, 72, 72, 72, 72, 72, - 638, 208, 208, 208, 208, 208, 208, 639, 208, 208, 640, 208, 641, 208, 208, 208, - 208, 208, 208, 208, 208, 322, 637, 642, 633, 323, 72, 72, 72, 72, 72, 72, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 622, 623, 72, 72, + 9, 9, 584, 11, 624, 370, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 488, 270, 270, 625, 626, 72, 72, 72, 72, + 488, 270, 627, 628, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 629, 48, 630, 631, 632, 633, 634, 635, 636, 206, 637, 206, 72, 72, 72, 638, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 314, 72, 72, + 209, 209, 326, 209, 209, 209, 209, 209, 209, 324, 335, 639, 639, 639, 209, 325, + 640, 209, 209, 209, 209, 209, 209, 209, 209, 209, 641, 72, 72, 72, 642, 209, + 643, 209, 209, 326, 577, 644, 325, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 645, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 646, 424, 424, + 209, 209, 209, 209, 209, 209, 209, 324, 209, 209, 209, 209, 209, 577, 326, 72, + 326, 209, 209, 209, 646, 176, 209, 209, 646, 209, 641, 644, 72, 72, 72, 72, + 209, 209, 209, 209, 209, 209, 209, 647, 209, 209, 209, 209, 648, 209, 209, 209, + 209, 209, 209, 209, 209, 324, 641, 649, 286, 209, 577, 286, 643, 286, 72, 72, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 650, 209, 209, 287, 72, 72, 192, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 204, 72, 72, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 203, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 205, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 643, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 469, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 100, 72, - 48, 203, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 101, 72, + 48, 204, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 644, 72, 645, 645, 645, 645, 645, 645, 72, 72, 72, 72, 72, 72, 72, 72, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 71, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 651, 72, 652, 652, 652, 652, 652, 652, 72, 72, 72, 72, 72, 72, 72, 72, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 72, - 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, - 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 646, - 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, - 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 647, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 653, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 654, 0, 0, 0, 0, 1, 2, 1, 2, 0, 0, 3, 3, 4, 5, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 0, 0, 7, 0, @@ -3272,31 +3299,31 @@ _hb_ucd_u16[11168] = 14, 14, 14, 16, 17, 18, 17, 17, 19, 20, 21, 21, 22, 21, 23, 24, 25, 26, 27, 27, 28, 29, 27, 30, 27, 27, 27, 27, 27, 31, 27, 27, 32, 33, 33, 33, 34, 27, 27, 27, 35, 35, 35, 36, 37, 37, 37, 38, - 39, 39, 40, 41, 42, 43, 44, 45, 45, 45, 27, 46, 45, 47, 48, 27, - 49, 49, 49, 49, 49, 50, 51, 49, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, - 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 110, 111, 112, 113, 110, 114, 115, 116, 117, 118, 119, 120, 121, - 122, 123, 123, 124, 123, 125, 45, 45, 126, 127, 128, 129, 130, 131, 45, 45, - 132, 132, 132, 132, 133, 132, 134, 135, 132, 133, 132, 136, 136, 137, 45, 45, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 139, 139, 140, 139, 139, 141, - 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, - 143, 143, 143, 143, 144, 145, 143, 143, 144, 143, 143, 146, 147, 148, 143, 143, - 143, 147, 143, 143, 143, 149, 143, 150, 143, 151, 152, 152, 152, 152, 152, 153, - 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, - 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, - 154, 154, 154, 154, 154, 154, 154, 154, 155, 156, 157, 157, 157, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 168, 168, 168, 168, 169, 170, 170, - 171, 172, 173, 173, 173, 173, 173, 174, 173, 173, 175, 154, 154, 154, 154, 176, - 177, 178, 179, 179, 180, 181, 182, 183, 184, 184, 185, 184, 186, 187, 168, 168, - 188, 189, 190, 190, 190, 191, 190, 192, 193, 193, 194, 195, 45, 45, 45, 45, - 196, 196, 196, 196, 197, 196, 196, 198, 199, 199, 199, 199, 200, 200, 200, 201, - 202, 202, 202, 203, 204, 205, 205, 205, 206, 139, 139, 207, 208, 209, 210, 211, - 4, 4, 212, 4, 4, 213, 214, 215, 4, 4, 4, 216, 8, 8, 8, 217, + 39, 39, 40, 41, 42, 43, 44, 45, 45, 45, 27, 46, 47, 48, 49, 27, + 50, 50, 50, 50, 50, 51, 52, 50, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 111, 112, 113, 114, 111, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 124, 125, 124, 126, 45, 45, 127, 128, 129, 130, 131, 132, 45, 45, + 133, 133, 133, 133, 134, 133, 135, 136, 133, 134, 133, 137, 137, 138, 45, 45, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 140, 140, 141, 140, 140, 142, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 144, 144, 144, 144, 145, 146, 144, 144, 145, 144, 144, 147, 148, 149, 144, 144, + 144, 148, 144, 144, 144, 150, 144, 151, 144, 152, 153, 153, 153, 153, 153, 154, + 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, 156, 157, 158, 158, 158, 158, 159, 160, + 161, 162, 163, 164, 165, 166, 167, 168, 169, 169, 169, 169, 169, 170, 171, 171, + 172, 173, 174, 174, 174, 174, 174, 175, 174, 174, 176, 155, 155, 155, 155, 177, + 178, 179, 180, 180, 181, 182, 183, 184, 185, 185, 186, 185, 187, 188, 169, 169, + 189, 190, 191, 191, 191, 192, 191, 193, 194, 194, 195, 8, 196, 45, 45, 45, + 197, 197, 197, 197, 198, 197, 197, 199, 200, 200, 200, 200, 201, 201, 201, 202, + 203, 203, 203, 204, 205, 206, 206, 206, 207, 140, 140, 208, 209, 210, 211, 212, + 4, 4, 213, 4, 4, 214, 215, 216, 4, 4, 4, 217, 8, 8, 8, 218, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 11, 218, 11, 11, 218, 219, 11, 220, 11, 11, 11, 221, 221, 222, 11, 223, - 224, 0, 0, 0, 0, 0, 225, 226, 227, 228, 0, 0, 45, 8, 8, 229, + 11, 219, 11, 11, 219, 220, 11, 221, 11, 11, 11, 222, 222, 223, 11, 224, + 225, 0, 0, 0, 0, 0, 226, 227, 228, 229, 0, 0, 45, 8, 8, 196, 0, 0, 230, 231, 232, 0, 4, 4, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3307,46 +3334,46 @@ _hb_ucd_u16[11168] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 238, 0, 0, 0, 0, 0, 0, 239, 239, 240, 239, 239, 240, 4, 4, 241, 241, 241, 241, 241, 241, 241, 242, - 139, 139, 140, 243, 243, 243, 244, 245, 143, 246, 247, 247, 247, 247, 14, 14, - 0, 0, 0, 0, 0, 45, 45, 45, 248, 249, 248, 248, 248, 248, 248, 250, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 251, 45, 252, - 253, 0, 254, 255, 256, 257, 257, 257, 257, 258, 259, 260, 260, 260, 260, 261, - 262, 263, 263, 264, 142, 142, 142, 142, 265, 0, 263, 266, 0, 0, 267, 260, - 142, 265, 0, 0, 0, 0, 142, 268, 0, 0, 0, 0, 0, 260, 260, 269, - 260, 260, 260, 260, 260, 270, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 251, 0, 0, 0, 0, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 45, - 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, - 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, - 271, 271, 271, 271, 271, 271, 271, 271, 272, 271, 271, 271, 273, 274, 274, 274, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 276, 45, 14, 14, 14, 14, 14, 14, 277, 277, 277, 277, 277, 278, - 0, 0, 279, 4, 4, 4, 4, 4, 280, 4, 4, 4, 281, 45, 45, 282, - 283, 283, 284, 285, 286, 286, 286, 287, 288, 288, 288, 288, 289, 290, 49, 49, - 291, 291, 292, 293, 293, 294, 142, 295, 296, 296, 296, 296, 297, 298, 138, 299, - 300, 300, 300, 301, 302, 303, 138, 138, 304, 304, 304, 304, 305, 306, 307, 308, - 309, 310, 247, 4, 4, 311, 312, 152, 152, 152, 152, 152, 307, 307, 313, 314, - 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, - 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, - 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, - 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 315, 142, 316, 142, 142, 317, + 140, 140, 141, 243, 243, 243, 244, 245, 144, 246, 247, 247, 247, 247, 14, 14, + 0, 0, 0, 0, 0, 248, 45, 45, 249, 250, 249, 249, 249, 249, 249, 251, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 252, 45, 253, + 254, 0, 255, 256, 257, 258, 258, 258, 258, 259, 260, 261, 261, 261, 261, 262, + 263, 264, 264, 265, 143, 143, 143, 143, 266, 0, 264, 264, 0, 0, 267, 261, + 143, 266, 0, 0, 0, 0, 143, 268, 0, 0, 0, 0, 0, 261, 261, 269, + 261, 261, 261, 261, 261, 270, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 0, 0, 0, 0, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 271, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 273, 272, 272, 272, 274, 275, 275, 275, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 277, 45, 14, 14, 14, 14, 14, 14, 278, 278, 278, 278, 278, 279, + 0, 0, 280, 4, 4, 4, 4, 4, 281, 4, 4, 4, 282, 45, 45, 283, + 284, 284, 285, 286, 287, 287, 287, 288, 289, 289, 289, 289, 290, 291, 50, 50, + 292, 292, 293, 294, 294, 295, 143, 296, 297, 297, 297, 297, 298, 299, 139, 300, + 301, 301, 301, 302, 303, 304, 139, 139, 305, 305, 305, 305, 306, 307, 308, 309, + 310, 311, 247, 4, 4, 312, 313, 153, 153, 153, 153, 153, 308, 308, 314, 315, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 316, 143, 317, 143, 143, 318, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 318, 248, 248, 248, 248, 248, 248, 319, 45, 45, - 320, 321, 21, 322, 323, 27, 27, 27, 27, 27, 27, 27, 324, 47, 27, 27, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 319, 249, 249, 249, 249, 249, 249, 320, 45, 45, + 321, 322, 21, 323, 324, 27, 27, 27, 27, 27, 27, 27, 325, 48, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 325, 45, 27, 27, 27, 27, 326, 27, 27, 327, 45, 45, 328, - 8, 285, 329, 0, 0, 330, 331, 332, 27, 27, 27, 27, 27, 27, 27, 333, - 334, 0, 1, 2, 1, 2, 335, 259, 260, 336, 142, 265, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 345, 45, 45, 342, 342, 342, 342, 342, 342, 342, 346, - 347, 0, 0, 348, 11, 11, 11, 11, 349, 252, 350, 45, 45, 0, 0, 351, - 45, 45, 45, 45, 45, 45, 45, 45, 352, 353, 354, 354, 354, 355, 356, 252, + 27, 27, 27, 326, 45, 27, 27, 27, 27, 327, 27, 27, 47, 45, 45, 328, + 8, 286, 329, 0, 0, 330, 331, 46, 27, 27, 27, 27, 27, 27, 27, 332, + 333, 0, 1, 2, 1, 2, 334, 260, 261, 335, 143, 266, 336, 337, 338, 339, + 340, 341, 342, 343, 344, 344, 45, 45, 341, 341, 341, 341, 341, 341, 341, 345, + 346, 0, 0, 347, 11, 11, 11, 11, 348, 349, 350, 45, 45, 0, 0, 351, + 45, 45, 45, 45, 45, 45, 45, 45, 352, 353, 354, 354, 354, 355, 356, 253, 357, 357, 358, 359, 360, 361, 361, 362, 363, 364, 365, 365, 366, 367, 45, 45, 368, 368, 368, 368, 368, 369, 369, 369, 370, 371, 372, 373, 373, 374, 373, 375, 376, 376, 377, 378, 378, 378, 379, 45, 45, 45, 45, 45, 45, 45, 45, 45, @@ -3358,101 +3385,105 @@ _hb_ucd_u16[11168] = 413, 413, 413, 414, 415, 416, 417, 418, 419, 420, 421, 45, 45, 45, 45, 45, 422, 422, 422, 422, 423, 45, 45, 45, 424, 424, 424, 425, 424, 424, 424, 426, 427, 427, 428, 429, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 27, 430, 45, 45, 45, 45, 45, 45, 45, 45, - 431, 431, 432, 433, 433, 434, 45, 45, 45, 45, 45, 45, 45, 45, 435, 436, - 437, 437, 437, 437, 438, 439, 437, 440, 441, 441, 441, 441, 442, 443, 444, 445, - 446, 446, 446, 447, 448, 449, 449, 450, 451, 451, 451, 451, 452, 451, 453, 454, - 455, 456, 455, 457, 45, 45, 45, 45, 458, 459, 460, 461, 461, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 471, 45, 45, 45, 45, 45, 45, 45, 45, - 472, 472, 472, 472, 472, 473, 45, 45, 474, 474, 474, 474, 475, 476, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 477, 477, 477, 478, 477, 479, 45, 45, - 480, 480, 480, 480, 481, 482, 483, 45, 484, 484, 484, 485, 486, 45, 45, 45, - 487, 488, 489, 487, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 490, 490, 490, 491, 45, 45, 45, 45, 45, 45, 492, 492, 492, 492, 492, 493, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 494, 495, 495, 494, 496, 45, - 497, 497, 497, 497, 498, 499, 499, 499, 499, 499, 500, 45, 501, 501, 501, 502, + 45, 45, 45, 45, 45, 45, 27, 430, 431, 431, 432, 433, 45, 45, 45, 45, + 434, 434, 435, 436, 436, 437, 45, 45, 45, 45, 45, 438, 439, 45, 440, 441, + 442, 442, 442, 442, 443, 444, 442, 445, 446, 446, 446, 446, 447, 448, 449, 450, + 451, 451, 451, 452, 453, 454, 454, 455, 456, 456, 456, 456, 456, 456, 457, 458, + 459, 460, 459, 461, 45, 45, 45, 45, 462, 463, 464, 465, 465, 465, 466, 467, + 468, 469, 470, 471, 472, 473, 474, 475, 45, 45, 45, 45, 45, 45, 45, 45, + 476, 476, 476, 476, 476, 477, 478, 45, 479, 479, 479, 479, 480, 481, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 482, 482, 482, 483, 482, 484, 45, 45, + 485, 485, 485, 485, 486, 487, 488, 45, 489, 489, 489, 490, 491, 45, 45, 45, + 492, 493, 494, 492, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 495, 495, 495, 496, 45, 45, 45, 45, 45, 45, 497, 497, 497, 497, 497, 498, + 499, 500, 501, 502, 503, 504, 45, 45, 45, 45, 505, 506, 506, 505, 507, 45, + 508, 508, 508, 508, 509, 510, 510, 510, 510, 510, 511, 45, 512, 512, 512, 513, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 503, 504, 504, 505, 506, 504, 507, 508, 508, 509, 510, 511, 45, 45, 45, 45, - 512, 513, 513, 514, 515, 516, 517, 518, 519, 520, 521, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 522, 523, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 524, 524, 524, 525, - 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, - 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, - 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, - 526, 526, 526, 526, 526, 526, 526, 526, 526, 527, 45, 45, 45, 45, 45, 45, - 526, 526, 526, 526, 526, 526, 528, 529, 526, 526, 526, 526, 526, 526, 526, 526, - 526, 526, 526, 526, 530, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, - 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, - 531, 531, 532, 533, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 514, 515, 515, 516, 517, 515, 518, 519, 519, 520, 521, 522, 45, 45, 45, 45, + 523, 524, 524, 525, 526, 527, 528, 529, 530, 531, 532, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 533, 534, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 535, 536, 536, 536, 537, + 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, + 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, + 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, + 538, 538, 538, 538, 538, 538, 538, 538, 538, 539, 45, 45, 45, 45, 45, 45, + 538, 538, 538, 538, 538, 538, 540, 541, 538, 538, 538, 538, 538, 538, 538, 538, + 538, 538, 538, 538, 542, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, + 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, + 543, 543, 544, 545, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, - 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, - 534, 534, 534, 534, 535, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, + 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, + 546, 546, 546, 546, 547, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 536, 537, 538, 539, 45, 45, 45, 45, 45, 45, 540, 541, 542, - 543, 543, 543, 543, 544, 545, 546, 547, 543, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 548, 548, 548, 548, 548, 549, 45, 45, 45, 45, 45, 45, - 550, 550, 550, 550, 551, 550, 550, 550, 552, 550, 45, 45, 45, 45, 553, 45, - 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, - 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, - 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, - 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 555, - 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 556, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 557, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, - 257, 558, 45, 45, 45, 559, 560, 561, 561, 561, 561, 561, 561, 561, 561, 561, - 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 562, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 563, 563, 563, 563, 563, 563, 564, 565, 566, 567, 267, 45, 45, 45, 45, 45, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 548, 549, 550, 551, 45, 45, 45, 45, 45, 45, 552, 553, 554, + 555, 555, 555, 555, 556, 557, 558, 559, 555, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 560, 560, 560, 560, 560, 561, 45, 45, 45, 45, 45, 45, + 562, 562, 562, 562, 563, 562, 562, 562, 564, 562, 45, 45, 45, 45, 565, 566, + 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, + 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, + 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, + 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 568, + 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, + 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, + 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 570, 45, 45, + 571, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 572, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, + 258, 573, 45, 45, 45, 574, 575, 576, 576, 576, 576, 576, 576, 576, 576, 576, + 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 577, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 568, - 0, 0, 569, 0, 0, 0, 570, 571, 572, 0, 573, 0, 0, 0, 574, 45, - 11, 11, 11, 11, 575, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 267, - 0, 0, 0, 0, 0, 234, 0, 574, 45, 45, 45, 45, 45, 45, 45, 45, - 0, 0, 0, 0, 0, 225, 0, 0, 0, 576, 577, 578, 579, 0, 0, 0, - 580, 581, 0, 582, 583, 584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 238, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 585, 0, 0, 0, - 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, - 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, - 586, 586, 586, 586, 586, 586, 586, 586, 587, 588, 589, 45, 45, 45, 45, 45, + 578, 578, 578, 578, 578, 578, 579, 580, 581, 582, 267, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 590, 591, 592, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 593, 593, 594, 595, 596, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 597, 597, 597, 598, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 583, + 0, 0, 584, 0, 0, 0, 585, 586, 587, 0, 588, 0, 0, 0, 589, 45, + 11, 11, 11, 11, 590, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 267, + 0, 0, 0, 0, 0, 234, 0, 589, 45, 45, 45, 45, 45, 45, 45, 45, + 0, 0, 0, 0, 0, 226, 0, 0, 0, 591, 592, 593, 594, 0, 0, 0, + 595, 596, 0, 597, 598, 599, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 600, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 601, 0, 0, 0, + 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, + 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, + 602, 602, 602, 602, 602, 602, 602, 602, 603, 604, 605, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 600, 601, 45, 45, - 602, 602, 602, 602, 603, 604, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 334, 0, 0, 0, 605, 45, 45, 45, 45, - 334, 0, 0, 606, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 607, 27, 608, 609, 610, 611, 612, 613, 614, 615, 616, 615, 45, 45, 45, 324, + 606, 607, 608, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 609, 609, 610, 611, 612, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 613, 613, 613, 614, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 0, 0, 252, 0, 0, 0, 0, 0, 0, 267, 227, 334, 334, 334, 0, 568, - 617, 0, 0, 0, 0, 0, 617, 0, 0, 0, 617, 45, 45, 45, 618, 0, - 619, 0, 0, 252, 574, 620, 568, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 568, 617, 235, - 0, 0, 0, 0, 0, 0, 0, 267, 0, 0, 0, 0, 0, 574, 252, 45, - 252, 0, 0, 0, 621, 285, 0, 0, 621, 0, 606, 45, 45, 45, 45, 45, - 622, 0, 0, 0, 0, 0, 0, 623, 0, 0, 624, 0, 625, 0, 0, 0, - 0, 0, 0, 0, 0, 267, 606, 626, 627, 568, 45, 45, 45, 45, 45, 45, + 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 616, 617, 45, 45, + 618, 618, 618, 618, 619, 620, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 333, 0, 0, 0, 621, 45, 45, 45, 45, + 333, 0, 0, 622, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 623, 27, 624, 625, 626, 627, 628, 629, 630, 631, 632, 631, 45, 45, 45, 325, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 628, 45, 45, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 629, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 318, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 630, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 631, 45, - 248, 318, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 0, 0, 253, 0, 0, 0, 0, 0, 0, 267, 228, 333, 333, 333, 0, 583, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 622, 45, 45, 45, 633, 0, + 634, 0, 0, 253, 589, 635, 583, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 636, 349, 349, + 0, 0, 0, 0, 0, 0, 0, 267, 0, 0, 0, 0, 0, 589, 253, 45, + 253, 0, 0, 0, 636, 286, 0, 0, 636, 0, 622, 635, 45, 45, 45, 45, + 0, 0, 0, 0, 0, 0, 0, 637, 0, 0, 0, 0, 638, 0, 0, 0, + 0, 0, 0, 0, 0, 267, 622, 639, 234, 0, 589, 234, 248, 234, 45, 45, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 330, 0, 0, 235, 45, 45, 286, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 319, 45, 45, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 640, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 319, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 566, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 641, 45, + 249, 319, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 632, 45, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 642, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 643, 45, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3727,14 +3758,18 @@ _hb_ucd_u16[11168] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1946,1947, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1948,1949, - 1950,1951,1952,1953,1954, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1948, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1949,1950, + 1951,1952,1953,1954,1955, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1955,1956,1957,1959,1958, - 1960, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1956,1957,1958,1960,1959, + 1961, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3801,7 +3836,7 @@ _hb_ucd_gc (unsigned u) static inline uint_fast8_t _hb_ucd_ccc (unsigned u) { - return u<125259u?_hb_ucd_u8[14026+(((_hb_ucd_u8[13034+(((_hb_ucd_u8[12544+(u>>4>>4)])<<4)+((u>>4)&15u))])<<4)+((u)&15u))]:0; + return u<125259u?_hb_ucd_u8[15060+(((_hb_ucd_u8[13636+(((_hb_ucd_u8[12656+(u>>3>>4)])<<4)+((u>>3)&15u))])<<3)+((u)&7u))]:0; } static inline unsigned _hb_ucd_b4 (const uint8_t* a, unsigned i) @@ -3811,24 +3846,24 @@ _hb_ucd_b4 (const uint8_t* a, unsigned i) static inline int_fast16_t _hb_ucd_bmg (unsigned u) { - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[16170+(((_hb_ucd_b4(16042+_hb_ucd_u8,u>>2>>6))<<6)+((u>>2)&63u))])<<2)+((u)&3u)]:0; + return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[16372+(((_hb_ucd_b4(16244+_hb_ucd_u8,u>>2>>6))<<6)+((u>>2)&63u))])<<2)+((u)&3u)]:0; } static inline uint_fast8_t _hb_ucd_sc (unsigned u) { - return u<918000u?_hb_ucd_u8[18924+(((_hb_ucd_u16[3008+(((_hb_ucd_u8[17130+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:2; + return u<918000u?_hb_ucd_u8[19126+(((_hb_ucd_u16[3040+(((_hb_ucd_u8[17332+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:2; } static inline uint_fast16_t _hb_ucd_dm (unsigned u) { - return u<195102u?_hb_ucd_u16[6048+(((_hb_ucd_u8[29052+(u>>6)])<<6)+((u)&63u))]:0; + return u<195102u?_hb_ucd_u16[6144+(((_hb_ucd_u8[29430+(u>>6)])<<6)+((u)&63u))]:0; } #elif !defined(HB_NO_UCD_UNASSIGNED) static const uint8_t -_hb_ucd_u8[17198] = +_hb_ucd_u8[17508] = { 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 9, 10, 11, 7, 7, 7, 7, 12, 13, 14, 14, 14, 15, @@ -3836,6 +3871,7 @@ _hb_ucd_u8[17198] = 25, 26, 21, 21, 21, 21, 27, 28, 21, 21, 29, 30, 31, 32, 33, 34, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 35, 7, 36, 37, 7, 38, 7, 7, 7, 39, 21, 40, + 7, 7, 41, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, @@ -3857,13 +3893,12 @@ _hb_ucd_u8[17198] = 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 42, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 41, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 42, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 43, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 44, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 34, 35, 36, 37, 38, 39, 34, 34, 34, 40, 41, 42, 43, @@ -3881,33 +3916,34 @@ _hb_ucd_u8[17198] = 108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, 108,108, 34, 34,109,110,111,112, 34, 34,113,114,115,116,117,118, 119,120,121,122,123,124,125,126,127,128,129,123, 34, 34,130,123, - 131,132,133,134,135,136,137,138,139,140,141,123,142,123,143,144, - 145,146,147,148,149,150,151,123,152,153,123,154,155,156,157,123, - 158,159,123,160,161,162,123,123,163,164,165,166,123,167,123,168, - 34, 34, 34, 34, 34, 34, 34,169,170, 34,171,123,123,123,123,123, + 131,132,133,134,135,136,137,138,139,140,141,123,142,143,144,145, + 146,147,148,149,150,151,152,123,153,154,123,155,156,157,158,123, + 159,160,161,162,163,164,123,123,165,166,167,168,123,169,123,170, + 34, 34, 34, 34, 34, 34, 34,171,172, 34,173,123,123,123,123,123, 123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, - 34, 34, 34, 34, 34, 34, 34, 34,172,123,123,123,123,123,123,123, - 123,123,123,123,123,123,123,123, 34, 34, 34, 34,173,123,123,123, - 34, 34, 34, 34,174,175,176,177,123,123,123,123,178,179,180,181, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,182, - 34, 34, 34, 34, 34,183,123,123,123,123,123,123,123,123,123,123, - 34, 34,184, 34, 34,185,123,123,123,123,123,123,123,123,123,123, - 123,123,123,123,123,123,123,123,186,187,123,123,123,123,123,123, - 69,188,189,190,191,192,193,123,194,195,196,197,198,199,200,201, - 69, 69, 69, 69,202,203,123,123,123,123,123,123,123,123,123,123, - 204,123,205,123,123,206,123,123,123,123,123,123,123,123,123,123, - 34,207,208,123,123,123,123,123,209,210,211,123,212,213,123,123, - 214,215,216,217,218,123, 69,219, 69, 69, 69, 69, 69,220,221,222, - 223,224,225,226,227,228,123,123,123,123,123,123,123,123,123,123, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,229, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,230, 34, - 231, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,232, 34, 34, - 34, 34, 34, 34, 34, 34, 34,233,123,123,123,123,123,123,123,123, - 34, 34, 34, 34,234,123,123,123,123,123,123,123,123,123,123,123, - 235,123,236,237,123,123,123,123,123,123,123,123,123,123,123,123, - 108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,238, - 108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,239, + 34, 34, 34, 34, 34, 34, 34, 34,174,123,123,123,123,123,123,123, + 123,123,123,123,123,123,123,123, 34, 34, 34, 34,175,123,123,123, + 34, 34, 34, 34,176,177,178,179,123,123,123,123,180,181,182,183, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,184, + 34, 34, 34, 34, 34, 34, 34, 34, 34,185,186,123,123,123,123,123, + 34, 34,187, 34, 34,188,123,123,123,123,123,123,123,123,123,123, + 123,123,123,123,123,123,123,123,189,190,123,123,123,123,123,123, + 69,191,192,193,194,195,196,123,197,198,199,200,201,202,203,204, + 69, 69, 69, 69,205,206,123,123,123,123,123,123,123,123,123,123, + 207,123,208,123,123,209,123,123,123,123,123,123,123,123,123,123, + 34,210,211,123,123,123,123,123,212,213,214,123,215,216,123,123, + 217,218,219,220,221,123, 69,222, 69, 69, 69, 69, 69,223,224,225, + 226,227,228,229,230,231, 69,232,123,123,123,123,123,123,123,123, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,233, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,234, 34, + 235, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,236, 34, 34, + 34, 34, 34, 34, 34, 34, 34,237,123,123,123,123,123,123,123,123, + 34, 34, 34, 34,238,123,123,123,123,123,123,123,123,123,123,123, + 34, 34, 34, 34, 34, 34,239,123,123,123,123,123,123,123,123,123, + 240,123,241,242,123,123,123,123,123,123,123,123,123,123,123,123, + 108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,243, + 108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,244, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2, 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, @@ -3944,78 +3980,79 @@ _hb_ucd_u8[17198] = 43, 43, 40, 21, 2, 81, 57, 20, 36, 36, 36, 43, 43, 75, 43, 43, 43, 43, 75, 43, 75, 43, 43, 44, 2, 2, 2, 2, 2, 2, 2, 64, 36, 36, 36, 36, 70, 43, 44, 64, 36, 36, 36, 36, 36, 61, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 36, 36, 61, 36, 36, 36, 36, 44, - 44, 57, 43, 43, 43, 43, 43, 43, 43, 82, 43, 43, 43, 43, 43, 43, - 43, 83, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 83, 71, 84, - 85, 43, 43, 43, 83, 84, 85, 84, 70, 43, 43, 43, 36, 36, 36, 36, - 36, 43, 2, 7, 7, 7, 7, 7, 86, 36, 36, 36, 36, 36, 36, 36, - 70, 84, 62, 36, 36, 36, 61, 62, 61, 62, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 61, 36, 36, 36, 61, 61, 44, 36, 36, 44, 71, 84, - 85, 43, 80, 87, 88, 87, 85, 61, 44, 44, 44, 87, 44, 44, 36, 62, - 36, 43, 44, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 56, 63, 80, - 57, 83, 62, 36, 36, 61, 44, 62, 61, 36, 62, 61, 36, 44, 80, 84, - 85, 80, 44, 57, 80, 57, 43, 44, 57, 44, 44, 44, 62, 36, 61, 61, - 44, 44, 44, 7, 7, 7, 7, 7, 43, 36, 70, 64, 44, 44, 44, 44, - 57, 83, 62, 36, 36, 36, 36, 62, 36, 62, 36, 36, 36, 36, 36, 36, - 61, 36, 62, 36, 36, 44, 71, 84, 85, 43, 43, 57, 83, 87, 85, 44, - 61, 44, 44, 44, 44, 44, 44, 44, 66, 44, 44, 44, 62, 43, 43, 43, - 57, 84, 62, 36, 36, 36, 61, 62, 61, 36, 62, 36, 36, 44, 71, 85, - 85, 43, 80, 87, 88, 87, 85, 44, 44, 44, 44, 83, 44, 44, 36, 62, - 78, 27, 27, 27, 44, 44, 44, 44, 44, 71, 62, 36, 36, 61, 44, 36, - 61, 36, 36, 44, 62, 61, 61, 36, 44, 62, 61, 44, 36, 61, 44, 36, - 36, 36, 36, 36, 36, 44, 44, 84, 83, 88, 44, 84, 88, 84, 85, 44, - 61, 44, 44, 87, 44, 44, 44, 44, 27, 89, 67, 67, 56, 90, 44, 44, - 83, 84, 71, 36, 36, 36, 61, 36, 61, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 44, 62, 43, 83, 84, 88, 43, 80, 43, 43, 44, - 44, 44, 57, 80, 36, 61, 44, 44, 44, 44, 44, 91, 27, 27, 27, 89, - 70, 84, 72, 36, 36, 36, 61, 36, 36, 36, 62, 36, 36, 44, 71, 85, - 84, 84, 88, 83, 88, 84, 43, 44, 44, 44, 87, 88, 44, 44, 44, 61, - 62, 61, 44, 44, 44, 44, 44, 44, 43, 84, 62, 36, 36, 36, 61, 36, - 36, 36, 36, 36, 36, 70, 71, 84, 85, 43, 80, 84, 88, 84, 85, 77, - 44, 44, 36, 92, 27, 27, 27, 93, 27, 27, 27, 27, 89, 36, 36, 36, - 44, 84, 62, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 36, 36, 36, - 36, 62, 36, 36, 36, 36, 62, 44, 36, 36, 36, 61, 44, 80, 44, 87, - 84, 43, 80, 80, 84, 84, 84, 84, 44, 84, 64, 44, 44, 44, 44, 44, - 62, 36, 36, 36, 36, 36, 36, 36, 70, 36, 43, 43, 43, 80, 44, 94, - 36, 36, 36, 75, 43, 43, 43, 60, 7, 7, 7, 7, 7, 2, 44, 44, - 62, 61, 61, 36, 36, 61, 36, 36, 36, 36, 62, 62, 36, 36, 36, 36, - 70, 36, 43, 43, 43, 43, 71, 44, 36, 36, 61, 81, 43, 43, 43, 44, - 7, 7, 7, 7, 7, 44, 36, 36, 77, 67, 2, 2, 2, 2, 2, 2, - 2, 95, 95, 67, 43, 67, 67, 67, 7, 7, 7, 7, 7, 27, 27, 27, - 27, 27, 50, 50, 50, 4, 4, 84, 36, 36, 36, 36, 62, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 61, 44, 57, 43, 43, 43, 43, 43, 43, 83, - 43, 43, 60, 43, 36, 36, 70, 43, 43, 43, 43, 43, 57, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 80, 67, 67, 67, 67, 76, 67, 67, 90, 67, - 2, 2, 95, 67, 21, 64, 44, 44, 36, 36, 36, 36, 36, 92, 85, 43, - 83, 43, 43, 43, 85, 83, 85, 71, 7, 7, 7, 7, 7, 2, 2, 2, - 36, 36, 36, 84, 43, 36, 36, 43, 71, 84, 96, 92, 84, 84, 84, 36, - 70, 43, 71, 36, 36, 36, 36, 36, 36, 83, 85, 83, 84, 84, 85, 92, - 7, 7, 7, 7, 7, 84, 85, 67, 11, 11, 11, 48, 44, 44, 48, 44, - 16, 16, 16, 16, 16, 53, 45, 16, 36, 36, 36, 36, 61, 36, 36, 44, - 36, 36, 36, 61, 61, 36, 36, 44, 61, 36, 36, 44, 36, 36, 36, 61, - 61, 36, 36, 44, 36, 36, 36, 36, 36, 36, 36, 61, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 61, 57, 43, 2, 2, 2, 2, 97, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 98, 44, 67, 67, 67, 67, 67, 44, 44, 44, - 11, 11, 11, 44, 16, 16, 16, 44, 99, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 77, 72,100, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36,101,102, 44, 36, 36, 36, 36, 36, 63, 2,103, - 104, 36, 36, 36, 61, 44, 44, 44, 36, 36, 36, 36, 36, 36, 61, 36, - 36, 43, 80, 44, 44, 44, 44, 44, 36, 43, 60, 64, 44, 44, 44, 44, - 36, 43, 44, 44, 44, 44, 44, 44, 61, 43, 44, 44, 44, 44, 44, 44, - 36, 36, 43, 85, 43, 43, 43, 84, 84, 84, 84, 83, 85, 43, 43, 43, - 43, 43, 2, 86, 2, 66, 70, 44, 7, 7, 7, 7, 7, 44, 44, 44, - 27, 27, 27, 27, 27, 44, 44, 44, 2, 2, 2,105, 2, 59, 43, 68, - 36,106, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 44, 44, - 36, 36, 70, 71, 36, 36, 36, 36, 36, 36, 36, 36, 70, 61, 44, 44, - 36, 36, 36, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 61, - 43, 83, 84, 85, 83, 84, 44, 44, 84, 83, 84, 84, 85, 43, 44, 44, - 90, 44, 2, 7, 7, 7, 7, 7, 36, 36, 36, 36, 36, 36, 36, 44, - 36, 36, 61, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 44, 44, - 36, 36, 36, 36, 36, 44, 44, 44, 7, 7, 7, 7, 7, 98, 44, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 36, 36, 36, 70, 83, 85, 44, 2, - 36, 36, 92, 83, 43, 43, 43, 80, 83, 83, 85, 43, 43, 43, 83, 84, - 84, 85, 43, 43, 43, 43, 80, 57, 2, 2, 2, 86, 2, 2, 2, 44, - 43, 43, 43, 43, 43, 43, 43,107, 43, 43, 96, 36, 36, 36, 36, 36, + 44, 44, 44, 44, 44, 44, 44, 44, 36, 36, 61, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 44, 44, 44, 44, 44, 57, 43, 43, 43, 43, 43, 43, + 43, 82, 43, 43, 43, 43, 43, 43, 43, 83, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 83, 71, 84, 85, 43, 43, 43, 83, 84, 85, 84, + 70, 43, 43, 43, 36, 36, 36, 36, 36, 43, 2, 7, 7, 7, 7, 7, + 86, 36, 36, 36, 36, 36, 36, 36, 70, 84, 62, 36, 36, 36, 61, 62, + 61, 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 36, 36, 36, + 61, 61, 44, 36, 36, 44, 71, 84, 85, 43, 80, 87, 88, 87, 85, 61, + 44, 44, 44, 87, 44, 44, 36, 62, 36, 43, 44, 7, 7, 7, 7, 7, + 36, 20, 27, 27, 27, 56, 63, 80, 57, 83, 62, 36, 36, 61, 44, 62, + 61, 36, 62, 61, 36, 44, 80, 84, 85, 80, 44, 57, 80, 57, 43, 44, + 57, 44, 44, 44, 62, 36, 61, 61, 44, 44, 44, 7, 7, 7, 7, 7, + 43, 36, 70, 64, 44, 44, 44, 44, 57, 83, 62, 36, 36, 36, 36, 62, + 36, 62, 36, 36, 36, 36, 36, 36, 61, 36, 62, 36, 36, 44, 71, 84, + 85, 43, 43, 57, 83, 87, 85, 44, 61, 44, 44, 44, 44, 44, 44, 44, + 66, 44, 44, 44, 62, 43, 43, 43, 57, 84, 62, 36, 36, 36, 61, 62, + 61, 36, 62, 36, 36, 44, 71, 85, 85, 43, 80, 87, 88, 87, 85, 44, + 44, 44, 57, 83, 44, 44, 36, 62, 78, 27, 27, 27, 44, 44, 44, 44, + 44, 71, 62, 36, 36, 61, 44, 36, 61, 36, 36, 44, 62, 61, 61, 36, + 44, 62, 61, 44, 36, 61, 44, 36, 36, 36, 36, 36, 36, 44, 44, 84, + 83, 88, 44, 84, 88, 84, 85, 44, 61, 44, 44, 87, 44, 44, 44, 44, + 27, 89, 67, 67, 56, 90, 44, 44, 83, 84, 71, 36, 36, 36, 61, 36, + 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 44, 62, 43, + 83, 84, 88, 43, 80, 43, 43, 44, 44, 44, 57, 80, 36, 61, 44, 44, + 44, 44, 44, 91, 27, 27, 27, 89, 70, 84, 72, 36, 36, 36, 61, 36, + 36, 36, 62, 36, 36, 44, 71, 85, 84, 84, 88, 83, 88, 84, 43, 44, + 44, 44, 87, 88, 44, 44, 44, 61, 62, 61, 44, 44, 44, 44, 44, 44, + 43, 84, 36, 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 70, 71, 84, + 85, 43, 80, 84, 88, 84, 85, 77, 44, 44, 36, 92, 27, 27, 27, 93, + 27, 27, 27, 27, 89, 36, 36, 36, 57, 84, 62, 36, 36, 36, 36, 36, + 36, 36, 36, 61, 44, 36, 36, 36, 36, 62, 36, 36, 36, 36, 62, 44, + 36, 36, 36, 61, 44, 80, 44, 87, 84, 43, 80, 80, 84, 84, 84, 84, + 44, 84, 64, 44, 44, 44, 44, 44, 62, 36, 36, 36, 36, 36, 36, 36, + 70, 36, 43, 43, 43, 80, 44, 94, 36, 36, 36, 75, 43, 43, 43, 60, + 7, 7, 7, 7, 7, 2, 44, 44, 62, 61, 61, 36, 36, 61, 36, 36, + 36, 36, 62, 62, 36, 36, 36, 36, 70, 36, 43, 43, 43, 43, 71, 44, + 36, 36, 61, 81, 43, 43, 43, 44, 7, 7, 7, 7, 7, 44, 36, 36, + 77, 67, 2, 2, 2, 2, 2, 2, 2, 95, 95, 67, 43, 67, 67, 67, + 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 50, 50, 50, 4, 4, 84, + 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, + 57, 43, 43, 43, 43, 43, 43, 83, 43, 43, 60, 43, 36, 36, 70, 43, + 43, 43, 43, 43, 57, 43, 43, 43, 43, 43, 43, 43, 43, 43, 80, 67, + 67, 67, 67, 76, 67, 67, 90, 67, 2, 2, 95, 67, 21, 64, 44, 44, + 36, 36, 36, 36, 36, 92, 85, 43, 83, 43, 43, 43, 85, 83, 85, 71, + 7, 7, 7, 7, 7, 2, 2, 2, 36, 36, 36, 84, 43, 36, 36, 43, + 71, 84, 96, 92, 84, 84, 84, 36, 70, 43, 71, 36, 36, 36, 36, 36, + 36, 83, 85, 83, 84, 84, 85, 92, 7, 7, 7, 7, 7, 84, 85, 67, + 11, 11, 11, 48, 44, 44, 48, 44, 16, 16, 16, 16, 16, 53, 45, 16, + 36, 36, 36, 36, 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44, + 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44, 36, 36, 36, 36, + 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 57, 43, + 2, 2, 2, 2, 97, 27, 27, 27, 27, 27, 27, 27, 27, 27, 98, 44, + 67, 67, 67, 67, 67, 44, 44, 44, 11, 11, 11, 44, 16, 16, 16, 44, + 99, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 77, 72, + 100, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,101,102, 44, + 36, 36, 36, 36, 36, 63, 2,103,104, 36, 36, 36, 61, 44, 44, 44, + 36, 36, 36, 36, 36, 36, 61, 36, 36, 43, 80, 44, 44, 44, 44, 44, + 36, 43, 60, 64, 44, 44, 44, 44, 36, 43, 44, 44, 44, 44, 44, 44, + 61, 43, 44, 44, 44, 44, 44, 44, 36, 36, 43, 85, 43, 43, 43, 84, + 84, 84, 84, 83, 85, 43, 43, 43, 43, 43, 2, 86, 2, 66, 70, 44, + 7, 7, 7, 7, 7, 44, 44, 44, 27, 27, 27, 27, 27, 44, 44, 44, + 2, 2, 2,105, 2, 59, 43, 68, 36,106, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 61, 44, 44, 44, 36, 36, 70, 71, 36, 36, 36, 36, + 36, 36, 36, 36, 70, 61, 44, 44, 36, 36, 36, 44, 44, 44, 44, 44, + 36, 36, 36, 36, 36, 36, 36, 61, 43, 83, 84, 85, 83, 84, 44, 44, + 84, 83, 84, 84, 85, 43, 44, 44, 90, 44, 2, 7, 7, 7, 7, 7, + 36, 36, 36, 36, 36, 36, 36, 44, 36, 36, 61, 44, 44, 44, 44, 44, + 36, 36, 36, 36, 36, 36, 44, 44, 36, 36, 36, 36, 36, 44, 44, 44, + 7, 7, 7, 7, 7, 98, 44, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 36, 36, 36, 70, 83, 85, 44, 2, 36, 36, 92, 83, 43, 43, 43, 80, + 83, 83, 85, 43, 43, 43, 83, 84, 84, 85, 43, 43, 43, 43, 80, 57, + 2, 2, 2, 86, 2, 2, 2, 44, 43, 43, 43, 43, 43, 43, 43,107, + 80, 44, 44, 44, 44, 44, 44, 44, 43, 43, 96, 36, 36, 36, 36, 36, 36, 36, 83, 43, 43, 83, 83, 84, 84, 83, 96, 36, 36, 36, 44, 44, 95, 67, 67, 67, 67, 50, 43, 43, 43, 43, 67, 67, 67, 67, 90, 44, 43, 96, 36, 36, 36, 36, 36, 36, 92, 43, 43, 84, 43, 85, 43, 36, @@ -4039,118 +4076,119 @@ _hb_ucd_u8[17198] = 65, 65, 68, 65, 65, 65, 65, 65,130, 44, 27, 27, 27, 8,127,131, 27, 27, 27, 27, 27, 8,127,102, 40, 40, 40, 40, 40, 40, 81, 44, 20, 20, 20, 20, 20, 20, 20, 20, 43, 43, 43, 43, 43, 43,132, 51, - 133, 51,133, 43, 43, 43, 43, 43, 80, 44, 44, 44, 44, 44, 44, 44, - 67,134, 67,135, 67, 34, 11, 16, 11, 32,135, 67, 49, 11, 11, 67, - 67, 67,134,134,134, 11, 11,136, 11, 11, 35, 36, 39, 67, 16, 11, - 8, 8, 49, 16, 16, 26, 67,137, 27, 27, 27, 27, 27, 27, 27, 27, - 103,103,103,103,103,103,103,103,103,138,139,103,140, 67, 44, 44, - 8, 8,141, 67, 67, 8, 67, 67,141, 26, 67,141, 67, 67, 67,141, - 67, 67, 67, 67, 67, 67, 67, 8, 67,141,141, 67, 67, 67, 67, 67, - 67, 67, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 67, 67, 67, 67, 4, 4, 67, 67, 8, 67, 67, 67,142,143, 67, 67, - 67, 67, 67, 67, 67, 67,141, 67, 67, 67, 67, 67, 67, 26, 8, 8, - 8, 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8, - 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 90, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 90, 44, 44, 27, 27, 27, 27, 27, 27, 67, 67, - 67, 67, 67, 67, 67, 27, 27, 27, 67, 67, 67, 26, 67, 67, 67, 67, - 26, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8, 8, 8, - 67, 67, 67, 67, 67, 67, 67, 26, 67, 67, 67, 67, 4, 4, 4, 4, - 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, - 8, 8,127,144, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, - 8,127,145,145,145,145,145,145,145,145,145,145,144, 8, 8, 8, - 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, - 8, 8,141, 26, 8, 8,141, 67, 67, 67, 44, 67, 67, 67, 67, 67, - 67, 67, 67, 44, 67, 67, 67, 67, 11, 11, 11, 11, 11, 11, 11, 47, - 16, 16, 16, 16, 16, 16, 16,108, 32, 11, 32, 34, 34, 34, 34, 11, - 32, 32, 34, 16, 16, 16, 40, 11, 32, 32,137, 67, 67,135, 34,146, - 43, 32, 44, 44, 91, 2, 97, 2, 16, 16, 16,147, 44, 44,147, 44, - 36, 36, 36, 36, 44, 44, 44, 52, 64, 44, 44, 44, 44, 44, 44, 57, - 36, 36, 36, 61, 44, 44, 44, 44, 36, 36, 36, 61, 36, 36, 36, 61, - 2,119,119, 2,123,124,119, 2, 2, 2, 2, 6, 2,105,119, 2, - 119, 4, 4, 4, 4, 2, 2, 86, 2, 2, 2, 2, 2,118, 2, 2, - 105,148, 2, 2, 2, 2, 2, 2, 67, 67, 67, 67, 67, 55, 67, 67, + 107, 51,107, 43, 43, 43, 43, 43, 67,133, 67,134, 67, 34, 11, 16, + 11, 32,134, 67, 49, 11, 11, 67, 67, 67,133,133,133, 11, 11,135, + 11, 11, 35, 36, 39, 67, 16, 11, 8, 8, 49, 16, 16, 26, 67,136, + 27, 27, 27, 27, 27, 27, 27, 27,103,103,103,103,103,103,103,103, + 103,137,138,103,139, 67, 44, 44, 8, 8,140, 67, 67, 8, 67, 67, + 140, 26, 67,140, 67, 67, 67,140, 67, 67, 67, 67, 67, 67, 67, 8, + 67,140,140, 67, 67, 67, 67, 67, 67, 67, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 67, 67, 67, 67, 4, 4, 67, 67, + 8, 67, 67, 67,141,142, 67, 67, 67, 67, 67, 67, 67, 67,140, 67, + 67, 67, 67, 67, 67, 26, 8, 8, 8, 8, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 8, 8, 8, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 90, 44, 44, 44, 44, 67, 67, 67, 67, 67, 90, 44, 44, + 27, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, + 67, 67, 67, 26, 67, 67, 67, 67, 26, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 8, 8, 8, 8, 67, 67, 67, 67, 67, 67, 67, 26, + 67, 67, 67, 67, 4, 4, 4, 4, 4, 4, 4, 27, 27, 27, 27, 27, + 27, 27, 67, 67, 67, 67, 67, 67, 8, 8,127,143, 8, 8, 8, 8, + 8, 8, 8, 4, 4, 4, 4, 4, 8,127,144,144,144,144,144,144, + 144,144,144,144,143, 8, 8, 8, 8, 8, 8, 8, 4, 4, 8, 8, + 8, 8, 8, 8, 8, 8, 4, 8, 8, 8,140, 26, 8, 8,140, 67, + 67, 67, 44, 67, 67, 67, 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, + 11, 11, 11, 11, 11, 11, 11, 47, 16, 16, 16, 16, 16, 16, 16,108, + 32, 11, 32, 34, 34, 34, 34, 11, 32, 32, 34, 16, 16, 16, 40, 11, + 32, 32,136, 67, 67,134, 34,145, 43, 32, 44, 44, 91, 2, 97, 2, + 16, 16, 16,146, 44, 44,146, 44, 36, 36, 36, 36, 44, 44, 44, 52, + 64, 44, 44, 44, 44, 44, 44, 57, 36, 36, 36, 61, 44, 44, 44, 44, + 36, 36, 36, 61, 36, 36, 36, 61, 2,119,119, 2,123,124,119, 2, + 2, 2, 2, 6, 2,105,119, 2,119, 4, 4, 4, 4, 2, 2, 86, + 2, 2, 2, 2, 2,118, 2, 2,105,147, 2, 2, 2, 2, 2, 2, + 67, 64, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, 44, 44, 44, 44, 44, 44, 67, 67, 67, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 67, 44, 44, 1, 2,149,150, 4, 4, 4, 4, - 4, 67, 4, 4, 4, 4,151,152,153,103,103,103,103, 43, 43, 84, - 154, 40, 40, 67,103,155, 63, 67, 36, 36, 36, 61, 57,156,157, 69, + 67, 67, 67, 67, 67, 67, 44, 44, 1, 2,148,149, 4, 4, 4, 4, + 4, 67, 4, 4, 4, 4,150,151,152,103,103,103,103, 43, 43, 84, + 153, 40, 40, 67,103,154, 63, 67, 36, 36, 36, 61, 57,155,156, 69, 36, 36, 36, 36, 36, 63, 40, 69, 44, 44, 62, 36, 36, 36, 36, 36, 67, 27, 27, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 90, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27, - 158, 27, 27, 27, 27, 27, 27, 27, 36, 36,106, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36,159, 2, 7, 7, 7, 7, 7, 36, 44, 44, - 32, 32, 32, 32, 32, 32, 32, 70, 51,160, 43, 43, 43, 43, 43, 86, + 157, 27, 27, 27, 27, 27, 27, 27, 36, 36,106, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36,158, 2, 7, 7, 7, 7, 7, 36, 44, 44, + 32, 32, 32, 32, 32, 32, 32, 70, 51,159, 43, 43, 43, 43, 43, 86, 32, 32, 32, 32, 32, 32, 40, 43, 36, 36, 36,103,103,103,103,103, - 43, 2, 2, 2, 44, 44, 44, 44, 41, 41, 41,157, 40, 40, 40, 40, + 43, 2, 2, 2, 44, 44, 44, 44, 41, 41, 41,156, 40, 40, 40, 40, 41, 32, 32, 32, 32, 32, 32, 32, 16, 32, 32, 32, 32, 32, 32, 32, - 45, 16, 16, 16, 34, 34, 34, 32, 32, 32, 32, 32, 42,161, 34, 35, + 45, 16, 16, 16, 34, 34, 34, 32, 32, 32, 32, 32, 42,160, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 11, 11, 32, - 11, 11, 32, 32, 32, 32, 32, 32, 44, 32, 11, 47, 44, 44, 44, 44, - 44, 44, 44, 62, 40, 35, 36, 36, 36, 71, 36, 71, 36, 70, 36, 36, - 36, 92, 85, 83, 67, 67, 44, 44, 27, 27, 27, 67,162, 44, 44, 44, + 11, 11, 32, 32, 32, 32, 32, 32, 44, 32, 11, 11, 34,108, 44, 44, + 44, 44, 48, 35, 40, 35, 36, 36, 36, 71, 36, 71, 36, 70, 36, 36, + 36, 92, 85, 83, 67, 67, 80, 44, 27, 27, 27, 67,161, 44, 44, 44, 36, 36, 2, 2, 44, 44, 44, 44, 84, 36, 36, 36, 36, 36, 36, 36, 36, 36, 84, 84, 84, 84, 84, 84, 84, 84, 43, 44, 44, 44, 44, 2, 43, 36, 36, 36, 2, 72, 72, 70, 36, 36, 36, 43, 43, 43, 43, 2, 36, 36, 36, 70, 43, 43, 43, 43, 43, 84, 44, 44, 44, 44, 44, 91, - 36, 70, 84, 43, 43, 84, 43, 84,163, 2, 2, 2, 2, 2, 2, 52, + 36, 70, 84, 43, 43, 84, 43, 84,162, 2, 2, 2, 2, 2, 2, 52, 7, 7, 7, 7, 7, 44, 44, 2, 36, 36, 70, 69, 36, 36, 36, 36, 7, 7, 7, 7, 7, 36, 36, 61, 36, 36, 36, 36, 70, 43, 43, 83, 85, 83, 85, 80, 44, 44, 44, 44, 36, 70, 36, 36, 36, 36, 83, 44, 7, 7, 7, 7, 7, 44, 2, 2, 69, 36, 36, 77, 67, 92, 83, 36, 71, 43, 71, 70, 71, 36, 36, 43, 70, 61, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 62,106, 2, 36, 36, 36, 36, 36, 92, 43, 84, - 2,106,164, 80, 44, 44, 44, 44, 62, 36, 36, 61, 62, 36, 36, 61, + 2,106,163, 80, 44, 44, 44, 44, 62, 36, 36, 61, 62, 36, 36, 61, 62, 36, 36, 61, 44, 44, 44, 44, 16, 16, 16, 16, 16,112, 40, 40, - 16, 16, 16, 16, 44, 44, 44, 44, 36, 92, 85, 84, 83,163, 85, 44, + 16, 16, 16, 16,109, 41, 44, 44, 36, 92, 85, 84, 83,162, 85, 44, 36, 36, 44, 44, 44, 44, 44, 44, 36, 36, 36, 61, 44, 62, 36, 36, - 165,165,165,165,165,165,165,165,166,166,166,166,166,166,166,166, - 16, 16, 16,108, 44, 44, 44, 44, 44,147, 16, 16, 44, 44, 62, 71, - 36, 36, 36, 36,167, 36, 36, 36, 36, 36, 36, 61, 36, 36, 61, 61, + 164,164,164,164,164,164,164,164,165,165,165,165,165,165,165,165, + 16, 16, 16,108, 44, 44, 44, 44, 44,146, 16, 16, 44, 44, 62, 71, + 36, 36, 36, 36,166, 36, 36, 36, 36, 36, 36, 61, 36, 36, 61, 61, 36, 62, 61, 36, 36, 36, 36, 36, 36, 41, 41, 41, 41, 41, 41, 41, 41, 44, 44, 44, 44, 44, 44, 44, 44, 62, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36,145, 44, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36,162, 44, - 2, 2, 2,168,128, 44, 44, 44, 6,169,170,145,145,145,145,145, - 145,145,128,168,128, 2,125,171, 2, 64, 2, 2,151,145,145,128, - 2,172, 8,173, 66, 2, 44, 44, 36, 36, 61, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36,144, 44, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36,161, 44, 2, 2, 2,167,128, 44, 44, 44, + 6,168,169,144,144,144,144,144,144,144,128,167,128, 2,125,170, + 2, 64, 2, 2,150,144,144,128, 2,171, 8,172, 66, 2, 44, 44, 36, 36, 36, 36, 36, 36, 61, 79, 91, 2, 3, 2, 4, 5, 6, 2, 16, 16, 16, 16, 16, 17, 18,127,128, 4, 2, 36, 36, 36, 36, 36, 69, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 40, 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 61, 44, - 20,174, 56,175, 26, 8,141, 90, 44, 44, 44, 44, 79, 65, 67, 44, + 20,173, 56,174, 26, 8,140, 90, 44, 44, 44, 44, 79, 65, 67, 44, 36, 36, 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 61, 36, 62, - 2, 64, 44,176, 27, 27, 27, 27, 27, 27, 44, 55, 67, 67, 67, 67, - 103,103,140, 27, 89, 67, 67, 67, 67, 67, 67, 67, 67, 27, 67, 90, - 90, 44, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 50, 44, - 177, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 44, 44, - 27, 27, 44, 44, 44, 44, 62, 36,150, 36, 36, 36, 36,178, 44, 44, - 36, 36, 36, 43, 43, 80, 44, 44, 36, 36, 36, 36, 36, 36, 36, 91, - 36, 36, 44, 44, 36, 36, 36, 36,179,103,103, 44, 44, 44, 44, 44, - 11, 11, 11, 11, 16, 16, 16, 16, 11, 11, 44, 44, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 44, 44, 36, 36, 44, 44, 44, 44, 44, 91, - 36, 36, 36, 44, 61, 36, 36, 36, 36, 36, 36, 62, 61, 44, 61, 62, - 36, 36, 36, 91, 27, 27, 27, 27, 36, 36, 36, 77,158, 27, 27, 27, - 44, 44, 44,176, 27, 27, 27, 27, 36, 61, 36, 44, 44,176, 27, 27, - 36, 36, 36, 27, 27, 27, 44, 91, 36, 36, 36, 36, 36, 44, 44, 91, - 36, 36, 36, 36, 44, 44, 27, 36, 44, 27, 27, 27, 27, 27, 27, 27, - 70, 43, 57, 80, 44, 44, 43, 43, 36, 36, 62, 36, 62, 36, 36, 36, - 36, 36, 36, 44, 43, 80, 44, 57, 27, 27, 27, 27, 98, 44, 44, 44, - 2, 2, 2, 2, 64, 44, 44, 44, 36, 36, 36, 36, 36, 36,180, 30, - 36, 36, 36, 36, 36, 36,180, 27, 36, 36, 36, 36, 78, 36, 36, 36, - 36, 36, 70, 80, 44,176, 27, 27, 2, 2, 2, 64, 44, 44, 44, 44, - 36, 36, 36, 44, 91, 2, 2, 2, 36, 36, 36, 44, 27, 27, 27, 27, - 36, 61, 44, 44, 27, 27, 27, 27, 36, 44, 44, 44, 91, 2, 64, 44, - 44, 44, 44, 44,176, 27, 27, 27, 11, 47, 44, 44, 44, 44, 44, 44, - 16,108, 44, 44, 44, 27, 27, 27, 36, 36, 43, 43, 44, 44, 44, 44, - 27, 27, 27, 27, 27, 27, 27, 98, 27, 27, 27, 93, 44, 44, 44, 44, - 177, 27, 30, 2, 2, 44, 44, 44, 85, 96, 36, 36, 36, 36, 36, 36, + 2, 64, 44,175, 27, 27, 27, 27, 27, 27, 44, 55, 67, 67, 67, 67, + 103,103,139, 27, 89, 67, 67, 67, 67, 67, 67, 67, 67, 27, 67, 90, + 67, 67, 67, 67, 67, 67, 90, 44, 90, 44, 44, 44, 44, 44, 44, 44, + 67, 67, 67, 67, 67, 67, 50, 44,176, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 44, 44, 27, 27, 44, 44, 44, 44, 62, 36, + 149, 36, 36, 36, 36,177, 44, 44, 36, 36, 36, 43, 43, 80, 44, 44, + 36, 36, 36, 36, 36, 36, 36, 91, 36, 36, 44, 44, 36, 36, 36, 36, + 178,103,103, 44, 44, 44, 44, 44, 11, 11, 11, 11, 16, 16, 16, 16, + 11, 11, 44, 44, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 44, 44, + 36, 36, 44, 44, 44, 44, 44, 91, 36, 36, 36, 44, 61, 36, 36, 36, + 36, 36, 36, 62, 61, 44, 61, 62, 36, 36, 36, 91, 27, 27, 27, 27, + 36, 36, 36, 77,157, 27, 27, 27, 44, 44, 44,175, 27, 27, 27, 27, + 36, 61, 36, 44, 44,175, 27, 27, 36, 36, 36, 27, 27, 27, 44, 91, + 36, 36, 36, 36, 36, 44, 44, 91, 36, 36, 36, 36, 44, 44, 27, 36, + 44, 27, 27, 27, 27, 27, 27, 27, 70, 43, 57, 80, 44, 44, 43, 43, + 36, 36, 62, 36, 62, 36, 36, 36, 36, 36, 36, 44, 43, 80, 44, 57, + 27, 27, 27, 27, 98, 44, 44, 44, 2, 2, 2, 2, 64, 44, 44, 44, + 36, 36, 36, 36, 36, 36,179, 30, 36, 36, 36, 36, 36, 36,179, 27, + 36, 36, 36, 36, 78, 36, 36, 36, 36, 36, 70, 80, 44,175, 27, 27, + 2, 2, 2, 64, 44, 44, 44, 44, 36, 36, 36, 44, 91, 2, 2, 2, + 36, 36, 36, 44, 27, 27, 27, 27, 36, 61, 44, 44, 27, 27, 27, 27, + 36, 44, 44, 44, 91, 2, 64, 44, 44, 44, 44, 44,175, 27, 27, 27, + 11, 47, 44, 44, 44, 44, 44, 44, 16,108, 44, 44, 44, 27, 27, 27, + 36, 36, 43, 43, 44, 44, 44, 44, 27, 27, 27, 27, 27, 27, 27, 98, + 36, 36, 36, 36, 36, 57,180, 44, 36, 44, 44, 44, 44, 44, 44, 44, + 27, 27, 27, 93, 44, 44, 44, 44,176, 27, 30, 2, 2, 44, 44, 44, + 36, 36,179, 27, 27, 27, 44, 44, 85, 96, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 43, 60, 2, 2, 2, 44, 27, 27, 27, 7, 7, 7, 7, 7, 44, 44, 44, 44, 44, 44, 44, 57, 84, 85, 43, 83, 85, 60,181, 2, 2, 44, 44, 44, 44, 44, 79, 44, 43, 71, 36, 36, 36, 36, 36, 36, 36, 36, 36, 70, 43, 43, 85, 43, - 43, 43, 80, 7, 7, 7, 7, 7, 2, 2, 92, 88, 44, 44, 44, 44, + 43, 43, 80, 7, 7, 7, 7, 7, 2, 2, 92, 96, 44, 44, 44, 44, 36, 70, 2, 61, 44, 44, 44, 44, 36, 92, 84, 43, 43, 43, 43, 83, - 96, 36, 63, 2, 59, 43, 60, 44, 7, 7, 7, 7, 7, 63, 63, 2, - 176, 27, 27, 27, 27, 27, 27, 27, 27, 27, 98, 44, 44, 44, 44, 44, + 96, 36, 63, 2, 59, 43, 60, 85, 7, 7, 7, 7, 7, 63, 63, 2, + 175, 27, 27, 27, 27, 27, 27, 27, 27, 27, 98, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 84, 85, 43, 84, 83, 43, 2, 2, 2, 80, 36, 36, 36, 61, 61, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 62, 36, 36, 36, 36, 63, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 70, @@ -4158,7 +4196,7 @@ _hb_ucd_u8[17198] = 61, 36, 62, 36, 36, 57, 71, 84, 83, 84, 88, 87, 88, 87, 84, 44, 61, 44, 44, 87, 44, 44, 62, 36, 36, 84, 44, 43, 43, 43, 80, 44, 43, 43, 80, 44, 44, 44, 44, 44, 36, 36, 92, 84, 43, 43, 43, 43, - 84, 43, 83, 71, 36, 63, 2, 2, 7, 7, 7, 7, 7, 91, 91, 71, + 84, 43, 83, 71, 36, 63, 2, 2, 7, 7, 7, 7, 7, 2, 91, 71, 84, 85, 43, 43, 83, 83, 84, 85, 83, 43, 36, 72, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 92, 84, 43, 43, 44, 84, 84, 43, 85, 60, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 43, 44, @@ -4166,7 +4204,9 @@ _hb_ucd_u8[17198] = 2, 2, 2, 2, 2, 2, 64, 44, 36, 36, 36, 36, 36, 70, 85, 84, 43, 43, 43, 85, 61, 44, 44, 44, 84, 43, 43, 85, 43, 43, 44, 44, 7, 7, 7, 7, 7, 27, 2, 95, 43, 43, 43, 43, 85, 60, 44, 44, - 27, 98, 44, 44, 44, 44, 44, 62, 36, 36, 36, 36, 44, 36, 36, 36, + 27, 98, 44, 44, 44, 44, 44, 62, 36, 36, 36, 61, 62, 44, 36, 36, + 36, 36, 62, 61, 36, 36, 36, 36, 84, 84, 84, 87, 88, 57, 83, 71, + 96, 85, 2, 64, 44, 44, 44, 44, 36, 36, 36, 36, 44, 36, 36, 36, 92, 84, 43, 43, 44, 43, 84, 84, 71, 72, 88, 44, 44, 44, 44, 44, 70, 43, 43, 43, 43, 71, 36, 36, 36, 70, 43, 43, 83, 70, 43, 60, 2, 2, 2, 59, 44, 44, 44, 44, 70, 43, 43, 83, 85, 43, 36, 36, @@ -4177,199 +4217,202 @@ _hb_ucd_u8[17198] = 83, 43, 85, 80, 44, 44, 44, 44, 36, 36, 36, 61, 36, 62, 36, 36, 70, 43, 43, 80, 44, 80, 43, 57, 43, 43, 43, 70, 44, 44, 44, 44, 36, 36, 36, 62, 61, 36, 36, 36, 36, 36, 36, 36, 36, 84, 84, 88, - 43, 87, 85, 85, 61, 44, 44, 44, 36, 70, 83,163, 64, 44, 44, 44, - 27, 27, 89, 67, 67, 67, 56, 20,162, 67, 67, 67, 67, 67, 67, 67, - 67, 44, 44, 44, 44, 44, 44, 91,103,103,103,103,103,103,103,178, + 43, 87, 85, 85, 61, 44, 44, 44, 36, 70, 83,162, 64, 44, 44, 44, + 27, 27, 89, 67, 67, 67, 56, 20,161, 67, 67, 67, 67, 67, 67, 67, + 67, 44, 44, 44, 44, 44, 44, 91,103,103,103,103,103,103,103,177, 2, 2, 64, 44, 44, 44, 44, 44, 65, 65, 65, 65, 68, 44, 44, 44, 43, 43, 60, 44, 44, 44, 44, 44, 43, 43, 43, 60, 2, 2, 67, 67, - 40, 40, 95, 44, 44, 44, 44, 44, 7, 7, 7, 7, 7,176, 27, 27, + 40, 40, 95, 44, 44, 44, 44, 44, 7, 7, 7, 7, 7,175, 27, 27, 27, 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 44, 44, 62, 36, 27, 27, 27, 30, 2, 64, 44, 44, 36, 36, 36, 36, 36, 61, 44, 57, 92, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 44, 44, 44, 57, 43, 74, 40, 40, 40, 40, 40, 40, - 40, 86, 44, 44, 44, 44, 44, 44, 36, 61, 44, 44, 44, 44, 44, 44, - 44, 44, 36, 36, 44, 44, 44, 44, 36, 36, 36, 36, 36, 44, 50, 60, - 65, 65, 44, 44, 44, 44, 44, 44, 67, 67, 67, 90, 55, 67, 67, 67, - 67, 67,182, 85, 43, 67,182, 84, 84,183, 65, 65, 65, 82, 43, 43, - 43, 76, 50, 43, 43, 43, 67, 67, 67, 67, 67, 67, 67, 43, 43, 67, - 67, 67, 67, 67, 90, 44, 44, 44, 67, 43, 76, 44, 44, 44, 44, 44, - 27, 27, 44, 44, 44, 44, 44, 44, 11, 11, 11, 11, 11, 16, 16, 16, - 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 16, - 16, 16,108, 16, 16, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 47, 11, 44, 47, 48, 47, 48, 11, 47, 11, - 11, 11, 11, 16, 16,147,147, 16, 16, 16,147, 16, 16, 16, 16, 16, - 16, 16, 11, 48, 11, 47, 48, 11, 11, 11, 47, 11, 11, 11, 47, 16, - 16, 16, 16, 16, 11, 48, 11, 47, 11, 11, 47, 47, 44, 11, 11, 11, - 47, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 11, - 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 44, 11, 11, 11, 11, - 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, - 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, - 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, - 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 44, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 43, 43, 43, 76, 67, 50, 43, 43, - 43, 43, 43, 43, 43, 43, 76, 67, 67, 67, 50, 67, 67, 67, 67, 67, - 67, 67, 76, 21, 2, 2, 44, 44, 44, 44, 44, 44, 44, 57, 43, 43, - 43, 43, 43, 80, 43, 43, 43, 43, 43, 43, 43, 43, 80, 57, 43, 43, - 43, 57, 80, 43, 43, 80, 44, 44, 43, 43, 43, 74, 40, 40, 40, 44, - 7, 7, 7, 7, 7, 44, 44, 77, 36, 36, 36, 36, 36, 36, 43, 43, - 7, 7, 7, 7, 7, 44, 44, 94, 36, 36, 61,176, 27, 27, 27, 27, - 43, 43, 43, 80, 44, 44, 44, 44, 16, 16, 43, 43, 43, 74, 44, 44, - 27, 27, 27, 27, 27, 27,158, 27,184, 27, 98, 44, 44, 44, 44, 44, - 27, 27, 27, 27, 27, 27, 27,158, 27, 27, 27, 27, 27, 27, 27, 44, - 36, 36, 62, 36, 36, 36, 36, 36, 62, 61, 61, 62, 62, 36, 36, 36, - 36, 61, 36, 36, 62, 62, 44, 44, 44, 61, 44, 62, 62, 62, 62, 36, - 62, 61, 61, 62, 62, 62, 62, 62, 62, 61, 61, 62, 36, 61, 36, 36, - 36, 61, 36, 36, 62, 36, 61, 61, 36, 36, 36, 36, 36, 62, 36, 36, - 62, 36, 62, 36, 36, 62, 36, 36, 8, 44, 44, 44, 44, 44, 44, 44, - 55, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 90, 44, + 40, 86, 80, 44, 44, 44, 44, 44, 84, 44, 44, 44, 44, 44, 44, 44, + 36, 61, 44, 44, 44, 44, 44, 44, 44, 44, 36, 36, 44, 44, 44, 44, + 36, 36, 36, 36, 36, 44, 50, 60, 65, 65, 44, 44, 44, 44, 44, 44, + 67, 67, 67, 90, 55, 67, 67, 67, 67, 67,182, 85, 43, 67,182, 84, + 84,183, 65, 65, 65, 82, 43, 43, 43, 76, 50, 43, 43, 43, 67, 67, + 67, 67, 67, 67, 67, 43, 43, 67, 67, 67, 67, 67, 90, 44, 44, 44, + 67, 43, 76, 44, 44, 44, 44, 44, 27, 27, 44, 44, 44, 44, 44, 44, + 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 16, 16, 16,108, 16, 16, 16, 16, 16, + 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 47, 11, + 44, 47, 48, 47, 48, 11, 47, 11, 11, 11, 11, 16, 16,146,146, 16, + 16, 16,146, 16, 16, 16, 16, 16, 16, 16, 11, 48, 11, 47, 48, 11, + 11, 11, 47, 11, 11, 11, 47, 16, 16, 16, 16, 16, 11, 48, 11, 47, + 11, 11, 47, 47, 44, 11, 11, 11, 47, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, + 16, 16, 16, 44, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, + 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, + 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, + 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, + 16, 33, 16, 16, 16, 32, 44, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 43, 43, 43, 76, 67, 50, 43, 43, 43, 43, 43, 43, 43, 43, 76, 67, + 67, 67, 50, 67, 67, 67, 67, 67, 67, 67, 76, 21, 2, 2, 44, 44, + 44, 44, 44, 44, 44, 57, 43, 43, 43, 43, 43, 80, 43, 43, 43, 43, + 43, 43, 43, 43, 80, 57, 43, 43, 43, 57, 80, 43, 43, 80, 44, 44, + 43, 43, 43, 74, 40, 40, 40, 44, 7, 7, 7, 7, 7, 44, 44, 77, + 36, 36, 36, 36, 36, 36, 43, 43, 7, 7, 7, 7, 7, 44, 44, 94, + 36, 36, 61,175, 27, 27, 27, 27, 43, 43, 43, 80, 44, 44, 44, 44, + 16, 16, 43, 43, 43, 74, 44, 44, 27, 27, 27, 27, 27, 27,157, 27, + 184, 27, 98, 44, 44, 44, 44, 44, 27, 27, 27, 27, 27, 27, 27,157, + 27, 27, 27, 27, 27, 27, 27, 44, 36, 36, 62, 36, 36, 36, 36, 36, + 62, 61, 61, 62, 62, 36, 36, 36, 36, 61, 36, 36, 62, 62, 44, 44, + 44, 61, 44, 62, 62, 62, 62, 36, 62, 61, 61, 62, 62, 62, 62, 62, + 62, 61, 61, 62, 36, 61, 36, 36, 36, 61, 36, 36, 62, 36, 61, 61, + 36, 36, 36, 36, 36, 62, 36, 36, 62, 36, 62, 36, 36, 62, 36, 36, + 8, 44, 44, 44, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, + 27, 27, 27, 27, 27, 27, 89, 67, 67, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 90, 44, 44, 44, 44, 44, 44, 67, 44, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 25, 41, 41, - 67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 67, 44, - 67, 67, 67, 67, 67, 67, 55, 67, 67, 55, 67, 90, 44, 67, 67, 67, - 67, 90, 55, 67, 67, 90, 44, 67, 67, 67, 67, 67, 67, 90, 55, 67, - 67, 67, 44, 44, 67, 90, 44, 44, 36, 44, 44, 44, 44, 44, 44, 44, - 79, 44, 44, 44, 44, 44, 44, 44, 65, 65, 65, 65, 65, 65, 65, 65, - 166,166,166,166,166,166,166, 44,166,166,166,166,166,166,166, 0, - 0, 0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13, - 25, 25, 25, 21, 21, 9, 9, 9, 9, 22, 21, 18, 24, 16, 24, 5, - 5, 5, 5, 22, 25, 18, 25, 0, 23, 23, 26, 21, 24, 26, 7, 20, - 25, 1, 26, 24, 26, 25, 15, 15, 24, 15, 7, 19, 15, 21, 9, 25, - 9, 5, 5, 25, 5, 9, 5, 7, 7, 7, 9, 8, 8, 5, 7, 5, - 6, 6, 24, 24, 6, 24, 12, 12, 2, 2, 6, 5, 9, 21, 9, 2, - 2, 9, 25, 9, 26, 12, 11, 11, 2, 6, 5, 21, 17, 2, 2, 26, - 26, 23, 2, 12, 17, 12, 21, 12, 12, 21, 7, 2, 2, 7, 7, 21, - 21, 2, 1, 1, 21, 23, 26, 26, 1, 2, 6, 7, 7, 12, 12, 7, - 21, 7, 12, 1, 12, 6, 6, 12, 12, 26, 7, 26, 26, 7, 2, 1, - 12, 2, 6, 2, 1, 12, 12, 10, 10, 10, 10, 12, 21, 6, 2, 10, - 10, 2, 15, 26, 26, 2, 2, 21, 7, 10, 15, 7, 2, 23, 21, 26, - 10, 7, 21, 15, 15, 2, 17, 7, 29, 7, 7, 22, 18, 2, 14, 14, - 14, 7, 17, 21, 7, 6, 11, 2, 5, 2, 5, 6, 8, 8, 8, 24, - 5, 24, 2, 24, 9, 24, 24, 2, 29, 29, 29, 1, 17, 17, 20, 19, - 22, 20, 27, 28, 1, 29, 21, 20, 19, 21, 21, 16, 16, 21, 25, 22, - 18, 21, 21, 29, 15, 6, 18, 6, 12, 11, 11, 12, 9, 26, 26, 9, - 26, 5, 5, 26, 14, 9, 5, 14, 14, 15, 25, 26, 26, 22, 18, 26, - 18, 25, 18, 22, 5, 12, 2, 5, 22, 21, 26, 6, 7, 14, 17, 22, - 18, 18, 26, 14, 17, 6, 14, 6, 12, 24, 24, 6, 26, 15, 6, 21, - 11, 21, 24, 9, 23, 26, 10, 21, 6, 10, 4, 4, 3, 3, 7, 25, - 21, 22, 17, 16, 16, 22, 16, 16, 25, 17, 25, 2, 25, 24, 23, 2, - 2, 15, 12, 15, 14, 2, 21, 14, 7, 15, 21, 1, 26, 10, 10, 1, - 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, - 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, - 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 37, 0, 0, 0, 0, - 0, 0, 38, 39, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, - 0, 0, 0, 0, 6, 7, 8, 0, 9, 0, 10, 11, 0, 0, 12, 13, - 14, 15, 16, 0, 0, 0, 0, 17, 18, 19, 20, 0, 0, 0, 21, 22, - 0, 23, 24, 0, 0, 23, 25, 26, 0, 23, 25, 0, 0, 23, 25, 0, - 0, 23, 25, 0, 0, 0, 25, 0, 0, 0, 27, 0, 0, 23, 25, 0, - 0, 28, 25, 0, 0, 0, 29, 0, 0, 30, 31, 0, 0, 32, 33, 0, - 34, 35, 0, 36, 37, 0, 38, 0, 0, 39, 0, 0, 40, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 42, 42, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 44, 0, 0, - 0, 45, 0, 0, 0, 0, 0, 0, 46, 0, 0, 47, 0, 48, 0, 0, - 0, 49, 50, 51, 0, 52, 0, 53, 0, 54, 0, 0, 0, 0, 55, 56, - 0, 0, 0, 0, 0, 0, 57, 58, 0, 0, 0, 0, 0, 0, 59, 60, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, - 0, 0, 0, 62, 0, 0, 0, 63, 0, 64, 0, 0, 65, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 67, 0, 0, 68, - 0, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 0, 0, 50, 70, - 0, 71, 72, 0, 0, 73, 74, 0, 0, 0, 0, 0, 0, 75, 76, 77, - 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, - 78, 0, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 81, - 0, 0, 0, 82, 0, 0, 0, 0, 83, 84, 0, 0, 0, 0, 0, 85, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 69, 62, 0, 88, 0, 0, - 89, 90, 0, 73, 0, 0, 91, 0, 0, 92, 0, 0, 0, 0, 0, 93, - 0, 94, 25, 95, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 97, 0, - 0, 0, 0, 0, 0, 62, 98, 0, 0, 62, 0, 0, 0, 99, 0, 0, - 0,100, 0, 0, 0, 0, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 74, 0, 42,101, 0,102, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, - 0, 0,103, 0,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105, - 0,106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,108,109,110, 0, 0, 0, 0,111, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,112,113, 0, 0, 0, 0, 0, 0, - 0,106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,114, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,115, 0, + 67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 67, 67, 90, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 55, 67, 67, 67, 90, 44, 67, 90, 44, 44, + 67, 90, 67, 67, 67, 67, 67, 67, 79, 44, 44, 44, 44, 44, 44, 44, + 65, 65, 65, 65, 65, 65, 65, 65,165,165,165,165,165,165,165, 44, + 165,165,165,165,165,165,165, 0, 0, 0, 29, 21, 21, 21, 23, 21, + 22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21, 9, 9, 9, + 9, 22, 21, 18, 24, 16, 24, 5, 5, 5, 5, 22, 25, 18, 25, 0, + 23, 23, 26, 21, 24, 26, 7, 20, 25, 1, 26, 24, 26, 25, 15, 15, + 24, 15, 7, 19, 15, 21, 9, 25, 9, 5, 5, 25, 5, 9, 5, 7, + 7, 7, 9, 8, 8, 5, 7, 5, 6, 6, 24, 24, 6, 24, 12, 12, + 2, 2, 6, 5, 9, 21, 9, 2, 2, 9, 25, 9, 26, 12, 11, 11, + 2, 6, 5, 21, 17, 2, 2, 26, 26, 23, 2, 12, 17, 12, 21, 12, + 12, 21, 7, 2, 2, 7, 7, 21, 21, 2, 1, 1, 21, 23, 26, 26, + 1, 2, 6, 7, 7, 12, 12, 7, 21, 7, 12, 1, 12, 6, 6, 12, + 12, 26, 7, 26, 26, 7, 2, 1, 12, 2, 6, 2, 1, 12, 12, 10, + 10, 10, 10, 12, 21, 6, 2, 10, 10, 2, 15, 26, 26, 2, 2, 21, + 7, 10, 15, 7, 2, 23, 21, 26, 10, 7, 21, 15, 15, 2, 17, 7, + 29, 7, 7, 22, 18, 2, 14, 14, 14, 7, 17, 21, 7, 6, 11, 12, + 5, 2, 5, 6, 8, 8, 8, 24, 5, 24, 2, 24, 9, 24, 24, 2, + 29, 29, 29, 1, 17, 17, 20, 19, 22, 20, 27, 28, 1, 29, 21, 20, + 19, 21, 21, 16, 16, 21, 25, 22, 18, 21, 21, 29, 15, 6, 18, 6, + 12, 11, 9, 26, 26, 9, 26, 5, 5, 26, 14, 9, 5, 14, 14, 15, + 25, 26, 26, 22, 18, 26, 18, 25, 18, 22, 5, 12, 2, 5, 22, 21, + 26, 6, 7, 14, 17, 22, 18, 18, 26, 14, 17, 6, 14, 6, 12, 24, + 24, 6, 26, 15, 6, 21, 11, 21, 24, 9, 23, 26, 10, 21, 6, 10, + 4, 4, 3, 3, 7, 25, 21, 22, 17, 16, 16, 22, 16, 16, 25, 17, + 25, 2, 25, 24, 23, 2, 2, 15, 12, 15, 14, 2, 21, 14, 7, 15, + 12, 17, 21, 1, 26, 10, 10, 1, 23, 15, 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 0, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 0, + 15, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 20, 0, 21, 22, 23, 0, 0, 0, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, + 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 37, 38, 0, 0, 0, 0, 0, 0, 39, 40, 0, 0, 41, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 0, + 9, 0, 10, 11, 0, 0, 12, 13, 14, 15, 16, 0, 0, 0, 0, 17, + 18, 19, 20, 0, 0, 0, 21, 22, 0, 23, 24, 0, 0, 23, 25, 26, + 0, 23, 25, 0, 0, 23, 25, 0, 0, 23, 25, 0, 0, 0, 25, 0, + 0, 0, 27, 0, 0, 23, 25, 0, 0, 28, 25, 0, 0, 0, 29, 0, + 0, 30, 31, 0, 0, 32, 33, 0, 34, 35, 0, 36, 37, 0, 38, 0, + 0, 39, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 42, 42, 0, 0, 0, 0, 43, 0, + 0, 0, 0, 0, 0, 44, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, + 46, 0, 0, 47, 0, 48, 49, 0, 0, 50, 51, 52, 0, 53, 0, 54, + 0, 55, 0, 0, 0, 0, 56, 57, 0, 0, 0, 0, 0, 0, 58, 59, + 0, 0, 0, 0, 0, 0, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63, 0, 0, 0, 64, + 0, 65, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 67, 68, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 0, + 70, 71, 0, 0, 0, 0, 51, 72, 0, 73, 74, 0, 0, 75, 76, 0, + 0, 0, 0, 0, 0, 77, 78, 79, 0, 0, 0, 0, 0, 0, 0, 25, + 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, + 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, + 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 83, 0, 0, 0, 0, + 84, 85, 0, 0, 0, 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 88, 0, 0, 0, 0, 89, 0, 0, 0, 0, 0, + 0, 0, 70, 63, 0, 90, 0, 0, 91, 92, 0, 75, 0, 0, 93, 0, + 0, 94, 0, 0, 0, 0, 0, 95, 0, 96, 25, 97, 0, 0, 0, 0, + 0, 0, 98, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, 63,100, 0, + 0, 63, 0, 0, 0,101, 0, 0, 0,102, 0, 0, 0, 0, 0, 0, + 0, 90, 0, 0, 0, 0, 0, 0, 0,103,104, 0, 0, 0, 0, 76, + 0, 42,105, 0,106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 63, 0, 0, 0, 0, 0, 0, 0, 0,107, 0,108, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,109, 0,110, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111, + 0, 0, 0, 0,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,113,114,115, 0, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 4, 4, 8, 9, 10, - 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, 0, 0, 0, 0, - 19, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 1, - 23, 4, 21, 24, 25, 26, 27, 28, 29, 30, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, 1, 36, - 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 38, 1, 39, - 14, 39, 40, 41, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, - 0, 0, 0, 0, 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 0, 0, - 0, 0, 19, 1, 21, 0, 0, 47, 0, 0, 0, 0, 0, 38, 48, 1, - 1, 49, 49, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, - 0, 0, 0, 0, 52, 1, 1, 1, 53, 21, 43, 54, 55, 21, 35, 1, - 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 57, 58, 59, 0, 0, - 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, - 0, 0, 0, 57, 0, 61, 0, 0, 0, 0, 0, 0, 0, 0, 62, 63, - 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 0, - 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, - 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 0, - 0, 0, 0, 0, 0, 70, 71, 0, 0, 0, 0, 0, 72, 73, 74, 75, - 76, 77, 0, 0, 0, 0, 0, 0, 0, 78, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 79, 80, 0, 0, 0, 0, 47, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 63, 0, 0, - 0, 0, 0, 0, 64, 0, 0, 81, 0, 0, 82, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 19, 84, 0, - 63, 0, 0, 0, 0, 49, 1, 85, 0, 0, 0, 0, 1, 54, 15, 41, + 117,118, 0, 0, 0, 0, 0, 0, 0,110, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,120, 0, 0, 0,121, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, + 5, 6, 7, 4, 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, + 18, 1, 1, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, 27, 28, + 29, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 31, 0, + 0, 0, 32, 33, 34, 35, 1, 36, 0, 0, 0, 0, 37, 0, 0, 0, + 0, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, 0, 0, 0, 0, + 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 43, 36, 44, 45, + 21, 45, 46, 0, 0, 0, 0, 0, 0, 0, 19, 1, 21, 0, 0, 47, + 0, 0, 0, 0, 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 52, 1, 1, 1, + 53, 21, 43, 54, 55, 21, 35, 1, 0, 0, 0, 0, 0, 0, 0, 56, + 0, 0, 0, 57, 58, 59, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 57, 0, 61, 0, 0, + 0, 0, 0, 0, 0, 0, 62, 63, 0, 0, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 70, 71, 0, + 0, 0, 0, 0, 72, 73, 74, 75, 76, 77, 0, 0, 0, 0, 0, 0, + 0, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 80, 0, + 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, + 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 64, 0, 0, 81, + 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, + 0, 0, 0, 0, 0, 19, 84, 0, 63, 0, 0, 0, 0, 49, 1, 85, + 0, 0, 0, 0, 1, 54, 15, 86, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, - 0, 0, 19, 10, 1, 0, 0, 0, 0, 0, 86, 0, 0, 0, 0, 0, - 0, 87, 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, - 0, 0, 0, 0, 88, 9, 12, 4, 89, 8, 90, 47, 0, 59, 50, 0, - 21, 1, 21, 91, 92, 1, 1, 1, 1, 1, 1, 1, 1, 93, 94, 95, - 0, 0, 0, 0, 96, 1, 97, 59, 81, 98, 99, 4, 59, 0, 0, 0, + 0, 0, 19, 10, 1, 0, 0, 0, 0, 0, 87, 0, 0, 0, 0, 0, + 0, 88, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, + 0, 0, 0, 0, 89, 9, 12, 4, 90, 8, 91, 47, 0, 59, 50, 0, + 21, 1, 21, 92, 93, 1, 1, 1, 1, 1, 1, 1, 1, 94, 95, 96, + 0, 0, 0, 0, 97, 1, 98, 59, 81, 99,100, 4, 59, 0, 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, - 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,100,101, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,102, 0, 0, 0, 0, 19, 0, 1, 1, 50, + 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,101,102, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,103, 0, 0, 0, 0, 19, 0, 1, 1, 50, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 50, 0, 0, 0, - 0, 64, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 50, 0, 0, 0, - 0, 0, 52, 69, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, - 0, 0, 0, 0, 79, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,103,104, 59, 38, 81, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0,105, - 1, 14, 4, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, - 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 88, 0, - 0, 0, 0,106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107, 62, - 0,108, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, - 0,109, 14, 54, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0,110, 0, - 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 63, 0, 0, - 63, 0, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,110, 0, 0, - 0, 0,111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 56, - 0, 38, 1, 59, 1, 59, 0, 0, 64, 87, 0, 0, 0, 0, 0, 60, - 112, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,112, 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, - 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, - 87,113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, - 0, 0, 0, 0, 8, 90, 0, 0, 0, 0, 0, 0, 1, 88, 0, 0, - 0, 0, 0, 0, 0, 0, 0,114, 0,115,116,117,118, 0, 52, 4, - 119, 49, 23, 0, 0, 0, 0, 0, 0, 0, 38, 50, 0, 0, 0, 0, - 38, 59, 0, 0, 0, 0, 0, 0, 1, 88, 1, 1, 1, 1, 39, 1, - 48,103, 88, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 4,119, 0, 0, 0, 1,120, 0, 0, 0, 0, 0, + 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, + 1, 1, 1, 1, 50, 0, 0, 0, 0, 0, 52, 69, 0, 0, 0, 0, + 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, 0, + 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104,105, 59, 38, + 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0,106, 1, 14, 4, 12, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 38, 89, 0, + 0, 0, 0,107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,108, 62, + 0,109, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 19, 59, 0, 0, 0, 0, 0,110, 14, 54, 84, 0, 0, 0, + 0, 0, 0, 0, 0, 0,111, 0, 89, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 62, 63, 0, 0, 63, 0, 88, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,111, 0, 0, 0, 0,112, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 79, 56, 0, 38, 1, 59, 1, 59, 0, 0, + 64, 88, 0, 0, 0, 0, 0, 60,113, 0, 0, 0, 0, 0, 0, 0, + 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,113, 0, 0, + 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, + 79, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 57, 0, 88,114, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 8, 91, 0, 0, + 0, 0, 0, 0, 1, 89, 0, 0, 0, 0, 0, 0,115, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,116, 0,117,118,119,120, 0, 52, 4, + 121, 49, 23, 0, 0, 0, 0, 0, 0, 0, 38, 50, 0, 0, 0, 0, + 38, 59, 0, 0, 0, 0, 0, 0, 1, 89, 1, 1, 1, 1, 39, 1, + 48,104, 89, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 4,121, 0, 0, 0, 1,122, 0, 0, 0, 0, 0, 0, 0, 0, 0,230,230,230,230,230,232,220,220,220,220,232,216, 220,220,220,220,220,202,202,220,220,220,220,202,202,220,220,220, 1, 1, 1, 1, 1,220,220,220,220,230,230,230,230,240,230,220, @@ -4391,58 +4434,58 @@ _hb_ucd_u8[17198] = 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130,130,130, 0, 0, 130, 0,230,230, 9, 0,230,230, 0, 0,220, 0, 0, 0, 0, 7, 0, 9, 9, 0, 0,230, 0, 0, 0,228, 0, 0, 0,222,230,220, - 220, 0, 0, 0,230, 0, 0,220, 0, 0, 9, 9, 0, 0, 7, 0, - 230,230,230, 0,230, 0, 1, 1, 1, 0, 0, 0,230,234,214,220, - 202,230,230,230,230,230,232,228,228,220, 0,230,233,220,230,220, - 230,230, 1, 1, 1, 1, 1,230, 0, 1, 1,230,220,230, 1, 1, - 0, 0,218,228,232,222,224,224, 0, 8, 8, 0,230, 0,230,230, - 220, 0, 0,230, 0, 0, 26, 0, 0,220, 0,230,230, 1,220, 0, - 0,230,220, 0, 0, 0,220,220, 0, 9, 7, 0, 0, 7, 9, 0, - 0, 0, 9, 7, 9, 9, 0, 0, 0, 0, 1, 0, 0,216,216, 1, - 1, 1, 0, 0, 0,226,216,216,216,216,216, 0,220,220,220, 0, - 230,230, 7, 0, 16, 17, 17, 17, 17, 17, 17, 33, 17, 17, 17, 19, - 17, 17, 17, 17, 20,101, 17,113,129,169, 17, 27, 28, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 220, 0, 0, 0,230, 0, 0,220,230,220, 0,220, 0, 0, 9, 9, + 0, 0, 7, 0,230,230,230, 0,230, 0, 1, 1, 1, 0, 0, 0, + 230,234,214,220,202,230,230,230,230,230,232,228,228,220, 0,230, + 233,220,230,220,230,230, 1, 1, 1, 1, 1,230, 0, 1, 1,230, + 220,230, 1, 1, 0, 0,218,228,232,222,224,224, 0, 8, 8, 0, + 230, 0,230,230,220, 0, 0,230, 0, 0, 26, 0, 0,220, 0,230, + 230, 1,220, 0, 0,230,220, 0, 0, 0,220,220, 0, 9, 7, 0, + 0, 7, 9, 0, 0, 0, 9, 7, 9, 9, 0, 0, 6, 6, 0, 0, + 0, 0, 1, 0, 0,216,216, 1, 1, 1, 0, 0, 0,226,216,216, + 216,216,216, 0,220,220,220, 0,230,230, 7, 0, 16, 17, 17, 17, + 17, 17, 17, 33, 17, 17, 17, 19, 17, 17, 17, 17, 20,101, 17,113, + 129,169, 17, 27, 28, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17,237, 0, 1, 2, 2, 0, 3, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 0, 0, 0, 0, 6, 7, 8, 9, 0, 0, 0, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, - 0, 0, 21, 22, 0, 0, 0, 0, 23, 24, 25, 26, 0, 27, 0, 28, - 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 33, 34, 35, 0, 0, - 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 38, - 0, 0, 0, 0, 1, 2, 39, 40, 0, 1, 2, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, - 0, 0, 3, 4, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, - 0, 0, 7, 1, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, - 0, 0, 10, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 11, 12, - 0, 13, 0, 14, 15, 16, 0, 0, 0, 0, 0, 1, 17, 18, 0, 19, - 7, 1, 0, 0, 0, 20, 20, 7, 20, 20, 20, 20, 20, 20, 20, 8, - 21, 0, 22, 0, 7, 23, 24, 0, 20, 20, 25, 0, 0, 0, 26, 27, - 1, 7, 20, 20, 20, 20, 20, 1, 28, 29, 30, 31, 0, 0, 20, 0, - 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 20, 20, - 20, 1, 0, 0, 8, 21, 32, 4, 0, 10, 0, 33, 7, 20, 20, 20, - 0, 0, 0, 0, 8, 34, 34, 35, 36, 34, 37, 0, 38, 1, 20, 20, - 0, 0, 39, 0, 1, 1, 0, 8, 21, 1, 20, 0, 0, 0, 1, 0, - 0, 40, 1, 1, 0, 0, 8, 21, 0, 1, 0, 1, 0, 1, 0, 0, - 0, 0, 26, 34, 34, 34, 34, 34, 34, 34, 34, 34, 21, 7, 20, 41, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 21, 0, 42, 43, 44, 0, 45, - 0, 8, 21, 0, 0, 0, 0, 0, 0, 0, 0, 46, 7, 1, 10, 1, - 0, 0, 0, 1, 20, 20, 1, 0, 0, 0, 0, 0, 0, 0, 20, 20, - 1, 20, 20, 0, 0, 0, 0, 0, 0, 0, 26, 21, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 47, 48, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 9, 10, 11, 12, 12, 12, 12, 13, 14, - 14, 14, 14, 15, 16, 17, 18, 19, 20, 14, 21, 14, 22, 14, 14, 14, - 14, 23, 24, 24, 25, 26, 14, 14, 14, 14, 27, 28, 14, 14, 29, 30, - 31, 32, 33, 34, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 35, 7, 36, 37, 7, 38, 7, 7, - 7, 39, 14, 40, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,237, 0, 1, 2, 2, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 6, 7, 8, + 9, 0, 0, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 21, 22, 0, 0, 0, 0, + 23, 24, 25, 26, 0, 27, 0, 28, 29, 30, 31, 32, 0, 0, 0, 0, + 0, 0, 0, 33, 34, 35, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, 0, 1, 2, 39, 40, + 0, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 5, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, + 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, + 0, 0, 0, 0, 0, 0, 11, 12, 0, 13, 0, 14, 15, 16, 0, 0, + 0, 0, 0, 1, 17, 18, 0, 19, 7, 1, 0, 0, 0, 20, 20, 7, + 20, 20, 20, 20, 20, 20, 20, 8, 21, 0, 22, 0, 7, 23, 24, 0, + 20, 20, 25, 0, 0, 0, 26, 27, 1, 7, 20, 20, 20, 20, 20, 1, + 28, 29, 30, 31, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 10, 0, + 0, 0, 0, 0, 0, 0, 20, 20, 20, 1, 0, 0, 8, 21, 32, 4, + 0, 10, 0, 33, 7, 20, 20, 20, 0, 0, 0, 0, 8, 34, 34, 35, + 36, 34, 37, 0, 38, 1, 20, 20, 0, 0, 39, 0, 1, 1, 0, 8, + 21, 1, 20, 0, 0, 0, 1, 0, 0, 40, 1, 1, 0, 0, 8, 21, + 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 26, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 21, 7, 20, 41, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 21, 0, 42, 43, 44, 0, 45, 0, 8, 21, 0, 0, 0, 0, 0, + 0, 0, 0, 46, 7, 1, 10, 1, 0, 0, 0, 1, 20, 20, 1, 0, + 0, 0, 0, 0, 0, 0, 20, 20, 1, 20, 20, 0, 0, 0, 0, 0, + 0, 0, 26, 21, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, + 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 9, + 10, 11, 12, 12, 12, 12, 13, 14, 14, 14, 14, 15, 16, 17, 18, 19, + 20, 14, 21, 14, 22, 14, 14, 14, 14, 23, 24, 24, 25, 26, 14, 14, + 14, 14, 27, 28, 14, 14, 29, 30, 31, 32, 33, 34, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 35, 7, 36, 37, 7, 38, 7, 7, 7, 39, 14, 40, 7, 7, 41, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, @@ -4464,75 +4507,76 @@ _hb_ucd_u8[17198] = 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 41, 0, 0, 1, 2, 2, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 37, - 37, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 2, 2, 53, 54, 55, 56, 57, 58, 59, 59, 59, 59, 60, 59, - 59, 59, 59, 59, 59, 59, 61, 61, 59, 59, 59, 59, 62, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 59, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 42, 0, 0, 1, + 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 32, 33, 34, 35, 36, 37, 37, 37, 37, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 2, 2, 53, 54, 55, 56, + 57, 58, 59, 59, 59, 59, 60, 59, 59, 59, 59, 59, 59, 59, 61, 61, + 59, 59, 59, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 59, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 79, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 80, 81, 81, 81, 81, 81, 81, 81, 81, 81, 82, - 83, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 79, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 80, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 82, 83, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 96, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, - 97, 97, 97, 97, 97, 97, 97, 97, 70, 70, 98, 99,100,101,102,102, - 103,104,105,106,107,108,109,110,111,112, 97,113,114,115,116,117, - 118, 97,119,119,120, 97,121,122,123,124,125,126,127,128,129,130, - 131, 97,132, 97,133,134,135,136,137,138,139,140,141, 97,142,143, - 97,144,145,146,147, 97,148,149, 97,150,151,152, 97, 97,153,154, - 155,156, 97,157, 97,158,159,159,159,159,159,159,159,160,161,159, - 162, 97, 97, 97, 97, 97,163,163,163,163,163,163,163,163,164, 97, - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,165,165, - 165,165,166, 97, 97, 97,167,167,167,167,168,169,170,171, 97, 97, - 97, 97,172,173,174,175,176,176,176,176,176,176,176,176,176,176, - 176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, - 176,176,176,176,176,177,176,176,176,176,176,178, 97, 97, 97, 97, - 97, 97, 97, 97, 97, 97,179,180,181,182,182,183, 97, 97, 97, 97, - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,184,185, - 97, 97, 97, 97, 97, 97, 59,186,187,188,189,190,191, 97,192,193, - 194, 59, 59,195, 59,196,197,197,197,197,197,198, 97, 97, 97, 97, - 97, 97, 97, 97, 97, 97,199, 97,200, 97, 97,201, 97, 97, 97, 97, - 97, 97, 97, 97, 97, 97,202,203,204, 97, 97, 97, 97, 97,205,206, - 207, 97,208,209, 97, 97,210,211,212,213,214, 97, 59, 59, 59, 59, - 59, 59, 59,215,216,217,218,219,220,221,222,223, 97, 97, 97, 97, - 97, 97, 97, 97, 97, 97, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70,224, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70,225, 70,226, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 96, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 70, 70, 98, 99,100,101,102,102,103,104,105,106,107,108,109,110, + 111,112, 97,113,114,115,116,117,118, 97,119,119,120, 97,121,122, + 123,124,125,126,127,128,129,130,131, 97,132,133,134,135,136,137, + 138,139,140,141,142, 97,143,144, 97,145,146,147,148, 97,149,150, + 151,152,153,154, 97, 97,155,156,157,158, 97,159, 97,160,161,161, + 161,161,161,161,161,162,163,161,164, 97, 97, 97, 97, 97,165,165, + 165,165,165,165,165,165,166, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97,167,167,167,167,168, 97, 97, 97,169,169, + 169,169,170,171,172,173, 97, 97, 97, 97,174,175,176,177,178,178, + 178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, + 178,178,178,178,178,178,178,178,178,178,178,178,178,179,178,178, + 178,178,178,178,180,180,180,181,182, 97, 97, 97, 97, 97,183,184, + 185,186,186,187, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97,188,189, 97, 97, 97, 97, 97, 97, 59,190, + 191,192,193,194,195, 97,196,197,198, 59, 59,199, 59,200,201,201, + 201,201,201,202, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,203, 97, + 204, 97, 97,205, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,206,207, + 208, 97, 97, 97, 97, 97,209,210,211, 97,212,213, 97, 97,214,215, + 59,216,217, 97, 59, 59, 59, 59, 59, 59, 59,218,219,220,221,222, + 223,224,225,226, 59,227, 97, 97, 97, 97, 97, 97, 97, 97, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,228, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,229, 70,230, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70,227, 70, 70, 70, 70, 70, 70, 70, 70, 70,228, 97, 97, - 97, 97, 97, 97, 97, 97, 70, 70, 70, 70,229, 97, 97, 97, 97, 97, - 97, 97, 97, 97, 97, 97,230, 97,231,232, 0, 1, 2, 2, 0, 1, - 2, 2, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 19, 19, - 19, 19, 19, 19, 19, 0, 19, 0, 0, 0, 0, 0, 0, 0, 19, 19, - 19, 19, 19, 0, 0, 0, 0, 0, 26, 26, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, 2, 2, - 9, 9, 9, 9, 0, 9, 2, 2, 2, 2, 9, 0, 9, 0, 9, 9, - 9, 2, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 2, 9, 9, 9, 9, 9, 9, 9, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 1, 1, 6, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 0, - 4, 2, 2, 4, 4, 4, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 2, 2, 2, 2, 2, 2, 2, 2, 14, 14, - 14, 2, 2, 2, 2, 14, 14, 14, 14, 14, 14, 2, 2, 2, 3, 3, - 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 2, 3, 0, 0, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 2, 37, 37, 37, - 37, 2, 2, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 2, 2, 2, 2, 2, 2, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 2, 2, 64, 64, 64, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 2, 2, 90, 90, 90, 90, 90, 90, 90, 2, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 2, 2, 95, 2, 37, 37, - 37, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, - 3, 3, 3, 3, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,231, 70, 70, 70, 70, + 70, 70, 70, 70, 70,232, 97, 97, 97, 97, 97, 97, 97, 97, 70, 70, + 70, 70,233, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 70, 70, + 70, 70, 70, 70,234, 97, 97, 97, 97, 97, 97, 97, 97, 97,235, 97, + 236,237, 0, 1, 2, 2, 0, 1, 2, 2, 2, 3, 4, 5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, + 19, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 0, 19, 0, + 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, + 26, 26, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, + 9, 9, 0, 9, 9, 9, 2, 2, 9, 9, 9, 9, 0, 9, 2, 2, + 2, 2, 9, 0, 9, 0, 9, 9, 9, 2, 9, 2, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 6, 2, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 2, 4, 4, 4, 2, 2, 4, 4, 4, 2, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 2, + 2, 2, 2, 2, 2, 2, 14, 14, 14, 2, 2, 2, 2, 14, 14, 14, + 14, 14, 14, 2, 2, 2, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, + 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 0, 3, 2, 3, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 3, + 3, 3, 3, 3, 3, 3, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 2, 37, 37, 37, 37, 2, 2, 37, 37, 37, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 2, 2, 2, 2, 2, 2, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 2, 2, 64, 64, 64, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 2, 2, 90, 90, + 90, 90, 90, 90, 90, 2, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 2, 2, 95, 2, 37, 37, 37, 2, 2, 2, 2, 2, 3, 3, + 3, 3, 3, 2, 3, 3, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, 1, 1, 1, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 2, @@ -4557,7 +4601,7 @@ _hb_ucd_u8[17198] = 2, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 2, 2, 2, 2, - 2, 2, 2, 2, 21, 21, 2, 2, 2, 2, 21, 21, 2, 21, 21, 21, + 2, 2, 2, 21, 21, 21, 2, 2, 2, 2, 21, 21, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, 2, 22, 22, 2, 22, 22, 22, 22, 22, 22, 2, 2, 2, 22, 22, 22, 2, 22, 22, 22, 22, 2, 2, 2, 22, 22, 2, 22, 2, 22, 22, 2, 2, 2, 22, 22, 2, 2, 2, 22, 22, @@ -4573,76 +4617,75 @@ _hb_ucd_u8[17198] = 2, 2, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 2, 2, 2, 2, 2, 2, 2, 16, 16, 2, 2, 2, 2, 2, 2, 2, 16, 2, 16, 16, 16, 16, 2, 2, 16, 16, 2, 16, 16, 2, 2, 2, 2, 2, 20, 20, - 20, 20, 2, 20, 20, 20, 20, 20, 20, 20, 20, 2, 20, 20, 20, 2, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 2, 2, - 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 2, 2, 20, 20, 2, 2, - 36, 36, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 2, 2, 2, 36, 36, 36, 36, 36, 36, 36, 36, - 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, 2, 2, - 36, 2, 2, 2, 2, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, 2, - 2, 2, 2, 2, 36, 36, 2, 2, 36, 36, 36, 2, 2, 2, 2, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 2, 2, 2, 2, 0, 24, 24, 24, 24, 2, 2, 2, 2, 2, 18, - 18, 2, 18, 2, 18, 18, 18, 18, 18, 2, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, 18, - 18, 18, 18, 18, 2, 2, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, - 2, 2, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25, 2, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 2, 2, 2, 25, 25, - 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 25, - 25, 2, 2, 2, 2, 2, 33, 33, 33, 33, 33, 33, 33, 33, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 2, 8, 2, 2, - 2, 2, 2, 8, 2, 2, 8, 8, 8, 0, 8, 8, 8, 8, 12, 12, - 12, 12, 12, 12, 12, 12, 30, 30, 30, 30, 30, 30, 30, 30, 30, 2, - 30, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, - 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, 30, 2, 2, 2, 30, 30, - 2, 2, 2, 2, 2, 2, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 2, 2, 28, 28, 28, 28, 28, 28, 28, 28, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 2, 2, 2, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 0, 0, 0, 35, 35, 35, 2, - 2, 2, 2, 2, 2, 2, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 2, 45, 45, 45, 45, 45, 45, 45, 2, 2, 2, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 2, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 2, 2, 2, 2, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 2, 46, 46, 46, 2, - 46, 46, 2, 2, 2, 2, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 2, 2, 31, 31, 2, 2, 2, 2, 2, 2, 32, 32, - 0, 0, 32, 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 2, 2, 2, 2, 2, 2, 32, 2, - 2, 2, 2, 2, 2, 2, 32, 32, 32, 2, 2, 2, 2, 2, 28, 28, - 28, 28, 28, 28, 2, 2, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 2, 48, 48, 48, 48, 2, 2, 2, 2, 48, 2, - 2, 2, 48, 48, 48, 48, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 2, 2, 52, 52, 52, 52, 52, 2, 2, 2, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 2, 2, 2, 2, 58, 58, - 2, 2, 2, 2, 2, 2, 58, 58, 58, 2, 2, 2, 58, 58, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 2, 2, 54, 54, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 2, 91, 91, - 91, 91, 91, 2, 2, 91, 91, 91, 2, 2, 2, 2, 2, 2, 91, 91, - 91, 91, 91, 91, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 2, 2, 2, 2, 62, 62, - 62, 62, 62, 2, 2, 2, 76, 76, 76, 76, 76, 76, 76, 76, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 2, 2, 2, 2, 2, 2, - 2, 2, 93, 93, 93, 93, 70, 70, 70, 70, 70, 70, 70, 70, 2, 2, - 2, 70, 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 73, 73, - 73, 73, 73, 73, 73, 73, 6, 2, 2, 2, 2, 2, 2, 2, 8, 8, - 8, 2, 2, 8, 8, 8, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 1, 1, 0, 2, 2, 2, 2, 2, 19, 19, - 19, 19, 19, 19, 9, 9, 9, 9, 9, 6, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 9, 9, 9, 9, - 9, 19, 19, 19, 19, 19, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 9, 1, 1, 2, 1, 1, 1, 1, 1, 9, 9, - 9, 9, 9, 9, 2, 2, 2, 9, 2, 9, 2, 9, 2, 9, 9, 9, - 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 2, 2, 9, 9, 9, 9, - 9, 9, 2, 9, 9, 9, 2, 2, 9, 9, 9, 2, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 2, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 2, 0, 0, 0, 19, 2, 2, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 2, 19, 19, - 19, 19, 19, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 2, 20, 20, 20, 2, + 20, 20, 20, 20, 20, 20, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, + 20, 20, 2, 2, 20, 20, 2, 36, 36, 36, 2, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2, + 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 2, 36, 2, 2, 2, 2, 36, 2, 2, 2, 2, 36, 36, 36, + 36, 36, 36, 2, 36, 2, 2, 2, 2, 2, 2, 2, 36, 36, 2, 2, + 36, 36, 36, 2, 2, 2, 2, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 2, 2, 2, 2, 0, 24, 24, + 24, 24, 2, 2, 2, 2, 2, 18, 18, 2, 18, 2, 18, 18, 18, 18, + 18, 2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 2, 18, 2, 18, 18, 18, 18, 18, 18, 18, 2, 2, 18, 18, + 18, 18, 18, 2, 18, 2, 18, 18, 2, 2, 18, 18, 18, 18, 25, 25, + 25, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 2, 2, 2, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25, + 25, 25, 25, 0, 0, 0, 0, 25, 25, 2, 2, 2, 2, 2, 33, 33, + 33, 33, 33, 33, 33, 33, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 2, 8, 2, 2, 2, 2, 2, 8, 2, 2, 8, 8, + 8, 0, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, 30, 30, 2, 2, 30, 30, + 30, 30, 30, 30, 30, 2, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, + 30, 30, 30, 2, 2, 2, 30, 30, 2, 2, 2, 2, 2, 2, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 2, 2, 28, 28, + 28, 28, 28, 28, 28, 28, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 2, 2, 2, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 0, 0, 0, 35, 35, 35, 2, 2, 2, 2, 2, 2, 2, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 2, 45, 45, 45, 45, + 45, 45, 45, 2, 2, 2, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 0, 0, 2, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 2, 2, 2, 2, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 2, 46, 46, 46, 2, 46, 46, 2, 2, 2, 2, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 2, 2, 31, 31, + 2, 2, 2, 2, 2, 2, 32, 32, 0, 0, 32, 0, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 2, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 2, 2, 2, 2, 2, 2, 32, 2, 2, 2, 2, 2, 2, 2, 32, 32, + 32, 2, 2, 2, 2, 2, 28, 28, 28, 28, 28, 28, 2, 2, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 2, 48, 48, + 48, 48, 2, 2, 2, 2, 48, 2, 2, 2, 48, 48, 48, 48, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 2, 2, 52, 52, + 52, 52, 52, 2, 2, 2, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 2, 2, 2, 2, 58, 58, 2, 2, 2, 2, 2, 2, 58, 58, + 58, 2, 2, 2, 58, 58, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 2, 2, 54, 54, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 2, 91, 91, 91, 91, 91, 2, 2, 91, 91, 91, + 2, 2, 2, 2, 2, 2, 91, 91, 91, 91, 91, 91, 2, 2, 1, 2, + 2, 2, 2, 2, 2, 2, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 2, 2, 2, 2, 62, 62, 62, 62, 62, 2, 2, 2, 76, 76, + 76, 76, 76, 76, 76, 76, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 2, 2, 2, 2, 2, 2, 2, 2, 93, 93, 93, 93, 70, 70, + 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 70, 70, 70, 70, + 2, 2, 2, 70, 70, 70, 73, 73, 73, 73, 73, 73, 73, 73, 6, 2, + 2, 2, 2, 2, 2, 2, 8, 8, 8, 2, 2, 8, 8, 8, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, + 0, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, + 9, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, 9, + 19, 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 19, 6, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 1, 1, + 2, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 2, 2, 2, 9, + 2, 9, 2, 9, 2, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, + 9, 9, 2, 2, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 2, 2, + 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 19, + 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, + 0, 0, 0, 0, 0, 2, 19, 19, 19, 19, 19, 2, 2, 2, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 19, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, - 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 56, 56, + 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 2, 55, 55, 55, 55, 2, 2, 2, 2, 2, 55, 55, 55, 55, 55, 55, 55, 61, 61, 61, 61, 61, 61, 61, 61, 2, 2, 2, 2, 2, 2, 2, 61, 61, 2, @@ -4656,44 +4699,46 @@ _hb_ucd_u8[17198] = 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, 17, 17, 2, 2, 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 2, 26, 26, 26, 2, 2, 2, 2, 2, 12, 12, - 12, 12, 12, 12, 12, 0, 17, 17, 17, 17, 17, 17, 17, 0, 39, 39, + 12, 12, 12, 12, 12, 2, 12, 12, 12, 12, 12, 12, 12, 0, 17, 17, + 17, 17, 17, 17, 17, 0, 13, 13, 13, 13, 13, 2, 2, 2, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 2, 2, 2, 39, 39, 39, 39, 39, 39, 39, 2, 86, 86, 86, 86, 86, 86, 86, 86, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 2, 2, 2, 2, 79, 79, 79, 79, 79, 79, 79, 79, 0, 0, 19, 19, 19, 19, 19, 19, 0, 0, - 0, 19, 19, 19, 19, 19, 2, 2, 19, 19, 19, 19, 19, 2, 2, 2, - 2, 2, 2, 2, 2, 19, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 65, 65, - 65, 65, 65, 65, 65, 65, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 2, 2, 75, 75, 75, 75, - 2, 2, 2, 2, 2, 2, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 0, 69, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 74, 12, 12, - 12, 12, 12, 2, 2, 2, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 2, 0, 84, 84, 2, 2, 2, 2, 84, 84, 33, 33, - 33, 33, 33, 33, 33, 2, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 2, 68, 68, 68, 68, 68, 68, 2, 2, 68, 68, - 2, 2, 68, 68, 68, 68, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 2, 2, 2, 2, 2, 2, 2, 2, 92, 92, 92, 92, 92, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 2, 2, 30, - 30, 30, 30, 30, 30, 2, 19, 19, 19, 0, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 9, 19, 19, 87, 87, 87, 87, 87, 87, 2, 2, 87, 87, + 0, 19, 19, 19, 19, 19, 2, 2, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 19, 19, 19, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 2, 2, 2, 0, 0, + 2, 2, 2, 2, 2, 2, 65, 65, 65, 65, 65, 65, 65, 65, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 2, 2, 2, 2, + 2, 2, 2, 2, 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 0, 69, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 74, 12, 12, 12, 12, 12, 2, 2, 2, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 2, 0, 84, 84, + 2, 2, 2, 2, 84, 84, 33, 33, 33, 33, 33, 33, 33, 2, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 2, 68, 68, + 68, 68, 68, 68, 2, 2, 68, 68, 2, 2, 68, 68, 68, 68, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 2, 2, 2, 2, 2, 2, 2, + 2, 92, 92, 92, 92, 92, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 2, 2, 30, 30, 30, 30, 30, 30, 2, 19, 19, + 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 19, 19, 19, 19, + 0, 0, 2, 2, 2, 2, 87, 87, 87, 87, 87, 87, 2, 2, 87, 87, 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 12, 13, 13, 2, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 19, 2, 2, 2, 2, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 14, 14, 14, 14, 14, 2, 14, 2, 14, 14, 2, 14, 14, 2, 14, 14, 3, 3, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 0, 0, 2, 2, - 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 6, 6, 0, 0, - 0, 2, 0, 0, 0, 0, 3, 3, 3, 3, 3, 2, 2, 0, 2, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, - 17, 17, 17, 17, 0, 0, 2, 2, 12, 12, 12, 12, 12, 12, 2, 2, - 12, 12, 12, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 2, 49, 49, 49, 2, 49, 49, 2, 49, 49, 49, - 49, 49, 49, 49, 2, 2, 49, 49, 49, 2, 2, 2, 2, 2, 0, 0, - 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 0, 9, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 1, 1, + 1, 1, 1, 1, 6, 6, 0, 0, 0, 2, 0, 0, 0, 0, 3, 3, + 3, 3, 3, 2, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 2, 2, + 12, 12, 12, 12, 12, 12, 2, 2, 12, 12, 12, 2, 2, 2, 2, 0, + 0, 0, 0, 0, 2, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, + 49, 2, 49, 49, 2, 49, 49, 49, 49, 49, 49, 49, 2, 2, 49, 49, + 49, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, + 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 1, 2, 2, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 2, 2, 2, 67, 67, 67, 67, 67, 67, 67, 67, 67, 2, 2, 2, 2, 2, 2, 2, 1, 0, @@ -4737,31 +4782,33 @@ _hb_ucd_u8[17198] = 2, 2, 2, 2, 2, 2,130,130,130,130,130,130,130,130,130,130, 130, 2, 2, 2, 2, 2, 2, 2,130,130,130,130,130,130,144,144, 144,144,144,144,144,144,144,144, 2, 2, 2, 2, 2, 2, 3, 3, - 3, 3, 3, 3, 3, 2,147,147,147,147,147,147,147,147,148,148, - 148,148,148,148,148,148,148,148, 2, 2, 2, 2, 2, 2,149,149, - 149,149,149,149,149,149,149,149,149,149,149,149,149, 2, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 2, 2, 2, 2, - 94, 94, 94, 94, 94, 94, 2, 2, 2, 2, 2, 2, 2, 94, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 85, 2, 2,101,101,101,101,101,101,101,101,101, 2, - 2, 2, 2, 2, 2, 2,101,101, 2, 2, 2, 2, 2, 2, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 2, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 2,111,111,111,111,111,111,111,111,111,111, - 111,111,111,111,111, 2,100,100,100,100,100,100,100,100,100,100, - 100,100,100,100, 2, 2, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 2, 2, 2,108,108,108,108,108,108,108,108,108,108, - 2,108,108,108,108,108,108,108,108,108,108,108,108, 2,129,129, - 129,129,129,129,129, 2,129, 2,129,129,129,129, 2,129,129,129, - 129,129,129,129,129,129,129,129,129,129,129,129, 2,129,129,129, - 2, 2, 2, 2, 2, 2,109,109,109,109,109,109,109,109,109,109, - 109, 2, 2, 2, 2, 2,109,109, 2, 2, 2, 2, 2, 2,107,107, - 107,107, 2,107,107,107,107,107,107,107,107, 2, 2,107,107, 2, - 2,107,107,107,107,107,107,107,107,107,107,107,107,107,107, 2, - 107,107,107,107,107,107,107, 2,107,107, 2,107,107,107,107,107, - 2, 1,107,107,107,107,107, 2, 2,107,107,107, 2, 2,107, 2, - 2, 2, 2, 2, 2,107, 2, 2, 2, 2, 2,107,107,107,107,107, - 107,107, 2, 2,107,107,107,107,107,107,107, 2, 2, 2,137,137, - 137,137,137,137,137,137,137,137, 2,137, 2,137,137,137,124,124, + 3, 3, 3, 3, 3, 2,156,156,156,156,156,156,156,156,156,156, + 2,156,156,156, 2, 2,156,156, 2, 2, 2, 2, 2, 2,147,147, + 147,147,147,147,147,147,148,148,148,148,148,148,148,148,148,148, + 2, 2, 2, 2, 2, 2,153,153,153,153,153,153,153,153,153,153, + 153,153, 2, 2, 2, 2,149,149,149,149,149,149,149,149,149,149, + 149,149,149,149,149, 2, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 2, 2, 2, 2, 94, 94, 94, 94, 94, 94, 2, 2, + 2, 2, 2, 2, 2, 94, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 85, 2, 2,101,101, + 101,101,101,101,101,101,101, 2, 2, 2, 2, 2, 2, 2,101,101, + 2, 2, 2, 2, 2, 2, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 2, 96, 96,111,111,111,111,111,111,111,111,111,111, + 111,111,111,111,111, 2,100,100,100,100,100,100,100,100, 2, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2,108,108, + 108,108,108,108,108,108,108,108, 2,108,108,108,108,108,108,108, + 108,108,108,108,108, 2,129,129,129,129,129,129,129, 2,129, 2, + 129,129,129,129, 2,129,129,129,129,129,129,129,129,129,129,129, + 129,129,129,129, 2,129,129,129, 2, 2, 2, 2, 2, 2,109,109, + 109,109,109,109,109,109,109,109,109, 2, 2, 2, 2, 2,109,109, + 2, 2, 2, 2, 2, 2,107,107,107,107, 2,107,107,107,107,107, + 107,107,107, 2, 2,107,107, 2, 2,107,107,107,107,107,107,107, + 107,107,107,107,107,107,107, 2,107,107,107,107,107,107,107, 2, + 107,107, 2,107,107,107,107,107, 2, 1,107,107,107,107,107, 2, + 2,107,107,107, 2, 2,107, 2, 2, 2, 2, 2, 2,107, 2, 2, + 2, 2, 2,107,107,107,107,107,107,107, 2, 2,107,107,107,107, + 107,107,107, 2, 2, 2,137,137,137,137,137,137,137,137,137,137, + 137,137, 2,137,137,137,137,137, 2, 2, 2, 2, 2, 2,124,124, 124,124,124,124,124,124,124,124, 2, 2, 2, 2, 2, 2,123,123, 123,123,123,123,123,123,123,123,123,123,123,123, 2, 2,114,114, 114,114,114,114,114,114,114,114,114,114,114, 2, 2, 2,114,114, @@ -4771,22 +4818,26 @@ _hb_ucd_u8[17198] = 126, 2, 2,126,126,126,126,126,126,126, 2, 2, 2, 2,142,142, 142,142,142,142,142,142,142,142,142,142, 2, 2, 2, 2,125,125, 125,125,125,125,125,125,125,125,125, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2,125,150,150,150,150,150,150,150,150, 2, 2, - 150,150,150,150,150,150,150,150,150,150,150, 2, 2, 2,141,141, - 141,141,141,141,141,141,140,140,140,140,140,140,140,140,140,140, - 140, 2, 2, 2, 2, 2,121,121,121,121,121,121,121,121,121, 2, - 2, 2, 2, 2, 2, 2,133,133,133,133,133,133,133,133,133, 2, - 133,133,133,133,133,133,133,133,133,133,133,133,133, 2,133,133, - 133,133,133,133, 2, 2,133,133,133,133,133, 2, 2, 2,134,134, - 134,134,134,134,134,134, 2, 2,134,134,134,134,134,134, 2,134, - 134,134,134,134,134,134,134,134,134,134,134,134,134, 2,138,138, - 138,138,138,138,138, 2,138,138, 2,138,138,138,138,138,138,138, - 138,138,138,138,138,138, 2, 2,138, 2,138,138, 2,138,138,138, - 2, 2, 2, 2, 2, 2,143,143,143,143,143,143, 2,143,143, 2, - 143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, - 143,143,143,143,143, 2,143,143, 2,143,143,143,143,143,143, 2, - 2, 2, 2, 2, 2, 2,143,143, 2, 2, 2, 2, 2, 2,145,145, - 145,145,145,145,145,145,145, 2, 2, 2, 2, 2, 2, 2, 22, 22, + 2, 2, 2, 2, 2,125,154,154,154,154,154,154,154, 2, 2,154, + 2, 2,154,154,154,154,154,154,154,154, 2,154,154, 2,154,154, + 154,154,154,154,154,154,154,154,154,154,154,154, 2,154,154, 2, + 2,154,154,154,154,154,154,154, 2, 2, 2, 2, 2, 2,150,150, + 150,150,150,150,150,150, 2, 2,150,150,150,150,150,150,150,150, + 150,150,150, 2, 2, 2,141,141,141,141,141,141,141,141,140,140, + 140,140,140,140,140,140,140,140,140, 2, 2, 2, 2, 2,121,121, + 121,121,121,121,121,121,121, 2, 2, 2, 2, 2, 2, 2,133,133, + 133,133,133,133,133,133,133, 2,133,133,133,133,133,133,133,133, + 133,133,133,133,133, 2,133,133,133,133,133,133, 2, 2,133,133, + 133,133,133, 2, 2, 2,134,134,134,134,134,134,134,134, 2, 2, + 134,134,134,134,134,134, 2,134,134,134,134,134,134,134,134,134, + 134,134,134,134,134, 2,138,138,138,138,138,138,138, 2,138,138, + 2,138,138,138,138,138,138,138,138,138,138,138,138,138, 2, 2, + 138, 2,138,138, 2,138,138,138, 2, 2, 2, 2, 2, 2,143,143, + 143,143,143,143, 2,143,143, 2,143,143,143,143,143,143,143,143, + 143,143,143,143,143,143,143,143,143,143,143,143,143, 2,143,143, + 2,143,143,143,143,143,143, 2, 2, 2, 2, 2, 2, 2,143,143, + 2, 2, 2, 2, 2, 2,145,145,145,145,145,145,145,145,145, 2, + 2, 2, 2, 2, 2, 2, 86, 2, 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 2, 2, 2, 2, 2, 2, 63, 63, 63, 63, 63, 63, 63, 2, 63, 63, 63, 63, 63, 2, 2, 2, 63, 63, @@ -4800,19 +4851,20 @@ _hb_ucd_u8[17198] = 2,119,119,119,119,119, 2, 2, 2, 2, 2,119,119,119,146,146, 146,146,146,146,146,146,146,146,146, 2, 2, 2, 2, 2, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 2, 2, 2, 2, 99, 2, 2, - 2, 2, 2, 2, 2, 99,136,139, 0, 0, 2, 2, 2, 2,136,136, - 136,136,136,136,136,136,136,136,136, 2, 2, 2, 2, 2, 17, 15, + 2, 2, 2, 2, 2, 99,136,139, 0, 0,155, 2, 2, 2,136,136, + 136,136,136,136,136,136,155,155,155,155,155,155,155,155,155,155, + 155,155,155,155, 2, 2,136, 2, 2, 2, 2, 2, 2, 2, 17, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17, 17, 17, 17,139,139,139,139,139,139,139,139,139,139, 139,139, 2, 2, 2, 2,105,105,105,105,105,105,105,105,105,105, 105, 2, 2, 2, 2, 2,105,105,105,105,105, 2, 2, 2,105, 2, 2, 2, 2, 2, 2, 2,105,105, 2, 2,105,105,105,105, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 0, 0, 2, 2, 0, - 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, - 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 0, 2, 2, 0, 0, 2, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0,131,131,131,131,131,131,131,131,131,131, @@ -4824,90 +4876,93 @@ _hb_ucd_u8[17198] = 152,152,152,152,152,152,152,152, 2, 2, 2, 2, 2,152,113,113, 113,113,113,113,113,113,113,113,113,113,113, 2, 2,113,113,113, 113,113,113,113,113, 2,132,132,132,132,132,132,132,132,132,132, - 132,132, 2, 2, 2, 2,132,132, 2, 2, 2, 2,132,132, 0, 0, - 0, 0, 0, 2, 2, 2, 3, 3, 3, 3, 2, 3, 3, 3, 2, 3, - 3, 2, 3, 2, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 2, 2, 2, 2, 2, 2, - 3, 2, 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 2, 3, - 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 3, - 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 3, - 3, 3, 2, 3, 3, 3, 2, 2, 2, 2, 2, 2, 0, 0, 15, 0, - 0, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 0, 0, 13, 13, - 13, 13, 13, 13, 13, 2, 13, 13, 13, 13, 13, 2, 2, 2, 13, 2, - 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 16, 50, - 84,118, 88, 89, 90, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 91, 85, 85, - 220, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 94, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 15, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 23, 0, 0, 24, 25, 26, 27, 28, 29, 30, 0, 0, 31, 32, - 0, 33, 0, 34, 0, 35, 0, 0, 0, 0, 36, 37, 38, 39, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 43, 44, 0, 45, 0, 0, 0, 0, 0, 0, 46, 47, 0, 0, 0, 0, - 0, 48, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 50, 51, 0, 0, 0, 52, 0, 0, 53, 0, 0, 0, 0, 0, - 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, - 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 58, 59, 60, 61, 62, 63, 64, 65, 0, 0, 0, 0, 0, 0, - 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 68, - 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 104, 0, 0, 0, 0, 0, 0,105,106, 0,107, 0, 0, 0,108, 0, - 109, 0,110, 0,111,112,113, 0,114, 0, 0, 0,115, 0, 0, 0, - 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,118,119,120,121, 0,122,123,124,125,126, 0,127, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,129, - 130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145, - 146,147,148,149,150,151,152,153,154,155,156,157, 0, 0, 0,158, - 159,160,161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,162,163, 0, 0, 0, 0, 0, 0, 0, - 164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,167, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,168,169, 0, 0, 0, 0,170,171, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,172,173, - 174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189, - 190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, + 132,132, 2, 2, 2, 2,132,132, 2, 2, 2, 2,132,132, 3, 3, + 3, 3, 2, 3, 3, 3, 2, 3, 3, 2, 3, 2, 2, 3, 2, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 3, + 2, 3, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 3, 2, 3, + 2, 3, 2, 3, 3, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + 3, 3, 3, 2, 3, 2, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 2, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 2, + 2, 2, 2, 2, 0, 0, 15, 0, 0, 2, 2, 2, 2, 2, 13, 2, + 2, 2, 2, 2, 2, 2, 13, 13, 13, 2, 2, 2, 2, 2, 2, 0, + 2, 2, 2, 2, 2, 2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 9, 9, 9, 10, 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 16, 17, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 19, + 20, 9, 21, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 22, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 24, 25, 26, 27, 28, + 29, 30, 0, 0, 31, 32, 0, 33, 0, 34, 0, 35, 0, 0, 0, 0, + 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 43, 44, 0, 45, 0, 0, 0, 0, 0, 0, + 46, 47, 0, 0, 0, 0, 0, 48, 0, 49, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 50, 51, 0, 0, 0, 52, 0, 0, + 53, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, + 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 58, 59, 60, 61, 62, 63, 64, 65, + 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 67, 68, 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99,100,101,102,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,104, 0, 0, 0, 0, 0, 0,105,106, 0, + 107, 0, 0, 0,108, 0,109, 0,110, 0,111,112,113, 0,114, 0, + 0, 0,115, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,118,119,120,121, 0,122,123,124, + 125,126, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,128,129,130,131,132,133,134,135,136,137,138,139, + 140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155, + 156,157, 0, 0, 0,158,159,160,161, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,162,163, 0, + 0, 0, 0, 0, 0, 0,164, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,165, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,166, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,167, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,168, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,169,170, 0, 0, 0, 0,171, + 172, 0, 0, 0,173,174,175,176,177,178,179,180,181,182,183,184, + 185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200, + 201,202,203,204,205,206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, 3, 4, }; static const uint16_t -_hb_ucd_u16[8944] = +_hb_ucd_u16[9080] = { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, @@ -4917,557 +4972,566 @@ _hb_ucd_u16[8944] = 13, 13, 13, 42, 9, 43, 11, 11, 44, 45, 32, 46, 47, 48, 49, 50, 51, 52, 48, 48, 53, 32, 54, 55, 48, 48, 48, 48, 48, 56, 57, 58, 59, 60, 48, 32, 61, 48, 48, 48, 48, 48, 62, 63, 64, 48, 65, 66, - 48, 67, 68, 69, 48, 70, 71, 72, 72, 72, 48, 73, 72, 74, 75, 32, - 76, 48, 48, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 83, 84, 91, 92, 93, 94, 95, 96, 97, 84, 98, 99, 100, 88, 101, - 102, 83, 84, 103, 104, 105, 88, 106, 107, 108, 109, 110, 111, 112, 94, 113, - 114, 115, 84, 116, 117, 118, 88, 119, 120, 115, 84, 121, 122, 123, 88, 124, - 125, 115, 48, 126, 127, 128, 88, 129, 130, 131, 48, 132, 133, 134, 94, 135, - 136, 48, 48, 137, 138, 139, 72, 72, 140, 48, 141, 142, 143, 144, 72, 72, - 145, 146, 147, 148, 149, 48, 150, 151, 152, 153, 32, 154, 155, 156, 72, 72, - 48, 48, 157, 158, 159, 160, 161, 162, 163, 164, 9, 9, 165, 11, 11, 166, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 167, 168, 48, 48, - 167, 48, 48, 169, 170, 171, 48, 48, 48, 170, 48, 48, 48, 172, 173, 174, - 48, 175, 9, 9, 9, 9, 9, 176, 177, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 178, 48, 179, 180, 48, 48, 48, 48, 181, 182, - 183, 184, 48, 185, 48, 186, 183, 187, 48, 48, 48, 188, 189, 190, 191, 192, - 193, 191, 48, 48, 194, 48, 48, 195, 196, 48, 197, 48, 48, 48, 48, 198, - 48, 199, 200, 201, 202, 48, 203, 204, 48, 48, 205, 48, 206, 207, 208, 208, - 48, 209, 48, 48, 48, 210, 211, 212, 191, 191, 213, 214, 72, 72, 72, 72, - 215, 48, 48, 216, 217, 159, 218, 219, 220, 48, 221, 64, 48, 48, 222, 223, - 48, 48, 224, 225, 226, 64, 48, 227, 228, 9, 9, 229, 230, 231, 232, 233, - 11, 11, 234, 27, 27, 27, 235, 236, 11, 237, 27, 27, 32, 32, 32, 238, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 239, 13, 13, 13, 13, 13, 13, - 240, 241, 240, 240, 241, 242, 240, 243, 244, 244, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 260, 72, 261, 262, 263, - 264, 265, 266, 267, 268, 269, 270, 270, 271, 272, 273, 208, 274, 275, 208, 276, - 277, 277, 277, 277, 277, 277, 277, 277, 278, 208, 279, 208, 208, 208, 208, 280, - 208, 281, 277, 282, 208, 283, 284, 208, 208, 208, 285, 72, 286, 72, 269, 269, - 269, 287, 208, 208, 208, 208, 288, 269, 208, 208, 208, 208, 208, 208, 208, 208, - 208, 208, 208, 289, 290, 208, 208, 291, 208, 208, 208, 208, 208, 208, 292, 208, - 208, 208, 208, 208, 208, 208, 293, 294, 269, 295, 208, 208, 296, 277, 297, 277, - 298, 299, 277, 277, 277, 300, 277, 301, 208, 208, 208, 277, 302, 208, 208, 303, - 208, 304, 208, 208, 208, 208, 208, 208, 9, 9, 305, 11, 11, 306, 307, 308, - 13, 13, 13, 13, 13, 13, 309, 310, 11, 11, 311, 48, 48, 48, 312, 313, - 48, 314, 315, 315, 315, 315, 32, 32, 316, 317, 318, 319, 320, 72, 72, 72, - 208, 321, 208, 208, 208, 208, 208, 322, 208, 208, 208, 208, 208, 323, 72, 324, - 325, 326, 327, 328, 136, 48, 48, 48, 48, 329, 177, 48, 48, 48, 48, 330, - 331, 48, 48, 136, 48, 48, 48, 48, 199, 332, 48, 71, 208, 208, 322, 48, - 208, 333, 334, 208, 335, 336, 208, 208, 334, 208, 208, 336, 208, 208, 208, 208, - 48, 48, 48, 198, 208, 208, 208, 208, 48, 48, 48, 48, 48, 48, 48, 72, - 48, 337, 48, 48, 48, 48, 48, 48, 150, 208, 208, 208, 285, 48, 48, 227, - 338, 48, 339, 72, 13, 13, 340, 341, 13, 342, 48, 48, 48, 48, 343, 344, - 31, 345, 346, 347, 13, 13, 13, 348, 349, 350, 351, 352, 353, 72, 72, 354, - 355, 48, 356, 357, 48, 48, 48, 358, 359, 48, 48, 360, 361, 191, 32, 362, - 64, 48, 363, 48, 364, 365, 48, 150, 76, 48, 48, 366, 367, 368, 369, 370, - 48, 48, 371, 372, 373, 374, 48, 375, 48, 48, 48, 376, 377, 378, 379, 380, - 381, 382, 315, 11, 11, 383, 384, 11, 11, 11, 11, 11, 48, 48, 385, 191, - 48, 48, 386, 48, 387, 48, 48, 205, 388, 388, 388, 388, 388, 388, 388, 388, - 389, 389, 389, 389, 389, 389, 389, 389, 48, 48, 48, 48, 48, 48, 203, 48, - 48, 48, 48, 48, 48, 206, 72, 72, 390, 391, 392, 393, 394, 48, 48, 48, - 48, 48, 48, 395, 396, 397, 48, 48, 48, 48, 48, 398, 72, 48, 48, 48, - 48, 399, 48, 48, 400, 72, 72, 401, 32, 402, 32, 403, 404, 405, 406, 407, + 48, 67, 68, 69, 48, 70, 71, 72, 72, 72, 48, 73, 74, 75, 76, 32, + 77, 48, 48, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 84, 85, 92, 93, 94, 95, 96, 97, 98, 85, 99, 100, 101, 89, 102, + 103, 84, 85, 104, 105, 106, 89, 107, 108, 109, 110, 111, 112, 113, 95, 114, + 115, 116, 85, 117, 118, 119, 89, 120, 121, 116, 85, 122, 123, 124, 89, 125, + 126, 116, 48, 127, 128, 129, 89, 130, 131, 132, 48, 133, 134, 135, 95, 136, + 137, 48, 48, 138, 139, 140, 72, 72, 141, 48, 142, 143, 144, 145, 72, 72, + 146, 147, 148, 149, 150, 48, 151, 152, 153, 154, 32, 155, 156, 157, 72, 72, + 48, 48, 158, 159, 160, 161, 162, 163, 164, 165, 9, 9, 166, 11, 11, 167, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 168, 169, 48, 48, + 168, 48, 48, 170, 171, 172, 48, 48, 48, 171, 48, 48, 48, 173, 174, 175, + 48, 176, 9, 9, 9, 9, 9, 177, 178, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 179, 48, 180, 181, 48, 48, 48, 48, 182, 183, + 184, 185, 48, 186, 48, 187, 184, 188, 48, 48, 48, 189, 190, 191, 192, 193, + 194, 192, 48, 48, 195, 48, 48, 196, 197, 48, 198, 48, 48, 48, 48, 199, + 48, 200, 201, 202, 203, 48, 204, 205, 48, 48, 206, 48, 207, 208, 209, 209, + 48, 210, 48, 48, 48, 211, 212, 213, 192, 192, 214, 215, 216, 72, 72, 72, + 217, 48, 48, 218, 219, 160, 220, 221, 222, 48, 223, 64, 48, 48, 224, 225, + 48, 48, 226, 227, 228, 64, 48, 229, 230, 9, 9, 231, 232, 233, 234, 235, + 11, 11, 236, 27, 27, 27, 237, 238, 11, 239, 27, 27, 32, 32, 32, 240, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 241, 13, 13, 13, 13, 13, 13, + 242, 243, 242, 242, 243, 244, 242, 245, 246, 246, 246, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 262, 72, 263, 264, 216, + 265, 266, 267, 268, 269, 270, 271, 271, 272, 273, 274, 209, 275, 276, 209, 277, + 278, 278, 278, 278, 278, 278, 278, 278, 279, 209, 280, 209, 209, 209, 209, 281, + 209, 282, 278, 283, 209, 284, 285, 209, 209, 209, 286, 72, 287, 72, 270, 270, + 270, 288, 209, 209, 209, 209, 289, 270, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 290, 291, 209, 209, 292, 209, 209, 209, 209, 209, 209, 293, 209, + 209, 209, 209, 209, 209, 209, 294, 295, 270, 296, 209, 209, 297, 278, 298, 278, + 299, 300, 278, 278, 278, 301, 278, 302, 209, 209, 209, 278, 303, 209, 209, 304, + 209, 305, 209, 209, 209, 209, 209, 209, 9, 9, 306, 11, 11, 307, 308, 309, + 13, 13, 13, 13, 13, 13, 310, 311, 11, 11, 312, 48, 48, 48, 313, 314, + 48, 315, 316, 316, 316, 316, 32, 32, 317, 318, 319, 320, 321, 322, 72, 72, + 209, 323, 209, 209, 209, 209, 209, 324, 209, 209, 209, 209, 209, 325, 72, 326, + 327, 328, 329, 330, 137, 48, 48, 48, 48, 331, 178, 48, 48, 48, 48, 332, + 333, 48, 48, 137, 48, 48, 48, 48, 200, 334, 48, 48, 209, 209, 324, 48, + 209, 335, 336, 209, 337, 338, 209, 209, 336, 209, 209, 338, 209, 209, 209, 209, + 48, 48, 48, 48, 209, 209, 209, 209, 48, 48, 48, 48, 48, 48, 48, 151, + 48, 339, 48, 48, 48, 48, 48, 48, 151, 209, 209, 209, 286, 48, 48, 229, + 340, 48, 341, 72, 13, 13, 342, 343, 13, 344, 48, 48, 48, 48, 345, 346, + 31, 347, 348, 349, 13, 13, 13, 350, 351, 352, 353, 354, 355, 72, 72, 356, + 357, 48, 358, 359, 48, 48, 48, 360, 361, 48, 48, 362, 363, 192, 32, 364, + 64, 48, 365, 48, 366, 367, 48, 151, 77, 48, 48, 368, 369, 370, 371, 372, + 48, 48, 373, 374, 375, 376, 48, 377, 48, 48, 48, 378, 379, 380, 381, 382, + 383, 384, 316, 11, 11, 385, 386, 11, 11, 11, 11, 11, 48, 48, 387, 192, + 48, 48, 388, 48, 389, 48, 48, 206, 390, 390, 390, 390, 390, 390, 390, 390, + 391, 391, 391, 391, 391, 391, 391, 391, 48, 48, 48, 48, 48, 48, 204, 48, + 48, 48, 48, 48, 48, 207, 72, 72, 392, 393, 394, 395, 396, 48, 48, 48, + 48, 48, 48, 397, 398, 399, 48, 48, 48, 48, 48, 400, 72, 48, 48, 48, + 48, 401, 48, 48, 74, 72, 72, 402, 32, 403, 32, 404, 405, 406, 407, 73, 48, 48, 48, 48, 48, 48, 48, 408, 409, 2, 3, 4, 5, 410, 411, 412, - 48, 413, 48, 199, 414, 415, 416, 417, 418, 48, 171, 419, 203, 203, 72, 72, - 48, 48, 48, 48, 48, 48, 48, 71, 420, 269, 269, 421, 270, 270, 270, 422, - 423, 324, 424, 72, 72, 208, 208, 425, 72, 72, 72, 72, 72, 72, 72, 72, - 48, 150, 48, 48, 48, 100, 426, 427, 48, 48, 428, 48, 429, 48, 48, 430, - 48, 431, 48, 48, 432, 433, 72, 72, 9, 9, 434, 11, 11, 48, 48, 48, - 48, 203, 191, 9, 9, 435, 11, 436, 48, 48, 400, 48, 48, 48, 437, 72, - 48, 48, 48, 314, 48, 198, 400, 72, 438, 48, 48, 439, 48, 440, 48, 441, - 48, 199, 442, 72, 72, 72, 48, 443, 48, 444, 48, 445, 72, 72, 72, 72, - 48, 48, 48, 446, 269, 447, 269, 269, 448, 449, 48, 450, 451, 452, 48, 453, - 48, 454, 72, 72, 455, 48, 456, 457, 48, 48, 48, 458, 48, 459, 48, 460, - 48, 461, 462, 72, 72, 72, 72, 72, 48, 48, 48, 48, 195, 72, 72, 72, - 9, 9, 9, 463, 11, 11, 11, 464, 48, 48, 465, 191, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 269, 466, 48, 454, 467, 48, 62, 468, 72, 72, - 72, 72, 72, 72, 72, 72, 48, 314, 469, 48, 48, 470, 471, 447, 472, 473, - 220, 48, 48, 474, 475, 48, 195, 191, 476, 48, 477, 478, 479, 48, 48, 480, - 220, 48, 48, 481, 482, 483, 484, 485, 48, 97, 486, 487, 72, 72, 72, 72, - 488, 489, 490, 48, 48, 491, 492, 191, 493, 83, 84, 494, 495, 496, 497, 498, - 48, 48, 48, 499, 500, 501, 72, 72, 48, 48, 48, 502, 503, 191, 72, 72, - 48, 48, 504, 505, 506, 507, 72, 72, 48, 48, 48, 508, 509, 191, 510, 72, - 48, 48, 511, 512, 191, 72, 72, 72, 48, 172, 513, 514, 72, 72, 72, 72, - 48, 48, 486, 515, 72, 72, 72, 72, 72, 72, 9, 9, 11, 11, 147, 516, - 72, 72, 517, 48, 48, 518, 519, 72, 520, 48, 48, 521, 522, 523, 48, 48, - 524, 525, 526, 72, 48, 48, 48, 195, 84, 48, 504, 527, 528, 147, 174, 529, - 48, 530, 531, 532, 72, 72, 72, 72, 533, 48, 48, 534, 535, 191, 536, 48, - 537, 538, 191, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 48, 539, - 72, 72, 72, 72, 269, 540, 541, 542, 48, 206, 72, 72, 72, 72, 72, 72, - 270, 270, 270, 270, 270, 270, 543, 544, 48, 48, 48, 48, 386, 72, 72, 72, - 48, 48, 199, 545, 72, 72, 72, 72, 48, 48, 48, 48, 314, 72, 72, 72, - 48, 48, 48, 195, 48, 199, 368, 72, 72, 72, 72, 72, 72, 48, 203, 546, - 48, 48, 48, 547, 548, 549, 550, 551, 48, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 9, 9, 11, 11, 269, 552, 72, 72, 72, 72, 72, 72, - 48, 48, 48, 48, 553, 554, 555, 555, 556, 557, 72, 72, 72, 72, 558, 72, - 48, 48, 48, 48, 48, 48, 48, 400, 48, 48, 48, 48, 48, 48, 48, 559, - 48, 199, 72, 72, 72, 559, 560, 48, 48, 48, 48, 48, 48, 48, 48, 205, - 48, 48, 48, 48, 48, 48, 71, 150, 195, 561, 562, 72, 72, 72, 72, 72, - 208, 208, 208, 208, 208, 208, 208, 323, 208, 208, 563, 208, 208, 208, 564, 565, - 566, 208, 567, 208, 208, 208, 568, 72, 208, 208, 208, 208, 569, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 269, 570, 208, 208, 208, 208, 208, 285, 269, 451, - 9, 571, 11, 572, 573, 574, 240, 9, 575, 576, 577, 578, 579, 9, 571, 11, - 580, 581, 11, 582, 583, 584, 585, 9, 586, 11, 9, 571, 11, 572, 573, 11, - 240, 9, 575, 585, 9, 586, 11, 9, 571, 11, 587, 9, 588, 589, 590, 591, - 11, 592, 9, 593, 594, 595, 596, 11, 597, 9, 598, 11, 599, 600, 600, 600, - 32, 32, 32, 601, 32, 32, 602, 603, 604, 605, 45, 72, 72, 72, 72, 72, - 606, 607, 608, 72, 72, 72, 72, 72, 48, 48, 150, 609, 610, 72, 72, 72, - 72, 72, 72, 72, 48, 48, 611, 612, 48, 48, 48, 48, 613, 614, 72, 72, - 9, 9, 575, 11, 615, 368, 72, 72, 72, 72, 72, 72, 72, 72, 72, 484, - 269, 269, 616, 617, 72, 72, 72, 72, 484, 269, 618, 619, 72, 72, 72, 72, - 620, 48, 621, 622, 623, 624, 625, 626, 627, 205, 628, 205, 72, 72, 72, 629, - 208, 208, 324, 208, 208, 208, 208, 208, 208, 322, 333, 630, 630, 630, 208, 323, - 174, 208, 208, 208, 208, 208, 631, 208, 208, 208, 631, 72, 72, 72, 632, 208, - 633, 208, 208, 324, 568, 634, 323, 72, 208, 208, 208, 208, 208, 208, 208, 635, - 208, 208, 208, 208, 208, 323, 631, 286, 208, 208, 208, 208, 208, 208, 208, 322, - 208, 208, 208, 208, 208, 568, 324, 72, 324, 208, 208, 208, 636, 175, 208, 208, - 636, 208, 637, 72, 72, 72, 72, 72, 638, 208, 208, 208, 208, 208, 208, 639, - 208, 208, 640, 208, 641, 208, 208, 208, 208, 208, 208, 208, 208, 322, 637, 642, - 633, 323, 72, 72, 72, 72, 72, 72, 48, 48, 48, 48, 48, 314, 72, 72, - 48, 48, 48, 204, 48, 48, 48, 48, 48, 203, 48, 48, 48, 48, 48, 48, - 48, 48, 643, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 100, 72, - 48, 203, 72, 72, 72, 72, 72, 72, 644, 72, 645, 645, 645, 645, 645, 645, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 72, - 389, 389, 389, 389, 389, 389, 389, 646, 389, 389, 389, 389, 389, 389, 389, 647, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 1, 2, 2, 3, - 0, 0, 0, 0, 0, 4, 0, 4, 2, 2, 5, 2, 2, 2, 5, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 6, 0, 0, 0, 0, 7, 8, 0, 0, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 11, - 12, 13, 14, 14, 15, 14, 14, 14, 14, 14, 14, 14, 16, 17, 14, 14, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 19, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 20, 21, 21, 21, 22, 20, 21, 21, 21, 21, - 21, 23, 24, 25, 25, 25, 25, 25, 25, 26, 25, 25, 25, 27, 28, 26, - 29, 30, 31, 32, 31, 31, 31, 31, 33, 34, 35, 31, 31, 31, 36, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 29, 31, 31, 31, 31, - 37, 38, 37, 37, 37, 37, 37, 37, 37, 39, 31, 31, 31, 31, 31, 31, - 40, 40, 40, 40, 40, 40, 41, 26, 42, 42, 42, 42, 42, 42, 42, 43, - 44, 44, 44, 44, 44, 45, 44, 46, 47, 47, 47, 48, 37, 49, 26, 26, - 26, 26, 26, 26, 31, 31, 50, 51, 26, 26, 52, 31, 53, 31, 31, 31, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 55, 54, 56, 54, 54, 54, - 57, 58, 59, 60, 60, 61, 62, 63, 58, 64, 65, 66, 67, 60, 60, 68, - 69, 70, 71, 72, 72, 73, 74, 75, 70, 76, 77, 78, 79, 72, 80, 26, - 81, 82, 83, 84, 84, 85, 86, 87, 82, 88, 89, 26, 90, 84, 91, 92, - 93, 94, 95, 96, 96, 97, 98, 99, 94, 100, 101, 102, 103, 96, 96, 26, - 104, 105, 106, 107, 108, 105, 109, 110, 105, 106, 111, 26, 112, 109, 109, 113, - 114, 115, 116, 114, 114, 116, 114, 117, 115, 118, 119, 120, 121, 114, 122, 114, - 123, 124, 125, 123, 123, 125, 126, 127, 124, 128, 129, 130, 131, 123, 132, 26, - 133, 134, 135, 136, 136, 136, 136, 136, 134, 135, 137, 136, 138, 136, 136, 136, - 139, 140, 141, 142, 140, 140, 143, 144, 141, 145, 146, 140, 147, 140, 148, 26, - 149, 150, 150, 150, 150, 150, 150, 151, 150, 150, 150, 152, 26, 26, 26, 26, - 153, 154, 155, 155, 156, 155, 155, 157, 158, 157, 155, 159, 26, 26, 26, 26, - 160, 160, 160, 160, 160, 160, 160, 160, 160, 161, 160, 160, 160, 162, 161, 160, - 160, 160, 160, 161, 160, 160, 160, 163, 160, 163, 164, 165, 26, 26, 26, 26, - 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 167, 167, 167, 167, 168, 169, 167, 167, 167, 167, 167, 170, - 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 173, 174, 173, 172, 172, 172, 172, - 172, 173, 172, 172, 172, 172, 173, 174, 173, 172, 174, 172, 172, 172, 172, 172, - 172, 172, 173, 172, 172, 172, 172, 172, 172, 172, 172, 175, 172, 172, 172, 176, - 172, 172, 172, 177, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 179, 179, - 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, - 181, 181, 181, 182, 183, 183, 183, 183, 183, 183, 183, 183, 183, 184, 183, 185, - 186, 187, 188, 26, 189, 189, 190, 26, 191, 191, 192, 26, 193, 194, 195, 26, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 197, 196, 198, 196, 198, - 199, 200, 201, 202, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 203, - 201, 201, 201, 201, 201, 204, 180, 180, 180, 180, 180, 180, 180, 180, 205, 26, - 206, 206, 206, 207, 206, 208, 206, 208, 209, 206, 210, 210, 210, 211, 212, 26, - 213, 213, 213, 213, 213, 214, 213, 213, 213, 215, 213, 216, 196, 196, 196, 196, - 217, 217, 217, 218, 219, 219, 219, 219, 219, 219, 219, 220, 219, 219, 219, 221, - 219, 222, 219, 222, 219, 223, 9, 224, 26, 26, 26, 26, 26, 26, 26, 26, - 225, 225, 225, 225, 225, 225, 225, 225, 225, 226, 225, 225, 225, 225, 225, 227, - 228, 228, 228, 228, 228, 228, 228, 228, 229, 229, 229, 229, 229, 229, 230, 231, - 232, 232, 232, 232, 232, 232, 232, 233, 232, 234, 235, 235, 235, 235, 235, 235, - 18, 236, 167, 167, 167, 167, 167, 237, 228, 26, 238, 9, 239, 240, 241, 242, - 2, 2, 2, 2, 243, 244, 2, 2, 2, 2, 2, 245, 246, 247, 2, 248, - 2, 2, 2, 2, 2, 2, 2, 249, 9, 9, 9, 9, 9, 9, 9, 250, - 14, 14, 251, 251, 14, 14, 14, 14, 251, 251, 14, 252, 14, 14, 14, 251, - 14, 14, 14, 14, 14, 14, 253, 14, 253, 14, 254, 255, 14, 14, 256, 257, - 0, 258, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, 0, 260, 261, - 0, 262, 2, 263, 0, 0, 0, 0, 26, 26, 9, 9, 9, 9, 264, 26, - 0, 0, 0, 0, 265, 266, 4, 0, 0, 267, 0, 0, 2, 2, 2, 2, - 2, 268, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 262, 26, 26, 26, 0, 269, 26, 26, 0, 0, 0, 0, - 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 271, 0, - 0, 0, 272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 273, 273, 273, 273, 273, 274, 273, 273, 273, 273, 273, 274, 2, 2, 2, 2, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 275, 276, - 167, 167, 167, 167, 168, 169, 277, 277, 277, 277, 277, 277, 277, 278, 279, 278, - 172, 172, 174, 26, 174, 174, 174, 174, 174, 174, 174, 174, 18, 18, 18, 18, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, - 280, 280, 280, 281, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 282, 26, - 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 283, 26, 26, 26, 0, 284, - 285, 0, 0, 0, 286, 287, 0, 288, 289, 290, 290, 290, 290, 290, 290, 290, - 290, 290, 291, 292, 293, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 295, - 296, 297, 297, 297, 297, 297, 298, 171, 171, 171, 171, 171, 171, 171, 171, 171, - 171, 299, 0, 0, 297, 297, 297, 300, 0, 0, 0, 0, 284, 26, 294, 294, - 171, 171, 171, 299, 0, 0, 0, 0, 0, 0, 0, 0, 171, 171, 171, 301, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 294, 294, 294, 294, 294, 302, - 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 0, 0, 0, 0, 0, - 280, 280, 280, 280, 280, 280, 283, 26, 0, 0, 0, 0, 0, 0, 0, 0, - 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 26, 26, - 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, - 303, 304, 303, 303, 303, 303, 303, 303, 305, 26, 306, 306, 306, 306, 306, 306, - 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 308, 26, 26, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 26, - 0, 0, 0, 0, 310, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 311, 2, 2, 2, 2, 2, 2, 312, 26, 26, 26, 26, 26, 313, 2, - 314, 314, 314, 314, 314, 315, 0, 316, 317, 317, 317, 317, 317, 317, 317, 26, - 318, 318, 318, 318, 318, 318, 318, 318, 319, 320, 318, 321, 54, 54, 54, 54, - 322, 322, 322, 322, 322, 323, 324, 324, 324, 324, 325, 326, 171, 171, 171, 327, - 328, 328, 328, 328, 328, 328, 328, 328, 328, 329, 328, 330, 166, 166, 166, 331, - 332, 332, 332, 332, 332, 332, 333, 26, 332, 334, 332, 335, 166, 166, 166, 166, - 336, 336, 336, 336, 336, 336, 336, 336, 337, 26, 26, 338, 339, 339, 340, 26, - 341, 341, 341, 26, 174, 174, 2, 2, 2, 2, 2, 342, 343, 26, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, 339, 339, 339, 339, 339, 344, 339, 345, - 171, 171, 171, 171, 346, 26, 171, 171, 299, 347, 171, 171, 171, 171, 171, 346, + 48, 413, 48, 200, 414, 415, 416, 417, 418, 48, 172, 419, 204, 204, 72, 72, + 48, 48, 48, 48, 48, 48, 48, 71, 420, 270, 270, 421, 271, 271, 271, 422, + 423, 424, 425, 72, 72, 209, 209, 426, 72, 72, 72, 72, 72, 72, 72, 72, + 48, 151, 48, 48, 48, 101, 427, 428, 48, 48, 429, 48, 430, 48, 48, 431, + 48, 432, 48, 48, 433, 434, 72, 72, 9, 9, 435, 11, 11, 48, 48, 48, + 48, 204, 192, 9, 9, 436, 11, 437, 48, 48, 74, 48, 48, 48, 438, 72, + 48, 48, 48, 315, 48, 199, 74, 72, 439, 48, 48, 440, 48, 441, 48, 442, + 48, 200, 443, 72, 72, 72, 48, 444, 48, 445, 48, 446, 72, 72, 72, 72, + 48, 48, 48, 447, 270, 448, 270, 270, 449, 450, 48, 451, 452, 453, 48, 454, + 48, 455, 72, 72, 456, 48, 457, 458, 48, 48, 48, 459, 48, 460, 48, 461, + 48, 462, 463, 72, 72, 72, 72, 72, 48, 48, 48, 48, 196, 72, 72, 72, + 9, 9, 9, 464, 11, 11, 11, 465, 48, 48, 466, 192, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 270, 467, 48, 48, 468, 469, 72, 72, 72, 72, + 48, 455, 470, 48, 62, 471, 72, 72, 72, 72, 72, 48, 472, 72, 48, 315, + 473, 48, 48, 474, 475, 448, 476, 477, 222, 48, 48, 478, 479, 48, 196, 192, + 480, 48, 481, 482, 483, 48, 48, 484, 222, 48, 48, 485, 486, 487, 488, 489, + 48, 98, 490, 491, 72, 72, 72, 72, 492, 493, 494, 48, 48, 495, 496, 192, + 497, 84, 85, 498, 499, 500, 501, 502, 48, 48, 48, 503, 504, 505, 469, 72, + 48, 48, 48, 506, 507, 192, 72, 72, 48, 48, 508, 509, 510, 511, 72, 72, + 48, 48, 48, 512, 513, 192, 514, 72, 48, 48, 515, 516, 192, 72, 72, 72, + 48, 173, 517, 518, 72, 72, 72, 72, 48, 48, 490, 519, 72, 72, 72, 72, + 72, 72, 9, 9, 11, 11, 148, 520, 521, 522, 48, 523, 524, 192, 72, 72, + 72, 72, 525, 48, 48, 526, 527, 72, 528, 48, 48, 529, 530, 531, 48, 48, + 532, 533, 534, 72, 48, 48, 48, 196, 85, 48, 508, 535, 536, 148, 175, 537, + 48, 538, 539, 540, 72, 72, 72, 72, 541, 48, 48, 542, 543, 192, 544, 48, + 545, 546, 192, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 48, 547, + 72, 72, 72, 101, 270, 548, 549, 550, 48, 207, 72, 72, 72, 72, 72, 72, + 271, 271, 271, 271, 271, 271, 551, 552, 48, 48, 48, 48, 388, 72, 72, 72, + 48, 48, 200, 553, 72, 72, 72, 72, 48, 48, 48, 48, 315, 72, 72, 72, + 48, 48, 48, 196, 48, 200, 370, 72, 72, 72, 72, 72, 72, 48, 204, 554, + 48, 48, 48, 555, 556, 557, 558, 559, 48, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 9, 9, 11, 11, 270, 560, 72, 72, 72, 72, 72, 72, + 48, 48, 48, 48, 561, 562, 563, 563, 564, 565, 72, 72, 72, 72, 566, 567, + 48, 48, 48, 48, 48, 48, 48, 74, 48, 48, 48, 48, 48, 199, 72, 72, + 196, 72, 72, 72, 72, 72, 72, 72, 48, 200, 72, 72, 72, 568, 569, 48, + 48, 48, 48, 48, 48, 48, 48, 206, 48, 48, 48, 48, 48, 48, 71, 151, + 196, 570, 571, 72, 72, 72, 72, 72, 209, 209, 209, 209, 209, 209, 209, 325, + 209, 209, 572, 209, 209, 209, 573, 574, 575, 209, 576, 209, 209, 209, 577, 72, + 209, 209, 209, 209, 578, 72, 72, 72, 72, 72, 72, 72, 72, 72, 270, 579, + 209, 209, 209, 209, 209, 286, 270, 452, 9, 580, 11, 581, 582, 583, 242, 9, + 584, 585, 586, 587, 588, 9, 580, 11, 589, 590, 11, 591, 592, 593, 594, 9, + 595, 11, 9, 580, 11, 581, 582, 11, 242, 9, 584, 594, 9, 595, 11, 9, + 580, 11, 596, 9, 597, 598, 599, 600, 11, 601, 9, 602, 603, 604, 605, 11, + 606, 9, 607, 11, 608, 609, 609, 609, 32, 32, 32, 610, 32, 32, 611, 612, + 613, 614, 45, 72, 72, 72, 72, 72, 615, 616, 617, 72, 72, 72, 72, 72, + 48, 48, 151, 618, 619, 72, 72, 72, 72, 72, 72, 72, 48, 48, 620, 621, + 48, 48, 48, 48, 622, 623, 72, 72, 9, 9, 584, 11, 624, 370, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 488, 270, 270, 625, 626, 72, 72, 72, 72, + 488, 270, 627, 628, 72, 72, 72, 72, 629, 48, 630, 631, 632, 633, 634, 635, + 636, 206, 637, 206, 72, 72, 72, 638, 209, 209, 326, 209, 209, 209, 209, 209, + 209, 324, 335, 639, 639, 639, 209, 325, 640, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 641, 72, 72, 72, 642, 209, 643, 209, 209, 326, 577, 644, 325, 72, + 209, 209, 209, 209, 209, 209, 209, 645, 209, 209, 209, 209, 209, 646, 424, 424, + 209, 209, 209, 209, 209, 209, 209, 324, 209, 209, 209, 209, 209, 577, 326, 72, + 326, 209, 209, 209, 646, 176, 209, 209, 646, 209, 641, 644, 72, 72, 72, 72, + 209, 209, 209, 209, 209, 209, 209, 647, 209, 209, 209, 209, 648, 209, 209, 209, + 209, 209, 209, 209, 209, 324, 641, 649, 286, 209, 577, 286, 643, 286, 72, 72, + 209, 650, 209, 209, 287, 72, 72, 192, 48, 48, 48, 48, 48, 204, 72, 72, + 48, 48, 48, 205, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, + 48, 48, 469, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 101, 72, + 48, 204, 72, 72, 72, 72, 72, 72, 48, 48, 48, 48, 71, 72, 72, 72, + 651, 72, 652, 652, 652, 652, 652, 652, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 72, 391, 391, 391, 391, 391, 391, 391, 653, + 391, 391, 391, 391, 391, 391, 391, 654, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, 2, 3, 1, 2, 2, 3, 0, 0, 0, 0, 0, 4, 0, 4, + 2, 2, 5, 2, 2, 2, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, + 0, 0, 0, 0, 7, 8, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 10, 11, 12, 13, 14, 14, 15, 14, 14, 14, + 14, 14, 14, 14, 16, 17, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 19, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 20, 21, + 21, 21, 22, 20, 21, 21, 21, 21, 21, 23, 24, 25, 25, 25, 25, 25, + 25, 26, 25, 25, 25, 27, 28, 26, 29, 30, 31, 32, 31, 31, 31, 31, + 33, 34, 35, 31, 31, 31, 36, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 29, 31, 31, 31, 31, 37, 38, 37, 37, 37, 37, 37, 37, + 37, 39, 31, 31, 31, 31, 31, 31, 40, 40, 40, 40, 40, 40, 41, 26, + 42, 42, 42, 42, 42, 42, 42, 43, 44, 44, 44, 44, 44, 45, 44, 46, + 47, 47, 47, 48, 37, 49, 26, 26, 26, 26, 26, 26, 31, 31, 50, 31, + 31, 26, 51, 31, 52, 31, 31, 31, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 54, 53, 55, 53, 53, 53, 56, 57, 58, 59, 59, 60, 61, 62, + 57, 63, 64, 65, 66, 59, 59, 67, 68, 69, 70, 71, 71, 72, 73, 74, + 69, 75, 76, 77, 78, 71, 79, 26, 80, 81, 82, 83, 83, 84, 85, 86, + 81, 87, 88, 26, 89, 83, 90, 91, 92, 93, 94, 95, 95, 96, 97, 98, + 93, 99, 100, 101, 102, 95, 95, 26, 103, 104, 105, 106, 107, 104, 108, 109, + 104, 105, 110, 26, 111, 108, 108, 112, 113, 114, 115, 113, 113, 115, 113, 116, + 114, 117, 118, 119, 120, 113, 121, 113, 122, 123, 124, 122, 122, 124, 125, 126, + 123, 127, 128, 129, 130, 122, 131, 26, 132, 133, 134, 132, 132, 132, 132, 132, + 133, 134, 135, 132, 136, 132, 132, 132, 137, 138, 139, 140, 138, 138, 141, 142, + 139, 143, 144, 138, 145, 138, 146, 26, 147, 148, 148, 148, 148, 148, 148, 149, + 148, 148, 148, 150, 26, 26, 26, 26, 151, 152, 153, 153, 154, 153, 153, 155, + 156, 155, 153, 157, 26, 26, 26, 26, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 159, 158, 158, 158, 160, 159, 158, 158, 158, 158, 159, 158, 158, 158, 161, + 158, 161, 162, 163, 26, 26, 26, 26, 164, 164, 164, 164, 164, 164, 164, 164, + 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 165, 165, 165, 165, + 166, 167, 165, 165, 165, 165, 165, 168, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 171, 172, 171, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 171, 172, + 171, 170, 172, 170, 170, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 170, + 170, 170, 170, 173, 170, 170, 170, 174, 170, 170, 170, 175, 176, 176, 176, 176, + 176, 176, 176, 176, 176, 176, 177, 177, 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, 179, 179, 179, 180, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 182, 181, 183, 184, 185, 186, 26, 187, 187, 188, 26, + 189, 189, 190, 26, 191, 192, 193, 26, 194, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 195, 194, 196, 194, 196, 197, 198, 199, 200, 199, 199, 199, 199, + 199, 199, 199, 199, 199, 199, 199, 201, 199, 199, 199, 199, 199, 202, 178, 178, + 178, 178, 178, 178, 178, 178, 203, 26, 204, 204, 204, 205, 204, 206, 204, 206, + 207, 204, 208, 208, 208, 209, 210, 26, 211, 211, 211, 211, 211, 212, 211, 211, + 211, 213, 211, 214, 194, 194, 194, 194, 215, 215, 215, 216, 217, 217, 217, 217, + 217, 217, 217, 218, 217, 217, 217, 219, 217, 220, 217, 220, 217, 221, 9, 9, + 222, 26, 26, 26, 26, 26, 26, 26, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 224, 223, 223, 223, 223, 223, 225, 226, 226, 226, 226, 226, 226, 226, 226, + 227, 227, 227, 227, 227, 227, 228, 229, 230, 230, 230, 230, 230, 230, 230, 231, + 230, 232, 233, 233, 233, 233, 233, 233, 18, 234, 165, 165, 165, 165, 165, 235, + 226, 26, 236, 9, 237, 238, 239, 240, 2, 2, 2, 2, 241, 242, 2, 2, + 2, 2, 2, 243, 244, 245, 2, 246, 2, 2, 2, 2, 2, 2, 2, 247, + 9, 9, 9, 9, 9, 9, 9, 248, 14, 14, 249, 249, 14, 14, 14, 14, + 249, 249, 14, 250, 14, 14, 14, 249, 14, 14, 14, 14, 14, 14, 251, 14, + 251, 14, 252, 253, 14, 14, 254, 255, 0, 256, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 257, 0, 258, 259, 0, 260, 2, 261, 0, 0, 0, 0, + 26, 26, 9, 9, 9, 9, 222, 26, 0, 0, 0, 0, 262, 263, 4, 0, + 0, 264, 0, 0, 2, 2, 2, 2, 2, 265, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 260, 26, 26, 26, + 0, 266, 26, 26, 0, 0, 0, 0, 267, 267, 267, 267, 267, 267, 267, 267, + 267, 267, 267, 267, 267, 267, 267, 267, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 268, 0, 0, 0, 269, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 270, 270, 270, 270, 270, 271, 270, 270, + 270, 270, 270, 271, 2, 2, 2, 2, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 272, 273, 165, 165, 165, 165, 166, 167, 274, 274, + 274, 274, 274, 274, 274, 275, 276, 275, 170, 170, 172, 26, 172, 172, 172, 172, + 172, 172, 172, 172, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 266, 26, 26, 26, 26, 26, 277, 277, 277, 278, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 279, 26, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 280, 26, 26, 26, 0, 281, 282, 0, 0, 0, 283, 284, 0, 285, + 286, 287, 287, 287, 287, 287, 287, 287, 287, 287, 288, 289, 290, 291, 291, 291, + 291, 291, 291, 291, 291, 291, 291, 292, 293, 294, 294, 294, 294, 294, 295, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 296, 0, 0, 294, 294, 294, 294, + 0, 0, 0, 0, 281, 26, 291, 291, 169, 169, 169, 296, 0, 0, 0, 0, + 0, 0, 0, 0, 169, 169, 169, 297, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 291, 291, 291, 291, 291, 298, 291, 291, 291, 291, 291, 291, 291, 291, + 291, 291, 291, 0, 0, 0, 0, 0, 277, 277, 277, 277, 277, 277, 277, 277, + 0, 0, 0, 0, 0, 0, 0, 0, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 299, 300, 300, 300, 300, 300, 300, 300, 300, + 300, 300, 300, 300, 300, 300, 300, 300, 300, 301, 300, 300, 300, 300, 300, 300, + 302, 26, 303, 303, 303, 303, 303, 303, 304, 304, 304, 304, 304, 304, 304, 304, + 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 305, 26, 26, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 26, 0, 0, 0, 0, 307, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 308, 2, 2, 2, 2, 2, 2, + 309, 310, 26, 26, 26, 26, 311, 2, 312, 312, 312, 312, 312, 313, 0, 314, + 315, 315, 315, 315, 315, 315, 315, 26, 316, 316, 316, 316, 316, 316, 316, 316, + 317, 318, 316, 319, 53, 53, 53, 53, 320, 320, 320, 320, 320, 321, 322, 322, + 322, 322, 323, 324, 169, 169, 169, 325, 326, 326, 326, 326, 326, 326, 326, 326, + 326, 327, 326, 328, 164, 164, 164, 329, 330, 330, 330, 330, 330, 330, 331, 26, + 330, 332, 330, 333, 164, 164, 164, 164, 334, 334, 334, 334, 334, 334, 334, 334, + 335, 26, 26, 336, 337, 337, 338, 26, 339, 339, 339, 26, 172, 172, 2, 2, + 2, 2, 2, 340, 341, 342, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, + 337, 337, 337, 337, 337, 343, 337, 344, 169, 169, 169, 169, 345, 26, 169, 169, + 296, 346, 169, 169, 169, 169, 169, 345, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 280, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 347, 26, 26, 26, 26, 348, 26, 349, 350, 25, 25, 351, 352, + 353, 25, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 354, 26, 51, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 355, + 26, 26, 31, 31, 31, 31, 31, 31, 31, 31, 356, 31, 31, 31, 31, 31, + 31, 26, 26, 26, 26, 26, 31, 357, 9, 9, 0, 314, 9, 358, 0, 0, + 0, 0, 359, 0, 260, 281, 50, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 360, 361, 0, 0, 0, 1, 2, 2, 3, + 1, 2, 2, 3, 362, 291, 290, 291, 291, 291, 291, 363, 169, 169, 169, 296, + 364, 364, 364, 365, 260, 260, 26, 366, 367, 368, 367, 367, 369, 367, 367, 370, + 367, 371, 367, 371, 26, 26, 26, 26, 367, 367, 367, 367, 367, 367, 367, 367, + 367, 367, 367, 367, 367, 367, 367, 372, 373, 0, 0, 0, 0, 0, 374, 0, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 255, 0, 375, 376, 26, 26, 26, + 26, 26, 0, 0, 0, 0, 0, 377, 378, 378, 378, 379, 380, 380, 380, 380, + 380, 380, 381, 26, 382, 0, 0, 281, 383, 383, 383, 383, 384, 385, 386, 386, + 386, 387, 388, 388, 388, 388, 388, 389, 390, 390, 390, 391, 392, 392, 392, 392, + 393, 392, 394, 26, 26, 26, 26, 26, 395, 395, 395, 395, 395, 395, 395, 395, + 395, 395, 396, 396, 396, 396, 396, 396, 397, 397, 397, 398, 397, 399, 400, 400, + 400, 400, 401, 400, 400, 400, 400, 401, 402, 402, 402, 402, 402, 26, 403, 403, + 403, 403, 403, 403, 404, 405, 26, 26, 406, 406, 406, 406, 406, 406, 406, 406, + 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 407, 26, + 406, 406, 408, 26, 406, 26, 26, 26, 409, 410, 411, 411, 411, 411, 412, 413, + 414, 414, 415, 414, 416, 416, 416, 416, 417, 417, 417, 418, 419, 417, 26, 26, + 26, 26, 26, 26, 420, 420, 421, 422, 423, 423, 423, 424, 425, 425, 425, 426, + 26, 26, 26, 26, 26, 26, 26, 26, 427, 427, 427, 427, 428, 428, 428, 429, + 428, 428, 430, 428, 428, 428, 428, 428, 431, 432, 433, 434, 435, 435, 436, 437, + 435, 438, 435, 438, 439, 439, 439, 439, 440, 440, 440, 440, 26, 26, 26, 26, + 441, 441, 441, 441, 442, 443, 442, 26, 444, 444, 444, 444, 444, 444, 445, 446, + 447, 447, 448, 447, 449, 449, 450, 449, 451, 451, 452, 453, 26, 454, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 455, 455, 455, 455, 455, 455, 455, 455, + 455, 456, 26, 26, 26, 26, 26, 26, 457, 457, 457, 457, 457, 457, 458, 26, + 457, 457, 457, 457, 457, 457, 458, 459, 460, 460, 460, 460, 460, 26, 460, 461, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 31, 31, 31, 462, 463, 463, 463, 463, 463, 464, 465, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 466, 466, 466, 466, 466, 26, 467, 467, + 467, 467, 467, 468, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 469, 469, + 469, 470, 26, 26, 471, 471, 472, 26, 473, 473, 473, 473, 473, 473, 473, 473, + 473, 474, 475, 473, 473, 473, 26, 476, 477, 477, 477, 477, 477, 477, 477, 477, + 478, 479, 480, 480, 480, 481, 480, 482, 483, 483, 483, 483, 483, 483, 484, 483, + 483, 26, 485, 485, 485, 485, 486, 26, 487, 487, 487, 487, 487, 487, 487, 487, + 487, 487, 487, 487, 488, 138, 489, 26, 490, 490, 491, 490, 490, 490, 490, 492, + 26, 26, 26, 26, 26, 26, 26, 26, 493, 494, 495, 496, 495, 497, 498, 498, + 498, 498, 498, 498, 498, 499, 498, 500, 501, 502, 503, 504, 504, 505, 506, 507, + 502, 508, 509, 510, 511, 512, 512, 26, 513, 513, 513, 513, 513, 513, 513, 513, + 513, 513, 513, 514, 515, 26, 26, 26, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 26, 516, 517, 26, 26, 26, 26, 518, 518, 518, 518, 518, 518, 519, 518, + 518, 518, 518, 519, 26, 26, 26, 26, 520, 520, 520, 520, 520, 520, 520, 520, + 521, 26, 520, 522, 199, 523, 26, 26, 524, 524, 524, 524, 524, 524, 524, 525, + 524, 526, 26, 26, 26, 26, 26, 26, 527, 527, 527, 528, 527, 529, 527, 527, + 26, 26, 26, 26, 26, 26, 26, 26, 530, 530, 530, 530, 530, 530, 530, 531, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 532, 532, 532, 532, + 532, 532, 532, 532, 532, 532, 533, 534, 535, 536, 537, 538, 538, 538, 539, 540, + 535, 26, 538, 541, 26, 26, 26, 26, 26, 26, 26, 26, 542, 543, 542, 542, + 542, 542, 542, 543, 544, 26, 26, 26, 545, 545, 545, 545, 545, 545, 545, 545, + 545, 26, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 547, 26, 26, 26, + 548, 548, 548, 548, 548, 548, 548, 549, 550, 551, 550, 550, 550, 550, 552, 550, + 553, 26, 550, 550, 550, 554, 555, 555, 555, 555, 556, 555, 555, 557, 558, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 559, 560, 561, 561, 561, 561, 559, 562, + 561, 26, 561, 563, 564, 565, 566, 566, 566, 567, 568, 569, 566, 570, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 571, 571, 571, 572, 26, 26, 26, 26, 26, 26, 573, 26, + 108, 108, 108, 108, 108, 108, 574, 575, 576, 576, 576, 576, 576, 576, 576, 576, + 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 577, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 576, 576, 576, 576, 576, 576, 576, 576, + 576, 576, 576, 576, 576, 578, 579, 26, 576, 576, 576, 576, 576, 576, 576, 576, + 580, 26, 26, 26, 26, 26, 26, 26, 581, 581, 581, 581, 581, 581, 581, 581, + 581, 581, 581, 581, 581, 581, 581, 581, 581, 581, 581, 581, 581, 582, 581, 583, + 26, 26, 26, 26, 26, 26, 26, 26, 584, 584, 584, 584, 584, 584, 584, 584, + 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, + 585, 26, 26, 26, 26, 26, 26, 26, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 586, + 587, 587, 587, 588, 587, 589, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 590, 590, 590, 591, 591, 26, 592, 592, 592, 592, 592, 592, 592, 592, + 593, 26, 592, 594, 594, 592, 592, 595, 592, 592, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 283, 280, 280, - 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 348, 26, 26, 26, 26, - 349, 26, 350, 351, 25, 25, 352, 353, 354, 25, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 355, 26, 52, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 356, 26, 26, 31, 31, 31, 31, 31, 31, - 31, 31, 357, 31, 31, 31, 31, 31, 31, 26, 26, 26, 26, 26, 31, 51, - 9, 9, 0, 316, 9, 358, 0, 0, 0, 0, 359, 0, 262, 284, 50, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 360, - 361, 0, 0, 0, 1, 2, 2, 3, 1, 2, 2, 3, 362, 294, 293, 294, - 294, 294, 294, 363, 171, 171, 171, 299, 364, 364, 364, 365, 262, 262, 26, 366, - 367, 368, 367, 367, 369, 367, 367, 370, 367, 371, 367, 371, 26, 26, 26, 26, - 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 372, - 373, 0, 0, 0, 0, 0, 374, 0, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 257, 0, 284, 375, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 376, - 377, 377, 377, 378, 379, 379, 379, 379, 379, 379, 380, 26, 381, 0, 0, 284, - 382, 382, 382, 382, 383, 384, 385, 385, 385, 386, 387, 387, 387, 387, 387, 388, - 389, 389, 389, 390, 391, 391, 391, 391, 392, 391, 393, 26, 26, 26, 26, 26, - 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 395, 395, 395, 395, 395, 395, - 396, 396, 396, 397, 396, 398, 399, 399, 399, 399, 400, 399, 399, 399, 399, 400, - 401, 401, 401, 401, 401, 26, 402, 402, 402, 402, 402, 402, 403, 404, 26, 26, - 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, - 405, 405, 405, 405, 405, 405, 406, 26, 405, 405, 407, 26, 405, 26, 26, 26, - 408, 409, 410, 410, 410, 410, 411, 412, 413, 413, 414, 413, 415, 415, 415, 415, - 416, 416, 416, 417, 418, 416, 26, 26, 26, 26, 26, 26, 419, 419, 420, 421, - 422, 422, 422, 423, 424, 424, 424, 425, 26, 26, 26, 26, 26, 26, 26, 26, - 426, 426, 426, 426, 427, 427, 427, 428, 427, 427, 429, 427, 427, 427, 427, 427, - 430, 431, 432, 433, 434, 434, 435, 436, 434, 437, 434, 437, 438, 438, 438, 438, - 439, 439, 439, 439, 26, 26, 26, 26, 440, 440, 440, 440, 441, 442, 441, 26, - 443, 443, 443, 443, 443, 443, 444, 445, 446, 446, 447, 446, 448, 448, 449, 448, - 450, 450, 451, 452, 26, 453, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 454, 454, 454, 454, 454, 454, 454, 454, 454, 455, 26, 26, 26, 26, 26, 26, - 456, 456, 456, 456, 456, 456, 457, 26, 456, 456, 456, 456, 456, 456, 457, 458, - 459, 459, 459, 459, 459, 26, 459, 460, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 31, 31, 31, 461, - 462, 462, 462, 462, 462, 26, 463, 463, 463, 463, 463, 464, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 465, 465, 466, 26, - 467, 467, 467, 467, 467, 467, 467, 467, 467, 468, 469, 467, 467, 467, 26, 470, - 471, 471, 471, 471, 471, 471, 471, 471, 472, 473, 474, 474, 474, 475, 474, 476, - 477, 477, 477, 477, 477, 477, 478, 477, 479, 26, 480, 480, 480, 480, 481, 26, - 482, 482, 482, 482, 482, 482, 482, 482, 482, 483, 482, 482, 484, 140, 485, 26, - 486, 486, 487, 486, 486, 486, 486, 488, 26, 26, 26, 26, 26, 26, 26, 26, - 489, 490, 491, 492, 491, 493, 494, 494, 494, 494, 494, 494, 494, 495, 494, 496, - 497, 498, 499, 500, 500, 501, 502, 503, 498, 504, 505, 506, 507, 508, 508, 26, - 509, 509, 509, 509, 509, 509, 509, 509, 509, 509, 509, 510, 26, 26, 26, 26, - 511, 511, 511, 511, 511, 511, 511, 511, 511, 26, 511, 512, 26, 26, 26, 26, - 513, 513, 513, 513, 513, 513, 514, 513, 513, 513, 513, 514, 26, 26, 26, 26, - 515, 515, 515, 515, 515, 515, 515, 515, 516, 26, 515, 517, 201, 518, 26, 26, - 519, 519, 519, 519, 519, 519, 519, 520, 519, 521, 26, 26, 26, 26, 26, 26, - 522, 522, 522, 523, 522, 524, 522, 522, 26, 26, 26, 26, 26, 26, 26, 26, - 525, 525, 525, 525, 525, 525, 525, 526, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 528, 529, - 26, 26, 26, 26, 530, 531, 530, 530, 530, 530, 530, 531, 532, 26, 26, 26, - 533, 533, 533, 533, 533, 533, 533, 533, 533, 26, 534, 534, 534, 534, 534, 534, - 534, 534, 534, 534, 535, 26, 26, 26, 536, 536, 536, 536, 536, 536, 536, 537, - 538, 539, 538, 538, 538, 538, 540, 538, 541, 26, 538, 538, 538, 542, 543, 543, - 543, 543, 544, 543, 543, 545, 546, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 547, 548, 549, 549, 549, 549, 547, 550, 549, 26, 549, 551, 552, 553, 554, 554, - 554, 555, 556, 557, 554, 558, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 559, 559, 559, 560, - 26, 26, 26, 26, 26, 26, 26, 26, 109, 109, 109, 109, 109, 109, 561, 562, - 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, - 563, 563, 563, 564, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, 565, 566, 26, - 563, 563, 563, 563, 563, 563, 563, 563, 567, 26, 26, 26, 26, 26, 26, 26, - 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, - 568, 568, 568, 568, 568, 569, 568, 570, 26, 26, 26, 26, 26, 26, 26, 26, - 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, - 571, 571, 571, 571, 571, 571, 571, 571, 572, 26, 26, 26, 26, 26, 26, 26, - 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, - 309, 309, 309, 309, 309, 309, 309, 573, 574, 574, 574, 575, 574, 576, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 577, 577, 577, 578, 578, 26, - 579, 579, 579, 579, 579, 579, 579, 579, 580, 26, 579, 581, 581, 579, 579, 582, - 579, 579, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 583, 583, 583, 583, 583, 583, 583, 583, - 583, 583, 583, 584, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 585, 585, 585, 585, 585, 585, 585, 585, 585, 586, 585, 585, 585, 585, 585, 585, - 585, 587, 585, 585, 26, 26, 26, 26, 26, 26, 26, 26, 588, 26, 26, 26, - 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, - 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 26, - 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 590, 26, - 591, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, - 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, - 290, 290, 290, 291, 26, 26, 26, 26, 26, 26, 592, 26, 593, 26, 594, 594, - 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, - 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 595, - 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 597, 596, 598, - 596, 599, 596, 600, 284, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 272, 26, - 0, 0, 0, 0, 262, 361, 0, 0, 0, 0, 0, 0, 601, 602, 0, 603, - 604, 605, 0, 0, 0, 606, 0, 0, 0, 0, 0, 0, 0, 607, 26, 26, - 14, 14, 14, 14, 14, 14, 14, 14, 251, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 284, 26, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, 26, 0, 0, 0, 607, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, 0, - 0, 0, 0, 259, 608, 609, 0, 610, 611, 0, 0, 0, 0, 0, 0, 0, - 612, 613, 259, 259, 0, 0, 0, 614, 615, 616, 617, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 271, 0, 0, 0, 0, 0, 0, - 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, - 618, 619, 26, 620, 621, 618, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 274, 273, 273, 622, 623, 624, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 625, 625, 625, 625, 625, 626, 625, 627, 625, 628, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 629, 629, 629, 629, 629, 629, 629, 630, - 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, - 631, 631, 631, 631, 631, 631, 631, 631, 632, 631, 633, 26, 26, 26, 26, 26, - 634, 634, 634, 634, 634, 634, 634, 634, 634, 635, 634, 636, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 361, 0, - 0, 0, 0, 0, 0, 0, 637, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 361, 0, 0, 0, 0, 0, 0, 272, 26, 26, 26, 26, 26, 26, 26, 26, - 638, 31, 31, 31, 639, 640, 641, 642, 643, 644, 639, 645, 639, 641, 641, 646, - 31, 647, 31, 648, 649, 647, 31, 648, 26, 26, 26, 26, 26, 26, 355, 26, - 0, 0, 0, 0, 0, 284, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 284, 26, 0, 262, 361, 0, 361, 0, 361, 0, 0, 0, 272, 26, - 0, 637, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 637, 0, 0, - 0, 0, 0, 0, 0, 637, 26, 26, 26, 26, 26, 26, 650, 0, 0, 0, - 651, 26, 0, 0, 0, 0, 0, 284, 0, 607, 316, 26, 272, 26, 26, 26, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 272, 26, 0, 637, 0, 269, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 284, 26, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 607, 0, 284, 26, 26, - 0, 284, 0, 0, 0, 0, 0, 0, 0, 26, 0, 316, 0, 0, 0, 0, - 0, 26, 0, 0, 0, 272, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 0, 611, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 614, 616, - 0, 0, 0, 0, 613, 652, 0, 0, 0, 613, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 284, 26, 0, 272, 284, 269, - 269, 26, 272, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 653, 26, 26, 26, 26, 26, - 280, 280, 280, 280, 280, 280, 654, 26, 280, 280, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 283, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 280, 348, 26, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 655, 26, 26, 26, - 280, 280, 280, 283, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 656, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 597, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 598, 598, 598, 598, 598, 598, 598, 600, 598, 598, 26, 26, 26, 26, + 26, 26, 26, 26, 601, 26, 347, 26, 602, 602, 602, 602, 602, 602, 602, 602, + 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, + 602, 602, 602, 602, 602, 602, 602, 26, 603, 603, 603, 603, 603, 603, 603, 603, + 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, + 603, 603, 604, 26, 26, 26, 26, 26, 602, 605, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 606, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 288, 26, 26, 26, 26, + 26, 26, 607, 26, 608, 26, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, + 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, + 609, 609, 609, 609, 609, 609, 609, 610, 611, 611, 611, 611, 611, 611, 611, 611, + 611, 611, 611, 611, 611, 612, 611, 613, 611, 614, 611, 615, 281, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 616, 26, 0, 0, 0, 0, 260, 361, 0, 0, + 0, 0, 0, 0, 617, 618, 0, 619, 620, 621, 0, 0, 0, 622, 0, 0, + 0, 0, 0, 0, 0, 623, 26, 26, 14, 14, 14, 14, 14, 14, 14, 14, + 249, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 0, 0, 281, 26, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 260, 26, 0, 0, 0, 623, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 257, 0, 0, 0, 0, 0, 0, 0, 0, 257, 624, 625, 0, 626, + 627, 0, 0, 0, 0, 0, 0, 0, 269, 628, 257, 257, 0, 0, 0, 629, + 630, 631, 632, 0, 0, 0, 0, 0, 0, 0, 0, 0, 616, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 268, 0, 0, 0, 0, 0, 0, 633, 633, 633, 633, 633, 633, 633, 633, + 633, 633, 633, 633, 633, 633, 633, 633, 633, 634, 26, 635, 636, 633, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 271, 270, 270, 637, 638, 639, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 640, 640, 640, 640, 640, 641, 640, 642, + 640, 643, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 644, 644, 644, 644, 644, 644, 644, 645, 646, 646, 646, 646, 646, 646, 646, 646, + 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, + 647, 646, 648, 26, 26, 26, 26, 26, 649, 649, 649, 649, 649, 649, 649, 649, + 649, 650, 649, 651, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 361, 0, 0, 0, 0, 0, 0, 0, 375, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 361, 0, 0, 0, 0, 0, 0, 616, + 26, 26, 26, 26, 26, 26, 26, 26, 652, 31, 31, 31, 653, 654, 655, 656, + 657, 658, 653, 659, 653, 655, 655, 660, 31, 661, 31, 662, 663, 661, 31, 662, + 26, 26, 26, 26, 26, 26, 354, 26, 0, 0, 0, 0, 0, 281, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 281, 26, 0, 260, 361, 0, + 361, 0, 361, 0, 0, 0, 616, 26, 0, 0, 0, 0, 0, 616, 26, 26, + 26, 26, 26, 26, 664, 0, 0, 0, 665, 26, 0, 0, 0, 0, 0, 281, + 0, 623, 314, 26, 616, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 26, 0, 375, 0, 375, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 281, 26, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 623, 0, 281, 26, 26, 0, 281, 0, 0, 0, 0, 0, 0, + 0, 26, 0, 314, 0, 0, 0, 0, 0, 26, 0, 0, 0, 616, 314, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 632, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 627, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 281, 26, 0, 616, 375, 266, 260, 26, 0, 0, 0, 623, 260, 26, + 266, 26, 260, 26, 26, 26, 26, 26, 0, 0, 359, 0, 0, 0, 0, 0, + 0, 266, 26, 26, 26, 26, 0, 314, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 280, 26, 26, 26, 26, 277, 277, 277, 277, 277, 277, 299, 26, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 347, 26, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 666, 26, 26, 26, 277, 277, 277, 280, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 667, 26, 26, 26, 26, 26, 26, 668, 26, 26, 26, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962, + 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0, + 0,1080,1081,1082,1086,1110, 0, 0,1124,1125,1126,1127,1131,1133, 0,1147, + 1154,1155,1156,1161,1187,1188,1189,1193, 0,1219,1226,1227,1228,1229,1233, 0, + 0,1267,1268,1269,1273,1298, 0,1303, 943,1128, 944,1129, 954,1139, 958,1143, + 959,1144, 960,1145, 961,1146, 964,1149, 0, 0, 973,1158, 974,1159, 975,1160, + 983,1168, 978,1163, 988,1173, 990,1175, 991,1176, 993,1178, 994,1179, 0, 0, + 1004,1190,1005,1191,1006,1192,1014,1199,1007, 0, 0, 0,1016,1201,1020,1206, + 0,1022,1208,1025,1211,1023,1209, 0, 0, 0, 0,1032,1218,1037,1223,1035, + 1221, 0, 0, 0,1044,1230,1045,1231,1049,1235, 0, 0,1058,1244,1064,1250, + 1060,1246,1066,1252,1067,1253,1072,1258,1069,1255,1077,1264,1074,1261, 0, 0, + 1083,1270,1084,1271,1085,1272,1088,1275,1089,1276,1096,1283,1103,1290,1111,1299, + 1115,1118,1307,1120,1309,1121,1310, 0,1053,1239, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,1093,1280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976,1001,1002,1003,1008, - 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082,1086,1110, 0, 0, - 1124,1125,1126,1127,1131,1133, 0,1147,1154,1155,1156,1161,1187,1188,1189,1193, - 0,1219,1226,1227,1228,1229,1233, 0, 0,1267,1268,1269,1273,1298, 0,1303, - 943,1128, 944,1129, 954,1139, 958,1143, 959,1144, 960,1145, 961,1146, 964,1149, - 0, 0, 973,1158, 974,1159, 975,1160, 983,1168, 978,1163, 988,1173, 990,1175, - 991,1176, 993,1178, 994,1179, 0, 0,1004,1190,1005,1191,1006,1192,1014,1199, - 1007, 0, 0, 0,1016,1201,1020,1206, 0,1022,1208,1025,1211,1023,1209, 0, - 0, 0, 0,1032,1218,1037,1223,1035,1221, 0, 0, 0,1044,1230,1045,1231, - 1049,1235, 0, 0,1058,1244,1064,1250,1060,1246,1066,1252,1067,1253,1072,1258, - 1069,1255,1077,1264,1074,1261, 0, 0,1083,1270,1084,1271,1085,1272,1088,1275, - 1089,1276,1096,1283,1103,1290,1111,1299,1115,1118,1307,1120,1309,1121,1310, 0, - 1053,1239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1093, - 1280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 949,1134,1010, - 1195,1050,1236,1090,1277,1341,1368,1340,1367,1342,1369,1339,1366, 0,1320,1347, - 1418,1419,1323,1350, 0, 0, 992,1177,1018,1204,1055,1241,1416,1417,1415,1424, - 1202, 0, 0, 0, 987,1172, 0, 0,1031,1217,1321,1348,1322,1349,1338,1365, - 950,1135, 951,1136, 979,1164, 980,1165,1011,1196,1012,1197,1051,1237,1052,1238, - 1061,1247,1062,1248,1091,1278,1092,1279,1071,1257,1076,1263, 0, 0, 997,1182, - 0, 0, 0, 0, 0, 0, 945,1130, 982,1167,1337,1364,1335,1362,1046,1232, - 1422,1423,1113,1301, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 8, 9, 0, 10,1425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0,1314,1427, 5,1434,1438,1443, 0,1450, 0,1455,1461, - 1514, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1446,1458,1468,1476,1480,1486, - 1517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1489,1503,1494,1500,1508, 0, - 0, 0, 0,1520,1521, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1526,1528, 0,1525, 0, 0, 0,1522, 0, 0, 0, 0,1536,1532,1539, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1534, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1556, 0, 0, 0, 0, 0, 0, - 1548,1550, 0,1547, 0, 0, 0,1567, 0, 0, 0, 0,1558,1554,1561, 0, - 0, 0, 0, 0, 0, 0,1568,1569, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1529,1551, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1523,1545,1524,1546, 0, 0,1527,1549, 0, 0,1570,1571,1530,1552,1531,1553, - 0, 0,1533,1555,1535,1557,1537,1559, 0, 0,1572,1573,1544,1566,1538,1560, - 1540,1562,1541,1563,1542,1564, 0, 0,1543,1565, 0, 0, 0, 0, 0, 0, - 0, 0,1606,1607,1609,1608,1610, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1613, 0,1611, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1620, 0, 0, 0, 0, 0, 0, - 0,1623, 0, 0,1624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1614,1615,1616,1617,1618,1619,1621,1622, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1628,1629, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1625,1626, 0,1627, - 0, 0, 0,1634, 0, 0,1635, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1630,1631,1632, 0, 0,1633, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1639, 0, 0,1638,1640, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1636,1637, 0, 0, - 0, 0, 0, 0,1641, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1642,1644,1643, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1645, 0, 0, 0, 0, 0, 0, 0, - 1646, 0, 0, 0, 0, 0, 0,1648,1649, 0,1647,1650, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1651,1653,1652, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1654, 0,1655,1657,1656, 0, - 0, 0, 0,1659, 0, 0, 0, 0, 0, 0, 0, 0, 0,1660, 0, 0, - 0, 0,1661, 0, 0, 0, 0,1662, 0, 0, 0, 0,1663, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1658, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1664, 0,1665,1673, 0,1674, 0, 0, 0, 0, 0, 0, 0, - 0,1666, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1668, 0, 0, 0, 0, 0, 0, 0, 0, 0,1669, 0, 0, - 0, 0,1670, 0, 0, 0, 0,1671, 0, 0, 0, 0,1672, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1667, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1675, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1676, 0,1677, 0,1678, 0,1679, 0,1680, 0, - 0, 0,1681, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1682, 0,1683, 0, 0, - 1684,1685, 0,1686, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 953,1138, 955,1140, 956,1141, 957,1142,1324,1351, 963,1148, 965,1150, 968,1153, - 966,1151, 967,1152,1378,1380,1379,1381, 984,1169, 985,1170,1420,1421, 986,1171, - 989,1174, 995,1180, 998,1183, 996,1181, 999,1184,1000,1185,1015,1200,1329,1356, - 1017,1203,1019,1205,1021,1207,1024,1210,1687,1688,1027,1213,1026,1212,1028,1214, - 1029,1215,1030,1216,1034,1220,1036,1222,1039,1225,1038,1224,1334,1361,1336,1363, - 1382,1384,1383,1385,1056,1242,1057,1243,1059,1245,1063,1249,1689,1690,1065,1251, - 1068,1254,1070,1256,1386,1387,1388,1389,1691,1692,1073,1259,1075,1262,1079,1266, - 1078,1265,1095,1282,1098,1285,1097,1284,1390,1391,1392,1393,1099,1286,1100,1287, - 1101,1288,1102,1289,1105,1292,1104,1291,1106,1294,1107,1295,1108,1296,1114,1302, - 1119,1308,1122,1311,1123,1312,1186,1260,1293,1305, 0,1394, 0, 0, 0, 0, - 952,1137, 947,1132,1317,1344,1316,1343,1319,1346,1318,1345,1693,1695,1371,1375, - 1370,1374,1373,1377,1372,1376,1694,1696, 981,1166, 977,1162, 972,1157,1326,1353, - 1325,1352,1328,1355,1327,1354,1697,1698,1009,1194,1013,1198,1054,1240,1048,1234, - 1331,1358,1330,1357,1333,1360,1332,1359,1699,1700,1396,1401,1395,1400,1398,1403, - 1397,1402,1399,1404,1094,1281,1087,1274,1406,1411,1405,1410,1408,1413,1407,1412, - 1409,1414,1109,1297,1117,1306,1116,1304,1112,1300, 0, 0, 0, 0, 0, 0, - 1471,1472,1701,1705,1702,1706,1703,1707,1430,1431,1715,1719,1716,1720,1717,1721, - 1477,1478,1729,1731,1730,1732, 0, 0,1435,1436,1733,1735,1734,1736, 0, 0, - 1481,1482,1737,1741,1738,1742,1739,1743,1439,1440,1751,1755,1752,1756,1753,1757, - 1490,1491,1765,1768,1766,1769,1767,1770,1447,1448,1771,1774,1772,1775,1773,1776, - 1495,1496,1777,1779,1778,1780, 0, 0,1451,1452,1781,1783,1782,1784, 0, 0, - 1504,1505,1785,1788,1786,1789,1787,1790, 0,1459, 0,1791, 0,1792, 0,1793, - 1509,1510,1794,1798,1795,1799,1796,1800,1462,1463,1808,1812,1809,1813,1810,1814, - 1467, 21,1475, 22,1479, 23,1485, 24,1493, 27,1499, 28,1507, 29, 0, 0, - 1704,1708,1709,1710,1711,1712,1713,1714,1718,1722,1723,1724,1725,1726,1727,1728, - 1740,1744,1745,1746,1747,1748,1749,1750,1754,1758,1759,1760,1761,1762,1763,1764, - 1797,1801,1802,1803,1804,1805,1806,1807,1811,1815,1816,1817,1818,1819,1820,1821, - 1470,1469,1822,1474,1465, 0,1473,1825,1429,1428,1426, 12,1432, 0, 26, 0, - 0,1315,1823,1484,1466, 0,1483,1829,1433, 13,1437, 14,1441,1826,1827,1828, - 1488,1487,1513, 19, 0, 0,1492,1515,1445,1444,1442, 15, 0,1831,1832,1833, - 1502,1501,1516, 25,1497,1498,1506,1518,1457,1456,1454, 17,1453,1313, 11, 3, - 0, 0,1824,1512,1519, 0,1511,1830,1449, 16,1460, 18,1464, 4, 0, 0, - 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 2, 6, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1834,1835, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1836, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1837,1839,1838, - 0, 0, 0, 0,1840, 0, 0, 0, 0,1841, 0, 0,1842, 0, 0, 0, - 0, 0, 0, 0,1843, 0,1844, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1845, 0, 0,1846, 0, 0,1847, 0,1848, 0, 0, 0, 0, 0, 0, - 937, 0,1850, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1849, 936, 938, - 1851,1852, 0, 0,1853,1854, 0, 0,1855,1856, 0, 0, 0, 0, 0, 0, - 1857,1858, 0, 0,1861,1862, 0, 0,1863,1864, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1867,1868,1869,1870, - 1859,1860,1865,1866, 0, 0, 0, 0, 0, 0,1871,1872,1873,1874, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 33, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1875, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1877, 0,1878, 0, - 1879, 0,1880, 0,1881, 0,1882, 0,1883, 0,1884, 0,1885, 0,1886, 0, - 1887, 0,1888, 0, 0,1889, 0,1890, 0,1891, 0, 0, 0, 0, 0, 0, - 1892,1893, 0,1894,1895, 0,1896,1897, 0,1898,1899, 0,1900,1901, 0, 0, - 0, 0, 0, 0,1876, 0, 0, 0, 0, 0, 0, 0, 0, 0,1902, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1904, 0,1905, 0, - 1906, 0,1907, 0,1908, 0,1909, 0,1910, 0,1911, 0,1912, 0,1913, 0, - 1914, 0,1915, 0, 0,1916, 0,1917, 0,1918, 0, 0, 0, 0, 0, 0, - 1919,1920, 0,1921,1922, 0,1923,1924, 0,1925,1926, 0,1927,1928, 0, 0, - 0, 0, 0, 0,1903, 0, 0,1929,1930,1931,1932, 0, 0, 0,1933, 0, - 710, 385, 724, 715, 455, 103, 186, 825, 825, 242, 751, 205, 241, 336, 524, 601, - 663, 676, 688, 738, 411, 434, 474, 500, 649, 746, 799, 108, 180, 416, 482, 662, - 810, 275, 462, 658, 692, 344, 618, 679, 293, 388, 440, 492, 740, 116, 146, 168, - 368, 414, 481, 527, 606, 660, 665, 722, 781, 803, 809, 538, 553, 588, 642, 758, - 811, 701, 233, 299, 573, 612, 487, 540, 714, 779, 232, 267, 412, 445, 457, 585, - 594, 766, 167, 613, 149, 148, 560, 589, 648, 768, 708, 345, 411, 704, 105, 259, - 313, 496, 518, 174, 542, 120, 307, 101, 430, 372, 584, 183, 228, 529, 650, 697, - 424, 732, 428, 349, 632, 355, 517, 110, 135, 147, 403, 580, 624, 700, 750, 170, - 193, 245, 297, 374, 463, 543, 763, 801, 812, 815, 162, 384, 420, 730, 287, 330, - 337, 366, 459, 476, 509, 558, 591, 610, 726, 652, 734, 759, 154, 163, 198, 473, - 683, 697, 292, 311, 353, 423, 572, 494, 113, 217, 259, 280, 314, 499, 506, 603, - 608, 752, 778, 782, 788, 117, 557, 748, 774, 320, 109, 126, 260, 265, 373, 411, - 479, 523, 655, 737, 823, 380, 765, 161, 395, 398, 438, 451, 502, 516, 537, 583, - 791, 136, 340, 769, 122, 273, 446, 727, 305, 322, 400, 496, 771, 155, 190, 269, - 377, 391, 406, 432, 501, 519, 599, 684, 687, 749, 776, 175, 452, 191, 480, 510, - 659, 772, 805, 813, 397, 444, 619, 566, 568, 575, 491, 471, 707, 111, 636, 156, - 153, 288, 346, 578, 256, 435, 383, 729, 680, 767, 694, 295, 128, 210, 0, 0, - 227, 0, 379, 0, 0, 150, 493, 525, 544, 551, 552, 556, 783, 576, 604, 0, - 661, 0, 703, 0, 0, 735, 743, 0, 0, 0, 793, 794, 795, 808, 741, 773, - 118, 127, 130, 166, 169, 177, 207, 213, 215, 226, 229, 268, 270, 317, 327, 329, - 335, 369, 375, 381, 404, 441, 448, 458, 477, 484, 503, 539, 545, 547, 546, 548, - 549, 550, 554, 555, 561, 564, 569, 591, 593, 595, 598, 607, 620, 625, 625, 651, - 690, 695, 705, 706, 716, 717, 733, 735, 777, 786, 790, 315, 869, 623, 0, 0, - 102, 145, 134, 115, 129, 138, 165, 171, 207, 202, 206, 212, 227, 231, 240, 243, - 250, 254, 294, 296, 303, 308, 319, 325, 321, 329, 326, 335, 341, 357, 360, 362, - 370, 379, 388, 389, 393, 421, 424, 438, 456, 454, 458, 465, 477, 535, 485, 490, - 493, 507, 512, 514, 521, 522, 525, 526, 528, 533, 532, 541, 565, 569, 574, 586, - 591, 597, 607, 637, 647, 674, 691, 693, 695, 698, 703, 699, 705, 704, 702, 706, - 709, 717, 728, 736, 747, 754, 770, 777, 783, 784, 786, 787, 790, 802, 825, 848, - 847, 857, 55, 65, 66, 883, 892, 916, 822, 824, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1586, 0,1605, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1602,1603,1934,1935,1574,1575, - 1576,1577,1579,1580,1581,1583,1584, 0,1585,1587,1588,1589,1591, 0,1592, 0, - 1593,1594, 0,1595,1596, 0,1598,1599,1600,1601,1604,1582,1578,1590,1597, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1936, 0,1937, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1938, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1939,1940, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1941,1942, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1944,1943, 0,1945, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1946,1947, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1948,1949, - 1950,1951,1952,1953,1954, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1955,1956,1957,1959,1958, - 1960, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 106, 104, 107, 826, 114, 118, 119, 121, 123, 124, 127, 125, 34, 830, 130, 131, - 132, 137, 827, 35, 133, 139, 829, 142, 143, 112, 144, 145, 924, 151, 152, 37, - 157, 158, 159, 160, 38, 165, 166, 169, 171, 172, 173, 174, 176, 177, 178, 179, - 181, 182, 182, 182, 833, 468, 184, 185, 834, 187, 188, 189, 196, 192, 194, 195, - 197, 199, 200, 201, 203, 204, 204, 206, 208, 209, 211, 218, 213, 219, 214, 216, - 153, 234, 221, 222, 223, 220, 225, 224, 230, 835, 235, 236, 237, 238, 239, 244, - 836, 837, 247, 248, 249, 246, 251, 39, 40, 253, 255, 255, 838, 257, 258, 259, - 261, 839, 262, 263, 301, 264, 41, 266, 270, 272, 271, 841, 274, 842, 277, 276, - 278, 281, 282, 42, 283, 284, 285, 286, 43, 843, 44, 289, 290, 291, 293, 934, - 298, 845, 845, 621, 300, 300, 45, 852, 894, 302, 304, 46, 306, 309, 310, 312, - 316, 48, 47, 317, 846, 318, 323, 324, 325, 324, 328, 329, 333, 331, 332, 334, - 335, 336, 338, 339, 342, 343, 347, 351, 849, 350, 348, 352, 354, 359, 850, 361, - 358, 356, 49, 363, 365, 367, 364, 50, 369, 371, 851, 376, 386, 378, 53, 381, - 52, 51, 140, 141, 387, 382, 614, 78, 388, 389, 390, 394, 392, 856, 54, 399, - 396, 402, 404, 858, 405, 401, 407, 55, 408, 409, 410, 413, 859, 415, 56, 417, - 860, 418, 57, 419, 422, 424, 425, 861, 840, 862, 426, 863, 429, 431, 427, 433, - 437, 441, 438, 439, 442, 443, 864, 436, 449, 450, 58, 454, 453, 865, 447, 460, - 866, 867, 461, 466, 465, 464, 59, 467, 470, 469, 472, 828, 475, 868, 478, 870, - 483, 485, 486, 871, 488, 489, 872, 873, 495, 497, 60, 498, 61, 61, 504, 505, - 507, 508, 511, 62, 513, 874, 515, 875, 518, 844, 520, 876, 877, 878, 63, 64, - 528, 880, 879, 881, 882, 530, 531, 531, 533, 66, 534, 67, 68, 884, 536, 538, - 541, 69, 885, 549, 886, 887, 556, 559, 70, 561, 562, 563, 888, 889, 889, 567, - 71, 890, 570, 571, 72, 891, 577, 73, 581, 579, 582, 893, 587, 74, 590, 592, - 596, 75, 895, 896, 76, 897, 600, 898, 602, 605, 607, 899, 900, 609, 901, 611, - 853, 77, 615, 616, 79, 617, 252, 902, 903, 854, 855, 621, 622, 731, 80, 627, - 626, 628, 164, 629, 630, 631, 633, 904, 632, 634, 639, 640, 635, 641, 646, 651, - 638, 643, 644, 645, 905, 907, 906, 81, 653, 654, 656, 911, 657, 908, 82, 83, - 909, 910, 84, 664, 665, 666, 667, 669, 668, 671, 670, 674, 672, 673, 675, 85, - 677, 678, 86, 681, 682, 912, 685, 686, 87, 689, 36, 913, 914, 88, 89, 696, - 702, 709, 711, 915, 712, 713, 718, 719, 917, 831, 721, 720, 723, 832, 725, 728, - 918, 919, 739, 742, 744, 920, 745, 753, 756, 757, 755, 760, 761, 921, 762, 90, - 764, 922, 91, 775, 279, 780, 923, 925, 92, 93, 785, 926, 94, 927, 787, 787, - 789, 928, 792, 95, 796, 797, 798, 800, 96, 929, 802, 804, 806, 97, 98, 807, - 930, 99, 931, 932, 933, 814, 100, 816, 817, 818, 819, 820, 821, 935, 0, 0, + 0, 0, 0, 0, 0, 949,1134,1010,1195,1050,1236,1090,1277,1341,1368,1340, + 1367,1342,1369,1339,1366, 0,1320,1347,1418,1419,1323,1350, 0, 0, 992,1177, + 1018,1204,1055,1241,1416,1417,1415,1424,1202, 0, 0, 0, 987,1172, 0, 0, + 1031,1217,1321,1348,1322,1349,1338,1365, 950,1135, 951,1136, 979,1164, 980,1165, + 1011,1196,1012,1197,1051,1237,1052,1238,1061,1247,1062,1248,1091,1278,1092,1279, + 1071,1257,1076,1263, 0, 0, 997,1182, 0, 0, 0, 0, 0, 0, 945,1130, + 982,1167,1337,1364,1335,1362,1046,1232,1422,1423,1113,1301, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 10,1425, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,1314,1427, 5, + 1434,1438,1443, 0,1450, 0,1455,1461,1514, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1446,1458,1468,1476,1480,1486,1517, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1489,1503,1494,1500,1508, 0, 0, 0, 0,1520,1521, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1526,1528, 0,1525, 0, 0, 0,1522, + 0, 0, 0, 0,1536,1532,1539, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1556, 0, 0, 0, 0, 0, 0,1548,1550, 0,1547, 0, 0, 0,1567, + 0, 0, 0, 0,1558,1554,1561, 0, 0, 0, 0, 0, 0, 0,1568,1569, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1529,1551, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1523,1545,1524,1546, 0, 0,1527,1549, + 0, 0,1570,1571,1530,1552,1531,1553, 0, 0,1533,1555,1535,1557,1537,1559, + 0, 0,1572,1573,1544,1566,1538,1560,1540,1562,1541,1563,1542,1564, 0, 0, + 1543,1565, 0, 0, 0, 0, 0, 0, 0, 0,1606,1607,1609,1608,1610, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1613, 0,1611, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1612, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1620, 0, 0, 0, 0, 0, 0, 0,1623, 0, 0,1624, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1614,1615,1616,1617,1618,1619,1621,1622, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1628,1629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1625,1626, 0,1627, 0, 0, 0,1634, 0, 0,1635, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1630,1631,1632, 0, 0,1633, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1639, 0, 0,1638,1640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1636,1637, 0, 0, 0, 0, 0, 0,1641, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1642,1644,1643, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1645, 0, 0, 0, 0, 0, 0, 0,1646, 0, 0, 0, 0, 0, 0,1648, + 1649, 0,1647,1650, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1651,1653,1652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1654, 0,1655,1657,1656, 0, 0, 0, 0,1659, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1660, 0, 0, 0, 0,1661, 0, 0, 0, 0,1662, + 0, 0, 0, 0,1663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1658, 0, 0, 0, 0, 0, 0, 0, 0, 0,1664, 0,1665,1673, 0, + 1674, 0, 0, 0, 0, 0, 0, 0, 0,1666, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1668, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1669, 0, 0, 0, 0,1670, 0, 0, 0, 0,1671, + 0, 0, 0, 0,1672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1675, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1676, 0, + 1677, 0,1678, 0,1679, 0,1680, 0, 0, 0,1681, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1682, 0,1683, 0, 0,1684,1685, 0,1686, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 953,1138, 955,1140, 956,1141, 957,1142, + 1324,1351, 963,1148, 965,1150, 968,1153, 966,1151, 967,1152,1378,1380,1379,1381, + 984,1169, 985,1170,1420,1421, 986,1171, 989,1174, 995,1180, 998,1183, 996,1181, + 999,1184,1000,1185,1015,1200,1329,1356,1017,1203,1019,1205,1021,1207,1024,1210, + 1687,1688,1027,1213,1026,1212,1028,1214,1029,1215,1030,1216,1034,1220,1036,1222, + 1039,1225,1038,1224,1334,1361,1336,1363,1382,1384,1383,1385,1056,1242,1057,1243, + 1059,1245,1063,1249,1689,1690,1065,1251,1068,1254,1070,1256,1386,1387,1388,1389, + 1691,1692,1073,1259,1075,1262,1079,1266,1078,1265,1095,1282,1098,1285,1097,1284, + 1390,1391,1392,1393,1099,1286,1100,1287,1101,1288,1102,1289,1105,1292,1104,1291, + 1106,1294,1107,1295,1108,1296,1114,1302,1119,1308,1122,1311,1123,1312,1186,1260, + 1293,1305, 0,1394, 0, 0, 0, 0, 952,1137, 947,1132,1317,1344,1316,1343, + 1319,1346,1318,1345,1693,1695,1371,1375,1370,1374,1373,1377,1372,1376,1694,1696, + 981,1166, 977,1162, 972,1157,1326,1353,1325,1352,1328,1355,1327,1354,1697,1698, + 1009,1194,1013,1198,1054,1240,1048,1234,1331,1358,1330,1357,1333,1360,1332,1359, + 1699,1700,1396,1401,1395,1400,1398,1403,1397,1402,1399,1404,1094,1281,1087,1274, + 1406,1411,1405,1410,1408,1413,1407,1412,1409,1414,1109,1297,1117,1306,1116,1304, + 1112,1300, 0, 0, 0, 0, 0, 0,1471,1472,1701,1705,1702,1706,1703,1707, + 1430,1431,1715,1719,1716,1720,1717,1721,1477,1478,1729,1731,1730,1732, 0, 0, + 1435,1436,1733,1735,1734,1736, 0, 0,1481,1482,1737,1741,1738,1742,1739,1743, + 1439,1440,1751,1755,1752,1756,1753,1757,1490,1491,1765,1768,1766,1769,1767,1770, + 1447,1448,1771,1774,1772,1775,1773,1776,1495,1496,1777,1779,1778,1780, 0, 0, + 1451,1452,1781,1783,1782,1784, 0, 0,1504,1505,1785,1788,1786,1789,1787,1790, + 0,1459, 0,1791, 0,1792, 0,1793,1509,1510,1794,1798,1795,1799,1796,1800, + 1462,1463,1808,1812,1809,1813,1810,1814,1467, 21,1475, 22,1479, 23,1485, 24, + 1493, 27,1499, 28,1507, 29, 0, 0,1704,1708,1709,1710,1711,1712,1713,1714, + 1718,1722,1723,1724,1725,1726,1727,1728,1740,1744,1745,1746,1747,1748,1749,1750, + 1754,1758,1759,1760,1761,1762,1763,1764,1797,1801,1802,1803,1804,1805,1806,1807, + 1811,1815,1816,1817,1818,1819,1820,1821,1470,1469,1822,1474,1465, 0,1473,1825, + 1429,1428,1426, 12,1432, 0, 26, 0, 0,1315,1823,1484,1466, 0,1483,1829, + 1433, 13,1437, 14,1441,1826,1827,1828,1488,1487,1513, 19, 0, 0,1492,1515, + 1445,1444,1442, 15, 0,1831,1832,1833,1502,1501,1516, 25,1497,1498,1506,1518, + 1457,1456,1454, 17,1453,1313, 11, 3, 0, 0,1824,1512,1519, 0,1511,1830, + 1449, 16,1460, 18,1464, 4, 0, 0, 30, 31, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, + 0, 0, 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1834,1835, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1836, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1837,1839,1838, 0, 0, 0, 0,1840, 0, 0, 0, + 0,1841, 0, 0,1842, 0, 0, 0, 0, 0, 0, 0,1843, 0,1844, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1845, 0, 0,1846, 0, 0,1847, + 0,1848, 0, 0, 0, 0, 0, 0, 937, 0,1850, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1849, 936, 938,1851,1852, 0, 0,1853,1854, 0, 0, + 1855,1856, 0, 0, 0, 0, 0, 0,1857,1858, 0, 0,1861,1862, 0, 0, + 1863,1864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1867,1868,1869,1870,1859,1860,1865,1866, 0, 0, 0, 0, + 0, 0,1871,1872,1873,1874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1877, 0,1878, 0,1879, 0,1880, 0,1881, 0,1882, 0, + 1883, 0,1884, 0,1885, 0,1886, 0,1887, 0,1888, 0, 0,1889, 0,1890, + 0,1891, 0, 0, 0, 0, 0, 0,1892,1893, 0,1894,1895, 0,1896,1897, + 0,1898,1899, 0,1900,1901, 0, 0, 0, 0, 0, 0,1876, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1902, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1904, 0,1905, 0,1906, 0,1907, 0,1908, 0,1909, 0, + 1910, 0,1911, 0,1912, 0,1913, 0,1914, 0,1915, 0, 0,1916, 0,1917, + 0,1918, 0, 0, 0, 0, 0, 0,1919,1920, 0,1921,1922, 0,1923,1924, + 0,1925,1926, 0,1927,1928, 0, 0, 0, 0, 0, 0,1903, 0, 0,1929, + 1930,1931,1932, 0, 0, 0,1933, 0, 710, 385, 724, 715, 455, 103, 186, 825, + 825, 242, 751, 205, 241, 336, 524, 601, 663, 676, 688, 738, 411, 434, 474, 500, + 649, 746, 799, 108, 180, 416, 482, 662, 810, 275, 462, 658, 692, 344, 618, 679, + 293, 388, 440, 492, 740, 116, 146, 168, 368, 414, 481, 527, 606, 660, 665, 722, + 781, 803, 809, 538, 553, 588, 642, 758, 811, 701, 233, 299, 573, 612, 487, 540, + 714, 779, 232, 267, 412, 445, 457, 585, 594, 766, 167, 613, 149, 148, 560, 589, + 648, 768, 708, 345, 411, 704, 105, 259, 313, 496, 518, 174, 542, 120, 307, 101, + 430, 372, 584, 183, 228, 529, 650, 697, 424, 732, 428, 349, 632, 355, 517, 110, + 135, 147, 403, 580, 624, 700, 750, 170, 193, 245, 297, 374, 463, 543, 763, 801, + 812, 815, 162, 384, 420, 730, 287, 330, 337, 366, 459, 476, 509, 558, 591, 610, + 726, 652, 734, 759, 154, 163, 198, 473, 683, 697, 292, 311, 353, 423, 572, 494, + 113, 217, 259, 280, 314, 499, 506, 603, 608, 752, 778, 782, 788, 117, 557, 748, + 774, 320, 109, 126, 260, 265, 373, 411, 479, 523, 655, 737, 823, 380, 765, 161, + 395, 398, 438, 451, 502, 516, 537, 583, 791, 136, 340, 769, 122, 273, 446, 727, + 305, 322, 400, 496, 771, 155, 190, 269, 377, 391, 406, 432, 501, 519, 599, 684, + 687, 749, 776, 175, 452, 191, 480, 510, 659, 772, 805, 813, 397, 444, 619, 566, + 568, 575, 491, 471, 707, 111, 636, 156, 153, 288, 346, 578, 256, 435, 383, 729, + 680, 767, 694, 295, 128, 210, 0, 0, 227, 0, 379, 0, 0, 150, 493, 525, + 544, 551, 552, 556, 783, 576, 604, 0, 661, 0, 703, 0, 0, 735, 743, 0, + 0, 0, 793, 794, 795, 808, 741, 773, 118, 127, 130, 166, 169, 177, 207, 213, + 215, 226, 229, 268, 270, 317, 327, 329, 335, 369, 375, 381, 404, 441, 448, 458, + 477, 484, 503, 539, 545, 547, 546, 548, 549, 550, 554, 555, 561, 564, 569, 591, + 593, 595, 598, 607, 620, 625, 625, 651, 690, 695, 705, 706, 716, 717, 733, 735, + 777, 786, 790, 315, 869, 623, 0, 0, 102, 145, 134, 115, 129, 138, 165, 171, + 207, 202, 206, 212, 227, 231, 240, 243, 250, 254, 294, 296, 303, 308, 319, 325, + 321, 329, 326, 335, 341, 357, 360, 362, 370, 379, 388, 389, 393, 421, 424, 438, + 456, 454, 458, 465, 477, 535, 485, 490, 493, 507, 512, 514, 521, 522, 525, 526, + 528, 533, 532, 541, 565, 569, 574, 586, 591, 597, 607, 637, 647, 674, 691, 693, + 695, 698, 703, 699, 705, 704, 702, 706, 709, 717, 728, 736, 747, 754, 770, 777, + 783, 784, 786, 787, 790, 802, 825, 848, 847, 857, 55, 65, 66, 883, 892, 916, + 822, 824, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1586, 0,1605, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1602,1603,1934,1935,1574,1575,1576,1577,1579,1580,1581,1583,1584, 0, + 1585,1587,1588,1589,1591, 0,1592, 0,1593,1594, 0,1595,1596, 0,1598,1599, + 1600,1601,1604,1582,1578,1590,1597, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1936, 0,1937, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1938, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1939,1940, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1944,1943, 0,1945, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1946,1947, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1949,1950,1951,1952,1953,1954,1955, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1956,1957,1958,1960,1959,1961, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 106, 104, 107, 826, 114, 118, 119, 121, + 123, 124, 127, 125, 34, 830, 130, 131, 132, 137, 827, 35, 133, 139, 829, 142, + 143, 112, 144, 145, 924, 151, 152, 37, 157, 158, 159, 160, 38, 165, 166, 169, + 171, 172, 173, 174, 176, 177, 178, 179, 181, 182, 182, 182, 833, 468, 184, 185, + 834, 187, 188, 189, 196, 192, 194, 195, 197, 199, 200, 201, 203, 204, 204, 206, + 208, 209, 211, 218, 213, 219, 214, 216, 153, 234, 221, 222, 223, 220, 225, 224, + 230, 835, 235, 236, 237, 238, 239, 244, 836, 837, 247, 248, 249, 246, 251, 39, + 40, 253, 255, 255, 838, 257, 258, 259, 261, 839, 262, 263, 301, 264, 41, 266, + 270, 272, 271, 841, 274, 842, 277, 276, 278, 281, 282, 42, 283, 284, 285, 286, + 43, 843, 44, 289, 290, 291, 293, 934, 298, 845, 845, 621, 300, 300, 45, 852, + 894, 302, 304, 46, 306, 309, 310, 312, 316, 48, 47, 317, 846, 318, 323, 324, + 325, 324, 328, 329, 333, 331, 332, 334, 335, 336, 338, 339, 342, 343, 347, 351, + 849, 350, 348, 352, 354, 359, 850, 361, 358, 356, 49, 363, 365, 367, 364, 50, + 369, 371, 851, 376, 386, 378, 53, 381, 52, 51, 140, 141, 387, 382, 614, 78, + 388, 389, 390, 394, 392, 856, 54, 399, 396, 402, 404, 858, 405, 401, 407, 55, + 408, 409, 410, 413, 859, 415, 56, 417, 860, 418, 57, 419, 422, 424, 425, 861, + 840, 862, 426, 863, 429, 431, 427, 433, 437, 441, 438, 439, 442, 443, 864, 436, + 449, 450, 58, 454, 453, 865, 447, 460, 866, 867, 461, 466, 465, 464, 59, 467, + 470, 469, 472, 828, 475, 868, 478, 870, 483, 485, 486, 871, 488, 489, 872, 873, + 495, 497, 60, 498, 61, 61, 504, 505, 507, 508, 511, 62, 513, 874, 515, 875, + 518, 844, 520, 876, 877, 878, 63, 64, 528, 880, 879, 881, 882, 530, 531, 531, + 533, 66, 534, 67, 68, 884, 536, 538, 541, 69, 885, 549, 886, 887, 556, 559, + 70, 561, 562, 563, 888, 889, 889, 567, 71, 890, 570, 571, 72, 891, 577, 73, + 581, 579, 582, 893, 587, 74, 590, 592, 596, 75, 895, 896, 76, 897, 600, 898, + 602, 605, 607, 899, 900, 609, 901, 611, 853, 77, 615, 616, 79, 617, 252, 902, + 903, 854, 855, 621, 622, 731, 80, 627, 626, 628, 164, 629, 630, 631, 633, 904, + 632, 634, 639, 640, 635, 641, 646, 651, 638, 643, 644, 645, 905, 907, 906, 81, + 653, 654, 656, 911, 657, 908, 82, 83, 909, 910, 84, 664, 665, 666, 667, 669, + 668, 671, 670, 674, 672, 673, 675, 85, 677, 678, 86, 681, 682, 912, 685, 686, + 87, 689, 36, 913, 914, 88, 89, 696, 702, 709, 711, 915, 712, 713, 718, 719, + 917, 831, 721, 720, 723, 832, 725, 728, 918, 919, 739, 742, 744, 920, 745, 753, + 756, 757, 755, 760, 761, 921, 762, 90, 764, 922, 91, 775, 279, 780, 923, 925, + 92, 93, 785, 926, 94, 927, 787, 787, 789, 928, 792, 95, 796, 797, 798, 800, + 96, 929, 802, 804, 806, 97, 98, 807, 930, 99, 931, 932, 933, 814, 100, 816, + 817, 818, 819, 820, 821, 935, 0, 0, }; static const int16_t _hb_ucd_i16[196] = @@ -5490,12 +5554,12 @@ _hb_ucd_i16[196] = static inline uint_fast8_t _hb_ucd_gc (unsigned u) { - return u<1114110u?_hb_ucd_u8[6432+(((_hb_ucd_u8[1248+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; + return u<1114110u?_hb_ucd_u8[6504+(((_hb_ucd_u8[1264+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; } static inline uint_fast8_t _hb_ucd_ccc (unsigned u) { - return u<125259u?_hb_ucd_u8[8640+(((_hb_ucd_u8[7704+(((_hb_ucd_u8[7048+(((_hb_ucd_u8[6802+(u>>2>>3>>4)])<<4)+((u>>2>>3)&15u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u))]:0; + return u<125259u?_hb_ucd_u8[8768+(((_hb_ucd_u8[7792+(((_hb_ucd_u8[7120+(((_hb_ucd_u8[6874+(u>>2>>3>>4)])<<4)+((u>>2>>3)&15u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u))]:0; } static inline unsigned _hb_ucd_b4 (const uint8_t* a, unsigned i) @@ -5505,28 +5569,29 @@ _hb_ucd_b4 (const uint8_t* a, unsigned i) static inline int_fast16_t _hb_ucd_bmg (unsigned u) { - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9372+(((_hb_ucd_u8[9252+(((_hb_ucd_b4(9124+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0; + return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9508+(((_hb_ucd_u8[9388+(((_hb_ucd_b4(9260+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0; } static inline uint_fast8_t _hb_ucd_sc (unsigned u) { - return u<918000u?_hb_ucd_u8[10822+(((_hb_ucd_u16[1920+(((_hb_ucd_u8[10150+(((_hb_ucd_u8[9700+(u>>3>>4>>4)])<<4)+((u>>3>>4)&15u))])<<4)+((u>>3)&15u))])<<3)+((u)&7u))]:2; + return u<918000u?_hb_ucd_u8[10974+(((_hb_ucd_u16[1960+(((_hb_ucd_u8[10286+(((_hb_ucd_u8[9836+(u>>3>>4>>4)])<<4)+((u>>3>>4)&15u))])<<4)+((u>>3)&15u))])<<3)+((u)&7u))]:2; } static inline uint_fast16_t _hb_ucd_dm (unsigned u) { - return u<195102u?_hb_ucd_u16[5648+(((_hb_ucd_u8[16174+(((_hb_ucd_b4(16078+_hb_ucd_u8,u>>4>>6))<<6)+((u>>4)&63u))])<<4)+((u)&15u))]:0; + return u<195102u?_hb_ucd_u16[5768+(((_hb_ucd_u8[16708+(((_hb_ucd_u8[16326+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; } #else static const uint8_t -_hb_ucd_u8[13072] = +_hb_ucd_u8[13344] = { 0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 6, 5, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 17, 15, 15, 18, 15, 19, 20, 21, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 22, 23, + 5, 24, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, @@ -5537,8 +5602,7 @@ _hb_ucd_u8[13072] = 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 24, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 25, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -5562,34 +5626,36 @@ _hb_ucd_u8[13072] = 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, 100,100, 34, 34, 34, 34,101,102, 34, 34,103,104,105,106,107,108, 34, 34,109,110,111,112,113,114,115,116,117,111, 34, 34, 34,111, - 118,119,120,121,122,123,124,125, 34,126,127,111,128,111,129, 34, - 130,131,132,133,134,135,136,111,137,138,111,139,140,141,142,111, - 143,144,111,145,146,147,111,111,148,149,150,151,111,152,111,153, - 34, 34, 34, 34, 34, 34, 34, 34,154, 34, 34,111,111,111,111,111, + 118,119,120,121,122,123,124,125, 34,126,127,111,128,129,130,131, + 132,133,134,135,136,137,138,111,139,140,111,141,142,143,144,111, + 145,146,147,148,149,150,111,111,151,152,153,154,111,155,111,156, + 34, 34, 34, 34, 34, 34, 34, 34,157, 34, 34,111,111,111,111,111, 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, - 34, 34, 34, 34, 34, 34, 34, 34,155,111,111,111,111,111,111,111, + 34, 34, 34, 34, 34, 34, 34, 34,158,111,111,111,111,111,111,111, 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, 111,111,111,111,111,111,111,111, 34, 34, 34, 34, 34,111,111,111, 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, - 34, 34, 34, 34,156,157,158, 34,111,111,111,111,159,160,161,162, + 34, 34, 34, 34,159,160,161, 34,111,111,111,111,162,163,164,165, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111, 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111, - 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111, - 111,111,111,111,111,111,111,111, 34,163,111,111,111,111,111,111, - 67, 67,164,165,166,128, 65,111,167,168,169,170,171,172,173,174, - 67, 67, 67, 67,175,176,111,111,111,111,111,111,111,111,111,111, - 177,111,178,111,111,179,111,111,111,111,111,111,111,111,111,111, - 34,180,181,111,111,111,111,111,128,182,183,111, 34,184,111,111, - 67, 67,185, 67, 67,111, 67,186, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67,111,111,111,111,111,111,111,111,111,111, + 111,111,111,111,111,111,111,111, 34,166,111,111,111,111,111,111, + 67, 67,167,168,169,128, 65,111,170,171,172,173,174,175,176,177, + 67, 67, 67, 67,178,179,111,111,111,111,111,111,111,111,111,111, + 180,111,181,111,111,182,111,111,111,111,111,111,111,111,111,111, + 34,183,184,111,111,111,111,111,128,185,186,111, 34,187,111,111, + 67, 67,188, 67, 67,111, 67,189, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67,190,111,111,111,111,111,111,111,111, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111, 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111,111, - 187,111,177,177,111,111,111,111,111,111,111,111,111,111,111,111, + 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111, + 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, + 191,111,180,180,111,111,111,111,111,111,111,111,111,111,111,111, 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2, 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, @@ -5646,9 +5712,9 @@ _hb_ucd_u8[13072] = 43, 43, 43, 43, 36, 36, 36, 36, 7, 7, 7, 82, 27, 27, 27, 81, 63, 75, 65, 36, 36, 36, 36, 36, 75, 75, 75, 74, 75, 75, 43, 43, 43, 43, 74, 75, 75, 75, 75, 36, 83, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 63, 64, 75, 76, 43, 43, 75, 75, 75, 76, 70, - 61, 61, 36, 79, 27, 27, 27, 84, 27, 27, 27, 27, 81, 36, 36, 36, - 75, 75, 78, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 74, + 43, 75, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 63, 64, 75, + 76, 43, 43, 75, 75, 75, 76, 70, 61, 61, 36, 79, 27, 27, 27, 84, + 27, 27, 27, 27, 81, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 74, 75, 43, 43, 43, 75, 75, 75, 75, 7, 75, 2, 2, 2, 2, 2, 2, 63, 36, 43, 43, 43, 43, 43, 85, 36, 36, 36, 68, 43, 43, 43, 57, 7, 7, 7, 7, 7, 2, 2, 2, 63, 36, 43, 43, 43, 43, 64, 36, @@ -5676,51 +5742,51 @@ _hb_ucd_u8[13072] = 61, 61, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 27, 27, 61, 36, 36, 36, 63, 74, 76, 43, 2, 36, 36, 79, 74, 43, 43, 43, 43, 74, 74, 76, 43, 43, 43, 74, 75, 75, 76, 43, 43, 43, 43, 43, 43, - 2, 2, 2, 77, 2, 2, 2, 2, 43, 43, 43, 43, 43, 43, 43, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 43, 43, 78, 36, 36, 36, 36, 36, - 36, 36, 74, 43, 43, 74, 74, 75, 75, 74, 78, 36, 36, 36, 36, 36, - 86, 61, 61, 61, 61, 47, 43, 43, 43, 43, 61, 61, 61, 61, 61, 61, - 43, 78, 36, 36, 36, 36, 36, 36, 79, 43, 43, 75, 43, 76, 43, 36, - 36, 36, 36, 74, 43, 75, 76, 76, 43, 75, 75, 75, 75, 75, 2, 2, - 36, 36, 75, 75, 75, 75, 43, 43, 43, 43, 75, 43, 43, 57, 2, 2, - 7, 7, 7, 7, 7, 7, 83, 36, 36, 36, 36, 36, 40, 40, 40, 2, - 43, 57, 43, 43, 43, 43, 43, 43, 74, 43, 43, 43, 64, 36, 63, 36, - 36, 36, 64, 79, 43, 36, 36, 36, 16, 16, 16, 16, 16, 16, 40, 40, - 40, 40, 40, 40, 40, 44, 16, 16, 16, 16, 16, 16, 44, 16, 16, 16, - 16, 16, 16, 16, 16, 96, 40, 40, 32, 32, 32, 16, 16, 16, 16, 32, - 16, 16, 16, 16, 11, 11, 11, 11, 16, 16, 16, 16, 34, 11, 11, 11, - 16, 16, 16, 16, 97, 97, 97, 97, 16, 16, 16, 16, 11, 11, 98, 99, - 41, 16, 16, 16, 11, 11, 98, 41, 16, 16, 16, 16, 11, 11,100, 41, - 101,101,101,101,101,102, 59, 59, 51, 51, 51, 2,103,104,103,104, - 2, 2, 2, 2,105, 59, 59,106, 2, 2, 2, 2,107,108, 2,109, - 110, 2,111,112, 2, 2, 2, 2, 2, 9,110, 2, 2, 2, 2,113, - 59, 59, 59, 59, 59, 59, 59, 59,114, 40, 27, 27, 27, 8,111,115, - 27, 27, 27, 27, 27, 8,111, 91, 20, 20, 20, 20, 20, 20, 20, 20, - 43, 43, 43, 43, 43, 43,116, 48,117, 48,117, 43, 43, 43, 43, 43, - 61,118, 61,119, 61, 34, 11, 16, 11, 32,119, 61, 46, 11, 11, 61, - 61, 61,118,118,118, 11, 11,120, 11, 11, 35, 36, 39, 61, 16, 11, - 8, 8, 46, 16, 16, 26, 61,121, 92, 92, 92, 92, 92, 92, 92, 92, - 92,122,123, 92,124, 61, 61, 61, 8, 8,125, 61, 61, 8, 61, 61, - 125, 26, 61,125, 61, 61, 61,125, 61, 61, 61, 61, 61, 61, 61, 8, - 61,125,125, 61, 61, 61, 61, 61, 61, 61, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 61, 61, 61, 61, 4, 4, 61, 61, - 8, 61, 61, 61,126,127, 61, 61, 61, 61, 61, 61, 61, 61,125, 61, - 61, 61, 61, 61, 61, 26, 8, 8, 8, 8, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 8, 8, 8, 61, 61, 61, 61, 61, 61, 61, - 27, 27, 27, 27, 27, 27, 61, 61, 61, 61, 61, 61, 61, 27, 27, 27, - 61, 61, 61, 26, 61, 61, 61, 61, 26, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 8, 8, 8, 8, 61, 61, 61, 61, 61, 61, 61, 26, - 61, 61, 61, 61, 4, 4, 4, 4, 4, 4, 4, 27, 27, 27, 27, 27, - 27, 27, 61, 61, 61, 61, 61, 61, 8, 8,111,128, 8, 8, 8, 8, - 8, 8, 8, 4, 4, 4, 4, 4, 8,111,129,129,129,129,129,129, - 129,129,129,129,128, 8, 8, 8, 8, 8, 8, 8, 4, 4, 8, 8, - 8, 8, 8, 8, 8, 8, 4, 8, 8, 8,125, 26, 8, 8,125, 61, - 32, 11, 32, 34, 34, 34, 34, 11, 32, 32, 34, 16, 16, 16, 40, 11, - 32, 32,121, 61, 61,119, 34,130, 43, 32, 16, 16, 50, 2, 87, 2, - 36, 36, 36, 36, 36, 36, 36, 95, 2, 2, 2, 2, 2, 2, 2, 56, - 2,103,103, 2,107,108,103, 2, 2, 2, 2, 6, 2, 94,103, 2, - 103, 4, 4, 4, 4, 2, 2, 77, 2, 2, 2, 2, 2, 51, 2, 2, - 94,131, 2, 2, 2, 2, 2, 2, 1, 2,132,133, 4, 4, 4, 4, + 2, 2, 2, 77, 2, 2, 2, 2, 43, 43, 43, 43, 43, 43, 43, 96, + 43, 43, 78, 36, 36, 36, 36, 36, 36, 36, 74, 43, 43, 74, 74, 75, + 75, 74, 78, 36, 36, 36, 36, 36, 86, 61, 61, 61, 61, 47, 43, 43, + 43, 43, 61, 61, 61, 61, 61, 61, 43, 78, 36, 36, 36, 36, 36, 36, + 79, 43, 43, 75, 43, 76, 43, 36, 36, 36, 36, 74, 43, 75, 76, 76, + 43, 75, 75, 75, 75, 75, 2, 2, 36, 36, 75, 75, 75, 75, 43, 43, + 43, 43, 75, 43, 43, 57, 2, 2, 7, 7, 7, 7, 7, 7, 83, 36, + 36, 36, 36, 36, 40, 40, 40, 2, 43, 57, 43, 43, 43, 43, 43, 43, + 74, 43, 43, 43, 64, 36, 63, 36, 36, 36, 64, 79, 43, 36, 36, 36, + 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 44, 16, 16, + 16, 16, 16, 16, 44, 16, 16, 16, 16, 16, 16, 16, 16, 97, 40, 40, + 32, 32, 32, 16, 16, 16, 16, 32, 16, 16, 16, 16, 11, 11, 11, 11, + 16, 16, 16, 16, 34, 11, 11, 11, 16, 16, 16, 16, 98, 98, 98, 98, + 16, 16, 16, 16, 11, 11, 99,100, 41, 16, 16, 16, 11, 11, 99, 41, + 16, 16, 16, 16, 11, 11,101, 41,102,102,102,102,102,103, 59, 59, + 51, 51, 51, 2,104,105,104,105, 2, 2, 2, 2,106, 59, 59,107, + 2, 2, 2, 2,108,109, 2,110,111, 2,112,113, 2, 2, 2, 2, + 2, 9,111, 2, 2, 2, 2,114, 59, 59, 59, 59, 59, 59, 59, 59, + 115, 40, 27, 27, 27, 8,112,116, 27, 27, 27, 27, 27, 8,112, 91, + 20, 20, 20, 20, 20, 20, 20, 20, 43, 43, 43, 43, 43, 43,117, 48, + 96, 48, 96, 43, 43, 43, 43, 43, 61,118, 61,119, 61, 34, 11, 16, + 11, 32,119, 61, 46, 11, 11, 61, 61, 61,118,118,118, 11, 11,120, + 11, 11, 35, 36, 39, 61, 16, 11, 8, 8, 46, 16, 16, 26, 61,121, + 92, 92, 92, 92, 92, 92, 92, 92, 92,122,123, 92,124, 61, 61, 61, + 8, 8,125, 61, 61, 8, 61, 61,125, 26, 61,125, 61, 61, 61,125, + 61, 61, 61, 61, 61, 61, 61, 8, 61,125,125, 61, 61, 61, 61, 61, + 61, 61, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 61, 61, 61, 61, 4, 4, 61, 61, 8, 61, 61, 61,126,127, 61, 61, + 61, 61, 61, 61, 61, 61,125, 61, 61, 61, 61, 61, 61, 26, 8, 8, + 8, 8, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 8, 8, + 8, 61, 61, 61, 61, 61, 61, 61, 27, 27, 27, 27, 27, 27, 61, 61, + 61, 61, 61, 61, 61, 27, 27, 27, 61, 61, 61, 26, 61, 61, 61, 61, + 26, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 8, 8, 8, 8, + 61, 61, 61, 61, 61, 61, 61, 26, 61, 61, 61, 61, 4, 4, 4, 4, + 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 61, 61, 61, 61, 61, 61, + 8, 8,112,128, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, + 8,112,129,129,129,129,129,129,129,129,129,129,128, 8, 8, 8, + 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, + 8, 8,125, 26, 8, 8,125, 61, 32, 11, 32, 34, 34, 34, 34, 11, + 32, 32, 34, 16, 16, 16, 40, 11, 32, 32,121, 61, 61,119, 34,130, + 43, 32, 16, 16, 50, 2, 87, 2, 36, 36, 36, 36, 36, 36, 36, 95, + 2, 2, 2, 2, 2, 2, 2, 56, 2,104,104, 2,108,109,104, 2, + 2, 2, 2, 6, 2, 94,104, 2,104, 4, 4, 4, 4, 2, 2, 77, + 2, 2, 2, 2, 2, 51, 2, 2, 94,131, 2, 2, 2, 2, 2, 2, + 61, 2, 2, 2, 2, 2, 2, 2, 1, 2,132,133, 4, 4, 4, 4, 4, 61, 4, 4, 4, 4,134, 91,135, 92, 92, 92, 92, 43, 43, 75, 136, 40, 40, 61, 92,137, 58, 61, 71, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 63,138,139, 62, 36, 36, 36, 36, 36, 58, 40, 62, @@ -5733,99 +5799,102 @@ _hb_ucd_u8[13072] = 41, 32, 32, 32, 32, 32, 32, 32, 16, 32, 32, 32, 32, 32, 32, 32, 44, 16, 16, 16, 34, 34, 34, 32, 32, 32, 32, 32, 42,143, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 11, 11, 32, - 11, 11, 32, 32, 32, 32, 32, 32, 16, 32, 11, 11, 11, 11, 11, 11, - 11, 11, 11,144, 40, 35, 36, 36, 36, 64, 36, 64, 36, 63, 36, 36, - 36, 79, 76, 74, 61, 61, 61, 61, 27, 27, 27, 61,145, 61, 61, 61, + 11, 11, 32, 32, 32, 32, 32, 32, 16, 32, 11, 11, 34, 16, 16, 16, + 16, 16, 34, 35, 40, 35, 36, 36, 36, 64, 36, 64, 36, 63, 36, 36, + 36, 79, 76, 74, 61, 61, 43, 43, 27, 27, 27, 61,144, 61, 61, 61, 36, 36, 2, 2, 2, 2, 2, 2, 75, 36, 36, 36, 36, 36, 36, 36, 36, 36, 75, 75, 75, 75, 75, 75, 75, 75, 43, 43, 43, 43, 43, 2, 43, 36, 36, 36, 2, 65, 65, 63, 36, 36, 36, 43, 43, 43, 43, 2, - 36, 36, 36, 63, 43, 43, 43, 43, 43, 75, 75, 75, 75, 75, 75,146, - 36, 63, 75, 43, 43, 75, 43, 75,146, 2, 2, 2, 2, 2, 2, 77, + 36, 36, 36, 63, 43, 43, 43, 43, 43, 75, 75, 75, 75, 75, 75,145, + 36, 63, 75, 43, 43, 75, 43, 75,145, 2, 2, 2, 2, 2, 2, 77, 7, 7, 7, 7, 7, 7, 7, 2, 36, 36, 63, 62, 36, 36, 36, 36, 36, 36, 36, 36, 63, 43, 43, 74, 76, 74, 76, 43, 43, 43, 43, 43, 36, 63, 36, 36, 36, 36, 74, 75, 7, 7, 7, 7, 7, 7, 2, 2, 62, 36, 36, 70, 61, 79, 74, 36, 64, 43, 64, 63, 64, 36, 36, 43, 36, 36, 36, 36, 36, 36, 95, 2, 36, 36, 36, 36, 36, 79, 43, 75, - 2, 95,147, 43, 43, 43, 43, 43, 16, 16, 16, 16, 16, 99, 40, 40, - 36, 79, 76, 75, 74,146, 76, 43,148,148,148,148,148,148,148,148, - 149,149,149,149,149,149,149,149, 16, 16, 16, 16, 16, 16, 35, 64, - 36, 36, 36, 36,150, 36, 36, 36, 36, 41, 41, 41, 41, 41, 41, 41, - 41,151, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,129, - 152,152,152,152,152,152,152,152, 36, 36, 36, 36, 36, 36,145, 61, - 2, 2, 2,153,112, 2, 2, 2, 6,154,155,129,129,129,129,129, - 129,129,112,153,112, 2,109,156, 2, 2, 2, 2,134,129,129,112, - 2,157, 8, 8, 60, 2, 2, 2, 36, 36, 36, 36, 36, 36, 36,158, - 2, 2, 3, 2, 4, 5, 6, 2, 16, 16, 16, 16, 16, 17, 18,111, - 112, 4, 2, 36, 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 40, 20,159, 53, 20, 26, 8,125, 61, - 61, 61, 61, 61,160, 59, 61, 61, 2, 2, 2, 87, 27, 27, 27, 27, - 27, 27, 27, 81, 61, 61, 61, 61, 92, 92,124, 27, 81, 61, 61, 61, - 61, 61, 61, 61, 61, 27, 61, 61, 61, 61, 61, 61, 61, 61, 47, 43, - 161,161,161,161,161,161,161,161,162, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 84, 36,133, 36, 36, 36, 36, 92, 92, 92, - 36, 36, 36, 36, 36, 36, 36, 58,163, 92, 92, 92, 92, 92, 92, 92, - 36, 36, 36, 58, 27, 27, 27, 27, 36, 36, 36, 70,140, 27, 27, 27, - 36, 36, 36,164, 27, 27, 27, 27, 36, 36, 36, 36, 36,164, 27, 27, - 36, 36, 36, 27, 27, 27, 27, 30, 36, 36, 36, 36, 36, 36, 27, 36, - 63, 43, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 43, 43, 43, 43, - 36, 36, 36, 36, 36, 36,164, 30, 36, 36, 36, 36, 36, 36,164, 27, - 36, 36, 36, 36, 71, 36, 36, 36, 36, 36, 63, 43, 43,162, 27, 27, - 36, 36, 36, 36, 58, 2, 2, 2, 36, 36, 36, 36, 27, 27, 27, 27, - 16, 16, 16, 16, 16, 27, 27, 27, 36, 36, 43, 43, 43, 43, 43, 43, - 27, 27, 27, 84, 36, 36, 36, 36,162, 27, 30, 2, 2, 2, 2, 2, - 76, 78, 36, 36, 36, 36, 36, 36, 43, 43, 43, 57, 2, 2, 2, 2, - 2, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7,165, 75, 76, 43, 74, 76, 57, 72, 2, - 2, 2, 2, 2, 2, 2, 72, 59, 36, 36, 36, 63, 43, 43, 76, 43, - 43, 43, 43, 7, 7, 7, 7, 7, 2, 2, 79, 75, 75, 75, 75, 75, - 36, 63, 2, 36, 36, 36, 36, 36, 36, 79, 75, 43, 43, 43, 43, 74, - 78, 36, 58, 2, 56, 43, 57, 2, 7, 7, 7, 7, 7, 58, 58, 2, - 87, 27, 27, 27, 27, 27, 27, 27, 36, 36, 36, 36, 36, 36, 75, 76, - 43, 75, 74, 43, 2, 2, 2, 43, 36, 36, 36, 36, 36, 36, 36, 63, - 74, 75, 75, 75, 75, 75, 75, 75, 36, 36, 36, 79, 75, 75, 78, 36, - 36, 75, 75, 43, 43, 43, 43, 43, 36, 36, 79, 75, 43, 43, 43, 43, - 75, 43, 74, 64, 36, 58, 2, 2, 7, 7, 7, 7, 7, 82, 2, 64, - 75, 76, 43, 43, 74, 74, 75, 76, 74, 43, 36, 65, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 79, 75, 43, 43, 43, 75, 75, 43, 76, - 57, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 43, 43, - 75, 76, 43, 43, 43, 74, 76, 76, 57, 2, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 63, 76, 75, 43, 43, 43, 76, 36, 36, 36, 36, - 75, 43, 43, 76, 43, 43, 43, 43, 7, 7, 7, 7, 7, 27, 2, 86, - 43, 43, 43, 43, 76, 57, 2, 2, 27, 27, 27, 27, 27, 27, 27, 84, - 79, 75, 43, 43, 43, 43, 75, 75, 64, 65, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 75, 75, 75, 75, 75, 63, 43, 43, 43, 43, 64, 36, 36, - 36, 63, 43, 43, 74, 63, 43, 57, 2, 2, 2, 56, 43, 43, 43, 43, - 63, 43, 43, 74, 76, 43, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, - 43, 43, 43, 74, 43, 2, 65, 2, 43, 43, 43, 43, 43, 43, 43, 76, - 58, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 36, 36, 36, 36, 36, - 43, 43, 43, 43, 74, 43, 43, 43, 74, 43, 76, 43, 43, 43, 43, 43, - 43, 43, 43, 63, 43, 43, 43, 43, 36, 36, 36, 36, 36, 75, 75, 75, - 43, 74, 76, 76, 36, 36, 36, 36, 36, 63, 74,146, 2, 2, 2, 2, - 27, 27, 81, 61, 61, 61, 53, 20,145, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 21, 43, 43, 57, 2, 2, 2, 2, 2, - 43, 43, 43, 57, 2, 2, 61, 61, 40, 40, 86, 61, 61, 61, 61, 61, - 7, 7, 7, 7, 7,166, 27, 27, 27, 84, 36, 36, 36, 36, 36, 36, - 27, 27, 27, 30, 2, 2, 2, 2, 79, 75, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 75, 75, 75, 75, 76, 43, 67, 40, 40, 40, 40, 40, 40, - 40, 77, 40, 40, 40, 40, 40, 40, 36, 36, 36, 36, 36, 36, 47, 57, - 61, 61,167, 76, 43, 61,167, 75, 75,168, 59, 59, 59, 73, 43, 43, - 43, 69, 47, 43, 43, 43, 61, 61, 61, 61, 61, 61, 61, 43, 43, 61, - 61, 43, 69, 61, 61, 61, 61, 61, 11, 11, 11, 11, 11, 16, 16, 16, - 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 16, - 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 11, - 11, 11, 11, 16, 16, 16, 16, 16, 31, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, - 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, - 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, - 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, - 16, 33, 16, 16, 16, 32, 16, 7, 43, 43, 43, 69, 61, 47, 43, 43, - 43, 43, 43, 43, 43, 43, 69, 61, 61, 61, 47, 61, 61, 61, 61, 61, - 61, 61, 69, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 56, 43, 43, - 43, 43, 43, 67, 40, 40, 40, 40, 7, 7, 7, 7, 7, 7, 7, 70, - 36, 36, 36, 36, 36, 36, 43, 43, 7, 7, 7, 7, 7, 7, 7,169, - 16, 16, 43, 43, 43, 67, 40, 40, 27, 27, 27, 27, 27, 27,140, 27, - 170, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,140, + 2, 95,146, 43, 43, 43, 43, 43, 16, 16, 16, 16, 16,100, 40, 40, + 16, 16, 16, 16, 97, 41, 41, 41, 36, 79, 76, 75, 74,145, 76, 43, + 147,147,147,147,147,147,147,147,148,148,148,148,148,148,148,148, + 16, 16, 16, 16, 16, 16, 35, 64, 36, 36, 36, 36,149, 36, 36, 36, + 36, 41, 41, 41, 41, 41, 41, 41, 41,150, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36,129,151,151,151,151,151,151,151,151, + 36, 36, 36, 36, 36, 36,144, 61, 2, 2, 2,152,113, 2, 2, 2, + 6,153,154,129,129,129,129,129,129,129,113,152,113, 2,110,155, + 2, 2, 2, 2,134,129,129,113, 2,156, 8, 8, 60, 2, 2, 2, + 36, 36, 36, 36, 36, 36, 36,157, 2, 2, 3, 2, 4, 5, 6, 2, + 16, 16, 16, 16, 16, 17, 18,112,113, 4, 2, 36, 36, 36, 36, 36, + 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 40, + 20,158, 53, 20, 26, 8,125, 61, 61, 61, 61, 61,159, 59, 61, 61, + 2, 2, 2, 87, 27, 27, 27, 27, 27, 27, 27, 81, 61, 61, 61, 61, + 92, 92,124, 27, 81, 61, 61, 61, 61, 61, 61, 61, 61, 27, 61, 61, + 61, 61, 61, 61, 61, 61, 47, 43,160,160,160,160,160,160,160,160, + 161, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 84, 36, + 133, 36, 36, 36, 36, 92, 92, 92, 36, 36, 36, 36, 36, 36, 36, 58, + 162, 92, 92, 92, 92, 92, 92, 92, 36, 36, 36, 58, 27, 27, 27, 27, + 36, 36, 36, 70,140, 27, 27, 27, 36, 36, 36,163, 27, 27, 27, 27, + 36, 36, 36, 36, 36,163, 27, 27, 36, 36, 36, 27, 27, 27, 27, 30, + 36, 36, 36, 36, 36, 36, 27, 36, 63, 43, 43, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36,163, 30, + 36, 36, 36, 36, 36, 36,163, 27, 36, 36, 36, 36, 71, 36, 36, 36, + 36, 36, 63, 43, 43,161, 27, 27, 36, 36, 36, 36, 58, 2, 2, 2, + 36, 36, 36, 36, 27, 27, 27, 27, 16, 16, 16, 16, 16, 27, 27, 27, + 36, 36, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 63,164, 51, + 27, 27, 27, 84, 36, 36, 36, 36,161, 27, 30, 2, 2, 2, 2, 2, + 36, 36,163, 27, 27, 27, 27, 27, 76, 78, 36, 36, 36, 36, 36, 36, + 43, 43, 43, 57, 2, 2, 2, 2, 2, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,165, + 75, 76, 43, 74, 76, 57, 72, 2, 2, 2, 2, 2, 2, 2, 72, 59, + 36, 36, 36, 63, 43, 43, 76, 43, 43, 43, 43, 7, 7, 7, 7, 7, + 2, 2, 79, 78, 36, 36, 36, 36, 36, 63, 2, 36, 36, 36, 36, 36, + 36, 79, 75, 43, 43, 43, 43, 74, 78, 36, 58, 2, 56, 43, 57, 76, + 7, 7, 7, 7, 7, 58, 58, 2, 87, 27, 27, 27, 27, 27, 27, 27, + 36, 36, 36, 36, 36, 36, 75, 76, 43, 75, 74, 43, 2, 2, 2, 43, + 36, 36, 36, 36, 36, 36, 36, 63, 74, 75, 75, 75, 75, 75, 75, 75, + 36, 36, 36, 79, 75, 75, 78, 36, 36, 75, 75, 43, 43, 43, 43, 43, + 36, 36, 79, 75, 43, 43, 43, 43, 75, 43, 74, 64, 36, 58, 2, 2, + 7, 7, 7, 7, 7, 2, 2, 64, 75, 76, 43, 43, 74, 74, 75, 76, + 74, 43, 36, 65, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 79, + 75, 43, 43, 43, 75, 75, 43, 76, 57, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 36, 36, 43, 43, 75, 76, 43, 43, 43, 74, 76, 76, + 57, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 63, 76, 75, + 43, 43, 43, 76, 36, 36, 36, 36, 75, 43, 43, 76, 43, 43, 43, 43, + 7, 7, 7, 7, 7, 27, 2, 86, 43, 43, 43, 43, 76, 57, 2, 2, + 27, 27, 27, 27, 27, 27, 27, 84, 75, 75, 75, 75, 75, 76, 74, 64, + 78, 76, 2, 2, 2, 2, 2, 2, 79, 75, 43, 43, 43, 43, 75, 75, + 64, 65, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 63, 43, 43, 43, 43, 64, 36, 36, 36, 63, 43, 43, 74, 63, 43, 57, + 2, 2, 2, 56, 43, 43, 43, 43, 63, 43, 43, 74, 76, 43, 36, 36, + 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 74, 43, 2, 65, 2, + 43, 43, 43, 43, 43, 43, 43, 76, 58, 2, 2, 2, 2, 2, 2, 2, + 2, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 74, 43, 43, 43, + 74, 43, 76, 43, 43, 43, 43, 43, 43, 43, 43, 63, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 75, 75, 75, 43, 74, 76, 76, 36, 36, 36, 36, + 36, 63, 74,145, 2, 2, 2, 2, 27, 27, 81, 61, 61, 61, 53, 20, + 144, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 21, + 43, 43, 57, 2, 2, 2, 2, 2, 43, 43, 43, 57, 2, 2, 61, 61, + 40, 40, 86, 61, 61, 61, 61, 61, 7, 7, 7, 7, 7,166, 27, 27, + 27, 84, 36, 36, 36, 36, 36, 36, 27, 27, 27, 30, 2, 2, 2, 2, + 79, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 76, + 43, 67, 40, 40, 40, 40, 40, 40, 40, 77, 43, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 47, 57, 61, 61,167, 76, 43, 61,167, 75, + 75,168, 59, 59, 59, 73, 43, 43, 43, 69, 47, 43, 43, 43, 61, 61, + 61, 61, 61, 61, 61, 43, 43, 61, 61, 43, 69, 61, 61, 61, 61, 61, + 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 16, 11, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, + 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, + 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, + 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, + 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 16, 7, + 43, 43, 43, 69, 61, 47, 43, 43, 43, 43, 43, 43, 43, 43, 69, 61, + 61, 61, 47, 61, 61, 61, 61, 61, 61, 61, 69, 21, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 56, 43, 43, 43, 43, 43, 67, 40, 40, 40, 40, + 7, 7, 7, 7, 7, 7, 7, 70, 36, 36, 36, 36, 36, 36, 43, 43, + 7, 7, 7, 7, 7, 7, 7,169, 16, 16, 43, 43, 43, 67, 40, 40, + 27, 27, 27, 27, 27, 27,140, 27,170, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27,140, 27, 27, 27, 27, 27, 27, 81, 61, 61, 61, 61, 61, 61, 25, 41, 41, 0, 0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21, 9, 9, 9, 9, 22, 21, 18, 24, 16, 24, 5, 5, 5, 5, 22, 25, 18, 25, 0, @@ -5838,185 +5907,188 @@ _hb_ucd_u8[13072] = 6, 12, 12, 26, 7, 26, 26, 7, 21, 1, 1, 12, 12, 10, 10, 10, 10, 12, 21, 6, 10, 7, 7, 10, 23, 7, 15, 26, 13, 21, 13, 7, 15, 7, 12, 23, 21, 26, 21, 15, 17, 7, 29, 7, 7, 22, 18, 18, - 14, 14, 14, 7, 17, 21, 7, 6, 5, 6, 8, 8, 8, 24, 5, 24, - 9, 24, 29, 29, 29, 1, 20, 19, 22, 20, 27, 28, 1, 29, 21, 20, - 19, 21, 21, 16, 16, 21, 25, 22, 18, 21, 21, 29, 15, 6, 18, 6, - 12, 11, 11, 12, 9, 26, 26, 9, 26, 5, 5, 26, 14, 9, 5, 14, + 14, 14, 14, 7, 17, 21, 7, 6, 11, 12, 5, 6, 8, 8, 8, 24, + 5, 24, 9, 24, 29, 29, 29, 1, 20, 19, 22, 20, 27, 28, 1, 29, + 21, 20, 19, 21, 21, 16, 16, 21, 25, 22, 18, 21, 21, 29, 15, 6, + 18, 6, 12, 11, 9, 26, 26, 9, 26, 5, 5, 26, 14, 9, 5, 14, 14, 15, 25, 26, 26, 22, 18, 26, 18, 25, 18, 22, 5, 12, 22, 21, 26, 6, 7, 14, 17, 22, 26, 14, 17, 6, 14, 6, 12, 24, 24, 6, - 26, 15, 6, 21, 11, 21, 24, 9, 9, 7, 23, 26, 10, 21, 6, 10, - 4, 4, 3, 3, 7, 25, 24, 7, 22, 22, 21, 22, 17, 16, 16, 22, - 16, 16, 25, 17, 7, 1, 25, 24, 26, 1, 2, 2, 12, 15, 21, 14, - 7, 15, 13, 12, 13, 15, 26, 10, 10, 1, 13, 23, 23, 15, 0, 1, - 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 11, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 12, 13, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 14, 15, 16, 9, - 17, 18, 19, 20, 21, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 23, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 24, 9, 9, - 9, 9, 25, 9, 9, 9, 26, 9, 27, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 3, 0, 0, 0, - 4, 5, 6, 7, 0, 8, 9, 10, 0, 11, 12, 13, 0, 14, 15, 16, - 15, 17, 15, 18, 15, 18, 15, 18, 0, 18, 0, 19, 15, 18, 20, 18, - 0, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 0, 31, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 33, 0, 0, 34, 0, 0, 35, 0, 36, 0, - 0, 0, 37, 38, 39, 0, 40, 41, 42, 43, 44, 0, 0, 45, 0, 0, - 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 49, - 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 52, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 53, 54, 55, 0, 0, 0, 0, 56, 0, 0, 57, 58, 59, - 60, 61, 0, 0, 62, 63, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 67, 0, 0, 0, 68, 0, 69, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 70, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, - 0, 0, 0, 0, 0, 0, 0, 73, 0, 0, 0, 74, 75, 0, 76, 60, - 0, 77, 78, 0, 0, 79, 80, 81, 0, 0, 0, 82, 0, 83, 0, 0, - 49, 84, 49, 0, 85, 0, 86, 0, 0, 0, 75, 0, 0, 0, 0, 0, - 0, 87, 88, 89, 90, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 91, - 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 93, 94, 0, 0, 0, 0, 0, 95, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, - 97, 0, 0, 98, 0, 0, 0, 0, 0, 0, 99, 0, 0, 0, 94, 0, - 0, 0, 0, 0, 0,100, 0, 0, 0, 0, 0, 0, 0,101, 0,102, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, - 3, 4, 5, 6, 7, 0, 8, 0, 0, 0, 0, 9, 10, 11, 12, 0, - 0, 0, 0, 13, 0, 0, 14, 15, 0, 16, 0, 17, 18, 0, 0, 19, - 0, 20, 21, 0, 0, 0, 0, 0, 22, 23, 0, 24, 25, 0, 0, 26, - 0, 0, 0, 27, 28, 29, 0, 0, 0, 30, 31, 32, 0, 0, 31, 0, - 0, 33, 31, 0, 0, 0, 31, 34, 0, 0, 0, 0, 0, 35, 36, 0, - 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, 0, 0, 0, 39, 40, 0, - 0, 0, 0, 41, 0, 42, 0, 0, 0, 43, 44, 0, 0, 0, 45, 0, - 0, 0, 0, 0, 0, 46, 47, 0, 0, 0, 0, 48, 0, 0, 0, 49, - 0, 49, 0, 50, 0, 0, 0, 0, 51, 0, 0, 0, 0, 52, 0, 53, - 0, 0, 0, 0, 54, 55, 0, 0, 0, 56, 0, 0, 0, 57, 49, 0, - 58, 59, 0, 0, 60, 0, 0, 0, 61, 62, 0, 0, 0, 63, 0, 64, - 65, 66, 67, 68, 1, 69, 0, 70, 71, 72, 0, 0, 73, 74, 0, 0, - 0, 75, 0, 0, 1, 1, 0, 0, 76, 0, 0, 77, 0, 0, 0, 0, - 73, 78, 0, 79, 0, 0, 0, 0, 0, 74, 80, 0, 0, 0, 49, 0, - 1, 74, 0, 0, 81, 0, 0, 82, 0, 0, 0, 0, 0, 83, 54, 0, - 0, 0, 0, 0, 0, 84, 85, 0, 0, 80, 0, 0, 31, 0, 0, 86, - 0, 0, 0, 0, 87, 0, 0, 0, 0, 47, 0, 0, 88, 0, 0, 0, - 0, 89, 90, 0, 0, 91, 0, 0, 92, 0, 0, 0, 93, 0, 94, 88, - 0, 0, 80, 0, 0, 75, 0, 0, 0, 95, 96, 0, 0, 97, 98, 0, - 0, 0, 0, 0, 0, 99, 0, 0,100, 0, 0, 0, 0,101, 31, 0, - 102,103,104, 33, 0, 0,105, 0, 0, 0,106, 0, 0, 0, 0, 0, - 0,107, 0, 0,108, 0, 0, 0, 54, 0, 0, 0, 0, 49,109, 0, - 0, 0, 0,110, 0, 0,111, 0, 0, 0, 0,109, 0, 0, 0, 0, - 0,112, 0, 0, 0,113, 0,114, 0, 0, 0, 0,115,116,117, 0, - 118, 0,119, 0, 0, 0,120,121,122, 0, 0, 0,123, 0, 0,124, - 0, 0,125, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, - 3, 4, 5, 6, 7, 4, 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, - 16, 17, 18, 1, 1, 1, 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, - 21, 24, 25, 26, 27, 28, 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, - 32, 33, 34, 35, 1, 36, 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, - 40, 41, 42, 0, 0, 0, 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, - 19, 1, 21, 0, 0, 47, 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, - 51, 0, 52, 1, 1, 1, 53, 21, 43, 54, 55, 21, 35, 1, 0, 0, - 0, 56, 0, 0, 0, 57, 58, 59, 0, 0, 0, 0, 0, 60, 0, 61, - 0, 0, 0, 0, 62, 63, 0, 0, 64, 0, 0, 0, 65, 0, 0, 0, - 66, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 0, 69, 0, 0, 70, - 71, 0, 72, 73, 74, 75, 76, 77, 0, 0, 0, 78, 0, 0, 0, 79, - 80, 0, 0, 0, 0, 47, 0, 0, 0, 49, 0, 63, 0, 0, 64, 0, - 0, 81, 0, 0, 82, 0, 0, 0, 83, 0, 0, 19, 84, 0, 63, 0, - 0, 0, 0, 49, 1, 85, 1, 54, 15, 41, 0, 56, 0, 0, 0, 0, - 19, 10, 1, 0, 0, 0, 0, 0, 86, 0, 0, 87, 0, 0, 86, 0, - 0, 0, 0, 79, 0, 0, 88, 9, 12, 4, 89, 8, 90, 47, 0, 59, - 50, 0, 21, 1, 21, 91, 92, 1, 1, 1, 1, 93, 94, 95, 96, 1, - 97, 59, 81, 98, 99, 4, 59, 0, 0, 0, 0, 0, 0, 19, 50, 0, - 0, 0, 0, 0, 0, 62, 0, 0,100,101, 0, 0,102, 0, 0, 1, - 1, 50, 0, 0, 0, 38, 0, 64, 0, 0, 0, 0, 52, 69, 62, 0, - 0, 0, 79, 0, 0, 0,103,104, 59, 38, 81, 0, 0, 0, 0, 0, - 0,105, 1, 14, 4, 12, 84, 0, 0, 0, 0, 38, 88, 0, 0, 0, - 0,106, 0, 0,107, 62, 0,108, 0, 0, 0, 1, 0, 0, 0,109, - 14, 54, 0, 0,110, 0, 88, 0, 0, 0, 62, 63, 0, 0, 63, 0, - 87, 0, 0,110, 0, 0, 0, 0,111, 0, 0, 0, 79, 56, 0, 38, - 1, 59, 1, 59, 0, 0, 64, 87, 0, 0,112, 0, 0, 0, 56, 0, - 0, 0, 0,112, 0, 0, 0, 0, 62, 0, 0, 62, 0, 0, 0, 0, - 57, 0, 87,113, 0, 0, 8, 90, 0, 0, 1, 88, 0, 0, 0, 0, - 0,114, 0,115,116,117,118, 0, 52, 4,119, 49, 23, 0, 0, 0, - 38, 50, 38, 59, 0, 0, 1, 88, 1, 1, 1, 1, 39, 1, 48,103, - 88, 0, 0, 0, 0, 1, 4,119, 0, 0, 0, 1,120, 0, 0, 0, - 0, 0,230,230,230,230,230,232,220,220,220,220,232,216,220,220, - 220,220,220,202,202,220,220,220,220,202,202,220,220,220, 1, 1, - 1, 1, 1,220,220,220,220,230,230,230,230,240,230,220,220,220, - 230,230,230,220,220, 0,230,230,230,220,220,220,220,230,232,220, - 220,230,233,234,234,233,234,234,233,230, 0, 0, 0,230, 0,220, - 230,230,230,230,220,230,230,230,222,220,230,230,220,220,230,222, - 228,230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, - 0, 23, 0, 24, 25, 0,230,220, 0, 18, 30, 31, 32, 0, 0, 0, - 0, 27, 28, 29, 30, 31, 32, 33, 34,230,230,220,220,230,220,230, - 230,220, 35, 0, 0, 0, 0, 0,230,230,230, 0, 0,230,230, 0, - 220,230,230,220, 0, 0, 0, 36, 0, 0,230,220,230,230,220,220, - 230,220,220,230,220,230,220,230,230, 0, 0,220, 0, 0,230,230, - 0,230, 0,230,230,230,230,230, 0, 0, 0,220,220,220, 0, 0, - 0,220,230,230, 0,220,230,220,220,220, 27, 28, 29,230, 7, 0, - 0, 0, 0, 9, 0, 0, 0,230,220,230,230, 0, 0, 0, 0, 0, - 230, 0, 0, 84, 91, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, - 9, 0,103,103, 9, 0,107,107,107,107,118,118, 9, 0,122,122, - 122,122,220,220, 0, 0, 0,220, 0,220, 0,216, 0, 0, 0,129, - 130, 0,132, 0, 0, 0, 0, 0,130,130,130,130, 0, 0,130, 0, - 230,230, 9, 0,230,230, 0, 0,220, 0, 0, 0, 0, 7, 0, 9, - 9, 0, 0,230, 0, 0, 0,228, 0, 0, 0,222,230,220,220, 0, - 0, 0,230, 0, 0,220, 0, 0, 9, 9, 0, 0, 7, 0,230,230, - 230, 0,230, 0, 1, 1, 1, 0, 0, 0,230,234,214,220,202,230, - 230,230,230,230,232,228,228,220, 0,230,233,220,230,220,230,230, - 1, 1, 1, 1, 1,230, 0, 1, 1,230,220,230, 1, 1, 0, 0, - 218,228,232,222,224,224, 0, 8, 8, 0,230, 0,230,230,220, 0, - 0,230, 0, 0, 26, 0, 0,220, 0,230,230, 1,220, 0, 0,230, - 220, 0, 0, 0,220,220, 0, 9, 7, 0, 0, 7, 9, 0, 0, 0, - 9, 7, 9, 9, 0, 0, 0, 0, 1, 0, 0,216,216, 1, 1, 1, - 0, 0, 0,226,216,216,216,216,216, 0,220,220,220, 0,230,230, - 7, 0, 16, 17, 17, 33, 17, 49, 17, 17, 84, 97,135,145, 26, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 26, 15, 6, 21, 11, 21, 24, 9, 23, 26, 10, 21, 6, 10, 4, 4, + 3, 3, 7, 25, 24, 7, 22, 22, 21, 22, 17, 16, 16, 22, 16, 16, + 25, 17, 7, 1, 25, 24, 26, 1, 2, 2, 12, 15, 21, 14, 7, 15, + 12, 17, 13, 12, 13, 15, 26, 10, 10, 1, 13, 23, 23, 15, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 13, 0, 14, 0, + 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 21, 22, 23, + 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 34, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, 0, 0, 0, 39, 40, + 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, 0, 0, 0, 0, 3, 0, 0, 0, 4, 5, 6, 7, 0, 8, + 9, 10, 0, 11, 12, 13, 0, 14, 15, 16, 15, 17, 15, 18, 15, 18, + 15, 18, 0, 18, 0, 19, 15, 18, 20, 18, 0, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 0, 0, 0, 0, 0, 0, 33, 0, 0, 34, 0, 0, 35, 0, + 36, 0, 0, 0, 37, 38, 39, 40, 41, 42, 43, 44, 45, 0, 0, 46, + 0, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 49, + 0, 50, 0, 51, 52, 0, 53, 0, 0, 0, 0, 0, 0, 54, 55, 56, + 0, 0, 0, 0, 57, 0, 0, 58, 59, 60, 61, 62, 0, 0, 63, 64, + 0, 0, 0, 65, 0, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 69, + 0, 70, 0, 0, 71, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, + 73, 0, 0, 0, 0, 0, 74, 0, 0, 75, 0, 0, 0, 76, 77, 0, + 78, 61, 0, 79, 80, 0, 0, 81, 82, 83, 0, 0, 0, 84, 0, 85, + 0, 0, 50, 86, 50, 0, 87, 0, 88, 0, 0, 0, 77, 0, 0, 0, + 89, 90, 0, 91, 92, 93, 94, 0, 0, 0, 0, 0, 50, 0, 0, 0, + 0, 95, 96, 0, 0, 0, 0, 97, 98, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 99, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,101,102, 0, 0,103, 0, 0, 0, 0, 0, 0,104, 0, 0, 0, + 98, 0, 0, 0, 0, 0, 0,105, 0, 0, 0, 0, 0, 0, 0,106, + 0,107, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, + 8, 0, 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, + 14, 15, 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, 0, 0, + 0, 0, 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, 28, 29, + 0, 0, 0, 30, 31, 32, 0, 0, 31, 0, 0, 33, 31, 0, 0, 0, + 31, 34, 0, 0, 0, 0, 0, 35, 36, 0, 0, 0, 0, 0, 0, 37, + 38, 0, 0, 0, 0, 0, 0, 39, 40, 0, 0, 0, 0, 41, 0, 42, + 0, 0, 0, 43, 44, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 46, + 47, 0, 0, 0, 0, 48, 0, 0, 0, 49, 0, 49, 0, 50, 0, 0, + 0, 0, 51, 0, 0, 0, 0, 52, 0, 53, 0, 0, 0, 0, 54, 55, + 0, 0, 0, 56, 57, 0, 0, 0, 0, 0, 0, 58, 49, 0, 59, 60, + 0, 0, 61, 0, 0, 0, 62, 63, 0, 0, 0, 64, 0, 65, 66, 67, + 68, 69, 1, 70, 0, 71, 72, 73, 0, 0, 74, 75, 0, 0, 0, 76, + 0, 0, 1, 1, 0, 0, 77, 0, 0, 78, 0, 0, 0, 0, 74, 79, + 0, 80, 0, 0, 0, 0, 0, 75, 81, 0, 82, 0, 49, 0, 1, 75, + 0, 0, 83, 0, 0, 84, 0, 0, 0, 0, 0, 85, 54, 0, 0, 0, + 0, 0, 0, 86, 87, 0, 0, 81, 0, 0, 31, 0, 0, 88, 0, 0, + 0, 0, 89, 0, 0, 0, 0, 47, 0, 0, 57, 0, 0, 0, 0, 90, + 91, 0, 0, 92, 0, 0, 93, 0, 0, 0, 94, 0, 0, 0, 95, 0, + 96, 57, 0, 0, 81, 0, 0, 76, 0, 0, 0, 97, 98, 0, 0, 99, + 100, 0, 0, 0, 0, 0, 0,101, 0, 0,102, 0, 0, 0, 0,103, + 31, 0,104,105,106, 33, 0, 0,107, 0, 0, 0,108, 0, 0, 0, + 0, 0, 0,109, 0, 0,110, 0, 0, 0, 0,111, 85, 0, 0, 0, + 0, 0, 54, 0, 0, 0, 0, 49,112, 0, 0, 0, 0,113, 0, 0, + 114, 0, 0, 0, 0,112, 0, 0, 0, 0, 0,115, 0, 0, 0,116, + 0, 0, 0,117, 0,118, 0, 0, 0, 0,119,120,121, 0,122, 0, + 123, 0, 0, 0,124,125,126, 0, 0, 0,127, 0, 0,128, 0, 0, + 129, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, + 5, 6, 7, 4, 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, + 18, 1, 1, 1, 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, + 25, 26, 27, 28, 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, + 34, 35, 1, 36, 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, + 42, 0, 0, 0, 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, + 21, 0, 0, 47, 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, + 52, 1, 1, 1, 53, 21, 43, 54, 55, 21, 35, 1, 0, 0, 0, 56, + 0, 0, 0, 57, 58, 59, 0, 0, 0, 0, 0, 60, 0, 61, 0, 0, + 0, 0, 62, 63, 0, 0, 64, 0, 0, 0, 65, 0, 0, 0, 66, 0, + 0, 0, 67, 0, 0, 0, 68, 0, 0, 0, 69, 0, 0, 70, 71, 0, + 72, 73, 74, 75, 76, 77, 0, 0, 0, 78, 0, 0, 0, 79, 80, 0, + 0, 0, 0, 47, 0, 0, 0, 49, 0, 63, 0, 0, 64, 0, 0, 81, + 0, 0, 82, 0, 0, 0, 83, 0, 0, 19, 84, 0, 63, 0, 0, 0, + 0, 49, 1, 85, 1, 54, 15, 86, 84, 0, 0, 0, 0, 56, 0, 0, + 0, 0, 19, 10, 1, 0, 0, 0, 0, 0, 87, 0, 0, 88, 0, 0, + 87, 0, 0, 0, 0, 79, 0, 0, 89, 9, 12, 4, 90, 8, 91, 47, + 0, 59, 50, 0, 21, 1, 21, 92, 93, 1, 1, 1, 1, 94, 95, 96, + 97, 1, 98, 59, 81, 99,100, 4, 59, 0, 0, 0, 0, 0, 0, 19, + 50, 0, 0, 0, 0, 0, 0, 62, 0, 0,101,102, 0, 0,103, 0, + 0, 1, 1, 50, 0, 0, 0, 38, 0, 64, 0, 0, 0, 0, 0, 63, + 0, 0, 52, 69, 62, 0, 0, 0, 79, 0, 0, 0,104,105, 59, 38, + 81, 0, 0, 0, 0, 0, 0,106, 1, 14, 4, 12, 0, 38, 89, 0, + 0, 0, 0,107, 0, 0,108, 62, 0,109, 0, 0, 0, 1, 0, 0, + 0, 0, 19, 59, 0,110, 14, 54, 0, 0,111, 0, 89, 0, 0, 0, + 62, 63, 0, 0, 63, 0, 88, 0, 0,111, 0, 0, 0, 0,112, 0, + 0, 0, 79, 56, 0, 38, 1, 59, 1, 59, 0, 0, 64, 88, 0, 0, + 113, 0, 0, 0, 56, 0, 0, 0, 0,113, 0, 0, 0, 0, 62, 0, + 0, 0, 0, 80, 0, 62, 0, 0, 0, 0, 57, 0, 88,114, 0, 0, + 8, 91, 0, 0, 1, 89, 0, 0,115, 0, 0, 0, 0, 0, 0,116, + 0,117,118,119,120, 0, 52, 4,121, 49, 23, 0, 0, 0, 38, 50, + 38, 59, 0, 0, 1, 89, 1, 1, 1, 1, 39, 1, 48,104, 89, 0, + 0, 0, 0, 1, 4,121, 0, 0, 0, 1,122, 0, 0, 0, 0, 0, + 230,230,230,230,230,232,220,220,220,220,232,216,220,220,220,220, + 220,202,202,220,220,220,220,202,202,220,220,220, 1, 1, 1, 1, + 1,220,220,220,220,230,230,230,230,240,230,220,220,220,230,230, + 230,220,220, 0,230,230,230,220,220,220,220,230,232,220,220,230, + 233,234,234,233,234,234,233,230, 0, 0, 0,230, 0,220,230,230, + 230,230,220,230,230,230,222,220,230,230,220,220,230,222,228,230, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, + 0, 24, 25, 0,230,220, 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, + 28, 29, 30, 31, 32, 33, 34,230,230,220,220,230,220,230,230,220, + 35, 0, 0, 0, 0, 0,230,230,230, 0, 0,230,230, 0,220,230, + 230,220, 0, 0, 0, 36, 0, 0,230,220,230,230,220,220,230,220, + 220,230,220,230,220,230,230, 0, 0,220, 0, 0,230,230, 0,230, + 0,230,230,230,230,230, 0, 0, 0,220,220,220, 0, 0, 0,220, + 230,230, 0,220,230,220,220,220, 27, 28, 29,230, 7, 0, 0, 0, + 0, 9, 0, 0, 0,230,220,230,230, 0, 0, 0, 0, 0,230, 0, + 0, 84, 91, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 9, 0, + 103,103, 9, 0,107,107,107,107,118,118, 9, 0,122,122,122,122, + 220,220, 0, 0, 0,220, 0,220, 0,216, 0, 0, 0,129,130, 0, + 132, 0, 0, 0, 0, 0,130,130,130,130, 0, 0,130, 0,230,230, + 9, 0,230,230, 0, 0,220, 0, 0, 0, 0, 7, 0, 9, 9, 0, + 0,230, 0, 0, 0,228, 0, 0, 0,222,230,220,220, 0, 0, 0, + 230, 0, 0,220,230,220, 0,220, 0, 0, 9, 9, 0, 0, 7, 0, + 230,230,230, 0,230, 0, 1, 1, 1, 0, 0, 0,230,234,214,220, + 202,230,230,230,230,230,232,228,228,220, 0,230,233,220,230,220, + 230,230, 1, 1, 1, 1, 1,230, 0, 1, 1,230,220,230, 1, 1, + 0, 0,218,228,232,222,224,224, 0, 8, 8, 0,230, 0,230,230, + 220, 0, 0,230, 0, 0, 26, 0, 0,220, 0,230,230, 1,220, 0, + 0,230,220, 0, 0, 0,220,220, 0, 9, 7, 0, 0, 7, 9, 0, + 0, 0, 9, 7, 9, 9, 0, 0, 6, 6, 0, 0, 0, 0, 1, 0, + 0,216,216, 1, 1, 1, 0, 0, 0,226,216,216,216,216,216, 0, + 220,220,220, 0,230,230, 7, 0, 16, 17, 17, 33, 17, 49, 17, 17, + 84, 97,135,145, 26, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17,177, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 5, 3, 3, 3, - 3, 3, 6, 7, 8, 3, 3, 3, 3, 3, 9, 10, 11, 12, 13, 3, - 3, 3, 3, 3, 3, 3, 3, 14, 3, 15, 3, 3, 3, 3, 3, 3, - 16, 17, 18, 19, 20, 21, 3, 3, 3, 22, 23, 3, 3, 3, 3, 3, - 3, 3, 24, 3, 3, 3, 3, 3, 3, 3, 3, 25, 3, 3, 26, 27, - 0, 1, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, - 0, 3, 0, 0, 0, 0, 0, 4, 0, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, - 0, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 0, - 0, 14, 15, 16, 6, 0, 17, 18, 19, 19, 19, 20, 21, 22, 23, 24, - 19, 25, 0, 26, 27, 19, 19, 28, 29, 30, 0, 31, 0, 0, 0, 8, - 0, 0, 0, 0, 0, 0, 0, 19, 28, 0, 32, 33, 9, 34, 35, 19, - 0, 0, 36, 37, 38, 39, 40, 19, 0, 41, 42, 43, 44, 31, 0, 1, - 45, 42, 0, 0, 0, 0, 0, 32, 14, 14, 0, 0, 0, 0, 14, 0, - 0, 46, 47, 47, 47, 47, 48, 49, 47, 47, 47, 47, 50, 51, 52, 53, - 43, 21, 0, 0, 0, 0, 0, 0, 0, 54, 6, 55, 0, 14, 19, 1, - 0, 0, 0, 19, 56, 31, 0, 0, 0, 0, 0, 0, 0, 57, 14, 0, - 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 58, 59, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 3, 0, 4, - 5, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 1, 1, 0, 0, 8, - 9, 0, 8, 9, 0, 0, 0, 0, 8, 9, 10, 11, 12, 0, 0, 0, - 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, 0, 0, 1, 0, 0, 18, - 19, 0, 0, 0, 20, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, - 1, 1, 1, 1, 0, 8, 21, 9, 0, 0, 22, 0, 0, 0, 0, 1, - 0, 23, 24, 25, 0, 0, 26, 0, 0, 0, 8, 21, 27, 0, 1, 0, - 0, 1, 1, 1, 1, 0, 1, 28, 29, 30, 0, 31, 32, 20, 1, 1, - 0, 0, 0, 8, 21, 9, 1, 4, 5, 0, 0, 0, 33, 9, 0, 1, - 1, 1, 0, 8, 21, 21, 21, 21, 34, 1, 35, 21, 21, 21, 9, 36, - 0, 0, 37, 38, 1, 0, 39, 0, 0, 0, 1, 0, 1, 0, 0, 0, - 0, 8, 21, 9, 1, 0, 0, 0, 40, 0, 8, 21, 21, 21, 21, 21, - 21, 21, 21, 9, 0, 1, 1, 1, 1, 8, 21, 21, 21, 9, 0, 0, - 0, 41, 0, 42, 43, 0, 0, 0, 1, 44, 0, 0, 0, 45, 8, 9, - 1, 0, 1, 0, 1, 1, 8, 21, 21, 9, 0, 4, 5, 8, 9, 1, - 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 9, 10, 11, 11, 11, 11, 11, 12, 12, 12, - 12, 13, 14, 15, 16, 17, 18, 12, 19, 12, 20, 12, 12, 12, 12, 21, - 22, 22, 22, 23, 12, 12, 12, 12, 24, 25, 12, 12, 26, 27, 28, 29, - 30, 31, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 32, - 12, 33, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 17, 17, 17, 17, 17, 17, 17,177, 0, 1, 2, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, + 3, 3, 5, 3, 3, 3, 3, 3, 6, 7, 8, 3, 3, 3, 3, 3, + 9, 10, 11, 12, 13, 3, 3, 3, 3, 3, 3, 3, 3, 14, 3, 15, + 3, 3, 3, 3, 3, 3, 16, 17, 18, 19, 20, 21, 3, 3, 3, 22, + 23, 3, 3, 3, 3, 3, 3, 3, 24, 3, 3, 3, 3, 3, 3, 3, + 3, 25, 3, 3, 26, 27, 0, 1, 0, 0, 0, 0, 0, 1, 0, 2, + 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 0, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, + 9, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0, 0, 0, 0, 0, 0, + 0, 10, 11, 12, 13, 0, 0, 14, 15, 16, 6, 0, 17, 18, 19, 19, + 19, 20, 21, 22, 23, 24, 19, 25, 0, 26, 27, 19, 19, 28, 29, 30, + 0, 31, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 19, 28, 0, + 32, 33, 9, 34, 35, 19, 0, 0, 36, 37, 38, 39, 40, 19, 0, 41, + 42, 43, 44, 31, 0, 1, 45, 42, 0, 0, 0, 0, 0, 32, 14, 14, + 0, 0, 0, 0, 14, 0, 0, 46, 47, 47, 47, 47, 48, 49, 47, 47, + 47, 47, 50, 51, 52, 53, 43, 21, 0, 0, 0, 0, 0, 0, 0, 54, + 6, 55, 0, 14, 19, 1, 0, 0, 0, 19, 56, 31, 0, 0, 0, 0, + 0, 0, 0, 57, 14, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, + 0, 0, 0, 58, 59, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 2, 3, 0, 4, 5, 0, 0, 6, 0, 0, 0, 7, 0, 0, + 0, 1, 1, 0, 0, 8, 9, 0, 8, 9, 0, 0, 0, 0, 8, 9, + 10, 11, 12, 0, 0, 0, 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, + 0, 0, 1, 0, 0, 18, 19, 0, 0, 0, 20, 0, 0, 0, 1, 1, + 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 8, 21, 9, 0, 0, + 22, 0, 0, 0, 0, 1, 0, 23, 24, 25, 0, 0, 26, 0, 0, 0, + 8, 21, 27, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 28, 29, 30, + 0, 31, 32, 20, 1, 1, 0, 0, 0, 8, 21, 9, 1, 4, 5, 0, + 0, 0, 33, 9, 0, 1, 1, 1, 0, 8, 21, 21, 21, 21, 34, 1, + 35, 21, 21, 21, 9, 36, 0, 0, 37, 38, 1, 0, 39, 0, 0, 0, + 1, 0, 1, 0, 0, 0, 0, 8, 21, 9, 1, 0, 0, 0, 40, 0, + 8, 21, 21, 21, 21, 21, 21, 21, 21, 9, 0, 1, 1, 1, 1, 8, + 21, 21, 21, 9, 0, 0, 0, 41, 0, 42, 43, 0, 0, 0, 1, 44, + 0, 0, 0, 45, 8, 9, 1, 0, 1, 0, 1, 1, 8, 21, 21, 9, + 0, 4, 5, 8, 9, 1, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, + 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 9, 10, 11, 11, + 11, 11, 11, 12, 12, 12, 12, 13, 14, 15, 16, 17, 18, 12, 19, 12, + 20, 12, 12, 12, 12, 21, 22, 22, 22, 23, 12, 12, 12, 12, 24, 25, + 12, 12, 26, 27, 28, 29, 30, 31, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 32, 12, 33, 7, 7, 34, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, @@ -6038,245 +6110,268 @@ _hb_ucd_u8[13072] = 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 34, 0, 0, 1, 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 32, 33, 33, 33, 34, 35, 35, 35, 35, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 2, 2, 51, 51, 52, 53, 54, 55, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 57, 57, 56, 56, 56, 56, 56, 56, 58, 59, 60, 61, - 56, 62, 62, 63, 64, 65, 66, 67, 68, 69, 70, 56, 62, 62, 62, 62, + 12, 12, 12, 12, 12, 12, 12, 12, 35, 0, 0, 1, 2, 2, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 33, 33, + 33, 34, 35, 35, 35, 35, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 2, 2, 51, 51, 52, 53, 54, 55, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 56, 56, 56, 56, + 56, 56, 58, 59, 60, 61, 56, 62, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 56, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 71, - 62, 62, 62, 62, 72, 72, 72, 72, 72, 72, 72, 72, 72, 73, 74, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 62, 62, 62, 62, 88, 89, 89, 89, 90, 89, - 91, 92, 93, 94, 95, 95, 96, 97, 87, 98, 99,100,101,102,103, 87, - 104,104,104, 87,105,106,107,108,109,110,111,112,113,114,115, 87, - 89, 87,116,117,118,119,120,121,122,123,124, 87,125,126, 87,127, - 128,129,130, 87,131,132, 87,133,134,135, 87, 87,136,137,138,139, - 87,140, 87, 21,141,141,141,141,141,141,141,141,141,141,141, 87, - 87, 87, 87, 87,142,142,142,142,142,142,142,142,142, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,143,143,143,143, - 143, 87, 87, 87,144,144,144,144,145,146,147,147, 87, 87, 87, 87, - 148,148,149,150,151,151,151,151,151,151,151,151,151,151,151,151, - 151,151,151,151,151,151,151,151,151,151, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87,152,153,154,155,155,155, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,156,157, 87, 87, - 87, 87, 87, 87, 56, 56,158,159, 51, 56, 56, 87, 56, 56, 56, 56, - 56, 56, 56, 56,160,160,160,160,160,160, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87,161, 87,162, 87, 87,163, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87,164,164,165, 87, 87, 87, 87, 87, 56, 56, 56, 87, - 89, 89, 87, 87, 56, 56, 56, 56,166, 87, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 62, 62, 62, 62, 62, 62, 62, 62, 87, 87, 87, 87, - 87, 87, 87, 87, 62, 62, 62, 62, 62, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 56, 87,167,167, 0, 1, 2, 2, 0, 1, 2, 2, - 2, 3, 4, 5, 0, 0, 0, 0, 1, 2, 1, 2, 0, 0, 3, 3, - 4, 5, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, - 0, 0, 7, 0, 8, 8, 8, 8, 8, 8, 8, 9, 10, 11, 11, 11, - 11, 11, 12, 11, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 15, 16, 16, 16, 16, 17, 18, 19, 19, - 19, 19, 19, 19, 20, 21, 22, 22, 23, 24, 22, 25, 22, 22, 22, 22, - 22, 26, 22, 22, 27, 27, 27, 27, 27, 22, 22, 22, 28, 28, 28, 28, - 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 27, 27, 22, 22, 22, 22, - 22, 22, 32, 22, 33, 33, 33, 33, 33, 34, 35, 33, 36, 36, 36, 36, - 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 38, 38, 38, 38, - 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 40, 40, 40, 40, - 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 42, 42, 42, 42, - 42, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 44, 44, 44, 44, - 44, 44, 44, 44, 45, 45, 45, 46, 45, 45, 45, 45, 47, 47, 47, 47, - 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 49, 48, 48, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, - 51, 51, 51, 52, 53, 53, 53, 53, 53, 53, 53, 53, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, 56, 56, 56, 56, - 56, 56, 56, 56, 57, 57, 58, 58, 58, 58, 59, 58, 60, 60, 61, 62, - 63, 63, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 66, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 56, 56, 56, 56, 56, 68, 68, 68, 68, - 68, 69, 69, 69, 70, 70, 70, 70, 70, 70, 65, 65, 71, 71, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 8, 8, 8, 8, 8, 73, 73, 73, 73, - 73, 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, 75, 76, 76, 76, 76, - 76, 77, 77, 77, 13, 51, 51, 51, 74, 78, 79, 80, 4, 4, 81, 4, - 4, 82, 83, 84, 4, 4, 4, 85, 8, 8, 8, 8, 11, 11, 11, 11, - 11, 11, 11, 11, 86, 0, 0, 0, 0, 0, 0, 87, 0, 4, 0, 0, - 0, 8, 8, 8, 0, 0, 88, 89, 90, 0, 4, 4, 6, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91, 91, 91, 91, - 91, 91, 91, 91, 92, 92, 92, 92, 92, 92, 4, 4, 93, 93, 93, 93, - 93, 93, 93, 93, 51, 51, 51, 94, 94, 94, 94, 94, 54, 54, 54, 54, - 54, 54, 13, 13, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 0, 96, 0, 97, 98, 99,100,100,100,100,101,102,103, - 103,103,103,104,105,105,105,106, 53, 53, 53, 53, 53, 0,105,105, - 0, 0, 0,103, 53, 53, 0, 0, 0, 0, 53,107, 0, 0, 0, 0, - 0,103,103,108,103,103,103,103,103,109, 0, 0, 95, 95, 95, 95, - 0, 0, 0, 0,110,110,110,110,110,110,110,110,110,110,110,110, - 110,111,111,111,112,112,112,112,112,112,112,112,112,112,112,112, - 13, 13, 13, 13, 13, 13,113,113,113,113,113,113, 0, 0,114, 4, - 4, 4, 4, 4,115, 4, 4, 4, 4, 4, 4, 4,116,116,116, 0, - 117,117,117,117,118,118,118,118,118,118, 33, 33,119,119,120,121, - 121,121, 53, 53,122,122,122,122,123,122, 50, 50,124,124,124,124, - 124,124, 50, 50,125,125,125,125,125,125,126,126, 54, 54, 54, 4, - 4,127,128, 55, 55, 55, 55, 55,126,126,126,126,129,129,129,129, - 129,129,129,129, 4,130, 19, 19, 19, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22,131, 0, 22, 22, 22, 8, 0,132, 0, - 0, 0, 0, 22, 22, 22, 22, 22, 22, 22, 22,133, 0, 0, 1, 2, - 1, 2,134,102,103,135, 53, 53, 53, 53, 0, 0,136,136,136,136, - 136,136,136,136, 0, 0, 0, 0, 11, 11, 11, 11, 11, 0, 11, 11, - 11, 0, 0,137,138,138,139,139,139,139,140, 0,141,141,141,142, - 142,143,143,143,144,144,145,145,145,145,145,145,146,146,146,146, - 146,147,147,147,148,148,148,149,149,149,149,149,150,150,150,151, - 151,151,151,151,152,152,152,152,152,152,152,152,153,153,153,153, - 154,154,155,155,156,156,156,156,156,156,157,157,158,158,159,159, - 159,159,159,159,160,160,161,161,161,161,161,161,162,162,162,162, - 162,162,163,163,164,164,164,164,165,165,165,165,166,166,166,166, - 167,167,168,168,169,169,169,169,169,169,169,169,170,170,170,170, - 170,170,170,170,171,171,171,171,171,171,171,171,172,172,172,172, - 172,172,172,172,173,173,173,174,174,174,174,174,175,175,175,175, - 175,175,175,175,176,176,176,176,176,176,176,176,177,177,177,177, - 177,178,178,178,179,179,179,179,179,180,180,180,181,181,181,181, - 181,181,182, 44,183,183,183,183,183,183,183,183,184,184,184,185, - 185,185,185,185,186,186,186,187,186,186,186,186,188,188,188,188, - 188,188,188,188,189,189,189,189,189,189,189,189,190,190,190,190, - 190,190,190,190,191,191,191,191,191,191, 67, 67,192,192,192,192, - 192,192,192,192,193,193,193,193,193,193,193,193,194,194,194,194, - 194,194,194,194,195,195,195,195,195,195,195,195,196,196,196,196, - 196,196,196,196,197,197,197,197,197,198,198,198,198,198,198,198, - 199,199,199,199,200,200,200,200,200,200,200,201,201,201,201,201, - 201,201,201,201,202,202,202,202,202,202,203,203,203,203,203,203, - 203,203,203,203,204,204,204,204,204,204,204,204,205,205,205,205, - 205,205,205,205,206,206,206,206,206,206,206,206,207,207,207,207, - 207,207,207,207,113,113,113,113,113,113,113,113,113,113,113,113, - 208,208,208,208,209,209,209,209,209,209,209,209,210,210,210,210, - 210,210,210,210,211,211,211,211,211,211,211,211,212,212,212,212, - 212,212,212,212,212,212,212,212,212,212,213, 0,214,214,214,214, - 214,214,214,214,215,100,100,100,100,100,100,100,100,100,100,100, - 100,100,100,100,100,100,100,100,100,100,216,217,217,217,217,217, - 217,217,217,217,218,218,218,218,218,218,218,218,218,218, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,219,220,221, 0,222, 0, - 0, 0, 0, 0,223,223,223,223,223,223,223,223, 92, 92, 92, 92, - 92, 92, 92, 92,224,224,224,224,224,224,224,224,225,225,225,225, - 225,225,225,225,226,226,226,226,226,226,226,226,227,227,227,227, - 227,227,227,227,228, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, - 8, 8, 8, 8, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 3, 0, - 0, 0, 4, 0, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 5, 0, - 2, 5, 6, 0, 7, 7, 7, 7, 8, 9, 8, 10, 8, 11, 8, 8, - 8, 8, 8, 8, 12, 13, 13, 13, 14, 14, 14, 14, 14, 15, 14, 14, - 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 17, 19, 20, 20, 20, - 20, 20, 20, 20, 21, 22, 21, 23, 21, 21, 24, 24, 21, 21, 21, 21, - 23, 21, 25, 7, 7, 26, 21, 21, 27, 21, 21, 21, 21, 21, 21, 22, - 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, - 32, 32, 32, 32, 33, 21, 21, 21, 34, 34, 34, 34, 35, 36, 34, 34, - 34, 37, 34, 34, 38, 38, 38, 38, 39, 39, 39, 39, 40, 40, 40, 40, - 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, 44, 44, 44, 44, - 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 48, - 49, 49, 49, 49, 50, 50, 50, 50, 50, 51, 52, 50, 53, 53, 53, 53, - 54, 54, 54, 54, 54, 54, 55, 54, 56, 56, 56, 56, 57, 57, 57, 57, - 58, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 60, 61, 61, 61, 61, - 61, 61, 62, 63, 64, 64, 64, 64, 65, 65, 65, 65, 65, 66, 0, 0, - 67, 67, 67, 67, 68, 68, 68, 68, 69, 69, 69, 69, 70, 71, 72, 72, - 72, 72, 72, 72, 73, 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, 75, - 76, 76, 76, 76, 77, 77, 77, 77, 78, 78, 78, 78, 79, 79, 79, 79, - 80, 80, 80, 80, 81, 81, 81, 81, 82, 82, 82, 82, 83, 7, 7, 7, - 84, 7, 85, 86, 0, 85, 87, 0, 2, 88, 89, 2, 2, 2, 2, 90, - 91, 88, 92, 2, 2, 2, 93, 2, 2, 2, 2, 94, 0, 0, 0, 87, - 1, 0, 0, 95, 0, 96, 97, 0, 4, 0, 0, 0, 0, 0, 0, 4, - 98, 98, 98, 98, 99, 99, 99, 99, 13, 13, 13, 13,100,100,100,100, - 101,101,101,101, 0,102, 0, 0,103,101,104,105, 0, 0,101, 0, - 106,107,107,107,107,107,107,107,107,107,108,106,109,110,110,110, - 110,110,110,110,110,110,111,109,112,112,112,112,113, 56, 56, 56, - 56, 56, 56,114,110,110,110,111,110,110, 0, 0,115,115,115,115, - 116,116,116,116,117,117,117,117,118,118,118,118, 97, 2, 2, 2, - 2, 2, 95, 2,119,119,119,119,120,120,120,120,121,121,121,121, - 122,122,122,122,122,122,122,123,124,124,124,124,125,125,125,125, - 125,125,125,126,127,127,127,127,128,128,128,128,129,129,129,129, - 2, 2, 3, 2, 2,130, 2, 2,131,131,131,131,132, 17, 17, 19, - 21, 21, 21,133, 7, 7, 7,134, 21, 21, 21, 24, 0,135,110,110, - 110,110,110,136,137,137,137,137, 0, 0, 0,138,139,139,139,139, - 140,140,140,140, 85, 0, 0, 0,141,141,141,141,142,142,142,142, - 143,143,143,143,144,144,144,144,145,145,145,145,146,146,146,146, - 147,147,147,147,148,148,148,148,149,149,149,149,150,150,150,150, - 151,151,151,151,152,152,152,152,153,153,153,153,154,154,154,154, - 155,155,155,155,156,156,156,156,157,157,157,157,158,158,158,158, - 159,159,159,159,160,160,160,160,161,161,161,161,162,162,162,162, - 163,163,163,163,164,164,164,164,165,165,165,165,166,166,166,166, - 167,167,167,167,168,168,168,168,169,169,169,169,170,170,170,170, - 171,171,171,171,172,172,172,172,173,173,173,173,174,174,174,174, - 175,175,175,175,176,176,176,176,177,177,177,177,178,178,178,178, - 179,179,179,179,180,180,180,180,181,181,181,181,182, 46, 46, 46, - 183,183,183,183,184,184,184,184,185,185,185,185,186,186,186,186, - 186,186,187,186,188,188,188,188,189,189,189,189,190,190,190,190, - 191,191,191,191,192,192,192,192,193,193,193,193,194,194,194,194, - 195,195,195,195,196,196,196,196,197,197,197,197,198,198,198,198, - 199,199,199,199,200,200,200,200,201,201,201,201,202,202,202,202, - 203,203,203,203,204,204,204,204,205,205,205,205,206,206,206,206, - 207,207,207,207,208,208,208,208,209,209,209,209,210,210,210,210, - 211,211,211,211,212,212,212,212,213, 0, 0, 0,214,214,214,214, - 215,107,107,107,107,110,110,110,216,216,216,216,217,217,217,217, - 0,218, 87, 0, 0, 0,218, 7, 83,138, 7, 0, 0, 0,219, 87, - 220,220,220,220,221,221,221,221,222,222,222,222,223,223,223,223, - 224,224,224,224,225, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 19, 0, 19, 0, 0, 0, - 0, 0, 26, 26, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, - 9, 9, 0, 9, 9, 0, 9, 0, 9, 9, 55, 55, 55, 55, 55, 55, - 6, 6, 6, 6, 6, 1, 1, 6, 6, 4, 4, 4, 4, 4, 4, 4, - 4, 0, 4, 4, 4, 14, 14, 14, 14, 14, 14, 14, 3, 3, 3, 3, - 3, 0, 3, 3, 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 1, - 1, 1, 3, 3, 1, 3, 3, 3, 37, 37, 37, 37, 38, 38, 38, 38, - 64, 64, 64, 64, 90, 90, 90, 90, 95, 95, 95, 95, 3, 3, 0, 3, - 7, 7, 7, 7, 7, 1, 1, 1, 1, 7, 7, 7, 0, 0, 7, 7, - 5, 5, 5, 5, 11, 11, 11, 11, 10, 10, 10, 10, 21, 21, 21, 21, - 22, 22, 22, 22, 23, 23, 23, 23, 16, 16, 16, 16, 20, 20, 20, 20, - 36, 36, 36, 36, 24, 24, 24, 24, 24, 24, 24, 0, 18, 18, 18, 18, - 25, 25, 25, 25, 25, 0, 0, 0, 0, 25, 25, 25, 33, 33, 33, 33, - 8, 8, 8, 8, 8, 8, 8, 0, 12, 12, 12, 12, 30, 30, 30, 30, - 29, 29, 29, 29, 28, 28, 28, 28, 34, 34, 34, 34, 35, 35, 35, 35, - 35, 35, 35, 0, 0, 0, 35, 35, 45, 45, 45, 45, 44, 44, 44, 44, - 44, 0, 0, 0, 43, 43, 43, 43, 46, 46, 46, 46, 31, 31, 31, 31, - 32, 32, 0, 0, 32, 0, 32, 32, 32, 32, 32, 32, 48, 48, 48, 48, - 52, 52, 52, 52, 58, 58, 58, 58, 54, 54, 54, 54, 91, 91, 91, 91, - 62, 62, 62, 62, 76, 76, 76, 76, 93, 93, 93, 93, 70, 70, 70, 70, - 73, 73, 73, 73, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, - 0, 1, 0, 0, 1, 1, 0, 0, 19, 19, 9, 9, 9, 9, 9, 6, - 19, 9, 9, 9, 9, 9, 19, 19, 9, 9, 9, 19, 6, 19, 19, 19, - 19, 19, 19, 9, 0, 0, 0, 19, 0, 0, 9, 0, 0, 0, 19, 19, - 27, 27, 27, 27, 56, 56, 56, 56, 61, 61, 61, 61, 13, 13, 13, 13, - 0, 13, 0, 13, 0, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, - 0, 15, 15, 15, 15, 15, 15, 15, 15, 1, 1, 0, 0, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 0, 26, 26, 26, 26, 26, 12, 12, 12, - 12, 12, 12, 0, 39, 39, 39, 39, 86, 86, 86, 86, 77, 77, 77, 77, - 79, 79, 79, 79, 60, 60, 60, 60, 65, 65, 65, 65, 75, 75, 75, 75, - 69, 69, 69, 69, 69, 69, 0, 69, 74, 74, 74, 74, 84, 84, 84, 84, - 84, 84, 84, 0, 68, 68, 68, 68, 92, 92, 92, 92, 87, 87, 87, 87, - 19, 9, 19, 19, 2, 2, 2, 2, 19, 19, 19, 4, 3, 3, 0, 0, - 1, 1, 6, 6, 0, 0, 17, 17, 17, 17, 0, 0, 49, 49, 49, 49, - 0, 1, 1, 1, 71, 71, 71, 71, 67, 67, 67, 67, 42, 42, 42, 42, - 41, 41, 41, 41,118,118,118,118, 53, 53, 53, 53, 59, 59, 59, 59, - 40, 40, 40, 40, 51, 51, 51, 51, 50, 50, 50, 50,135,135,135,135, - 106,106,106,106,104,104,104,104,110,110,110,110, 47, 47, 47, 47, - 81, 81, 81, 81,120,120,120,120,116,116,116,116,128,128,128,128, - 66, 66, 66, 66, 72, 72, 72, 72, 98, 98, 98, 98, 97, 97, 97, 97, - 57, 57, 57, 57, 88, 88, 88, 88,117,117,117,117,112,112,112,112, - 78, 78, 78, 78, 83, 83, 83, 83, 82, 82, 82, 82,122,122,122,122, - 89, 89, 89, 89,130,130,130,130,144,144,144,144,147,147,147,147, - 148,148,148,148,149,149,149,149, 94, 94, 94, 94, 85, 85, 85, 85, - 101,101,101,101, 96, 96, 96, 96,111,111,111,111,100,100,100,100, - 100, 36, 36, 36,108,108,108,108,129,129,129,129,109,109,109,109, - 107,107,107,107,107,107,107, 1,137,137,137,137,124,124,124,124, - 123,123,123,123,114,114,114,114,102,102,102,102,126,126,126,126, - 142,142,142,142,125,125,125,125,150,150,150,150,141,141,141,141, - 140,140,140,140,121,121,121,121,133,133,133,133,134,134,134,134, - 138,138,138,138,143,143,143,143,145,145,145,145, 63, 63, 63, 63, - 80, 80, 80, 80,127,127,127,127,115,115,115,115,103,103,103,103, - 119,119,119,119,146,146,146,146, 99, 99, 99, 99,136,139, 0, 0, - 136,136,136,136, 17, 15, 15, 15,139,139,139,139,105,105,105,105, - 0, 0, 0, 1, 0, 0, 1, 1,131,131,131,131,151,151,151,151, - 152,152,152,152,113,113,113,113,132,132,132,132, 15, 0, 0, 0, - 16, 50, 84,118, 88, 89, 90, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 91, - 85, 85,220, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 94, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 15, + 62, 62, 62, 62, 62, 71, 62, 62, 62, 62, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 73, 74, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 62, 62, 62, 62, + 88, 89, 89, 89, 90, 89, 91, 92, 93, 94, 95, 95, 96, 97, 87, 98, + 99,100,101,102,103, 87,104,104,104, 87,105,106,107,108,109,110, + 111,112,113,114,115, 87, 89,116,117,118,119,120,121,122,123,124, + 125, 87,126,127, 87,128,129,130,131, 87,132,133,134,135,136,137, + 87, 87,138,139,140,141, 87,142, 87,143,144,144,144,144,144,144, + 144,144,144,144,144, 87, 87, 87, 87, 87,145,145,145,145,145,145, + 145,145,145, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87,146,146,146,146,146, 87, 87, 87,147,147,147,147,148,149, + 150,150, 87, 87, 87, 87,151,151,152,153,154,154,154,154,154,154, + 154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, + 155,155,155,155,154, 87, 87, 87, 87, 87,156,157,158,159,159,159, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87,160,161, 87, 87, 87, 87, 87, 87, 56, 56,162,163, 51, 56, + 56, 87, 56, 56, 56, 56, 56, 56, 56, 56,164,164,164,164,164,164, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,165, 87,166, 87, 87,167, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,168,168,169, 87, 87, 87, + 87, 87, 56, 56, 56, 87, 89, 89, 87, 87, 56, 56, 56, 56,170, 87, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 87, 87, 87, 87, 87, 87, 87, 87, 62, 62, 62, 62, 62, 62, + 62, 62, 87, 87, 87, 87, 87, 87, 87, 87, 62, 62, 62, 62, 62, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 62, 62, 62, 62, 62, 62, + 62, 87, 87, 87, 87, 87, 87, 87, 87, 87, 56, 87,171,171, 0, 1, + 2, 2, 0, 1, 2, 2, 2, 3, 4, 5, 0, 0, 0, 0, 1, 2, + 1, 2, 0, 0, 3, 3, 4, 5, 4, 5, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 6, 0, 0, 7, 0, 8, 8, 8, 8, 8, 8, + 8, 9, 10, 11, 11, 11, 11, 11, 12, 11, 13, 13, 13, 13, 13, 13, + 13, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 15, 16, 16, + 16, 16, 16, 17, 18, 18, 18, 18, 18, 18, 19, 20, 21, 21, 22, 23, + 21, 24, 21, 21, 21, 21, 21, 25, 21, 21, 26, 26, 26, 26, 26, 21, + 21, 21, 27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, + 26, 26, 21, 21, 21, 21, 21, 21, 31, 21, 32, 32, 32, 32, 32, 33, + 34, 32, 35, 35, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, + 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, 38, + 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, + 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 42, 42, 42, 42, 42, 42, + 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 44, 44, 44, 45, 44, 44, + 44, 44, 46, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 48, 47, 47, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 50, 50, 50, 50, 50, 51, 52, 52, 52, 52, 52, 52, + 52, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 54, 54, 54, 54, + 54, 54, 55, 55, 55, 55, 55, 55, 55, 55, 56, 56, 57, 57, 57, 57, + 58, 57, 59, 59, 60, 61, 62, 62, 63, 63, 64, 64, 64, 64, 64, 64, + 64, 64, 65, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 55, 55, 55, + 55, 55, 67, 67, 67, 67, 67, 68, 68, 68, 69, 69, 69, 69, 69, 69, + 64, 64, 70, 70, 71, 71, 71, 71, 71, 71, 71, 71, 71, 8, 8, 8, + 8, 8, 72, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 74, 74, + 74, 74, 75, 75, 75, 75, 75, 76, 76, 76, 13, 50, 50, 50, 73, 77, + 78, 79, 4, 4, 80, 4, 4, 81, 82, 83, 4, 4, 4, 84, 8, 8, + 8, 8, 11, 11, 11, 11, 11, 11, 11, 11, 85, 0, 0, 0, 0, 0, + 0, 86, 0, 4, 0, 0, 0, 8, 8, 8, 0, 0, 87, 88, 89, 0, + 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, + 4, 4, 92, 92, 92, 92, 92, 92, 92, 92, 50, 50, 50, 93, 93, 93, + 93, 93, 53, 53, 53, 53, 53, 53, 13, 13, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 0, 95, 0, 96, 97, 98, 99, + 99, 99, 99,100,101,102,102,102,102,103,104,104,104,105, 52, 52, + 52, 52, 52, 0,104,104, 0, 0, 0,102, 52, 52, 0, 0, 0, 0, + 52,106, 0, 0, 0, 0, 0,102,102,107,102,102,102,102,102,108, + 0, 0, 94, 94, 94, 94, 0, 0, 0, 0,109,109,109,109,109,109, + 109,109,109,109,109,109,109,110,110,110,111,111,111,111,111,111, + 111,111,111,111,111,111, 13, 13, 13, 13, 13, 13,112,112,112,112, + 112,112, 0, 0,113, 4, 4, 4, 4, 4,114, 4, 4, 4, 4, 4, + 4, 4,115,115,115, 0,116,116,116,116,117,117,117,117,117,117, + 32, 32,118,118,119,120,120,120, 52, 52,121,121,121,121,122,121, + 49, 49,123,123,123,123,123,123, 49, 49,124,124,124,124,124,124, + 125,125, 53, 53, 53, 4, 4,126,127, 54, 54, 54, 54, 54,125,125, + 125,125,128,128,128,128,128,128,128,128, 4,129, 18, 18, 18, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,130, 0, 21, + 21, 21, 8, 0,131, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 21, + 21,132, 0, 0, 1, 2, 1, 2,133,101,102,134, 52, 52, 52, 52, + 0, 0,135,135,135,135,135,135,135,135, 0, 0, 0, 0, 11, 11, + 11, 11, 11, 0, 11, 11, 11, 0, 0,136,137,137,138,138,138,138, + 139, 0,140,140,140,141,141,142,142,142,143,143,144,144,144,144, + 144,144,145,145,145,145,145,146,146,146,147,147,147,148,148,148, + 148,148,149,149,149,150,150,150,150,150,151,151,151,151,151,151, + 151,151,152,152,152,152,153,153,154,154,155,155,155,155,155,155, + 156,156,157,157,158,158,158,158,158,158,159,159,160,160,160,160, + 160,160,161,161,161,161,161,161,162,162,163,163,163,163,164,164, + 164,164,165,165,165,165,166,166,167,167,168,168,168,168,168,168, + 168,168,169,169,169,169,169,169,169,169,170,170,170,170,170,170, + 170,170,171,171,171,171,171,171,171,171,172,172,172,172,172,172, + 172,172,173,173,173,174,174,174,174,174,175,175,175,175,175,175, + 176,176,177,177,177,177,177,177,177,177,178,178,178,178,178,179, + 179,179,180,180,180,180,180,181,181,181,182,182,182,182,182,182, + 183, 43,184,184,184,184,184,184,184,184,185,185,185,186,186,186, + 186,186,187,187,187,188,187,187,187,187,189,189,189,189,189,189, + 189,189,190,190,190,190,190,190,190,190,191,191,191,191,191,191, + 191,191,192,192,192,192,192,192, 66, 66,193,193,193,193,193,193, + 193,193,194,194,194,194,194,194,194,194,195,195,195,195,195,195, + 195,195,196,196,196,196,196,196,196,196,197,197,197,197,197,197, + 197,197,198,198,198,198,198,198,198,198,199,199,199,199,199,200, + 200,200,200,200,200,200,201,201,201,201,202,202,202,202,202,202, + 202,203,203,203,203,203,203,203,203,203,204,204,204,204,204,204, + 205,205,205,205,205,205,205,205,205,205,206,206,206,206,206,206, + 206,206,110,110,110,110, 39, 39, 39, 39,207,207,207,207,207,207, + 207,207,208,208,208,208,208,208,208,208,209,209,209,209,209,209, + 209,209,112,112,112,112,112,112,112,112,112,112,112,112,210,210, + 210,210,211,211,211,211,211,211,211,211,212,212,212,212,212,212, + 212,212,213,213,213,213,213,213,213,213,214,214,214,214,214,214, + 214,214,214,214,214,214,214,214,215, 94,216,216,216,216,216,216, + 216,216,217,217,217,217,217,217,217,217,218, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 219,220,220,220,220,220,220,220,220,220,221,221,221,221,221,221, + 221,221,221,221, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 222,223,224, 0,225, 0, 0, 0, 0, 0,226,226,226,226,226,226, + 226,226, 91, 91, 91, 91, 91, 91, 91, 91,227,227,227,227,227,227, + 227,227,228,228,228,228,228,228,228,228,229,229,229,229,229,229, + 229,229,230,230,230,230,230,230,230,230,231, 0, 0, 0, 0, 0, + 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 1, 2, + 2, 2, 2, 2, 3, 0, 0, 0, 4, 0, 2, 2, 2, 2, 2, 3, + 2, 2, 2, 2, 5, 0, 2, 5, 6, 0, 7, 7, 7, 7, 8, 9, + 8, 10, 8, 11, 8, 8, 8, 8, 8, 8, 12, 13, 13, 13, 14, 14, + 14, 14, 14, 15, 14, 14, 16, 17, 17, 17, 17, 17, 17, 17, 18, 19, + 19, 19, 19, 19, 19, 19, 20, 21, 20, 22, 20, 20, 23, 23, 20, 20, + 20, 20, 22, 20, 24, 7, 7, 25, 20, 20, 26, 20, 20, 20, 20, 20, + 20, 21, 27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, + 30, 30, 31, 31, 31, 31, 32, 20, 20, 20, 33, 33, 33, 33, 34, 35, + 33, 33, 33, 36, 33, 33, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, + 39, 39, 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, + 43, 43, 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, + 46, 47, 48, 48, 48, 48, 49, 49, 49, 49, 49, 50, 51, 49, 52, 52, + 52, 52, 53, 53, 53, 53, 53, 53, 54, 53, 55, 55, 55, 55, 56, 56, + 56, 56, 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59, 60, 60, + 60, 60, 60, 60, 61, 62, 63, 63, 63, 63, 64, 64, 64, 64, 64, 65, + 0, 0, 66, 66, 66, 66, 67, 67, 67, 67, 68, 68, 68, 68, 69, 70, + 71, 71, 71, 71, 71, 71, 72, 72, 72, 72, 73, 73, 73, 73, 74, 74, + 74, 74, 75, 75, 75, 75, 76, 76, 76, 76, 77, 77, 77, 77, 78, 78, + 78, 78, 79, 79, 79, 79, 80, 80, 80, 80, 81, 81, 81, 81, 82, 7, + 7, 7, 83, 7, 84, 85, 0, 84, 86, 0, 2, 87, 88, 2, 2, 2, + 2, 89, 90, 87, 91, 2, 2, 2, 92, 2, 2, 2, 2, 93, 0, 0, + 0, 86, 1, 0, 0, 94, 0, 95, 96, 0, 4, 0, 0, 0, 0, 0, + 0, 4, 97, 97, 97, 97, 98, 98, 98, 98, 13, 13, 13, 13, 99, 99, + 99, 99,100,100,100,100, 0,101, 0, 0,102,100,103,104, 0, 0, + 100, 0,105,106,106,106,106,106,106,106,106,106,107,105,108,109, + 109,109,109,109,109,109,109,109,110,108,111,111,111,111,112, 55, + 55, 55, 55, 55, 55,113,109,109,109,110,109,109, 0, 0,114,114, + 114,114,115,115,115,115,116,116,116,116,117,117,117,117, 96, 2, + 2, 2, 2, 2, 94, 2,118,118,118,118,119,119,119,119,120,120, + 120,120,121,121,121,121,121,121,121,122,123,123,123,123,124,124, + 124,124,124,124,124,125,126,126,126,126,127,127,127,127,128,128, + 128,128, 2, 2, 3, 2, 2,129,130, 0,131,131,131,131,132, 17, + 17, 18, 20, 20, 20,133, 7, 7, 7,134, 20, 20, 20, 23, 0,135, + 109,109,109,109,109,136,137,137,137,137, 0, 0, 0,138,139,139, + 139,139,140,140,140,140, 84, 0, 0, 0,141,141,141,141,142,142, + 142,142,143,143,143,143,144,144,144,144,145,145,145,145,146,146, + 146,146,147,147,147,147,148,148,148,148,149,149,149,149,150,150, + 150,150,151,151,151,151,152,152,152,152,153,153,153,153,154,154, + 154,154,155,155,155,155,156,156,156,156,157,157,157,157,158,158, + 158,158,159,159,159,159,160,160,160,160,161,161,161,161,162,162, + 162,162,163,163,163,163,164,164,164,164,165,165,165,165,166,166, + 166,166,167,167,167,167,168,168,168,168,169,169,169,169,170,170, + 170,170,171,171,171,171,172,172,172,172,173,173,173,173,174,174, + 174,174,175,175,175,175,176,176,176,176,177,177,177,177,178,178, + 178,178,179,179,179,179,180,180,180,180,181,181,181,181,182,182, + 182,182,183,183,183,183,184, 45, 45, 45,185,185,185,185,186,186, + 186,186,187,187,187,187,188,188,188,188,188,188,189,188,190,190, + 190,190,191,191,191,191,192,192,192,192,193,193,193,193,194,194, + 194,194,195,195,195,195,196,196,196,196,197,197,197,197,198,198, + 198,198,199,199,199,199,200,200,200,200,201,201,201,201,202,202, + 202,202,203,203,203,203,204,204,204,204,205,205,205,205,206,206, + 206,206,207,207,207,207,208,208,208,208,209,209,209,209,210,210, + 210,210,211,211,211,211,212,212,212,212,213,213,213,213,214,214, + 214,214,215,215,215,215,216,217,217,217,218,218,218,218,217,217, + 217,217,219,106,106,106,106,109,109,109,220,220,220,220,221,221, + 221,221, 0,222, 86, 0, 0, 0,222, 7, 82,138, 7, 0, 0, 0, + 223, 86,224,224,224,224,225,225,225,225,226,226,226,226,227,227, + 227,227,228,228,228,228,229, 0, 0, 0, 0, 0, 0, 0, 0, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 19, 0, 19, 0, + 0, 0, 0, 0, 26, 26, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, + 9, 9, 9, 9, 0, 9, 9, 0, 9, 0, 9, 9, 55, 55, 55, 55, + 55, 55, 6, 6, 6, 6, 6, 1, 1, 6, 6, 4, 4, 4, 4, 4, + 4, 4, 4, 14, 14, 14, 14, 14, 14, 14, 3, 3, 3, 3, 3, 0, + 3, 3, 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 1, 1, 1, + 3, 3, 1, 3, 3, 3, 37, 37, 37, 37, 38, 38, 38, 38, 64, 64, + 64, 64, 90, 90, 90, 90, 95, 95, 95, 95, 3, 3, 0, 3, 7, 7, + 7, 7, 7, 1, 1, 1, 1, 7, 7, 7, 0, 0, 7, 7, 5, 5, + 5, 5, 11, 11, 11, 11, 10, 10, 10, 10, 21, 21, 21, 21, 22, 22, + 22, 22, 23, 23, 23, 23, 16, 16, 16, 16, 20, 20, 20, 20, 36, 36, + 36, 36, 24, 24, 24, 24, 24, 24, 24, 0, 18, 18, 18, 18, 25, 25, + 25, 25, 25, 0, 0, 0, 0, 25, 25, 25, 33, 33, 33, 33, 8, 8, + 8, 8, 8, 8, 8, 0, 12, 12, 12, 12, 30, 30, 30, 30, 29, 29, + 29, 29, 28, 28, 28, 28, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, + 35, 0, 0, 0, 35, 35, 45, 45, 45, 45, 44, 44, 44, 44, 44, 0, + 0, 0, 43, 43, 43, 43, 46, 46, 46, 46, 31, 31, 31, 31, 32, 32, + 0, 0, 32, 0, 32, 32, 32, 32, 32, 32, 48, 48, 48, 48, 52, 52, + 52, 52, 58, 58, 58, 58, 54, 54, 54, 54, 91, 91, 91, 91, 62, 62, + 62, 62, 76, 76, 76, 76, 93, 93, 93, 93, 70, 70, 70, 70, 73, 73, + 73, 73, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, + 0, 0, 1, 1, 0, 0, 19, 19, 9, 9, 9, 9, 9, 6, 19, 9, + 9, 9, 9, 9, 19, 19, 9, 9, 9, 19, 6, 19, 19, 19, 19, 19, + 19, 9, 0, 0, 0, 19, 0, 0, 9, 0, 0, 0, 19, 19, 27, 27, + 27, 27, 56, 56, 56, 56, 61, 61, 61, 61, 13, 13, 13, 13, 0, 13, + 0, 13, 0, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 0, 15, + 15, 15, 15, 15, 15, 15, 15, 1, 1, 0, 0, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 0, 26, 26, 26, 26, 26, 12, 12, 12, 12, 12, + 12, 0, 39, 39, 39, 39, 86, 86, 86, 86, 77, 77, 77, 77, 79, 79, + 79, 79, 60, 60, 60, 60, 65, 65, 65, 65, 75, 75, 75, 75, 69, 69, + 69, 69, 69, 69, 0, 69, 74, 74, 74, 74, 84, 84, 84, 84, 84, 84, + 84, 0, 68, 68, 68, 68, 92, 92, 92, 92, 87, 87, 87, 87, 19, 9, + 19, 19, 19, 19, 0, 0, 2, 2, 2, 2, 19, 19, 19, 4, 3, 3, + 0, 0, 1, 1, 6, 6, 0, 0, 17, 17, 17, 17, 0, 0, 49, 49, + 49, 49, 0, 1, 1, 1, 71, 71, 71, 71, 67, 67, 67, 67, 42, 42, + 42, 42, 41, 41, 41, 41,118,118,118,118, 53, 53, 53, 53, 59, 59, + 59, 59, 40, 40, 40, 40, 51, 51, 51, 51, 50, 50, 50, 50,135,135, + 135,135,106,106,106,106,104,104,104,104,110,110,110,110, 47, 47, + 47, 47, 81, 81, 81, 81,120,120,120,120,116,116,116,116,128,128, + 128,128, 66, 66, 66, 66, 72, 72, 72, 72, 98, 98, 98, 98, 97, 97, + 97, 97, 57, 57, 57, 57, 88, 88, 88, 88,117,117,117,117,112,112, + 112,112, 78, 78, 78, 78, 83, 83, 83, 83, 82, 82, 82, 82,122,122, + 122,122, 89, 89, 89, 89,130,130,130,130,144,144,144,144,156,156, + 156,156,147,147,147,147,148,148,148,148,153,153,153,153,149,149, + 149,149, 94, 94, 94, 94, 85, 85, 85, 85,101,101,101,101, 96, 96, + 96, 96,111,111,111,111,100,100,100,100,100, 36, 36, 36,108,108, + 108,108,129,129,129,129,109,109,109,109,107,107,107,107,107,107, + 107, 1,137,137,137,137,124,124,124,124,123,123,123,123,114,114, + 114,114,102,102,102,102,126,126,126,126,142,142,142,142,125,125, + 125,125,154,154,154,154,150,150,150,150,141,141,141,141,140,140, + 140,140,121,121,121,121,133,133,133,133,134,134,134,134,138,138, + 138,138,143,143,143,143,145,145,145,145, 63, 63, 63, 63, 80, 80, + 80, 80,127,127,127,127,115,115,115,115,103,103,103,103,119,119, + 119,119,146,146,146,146, 99, 99, 99, 99,136,139, 0, 0,155,155, + 155,155,136,136,136,136, 17, 15, 15, 15,139,139,139,139,105,105, + 105,105, 0, 0, 0, 1, 0, 0, 1, 1,131,131,131,131,151,151, + 151,151,152,152,152,152,113,113,113,113,132,132,132,132, 15, 0, + 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 10, + 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 16, 17, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 19, 20, 9, 21, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 22, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6298,30 +6393,18 @@ _hb_ucd_u8[13072] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 68, 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 0, 0, 0, 0, 0, 0,105,106, 0,107, 0, 0, 0, 108, 0,109, 0,110, 0,111,112,113, 0,114, 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,118,119,120,121, 0,122,123,124,125,126, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, 144,145,146,147,148,149,150,151,152,153,154,155,156,157, 0, 0, 0,158,159,160,161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6332,18 +6415,16 @@ _hb_ucd_u8[13072] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,168,169, 0, 0, 0, 0,170,171, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187, - 188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203, - 204,205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,169,170, 0, 0, 0, 0,171,172, 0, 0, 0, + 173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188, + 189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204, + 205,206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, }; static const uint16_t -_hb_ucd_u16[4800] = +_hb_ucd_u16[4848] = { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, @@ -6358,7 +6439,7 @@ _hb_ucd_u16[4800] = 82, 47, 47, 83, 84, 85, 86, 87, 82, 47, 47, 77, 88, 47, 80, 89, 90, 47, 47, 91, 92, 93, 80, 94, 95, 47, 47, 96, 97, 98, 99, 100, 101, 47, 47, 102, 103, 104, 80, 105, 106, 47, 47, 91, 107, 108, 80, 109, - 90, 47, 47, 110, 111, 112, 80, 113, 114, 47, 47, 47, 115, 116, 99, 117, + 110, 47, 47, 111, 112, 113, 80, 114, 90, 47, 47, 47, 115, 116, 99, 117, 47, 47, 47, 118, 119, 120, 66, 66, 47, 47, 47, 121, 122, 123, 47, 47, 124, 125, 126, 127, 47, 47, 47, 128, 129, 32, 32, 130, 131, 132, 66, 66, 47, 47, 133, 134, 120, 135, 136, 137, 138, 139, 9, 9, 9, 11, 11, 140, @@ -6368,77 +6449,79 @@ _hb_ucd_u16[4800] = 47, 152, 47, 153, 47, 152, 47, 152, 47, 47, 47, 154, 155, 156, 157, 143, 158, 157, 47, 47, 159, 47, 47, 47, 160, 47, 161, 47, 47, 47, 47, 47, 47, 47, 162, 163, 164, 47, 47, 47, 47, 47, 47, 47, 47, 165, 144, 144, - 47, 166, 47, 47, 47, 167, 168, 169, 157, 157, 170, 171, 172, 172, 172, 172, - 173, 47, 47, 174, 175, 120, 176, 177, 178, 47, 179, 61, 47, 47, 180, 181, - 47, 47, 182, 183, 184, 61, 47, 185, 11, 9, 9, 9, 66, 186, 187, 188, - 11, 11, 189, 27, 27, 27, 190, 191, 11, 192, 27, 27, 32, 32, 32, 32, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 193, 13, 13, 13, 13, 13, 13, - 194, 194, 194, 194, 194, 195, 194, 11, 196, 196, 196, 197, 198, 199, 199, 198, - 200, 201, 202, 203, 204, 205, 206, 207, 208, 27, 209, 209, 209, 210, 211, 32, - 212, 213, 214, 215, 216, 143, 217, 217, 218, 219, 220, 144, 221, 222, 144, 223, - 224, 224, 224, 224, 224, 224, 224, 224, 225, 144, 226, 144, 144, 144, 144, 227, - 144, 228, 224, 229, 144, 230, 231, 144, 144, 144, 144, 144, 144, 144, 143, 143, - 143, 232, 144, 144, 144, 144, 233, 143, 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 234, 235, 144, 144, 236, 144, 144, 144, 144, 144, 144, 237, 144, - 144, 144, 144, 144, 144, 144, 238, 239, 143, 240, 144, 144, 241, 224, 242, 224, - 243, 244, 224, 224, 224, 245, 224, 246, 144, 144, 144, 224, 247, 144, 144, 144, - 9, 9, 9, 11, 11, 11, 248, 249, 13, 13, 13, 13, 13, 13, 250, 251, - 11, 11, 11, 47, 47, 47, 252, 253, 47, 47, 47, 47, 47, 47, 32, 32, - 254, 255, 256, 257, 258, 66, 66, 66, 259, 260, 261, 262, 263, 47, 47, 47, + 47, 166, 47, 47, 47, 167, 168, 169, 157, 157, 170, 171, 32, 32, 32, 32, + 172, 47, 47, 173, 174, 120, 175, 176, 177, 47, 178, 61, 47, 47, 179, 180, + 47, 47, 181, 182, 183, 61, 47, 184, 11, 9, 9, 9, 66, 185, 186, 187, + 11, 11, 188, 27, 27, 27, 189, 190, 11, 191, 27, 27, 32, 32, 32, 32, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 192, 13, 13, 13, 13, 13, 13, + 193, 193, 193, 193, 193, 194, 193, 11, 195, 195, 195, 196, 197, 198, 198, 197, + 199, 200, 201, 202, 203, 204, 205, 206, 207, 27, 208, 208, 208, 209, 210, 32, + 211, 212, 213, 214, 215, 143, 216, 216, 217, 218, 219, 144, 220, 221, 144, 222, + 223, 223, 223, 223, 223, 223, 223, 223, 224, 144, 225, 144, 144, 144, 144, 226, + 144, 227, 223, 228, 144, 229, 230, 144, 144, 144, 144, 144, 144, 144, 143, 143, + 143, 231, 144, 144, 144, 144, 232, 143, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 233, 234, 144, 144, 235, 144, 144, 144, 144, 144, 144, 236, 144, + 144, 144, 144, 144, 144, 144, 237, 238, 143, 239, 144, 144, 240, 223, 241, 223, + 242, 243, 223, 223, 223, 244, 223, 245, 144, 144, 144, 223, 246, 144, 144, 144, + 9, 9, 9, 11, 11, 11, 247, 248, 13, 13, 13, 13, 13, 13, 249, 250, + 11, 11, 11, 47, 47, 47, 251, 252, 47, 47, 47, 47, 47, 47, 32, 32, + 253, 254, 255, 256, 257, 258, 66, 66, 259, 260, 261, 262, 263, 47, 47, 47, 47, 264, 146, 47, 47, 47, 47, 265, 47, 266, 47, 47, 144, 144, 144, 47, 144, 144, 267, 144, 268, 269, 144, 144, 267, 144, 144, 269, 144, 144, 144, 144, 47, 47, 47, 47, 144, 144, 144, 144, 47, 270, 47, 47, 47, 47, 47, 47, - 47, 144, 144, 144, 144, 47, 47, 185, 271, 47, 61, 47, 13, 13, 272, 273, + 47, 144, 144, 144, 144, 47, 47, 184, 271, 47, 61, 47, 13, 13, 272, 273, 13, 274, 47, 47, 47, 47, 275, 276, 31, 277, 278, 279, 13, 13, 13, 280, - 281, 282, 283, 284, 285, 9, 9, 286, 287, 47, 288, 289, 47, 47, 47, 290, + 281, 282, 283, 284, 285, 11, 11, 286, 287, 47, 288, 289, 47, 47, 47, 290, 291, 47, 47, 292, 293, 157, 32, 294, 61, 47, 295, 47, 296, 297, 47, 47, 70, 47, 47, 298, 299, 300, 301, 61, 47, 47, 302, 303, 304, 305, 47, 306, - 47, 47, 47, 307, 58, 308, 309, 310, 47, 47, 47, 11, 11, 311, 11, 11, - 11, 11, 11, 11, 47, 47, 312, 157, 313, 313, 313, 313, 313, 313, 313, 313, - 314, 314, 314, 314, 314, 314, 314, 314, 11, 315, 316, 47, 47, 47, 47, 47, - 47, 47, 47, 317, 31, 318, 47, 47, 47, 47, 47, 319, 320, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 321, 32, 322, 32, 323, 324, 325, 326, 47, - 47, 47, 47, 47, 47, 47, 47, 327, 328, 2, 3, 4, 5, 329, 330, 331, - 47, 332, 47, 47, 47, 47, 333, 334, 335, 143, 143, 336, 217, 217, 217, 337, - 338, 144, 144, 144, 144, 144, 144, 339, 340, 340, 340, 340, 340, 340, 340, 340, - 47, 47, 47, 47, 47, 47, 341, 143, 47, 47, 342, 47, 343, 47, 47, 60, - 47, 344, 47, 47, 47, 345, 217, 217, 9, 9, 145, 11, 11, 47, 47, 47, - 47, 47, 157, 9, 9, 145, 11, 11, 47, 47, 47, 47, 47, 47, 344, 66, - 47, 47, 47, 47, 47, 346, 47, 347, 47, 47, 348, 143, 143, 143, 47, 349, - 47, 350, 47, 344, 66, 66, 66, 66, 47, 47, 47, 351, 143, 143, 143, 143, - 352, 47, 47, 353, 143, 66, 47, 354, 47, 355, 143, 143, 356, 47, 357, 66, - 47, 47, 47, 358, 47, 359, 47, 359, 47, 358, 142, 143, 143, 143, 143, 143, - 9, 9, 9, 9, 11, 11, 11, 360, 47, 47, 361, 157, 157, 157, 157, 157, - 143, 143, 143, 143, 143, 143, 143, 143, 47, 355, 362, 47, 60, 363, 66, 66, - 364, 47, 47, 353, 365, 366, 367, 368, 178, 47, 47, 369, 370, 47, 47, 157, - 95, 47, 371, 372, 373, 47, 47, 374, 178, 47, 47, 375, 376, 377, 378, 143, - 47, 47, 379, 380, 32, 32, 32, 32, 47, 47, 358, 47, 47, 381, 169, 157, - 90, 47, 47, 110, 382, 383, 384, 32, 47, 47, 47, 385, 386, 387, 47, 47, - 47, 47, 47, 388, 389, 157, 157, 157, 47, 47, 390, 391, 392, 393, 32, 32, - 47, 47, 47, 394, 395, 157, 66, 66, 47, 47, 396, 397, 157, 157, 157, 157, - 47, 141, 398, 399, 144, 144, 144, 144, 47, 47, 379, 400, 66, 66, 66, 66, - 9, 9, 9, 9, 11, 11, 126, 401, 47, 47, 47, 47, 47, 402, 403, 404, - 405, 47, 47, 406, 407, 408, 47, 47, 409, 410, 66, 66, 47, 47, 47, 47, - 47, 47, 390, 411, 412, 126, 143, 413, 47, 152, 414, 415, 32, 32, 32, 32, - 47, 47, 47, 352, 416, 157, 47, 47, 417, 418, 157, 157, 157, 157, 157, 157, - 47, 47, 47, 47, 47, 47, 47, 419, 143, 143, 143, 143, 143, 420, 421, 422, - 217, 217, 217, 217, 217, 217, 217, 66, 47, 47, 47, 206, 206, 206, 206, 206, - 47, 47, 47, 47, 47, 47, 300, 66, 47, 47, 47, 47, 47, 47, 47, 423, - 47, 47, 47, 424, 425, 426, 427, 47, 9, 9, 9, 9, 9, 9, 11, 11, - 143, 428, 66, 66, 66, 66, 66, 66, 47, 47, 47, 47, 381, 429, 404, 404, - 430, 431, 27, 27, 27, 27, 432, 27, 47, 433, 206, 206, 206, 206, 206, 206, - 144, 144, 144, 144, 144, 144, 434, 435, 436, 144, 437, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 438, 144, 144, 144, 9, 439, 11, 440, 441, 11, 194, 9, - 442, 443, 9, 444, 11, 9, 439, 11, 440, 441, 11, 194, 9, 442, 443, 9, - 444, 11, 9, 439, 11, 440, 441, 11, 194, 9, 442, 443, 9, 444, 11, 9, - 439, 11, 194, 9, 445, 446, 447, 448, 11, 449, 9, 450, 451, 452, 453, 11, - 454, 9, 455, 11, 456, 157, 157, 157, 32, 32, 32, 457, 32, 32, 458, 459, - 460, 461, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 47, 47, 47, 462, 463, 144, 144, 144, 47, 47, 47, 47, 47, 47, 464, 465, - 47, 47, 47, 47, 348, 32, 32, 32, 9, 9, 442, 11, 466, 300, 66, 66, - 143, 143, 467, 468, 143, 143, 143, 143, 143, 143, 469, 143, 143, 143, 143, 143, - 47, 47, 47, 47, 47, 47, 47, 224, 143, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 470, 206, 206, 206, 206, 206, 206, 206, 206, + 47, 47, 47, 307, 58, 308, 309, 310, 47, 47, 47, 11, 11, 311, 312, 11, + 11, 11, 11, 11, 47, 47, 313, 157, 314, 314, 314, 314, 314, 314, 314, 314, + 315, 315, 315, 315, 315, 315, 315, 315, 11, 316, 317, 47, 47, 47, 47, 47, + 47, 47, 47, 318, 31, 319, 47, 47, 47, 47, 47, 320, 321, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 322, 32, 323, 32, 324, 325, 326, 327, 47, + 47, 47, 47, 47, 47, 47, 47, 328, 329, 2, 3, 4, 5, 330, 331, 332, + 47, 333, 47, 47, 47, 47, 334, 335, 336, 143, 143, 337, 216, 216, 216, 338, + 339, 144, 144, 144, 144, 144, 144, 340, 341, 341, 341, 341, 341, 341, 341, 341, + 47, 47, 47, 47, 47, 47, 342, 143, 47, 47, 343, 47, 344, 47, 47, 60, + 47, 345, 47, 47, 47, 346, 216, 216, 9, 9, 145, 11, 11, 47, 47, 47, + 47, 47, 157, 9, 9, 145, 11, 11, 47, 47, 47, 47, 47, 47, 345, 66, + 47, 47, 47, 47, 47, 347, 47, 348, 47, 47, 349, 143, 143, 143, 47, 350, + 47, 351, 47, 345, 66, 66, 66, 66, 47, 47, 47, 352, 143, 143, 143, 143, + 353, 47, 47, 354, 143, 66, 47, 355, 47, 356, 143, 143, 357, 47, 358, 66, + 47, 47, 47, 359, 47, 360, 47, 360, 47, 359, 142, 143, 143, 143, 143, 143, + 9, 9, 9, 9, 11, 11, 11, 361, 47, 47, 362, 157, 157, 157, 157, 157, + 143, 143, 143, 143, 143, 143, 143, 143, 47, 47, 363, 47, 47, 47, 47, 47, + 47, 356, 364, 47, 60, 365, 66, 66, 47, 47, 47, 47, 366, 143, 47, 47, + 367, 47, 47, 354, 368, 369, 370, 371, 177, 47, 47, 372, 373, 47, 47, 157, + 95, 47, 374, 375, 376, 47, 47, 377, 177, 47, 47, 378, 379, 380, 381, 143, + 47, 47, 382, 383, 32, 32, 32, 32, 47, 47, 359, 47, 47, 384, 169, 157, + 90, 47, 47, 111, 385, 386, 387, 32, 47, 47, 47, 388, 389, 390, 47, 47, + 47, 47, 47, 391, 392, 157, 157, 157, 47, 47, 393, 394, 395, 396, 32, 32, + 47, 47, 47, 397, 398, 157, 66, 66, 47, 47, 399, 400, 157, 157, 157, 157, + 47, 141, 401, 402, 144, 144, 144, 144, 47, 47, 382, 403, 66, 66, 66, 66, + 9, 9, 9, 9, 11, 11, 126, 404, 47, 47, 47, 405, 406, 157, 157, 157, + 47, 47, 47, 47, 47, 407, 408, 409, 410, 47, 47, 411, 412, 413, 47, 47, + 414, 415, 66, 66, 47, 47, 47, 47, 47, 47, 393, 416, 417, 126, 143, 418, + 47, 152, 419, 420, 32, 32, 32, 32, 47, 47, 47, 353, 421, 157, 47, 47, + 422, 423, 157, 157, 157, 157, 157, 157, 47, 47, 47, 47, 47, 47, 47, 424, + 47, 47, 47, 47, 143, 425, 426, 427, 216, 216, 216, 216, 216, 216, 216, 66, + 47, 47, 47, 205, 205, 205, 205, 205, 47, 47, 47, 47, 47, 47, 300, 66, + 47, 47, 47, 47, 47, 47, 47, 428, 47, 47, 47, 429, 430, 431, 432, 47, + 9, 9, 9, 9, 9, 9, 11, 11, 143, 433, 66, 66, 66, 66, 66, 66, + 47, 47, 47, 47, 384, 434, 409, 409, 435, 436, 27, 27, 27, 27, 437, 409, + 47, 438, 205, 205, 205, 205, 205, 205, 144, 144, 144, 144, 144, 144, 439, 440, + 441, 144, 442, 144, 144, 144, 144, 144, 144, 144, 144, 144, 443, 144, 144, 144, + 9, 444, 11, 445, 446, 11, 193, 9, 447, 448, 9, 449, 11, 9, 444, 11, + 445, 446, 11, 193, 9, 447, 448, 9, 449, 11, 9, 444, 11, 445, 446, 11, + 193, 9, 447, 448, 9, 449, 11, 9, 444, 11, 193, 9, 450, 451, 452, 453, + 11, 454, 9, 455, 456, 457, 458, 11, 459, 9, 460, 11, 461, 157, 157, 157, + 32, 32, 32, 462, 32, 32, 463, 464, 465, 466, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 47, 467, 468, 144, 144, 144, + 47, 47, 47, 47, 47, 47, 469, 470, 47, 47, 47, 47, 349, 32, 32, 32, + 9, 9, 447, 11, 471, 300, 66, 66, 143, 143, 472, 473, 143, 143, 143, 143, + 143, 143, 474, 143, 143, 143, 143, 143, 47, 47, 47, 47, 47, 47, 47, 223, + 475, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 476, + 144, 144, 144, 144, 144, 144, 144, 157, 205, 205, 205, 205, 205, 205, 205, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082,1086,1110, 0, 0, @@ -6607,10 +6690,11 @@ _hb_ucd_u16[4800] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1944,1943, 0,1945, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1946,1947, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1948,1949, - 1950,1951,1952,1953,1954, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1955,1956,1957,1959,1958, - 1960, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1948, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1949,1950, + 1951,1952,1953,1954,1955, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1956,1957,1958,1960,1959, + 1961, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 104, 107, 826, 114, 118, 119, 121, 123, 124, 127, 125, 34, 830, 130, 131, 132, 137, 827, 35, 133, 139, 829, 142, 143, 112, 144, 145, 924, 151, 152, 37, 157, 158, 159, 160, 38, 165, 166, 169, 171, 172, 173, 174, 176, 177, 178, 179, @@ -6660,12 +6744,12 @@ _hb_ucd_i16[92] = static inline uint_fast8_t _hb_ucd_gc (unsigned u) { - return u<1114112u?_hb_ucd_u8[4840+(((_hb_ucd_u8[1072+(((_hb_ucd_u16[((_hb_ucd_u8[272+(((_hb_ucd_u8[u>>1>>3>>3>>5])<<5)+((u>>1>>3>>3)&31u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; + return u<1114112u?_hb_ucd_u8[4920+(((_hb_ucd_u8[1104+(((_hb_ucd_u16[((_hb_ucd_u8[272+(((_hb_ucd_u8[u>>1>>3>>3>>5])<<5)+((u>>1>>3>>3)&31u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; } static inline uint_fast8_t _hb_ucd_ccc (unsigned u) { - return u<125259u?_hb_ucd_u8[6670+(((_hb_ucd_u8[6166+(((_hb_ucd_u8[5754+(((_hb_ucd_u8[5306+(((_hb_ucd_u8[5182+(u>>2>>2>>2>>4)])<<4)+((u>>2>>2>>2)&15u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; + return u<125259u?_hb_ucd_u8[6796+(((_hb_ucd_u8[6276+(((_hb_ucd_u8[5844+(((_hb_ucd_u8[5508+(((_hb_ucd_u8[5262+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; } static inline unsigned _hb_ucd_b4 (const uint8_t* a, unsigned i) @@ -6675,17 +6759,17 @@ _hb_ucd_b4 (const uint8_t* a, unsigned i) static inline int_fast16_t _hb_ucd_bmg (unsigned u) { - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[7538+(((_hb_ucd_u8[7314+(((_hb_ucd_u8[7218+(((_hb_ucd_b4(7154+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0; + return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[7672+(((_hb_ucd_u8[7448+(((_hb_ucd_u8[7352+(((_hb_ucd_b4(7288+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0; } static inline uint_fast8_t _hb_ucd_sc (unsigned u) { - return u<918016u?_hb_ucd_u8[11048+(((_hb_ucd_u8[10132+(((_hb_ucd_u8[8788+(((_hb_ucd_u8[8228+(((_hb_ucd_u8[7778+(u>>2>>2>>3>>4)])<<4)+((u>>2>>2>>3)&15u))])<<3)+((u>>2>>2)&7u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2; + return u<918016u?_hb_ucd_u8[11242+(((_hb_ucd_u8[10314+(((_hb_ucd_u8[8938+(((_hb_ucd_u8[8362+(((_hb_ucd_u8[7912+(u>>2>>2>>3>>4)])<<4)+((u>>2>>2>>3)&15u))])<<3)+((u>>2>>2)&7u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2; } static inline uint_fast16_t _hb_ucd_dm (unsigned u) { - return u<195102u?_hb_ucd_u16[1504+(((_hb_ucd_u8[12048+(((_hb_ucd_b4(11952+_hb_ucd_u8,u>>4>>6))<<6)+((u>>4)&63u))])<<4)+((u)&15u))]:0; + return u<195102u?_hb_ucd_u16[1536+(((_hb_ucd_u8[12544+(((_hb_ucd_u8[12162+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; } #endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ucd.cc b/src/3rdparty/harfbuzz-ng/src/hb-ucd.cc index b29f2a9c7d..ad72a26c04 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ucd.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ucd.cc @@ -136,20 +136,22 @@ hb_ucd_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED, if ((a & 0xFFFFF800u) == 0x0000u && (b & 0xFFFFFF80) == 0x0300u) { uint32_t k = HB_CODEPOINT_ENCODE3_11_7_14 (a, b, 0); - uint32_t *v = (uint32_t*) hb_bsearch (&k, _hb_ucd_dm2_u32_map, - ARRAY_LENGTH (_hb_ucd_dm2_u32_map), - sizeof (*_hb_ucd_dm2_u32_map), - _cmp_pair_11_7_14); + const uint32_t *v = hb_bsearch (k, + _hb_ucd_dm2_u32_map, + ARRAY_LENGTH (_hb_ucd_dm2_u32_map), + sizeof (*_hb_ucd_dm2_u32_map), + _cmp_pair_11_7_14); if (likely (!v)) return false; u = HB_CODEPOINT_DECODE3_11_7_14_3 (*v); } else { uint64_t k = HB_CODEPOINT_ENCODE3 (a, b, 0); - uint64_t *v = (uint64_t*) hb_bsearch (&k, _hb_ucd_dm2_u64_map, - ARRAY_LENGTH (_hb_ucd_dm2_u64_map), - sizeof (*_hb_ucd_dm2_u64_map), - _cmp_pair); + const uint64_t *v = hb_bsearch (k, + _hb_ucd_dm2_u64_map, + ARRAY_LENGTH (_hb_ucd_dm2_u64_map), + sizeof (*_hb_ucd_dm2_u64_map), + _cmp_pair); if (likely (!v)) return false; u = HB_CODEPOINT_DECODE3_3 (*v); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-unicode-emoji-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-unicode-emoji-table.hh index 1ff79c9778..eb7776eecb 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-unicode-emoji-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-unicode-emoji-table.hh @@ -7,13 +7,13 @@ * on file with this header: * * # emoji-data.txt - * # Date: 2019-01-15, 12:10:05 GMT - * # © 2019 Unicode®, Inc. + * # Date: 2020-01-28, 20:52:38 GMT + * # © 2020 Unicode®, Inc. * # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. * # For terms of use, see http://www.unicode.org/terms_of_use.html * # * # Emoji Data for UTS #51 - * # Version: 12.0 + * # Version: 13.0 * # * # For documentation and usage, see http://www.unicode.org/reports/tr51 */ @@ -36,7 +36,7 @@ _hb_emoji_u8[448] = 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 7, 7, 7, 14, 15, 16, 17, 18, 19, 20, 7, 7, 7, 7, 7, 21, 7, 7, 7, 7, 22, 23, 7, 7, 7, 24, 7, 14, 0, 25, 0, 26, - 27, 28, 29, 14, 30, 31, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 27, 28, 29, 14, 30, 31, 7, 7, 7, 7, 7, 14, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 1, 0, 2, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,254, 7, 3, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc b/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc index 08a4054cd0..7470bb1b6e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc @@ -40,11 +40,16 @@ * @include: hb.h * * Unicode functions are used to access Unicode character properties. - * Client can pass its own Unicode functions to HarfBuzz, or access - * the built-in Unicode functions that come with HarfBuzz. + * With these functions, client programs can query various properties from + * the Unicode Character Database for any code point, such as General + * Category (gc), Script (sc), Canonical Combining Class (ccc), etc. * - * With the Unicode functions, one can query variour Unicode character - * properties, such as General Category, Script, Combining Class, etc. + * Client programs can optionally pass in their own Unicode functions + * that implement the same queries. The set of functions available is + * defined by the virtual methods in #hb_unicode_funcs_t. + * + * HarfBuzz provides built-in default functions for each method in + * #hb_unicode_funcs_t. **/ @@ -133,6 +138,16 @@ hb_unicode_decompose_compatibility_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED #include "hb-icu.h" #endif +/** + * hb_unicode_funcs_get_default: + * + * Fetches a pointer to the default Unicode-functions structure that is used + * when no functions are explicitly set on #hb_buffer_t. + * + * Return value: (transfer none): a pointer to the #hb_unicode_funcs_t Unicode-functions structure + * + * Since: 0.9.2 + **/ hb_unicode_funcs_t * hb_unicode_funcs_get_default () { @@ -155,11 +170,11 @@ hb_unicode_funcs_get_default () /** * hb_unicode_funcs_create: (Xconstructor) - * @parent: (nullable): + * @parent: (nullable): Parent Unicode-functions structure * + * Creates a new #hb_unicode_funcs_t structure of Unicode functions. * - * - * Return value: (transfer full): + * Return value: (transfer full): The Unicode-functions structure * * Since: 0.9.2 **/ @@ -203,25 +218,25 @@ DEFINE_NULL_INSTANCE (hb_unicode_funcs_t) = /** * hb_unicode_funcs_get_empty: * + * Fetches the singleton empty Unicode-functions structure. * - * - * Return value: (transfer full): + * Return value: (transfer full): The empty Unicode-functions structure * * Since: 0.9.2 **/ hb_unicode_funcs_t * hb_unicode_funcs_get_empty () { - return const_cast<hb_unicode_funcs_t *> (&Null(hb_unicode_funcs_t)); + return const_cast<hb_unicode_funcs_t *> (&Null (hb_unicode_funcs_t)); } /** * hb_unicode_funcs_reference: (skip) - * @ufuncs: Unicode functions. + * @ufuncs: The Unicode-functions structure * + * Increases the reference count on a Unicode-functions structure. * - * - * Return value: (transfer full): + * Return value: (transfer full): The Unicode-functions structure * * Since: 0.9.2 **/ @@ -233,9 +248,11 @@ hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs) /** * hb_unicode_funcs_destroy: (skip) - * @ufuncs: Unicode functions. - * + * @ufuncs: The Unicode-functions structure * + * Decreases the reference count on a Unicode-functions structure. When + * the reference count reaches zero, the Unicode-functions structure is + * destroyed, freeing all memory. * * Since: 0.9.2 **/ @@ -256,15 +273,15 @@ hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs) /** * hb_unicode_funcs_set_user_data: (skip) - * @ufuncs: Unicode functions. - * @key: - * @data: - * @destroy: - * @replace: + * @ufuncs: The Unicode-functions structure + * @key: The user-data key + * @data: A pointer to the user data + * @destroy: (nullable): A callback to call when @data is not needed anymore + * @replace: Whether to replace an existing data with the same key * + * Attaches a user-data key/data pair to the specified Unicode-functions structure. * - * - * Return value: + * Return value: %true if success, %false otherwise * * Since: 0.9.2 **/ @@ -280,12 +297,13 @@ hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs, /** * hb_unicode_funcs_get_user_data: (skip) - * @ufuncs: Unicode functions. - * @key: - * + * @ufuncs: The Unicode-functions structure + * @key: The user-data key to query * + * Fetches the user-data associated with the specified key, + * attached to the specified Unicode-functions structure. * - * Return value: (transfer none): + * Return value: (transfer none): A pointer to the user data * * Since: 0.9.2 **/ @@ -299,9 +317,10 @@ hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs, /** * hb_unicode_funcs_make_immutable: - * @ufuncs: Unicode functions. - * + * @ufuncs: The Unicode-functions structure * + * Makes the specified Unicode-functions structure + * immutable. * * Since: 0.9.2 **/ @@ -316,11 +335,12 @@ hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs) /** * hb_unicode_funcs_is_immutable: - * @ufuncs: Unicode functions. - * + * @ufuncs: The Unicode-functions structure * + * Tests whether the specified Unicode-functions structure + * is immutable. * - * Return value: + * Return value: %true if @ufuncs is immutable, %false otherwise * * Since: 0.9.2 **/ @@ -332,11 +352,12 @@ hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs) /** * hb_unicode_funcs_get_parent: - * @ufuncs: Unicode functions. + * @ufuncs: The Unicode-functions structure * + * Fetches the parent of the Unicode-functions structure + * @ufuncs. * - * - * Return value: + * Return value: The parent Unicode-functions structure * * Since: 0.9.2 **/ @@ -389,14 +410,18 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE /** * hb_unicode_compose: - * @ufuncs: Unicode functions. - * @a: - * @b: - * @ab: (out): + * @ufuncs: The Unicode-functions structure + * @a: The first Unicode code point to compose + * @b: The second Unicode code point to compose + * @ab: (out): The composition of @a, @b * + * Fetches the composition of a sequence of two Unicode + * code points. * + * Calls the composition function of the specified + * Unicode-functions structure @ufuncs. * - * Return value: + * Return value: %true if @a and @b composed, %false otherwise * * Since: 0.9.2 **/ @@ -411,14 +436,17 @@ hb_unicode_compose (hb_unicode_funcs_t *ufuncs, /** * hb_unicode_decompose: - * @ufuncs: Unicode functions. - * @ab: - * @a: (out): - * @b: (out): + * @ufuncs: The Unicode-functions structure + * @ab: Unicode code point to decompose + * @a: (out): The first code point of the decomposition of @ab + * @b: (out): The second code point of the decomposition of @ab * + * Fetches the decomposition of a Unicode code point. * + * Calls the decomposition function of the specified + * Unicode-functions structure @ufuncs. * - * Return value: + * Return value: %true if @ab was decomposed, %false otherwise * * Since: 0.9.2 **/ @@ -434,13 +462,14 @@ hb_unicode_decompose (hb_unicode_funcs_t *ufuncs, #ifndef HB_DISABLE_DEPRECATED /** * hb_unicode_decompose_compatibility: - * @ufuncs: Unicode functions. - * @u: - * @decomposed: (out): - * + * @ufuncs: The Unicode-functions structure + * @u: Code point to decompose + * @decomposed: (out): Compatibility decomposition of @u * + * Fetches the compatibility decomposition of a Unicode + * code point. Deprecated. * - * Return value: + * Return value: length of @decomposed. * * Since: 0.9.2 * Deprecated: 2.0.0 diff --git a/src/3rdparty/harfbuzz-ng/src/hb-unicode.h b/src/3rdparty/harfbuzz-ng/src/hb-unicode.h index 61b1b0ba1f..c04ee15a09 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-unicode.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-unicode.h @@ -28,7 +28,7 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_H_IN +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb.h> instead." #endif @@ -41,14 +41,51 @@ HB_BEGIN_DECLS /** - * HB_UNICODE_MAX + * HB_UNICODE_MAX: + * + * Maximum valid Unicode code point. * * Since: 1.9.0 **/ #define HB_UNICODE_MAX 0x10FFFFu -/* hb_unicode_general_category_t */ +/** + * hb_unicode_general_category_t: + * @HB_UNICODE_GENERAL_CATEGORY_CONTROL: [Cc] + * @HB_UNICODE_GENERAL_CATEGORY_FORMAT: [Cf] + * @HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED: [Cn] + * @HB_UNICODE_GENERAL_CATEGORY_PRIVATE_USE: [Co] + * @HB_UNICODE_GENERAL_CATEGORY_SURROGATE: [Cs] + * @HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER: [Ll] + * @HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER: [Lm] + * @HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER: [Lo] + * @HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER: [Lt] + * @HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER: [Lu] + * @HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK: [Mc] + * @HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK: [Me] + * @HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK: [Mn] + * @HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER: [Nd] + * @HB_UNICODE_GENERAL_CATEGORY_LETTER_NUMBER: [Nl] + * @HB_UNICODE_GENERAL_CATEGORY_OTHER_NUMBER: [No] + * @HB_UNICODE_GENERAL_CATEGORY_CONNECT_PUNCTUATION: [Pc] + * @HB_UNICODE_GENERAL_CATEGORY_DASH_PUNCTUATION: [Pd] + * @HB_UNICODE_GENERAL_CATEGORY_CLOSE_PUNCTUATION: [Pe] + * @HB_UNICODE_GENERAL_CATEGORY_FINAL_PUNCTUATION: [Pf] + * @HB_UNICODE_GENERAL_CATEGORY_INITIAL_PUNCTUATION: [Pi] + * @HB_UNICODE_GENERAL_CATEGORY_OTHER_PUNCTUATION: [Po] + * @HB_UNICODE_GENERAL_CATEGORY_OPEN_PUNCTUATION: [Ps] + * @HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL: [Sc] + * @HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL: [Sk] + * @HB_UNICODE_GENERAL_CATEGORY_MATH_SYMBOL: [Sm] + * @HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL: [So] + * @HB_UNICODE_GENERAL_CATEGORY_LINE_SEPARATOR: [Zl] + * @HB_UNICODE_GENERAL_CATEGORY_PARAGRAPH_SEPARATOR: [Zp] + * @HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR: [Zs] + * + * Data type for the "General_Category" (gc) property from + * the Unicode Character Database. + **/ /* Unicode Character Database property: General_Category (gc) */ typedef enum @@ -85,13 +122,74 @@ typedef enum HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR /* Zs */ } hb_unicode_general_category_t; -/* hb_unicode_combining_class_t */ - -/* Note: newer versions of Unicode may add new values. Clients should be ready to handle - * any value in the 0..254 range being returned from hb_unicode_combining_class(). - */ - -/* Unicode Character Database property: Canonical_Combining_Class (ccc) */ +/** + * hb_unicode_combining_class_t: + * @HB_UNICODE_COMBINING_CLASS_NOT_REORDERED: Spacing and enclosing marks; also many vowel and consonant signs, even if nonspacing + * @HB_UNICODE_COMBINING_CLASS_OVERLAY: Marks which overlay a base letter or symbol + * @HB_UNICODE_COMBINING_CLASS_NUKTA: Diacritic nukta marks in Brahmi-derived scripts + * @HB_UNICODE_COMBINING_CLASS_KANA_VOICING: Hiragana/Katakana voicing marks + * @HB_UNICODE_COMBINING_CLASS_VIRAMA: Viramas + * @HB_UNICODE_COMBINING_CLASS_CCC10: [Hebrew] + * @HB_UNICODE_COMBINING_CLASS_CCC11: [Hebrew] + * @HB_UNICODE_COMBINING_CLASS_CCC12: [Hebrew] + * @HB_UNICODE_COMBINING_CLASS_CCC13: [Hebrew] + * @HB_UNICODE_COMBINING_CLASS_CCC14: [Hebrew] + * @HB_UNICODE_COMBINING_CLASS_CCC15: [Hebrew] + * @HB_UNICODE_COMBINING_CLASS_CCC16: [Hebrew] + * @HB_UNICODE_COMBINING_CLASS_CCC17: [Hebrew] + * @HB_UNICODE_COMBINING_CLASS_CCC18: [Hebrew] + * @HB_UNICODE_COMBINING_CLASS_CCC19: [Hebrew] + * @HB_UNICODE_COMBINING_CLASS_CCC20: [Hebrew] + * @HB_UNICODE_COMBINING_CLASS_CCC21: [Hebrew] + * @HB_UNICODE_COMBINING_CLASS_CCC22: [Hebrew] + * @HB_UNICODE_COMBINING_CLASS_CCC23: [Hebrew] + * @HB_UNICODE_COMBINING_CLASS_CCC24: [Hebrew] + * @HB_UNICODE_COMBINING_CLASS_CCC25: [Hebrew] + * @HB_UNICODE_COMBINING_CLASS_CCC26: [Hebrew] + * @HB_UNICODE_COMBINING_CLASS_CCC27: [Arabic] + * @HB_UNICODE_COMBINING_CLASS_CCC28: [Arabic] + * @HB_UNICODE_COMBINING_CLASS_CCC29: [Arabic] + * @HB_UNICODE_COMBINING_CLASS_CCC30: [Arabic] + * @HB_UNICODE_COMBINING_CLASS_CCC31: [Arabic] + * @HB_UNICODE_COMBINING_CLASS_CCC32: [Arabic] + * @HB_UNICODE_COMBINING_CLASS_CCC33: [Arabic] + * @HB_UNICODE_COMBINING_CLASS_CCC34: [Arabic] + * @HB_UNICODE_COMBINING_CLASS_CCC35: [Arabic] + * @HB_UNICODE_COMBINING_CLASS_CCC36: [Syriac] + * @HB_UNICODE_COMBINING_CLASS_CCC84: [Telugu] + * @HB_UNICODE_COMBINING_CLASS_CCC91: [Telugu] + * @HB_UNICODE_COMBINING_CLASS_CCC103: [Thai] + * @HB_UNICODE_COMBINING_CLASS_CCC107: [Thai] + * @HB_UNICODE_COMBINING_CLASS_CCC118: [Lao] + * @HB_UNICODE_COMBINING_CLASS_CCC122: [Lao] + * @HB_UNICODE_COMBINING_CLASS_CCC129: [Tibetan] + * @HB_UNICODE_COMBINING_CLASS_CCC130: [Tibetan] + * @HB_UNICODE_COMBINING_CLASS_CCC133: [Tibetan] + * @HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT: Marks attached at the bottom left + * @HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW: Marks attached directly below + * @HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE: Marks attached directly above + * @HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT: Marks attached at the top right + * @HB_UNICODE_COMBINING_CLASS_BELOW_LEFT: Distinct marks at the bottom left + * @HB_UNICODE_COMBINING_CLASS_BELOW: Distinct marks directly below + * @HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT: Distinct marks at the bottom right + * @HB_UNICODE_COMBINING_CLASS_LEFT: Distinct marks to the left + * @HB_UNICODE_COMBINING_CLASS_RIGHT: Distinct marks to the right + * @HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT: Distinct marks at the top left + * @HB_UNICODE_COMBINING_CLASS_ABOVE: Distinct marks directly above + * @HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT: Distinct marks at the top right + * @HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW: Distinct marks subtending two bases + * @HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE: Distinct marks extending above two bases + * @HB_UNICODE_COMBINING_CLASS_IOTA_SUBSCRIPT: Greek iota subscript only + * @HB_UNICODE_COMBINING_CLASS_INVALID: Invalid combining class + * + * Data type for the Canonical_Combining_Class (ccc) property + * from the Unicode Character Database. + * + * <note>Note: newer versions of Unicode may add new values. + * Client programs should be ready to handle any value in the 0..254 range + * being returned from hb_unicode_combining_class().</note> + * + **/ typedef enum { HB_UNICODE_COMBINING_CLASS_NOT_REORDERED = 0, @@ -176,6 +274,18 @@ typedef enum * hb_unicode_funcs_t */ +/** + * hb_unicode_funcs_t: + * + * Data type containing a set of virtual methods used for + * accessing various Unicode character properties. + * + * HarfBuzz provides a default function for each of the + * methods in #hb_unicode_funcs_t. Client programs can implement + * their own replacements for the individual Unicode functions, as + * needed, and replace the default by calling the setter for a + * method. + **/ typedef struct hb_unicode_funcs_t hb_unicode_funcs_t; @@ -227,40 +337,141 @@ hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs); /* typedefs */ +/** + * hb_unicode_combining_class_func_t: + * @ufuncs: A Unicode-functions structure + * @unicode: The code point to query + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_unicode_funcs_t structure. + * + * This method should retrieve the Canonical Combining Class (ccc) + * property for a specified Unicode code point. + * + * Return value: The #hb_unicode_combining_class_t of @unicode + * + **/ typedef hb_unicode_combining_class_t (*hb_unicode_combining_class_func_t) (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode, void *user_data); + +/** + * hb_unicode_general_category_func_t: + * @ufuncs: A Unicode-functions structure + * @unicode: The code point to query + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_unicode_funcs_t structure. + * + * This method should retrieve the General Category property for + * a specified Unicode code point. + * + * Return value: The #hb_unicode_general_category_t of @unicode + * + **/ typedef hb_unicode_general_category_t (*hb_unicode_general_category_func_t) (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode, void *user_data); + +/** + * hb_unicode_mirroring_func_t: + * @ufuncs: A Unicode-functions structure + * @unicode: The code point to query + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_unicode_funcs_t structure. + * + * This method should retrieve the Bi-Directional Mirroring Glyph + * code point for a specified Unicode code point. + * + * <note>Note: If a code point does not have a specified + * Bi-Directional Mirroring Glyph defined, the method should + * return the original code point.</note> + * + * Return value: The #hb_codepoint_t of the Mirroring Glyph for @unicode + * + **/ typedef hb_codepoint_t (*hb_unicode_mirroring_func_t) (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode, void *user_data); + +/** + * hb_unicode_script_func_t: + * @ufuncs: A Unicode-functions structure + * @unicode: The code point to query + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_unicode_funcs_t structure. + * + * This method should retrieve the Script property for a + * specified Unicode code point. + * + * Return value: The #hb_script_t of @unicode + * + **/ typedef hb_script_t (*hb_unicode_script_func_t) (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode, void *user_data); +/** + * hb_unicode_compose_func_t: + * @ufuncs: A Unicode-functions structure + * @a: The first code point to compose + * @b: The second code point to compose + * @ab: (out): The composed code point + * @user_data: user data pointer passed by the caller + * + * A virtual method for the #hb_unicode_funcs_t structure. + * + * This method should compose a sequence of two input Unicode code + * points by canonical equivalence, returning the composed code + * point in a #hb_codepoint_t output parameter (if successful). + * The method must return an #hb_bool_t indicating the success + * of the composition. + * + * Return value: %true is @a,@b composed, %false otherwise + * + **/ typedef hb_bool_t (*hb_unicode_compose_func_t) (hb_unicode_funcs_t *ufuncs, hb_codepoint_t a, hb_codepoint_t b, hb_codepoint_t *ab, void *user_data); + +/** + * hb_unicode_decompose_func_t: + * @ufuncs: A Unicode-functions structure + * @ab: The code point to decompose + * @a: (out): The first decomposed code point + * @b: (out): The second decomposed code point + * @user_data: user data pointer passed by the caller + * + * A virtual method for the #hb_unicode_funcs_t structure. + * + * This method should decompose an input Unicode code point, + * returning the two decomposed code points in #hb_codepoint_t + * output parameters (if successful). The method must return an + * #hb_bool_t indicating the success of the composition. + * + * Return value: %true if @ab decomposed, %false otherwise + * + **/ typedef hb_bool_t (*hb_unicode_decompose_func_t) (hb_unicode_funcs_t *ufuncs, hb_codepoint_t ab, hb_codepoint_t *a, hb_codepoint_t *b, void *user_data); -/* setters */ +/* func setters */ /** * hb_unicode_funcs_set_combining_class_func: - * @ufuncs: a Unicode function structure - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * + * @ufuncs: A Unicode-functions structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * + * Sets the implementation function for #hb_unicode_combining_class_func_t. * * Since: 0.9.2 **/ @@ -271,12 +482,12 @@ hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs, /** * hb_unicode_funcs_set_general_category_func: - * @ufuncs: a Unicode function structure - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * + * @ufuncs: A Unicode-functions structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * + * Sets the implementation function for #hb_unicode_general_category_func_t. * * Since: 0.9.2 **/ @@ -287,12 +498,12 @@ hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs, /** * hb_unicode_funcs_set_mirroring_func: - * @ufuncs: a Unicode function structure - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * + * @ufuncs: A Unicode-functions structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * + * Sets the implementation function for #hb_unicode_mirroring_func_t. * * Since: 0.9.2 **/ @@ -303,12 +514,12 @@ hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs, /** * hb_unicode_funcs_set_script_func: - * @ufuncs: a Unicode function structure - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * + * @ufuncs: A Unicode-functions structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * + * Sets the implementation function for #hb_unicode_script_func_t. * * Since: 0.9.2 **/ @@ -319,12 +530,12 @@ hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs, /** * hb_unicode_funcs_set_compose_func: - * @ufuncs: a Unicode function structure - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * + * @ufuncs: A Unicode-functions structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * + * Sets the implementation function for #hb_unicode_compose_func_t. * * Since: 0.9.2 **/ @@ -335,12 +546,12 @@ hb_unicode_funcs_set_compose_func (hb_unicode_funcs_t *ufuncs, /** * hb_unicode_funcs_set_decompose_func: - * @ufuncs: a Unicode function structure - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * + * @ufuncs: A Unicode-functions structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * + * Sets the implementation function for #hb_unicode_decompose_func_t. * * Since: 0.9.2 **/ @@ -353,6 +564,13 @@ hb_unicode_funcs_set_decompose_func (hb_unicode_funcs_t *ufuncs, /** * hb_unicode_combining_class: + * @ufuncs: The Unicode-functions structure + * @unicode: The code point to query + * + * Retrieves the Canonical Combining Class (ccc) property + * of code point @unicode. + * + * Return value: The #hb_unicode_combining_class_t of @unicode * * Since: 0.9.2 **/ @@ -362,6 +580,13 @@ hb_unicode_combining_class (hb_unicode_funcs_t *ufuncs, /** * hb_unicode_general_category: + * @ufuncs: The Unicode-functions structure + * @unicode: The code point to query + * + * Retrieves the General Category (gc) property + * of code point @unicode. + * + * Return value: The #hb_unicode_general_category_t of @unicode * * Since: 0.9.2 **/ @@ -371,6 +596,13 @@ hb_unicode_general_category (hb_unicode_funcs_t *ufuncs, /** * hb_unicode_mirroring: + * @ufuncs: The Unicode-functions structure + * @unicode: The code point to query + * + * Retrieves the Bi-directional Mirroring Glyph code + * point defined for code point @unicode. + * + * Return value: The #hb_codepoint_t of the Mirroring Glyph for @unicode * * Since: 0.9.2 **/ @@ -380,6 +612,13 @@ hb_unicode_mirroring (hb_unicode_funcs_t *ufuncs, /** * hb_unicode_script: + * @ufuncs: The Unicode-functions structure + * @unicode: The code point to query + * + * Retrieves the #hb_script_t script to which code + * point @unicode belongs. + * + * Return value: The #hb_script_t of @unicode * * Since: 0.9.2 **/ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-unicode.hh b/src/3rdparty/harfbuzz-ng/src/hb-unicode.hh index 0c355f1113..34d66d7aa3 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-unicode.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-unicode.hh @@ -324,10 +324,10 @@ DECLARE_NULL_INSTANCE (hb_unicode_funcs_t); * Modify Telugu length marks (ccc=84, ccc=91). * These are the only matras in the main Indic scripts range that have * a non-zero ccc. That makes them reorder with the Halant (ccc=9). - * Assign 5 and 6, which are otherwise unassigned. + * Assign 4 and 5, which are otherwise unassigned. */ -#define HB_MODIFIED_COMBINING_CLASS_CCC84 5 /* length mark */ -#define HB_MODIFIED_COMBINING_CLASS_CCC91 6 /* ai length mark */ +#define HB_MODIFIED_COMBINING_CLASS_CCC84 4 /* length mark */ +#define HB_MODIFIED_COMBINING_CLASS_CCC91 5 /* ai length mark */ /* Thai * diff --git a/src/3rdparty/harfbuzz-ng/src/hb-uniscribe.cc b/src/3rdparty/harfbuzz-ng/src/hb-uniscribe.cc index e93cf7f419..48a5dc50ad 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-uniscribe.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-uniscribe.cc @@ -55,7 +55,7 @@ * @short_description: Windows integration * @include: hb-uniscribe.h * - * Functions for using HarfBuzz with the Windows fonts. + * Functions for using HarfBuzz with Windows fonts. **/ typedef HRESULT (WINAPI *SIOT) /*ScriptItemizeOpenType*/( @@ -453,7 +453,7 @@ _hb_rename_font (hb_blob_t *blob, wchar_t *new_name) hb_blob_destroy (blob); return hb_blob_create ((const char *) new_sfnt_data, new_length, - HB_MEMORY_MODE_WRITABLE, nullptr, free); + HB_MEMORY_MODE_WRITABLE, new_sfnt_data, free); } hb_uniscribe_face_data_t * @@ -583,6 +583,16 @@ _hb_uniscribe_shaper_font_data_destroy (hb_uniscribe_font_data_t *data) free (data); } +/** + * hb_uniscribe_font_get_logfontw: + * @font: The #hb_font_t to work upon + * + * Fetches the LOGFONTW structure that corresponds to the + * specified #hb_font_t font. + * + * Return value: a pointer to the LOGFONTW retrieved + * + **/ LOGFONTW * hb_uniscribe_font_get_logfontw (hb_font_t *font) { @@ -590,6 +600,16 @@ hb_uniscribe_font_get_logfontw (hb_font_t *font) return data ? &data->log_font : nullptr; } +/** + * hb_uniscribe_font_get_hfont: + * @font: The #hb_font_t to work upon + * + * Fetches the HFONT handle that corresponds to the + * specified #hb_font_t font. + * + * Return value: the HFONT retreieved + * + **/ HFONT hb_uniscribe_font_get_hfont (hb_font_t *font) { diff --git a/src/3rdparty/harfbuzz-ng/src/hb-vector.hh b/src/3rdparty/harfbuzz-ng/src/hb-vector.hh index 7b150fba05..13517a9c29 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-vector.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-vector.hh @@ -80,7 +80,12 @@ struct hb_vector_t fini (); } - void reset () { resize (0); } + void reset () + { + if (unlikely (in_error ())) + allocated = length; // Big hack! + resize (0); + } hb_vector_t& operator = (const hb_vector_t &o) { @@ -117,7 +122,7 @@ struct hb_vector_t { unsigned int i = (unsigned int) i_; if (unlikely (i >= length)) - return Null(Type); + return Null (Type); return arrayZ[i]; } @@ -165,7 +170,7 @@ struct hb_vector_t Type *push () { if (unlikely (!resize (length + 1))) - return &Crap(Type); + return &Crap (Type); return &arrayZ[length - 1]; } template <typename T> @@ -181,7 +186,7 @@ struct hb_vector_t /* Allocate for size but don't adjust length. */ bool alloc (unsigned int size) { - if (unlikely (allocated < 0)) + if (unlikely (in_error ())) return false; if (likely (size <= (unsigned) allocated)) @@ -195,7 +200,7 @@ struct hb_vector_t Type *new_array = nullptr; bool overflows = - (int) new_allocated < 0 || + (int) in_error () || (new_allocated < (unsigned) allocated) || hb_unsigned_mul_overflows (new_allocated, sizeof (Type)); if (likely (!overflows)) @@ -228,7 +233,7 @@ struct hb_vector_t Type pop () { - if (!length) return Null(Type); + if (!length) return Null (Type); return hb_move (arrayZ[--length]); /* Does this move actually work? */ } @@ -277,6 +282,9 @@ struct hb_vector_t template <typename T> const Type *lsearch (const T &x, const Type *not_found = nullptr) const { return as_array ().lsearch (x, not_found); } + template <typename T> + bool lfind (const T &x, unsigned *pos = nullptr) const + { return as_array ().lfind (x, pos); } }; template <typename Type> diff --git a/src/3rdparty/harfbuzz-ng/src/hb-version.h b/src/3rdparty/harfbuzz-ng/src/hb-version.h index a564e9f5e1..6db58c3f7c 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-version.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-version.h @@ -24,7 +24,7 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_H_IN +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb.h> instead." #endif @@ -36,12 +36,41 @@ HB_BEGIN_DECLS +/** + * HB_VERSION_MAJOR: + * + * The major component of the library version available at compile-time. + */ #define HB_VERSION_MAJOR 2 -#define HB_VERSION_MINOR 6 -#define HB_VERSION_MICRO 4 +/** + * HB_VERSION_MINOR: + * + * The minor component of the library version available at compile-time. + */ +#define HB_VERSION_MINOR 8 +/** + * HB_VERSION_MICRO: + * + * The micro component of the library version available at compile-time. + */ +#define HB_VERSION_MICRO 0 -#define HB_VERSION_STRING "2.6.4" +/** + * HB_VERSION_STRING: + * + * A string literal containing the library version available at compile-time. + */ +#define HB_VERSION_STRING "2.8.0" +/** + * HB_VERSION_ATLEAST: + * @major: the major component of the version number + * @minor: the minor component of the version number + * @micro: the micro component of the version number + * + * Tests the library version at compile-time against a minimum value, + * as three integer components. + */ #define HB_VERSION_ATLEAST(major,minor,micro) \ ((major)*10000+(minor)*100+(micro) <= \ HB_VERSION_MAJOR*10000+HB_VERSION_MINOR*100+HB_VERSION_MICRO) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-version.h.in b/src/3rdparty/harfbuzz-ng/src/hb-version.h.in deleted file mode 100644 index 0ffd889b27..0000000000 --- a/src/3rdparty/harfbuzz-ng/src/hb-version.h.in +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright © 2011 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ - -#ifndef HB_H_IN -#error "Include <hb.h> instead." -#endif - -#ifndef HB_VERSION_H -#define HB_VERSION_H - -#include "hb-common.h" - -HB_BEGIN_DECLS - - -#define HB_VERSION_MAJOR @HB_VERSION_MAJOR@ -#define HB_VERSION_MINOR @HB_VERSION_MINOR@ -#define HB_VERSION_MICRO @HB_VERSION_MICRO@ - -#define HB_VERSION_STRING "@HB_VERSION@" - -#define HB_VERSION_ATLEAST(major,minor,micro) \ - ((major)*10000+(minor)*100+(micro) <= \ - HB_VERSION_MAJOR*10000+HB_VERSION_MINOR*100+HB_VERSION_MICRO) - - -HB_EXTERN void -hb_version (unsigned int *major, - unsigned int *minor, - unsigned int *micro); - -HB_EXTERN const char * -hb_version_string (void); - -HB_EXTERN hb_bool_t -hb_version_atleast (unsigned int major, - unsigned int minor, - unsigned int micro); - - -HB_END_DECLS - -#endif /* HB_VERSION_H */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb.h b/src/3rdparty/harfbuzz-ng/src/hb.h index c5e7072fba..360686ca68 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb.h +++ b/src/3rdparty/harfbuzz-ng/src/hb.h @@ -32,12 +32,14 @@ #include "hb-buffer.h" #include "hb-common.h" #include "hb-deprecated.h" +#include "hb-draw.h" #include "hb-face.h" #include "hb-font.h" #include "hb-map.h" #include "hb-set.h" #include "hb-shape.h" #include "hb-shape-plan.h" +#include "hb-style.h" #include "hb-unicode.h" #include "hb-version.h" diff --git a/src/3rdparty/harfbuzz-ng/src/hb.hh b/src/3rdparty/harfbuzz-ng/src/hb.hh index fcbd330588..18516581c7 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb.hh @@ -62,7 +62,6 @@ /* Error. Should never happen. */ #ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_ERROR -#pragma GCC diagnostic error "-Wc++11-narrowing" #pragma GCC diagnostic error "-Wcast-align" #pragma GCC diagnostic error "-Wcast-function-type" #pragma GCC diagnostic error "-Wdelete-non-virtual-dtor" @@ -75,6 +74,7 @@ #pragma GCC diagnostic error "-Wmissing-braces" #pragma GCC diagnostic error "-Wmissing-declarations" #pragma GCC diagnostic error "-Wmissing-prototypes" +#pragma GCC diagnostic error "-Wnarrowing" #pragma GCC diagnostic error "-Wnested-externs" #pragma GCC diagnostic error "-Wold-style-definition" #pragma GCC diagnostic error "-Wpointer-arith" @@ -107,6 +107,7 @@ #pragma GCC diagnostic warning "-Wmaybe-uninitialized" #pragma GCC diagnostic warning "-Wmissing-format-attribute" #pragma GCC diagnostic warning "-Wundef" +#pragma GCC diagnostic warning "-Wunused-but-set-variable" #endif /* Ignored currently, but should be fixed at some point. */ @@ -125,6 +126,7 @@ #pragma GCC diagnostic ignored "-Wformat-zero-length" #pragma GCC diagnostic ignored "-Wmissing-field-initializers" #pragma GCC diagnostic ignored "-Wpacked" // Erratic impl in clang +#pragma GCC diagnostic ignored "-Wrange-loop-analysis" // https://github.com/harfbuzz/harfbuzz/issues/2834 #pragma GCC diagnostic ignored "-Wstrict-aliasing" #pragma GCC diagnostic ignored "-Wtype-limits" #pragma GCC diagnostic ignored "-Wc++11-compat" // only gcc raises it @@ -174,36 +176,46 @@ #include "hb-aat.h" #define HB_AAT_H_IN -#include <limits.h> -#include <math.h> -#include <stdlib.h> -#include <stddef.h> -#include <string.h> -#include <assert.h> -#include <stdio.h> -#include <stdarg.h> +#include <cassert> +#include <cfloat> +#include <climits> +#include <cmath> +#include <cstdarg> +#include <cstddef> +#include <cstdio> +#include <cstdlib> +#include <cstring> #if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__) #ifdef __MINGW32_VERSION #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN 1 #endif -#include <windows.h> #else #include <intrin.h> #endif #endif +#ifdef _WIN32 +#include <windows.h> +#include <winapifamily.h> +#endif + #define HB_PASTE1(a,b) a##b #define HB_PASTE(a,b) HB_PASTE1(a,b) /* Compile-time custom allocator support. */ -#if defined(hb_malloc_impl) \ - && defined(hb_calloc_impl) \ - && defined(hb_realloc_impl) \ - && defined(hb_free_impl) +#if !defined(HB_CUSTOM_MALLOC) \ + && defined(hb_malloc_impl) \ + && defined(hb_calloc_impl) \ + && defined(hb_realloc_impl) \ + && defined(hb_free_impl) +#define HB_CUSTOM_MALLOC +#endif + +#ifdef HB_CUSTOM_MALLOC extern "C" void* hb_malloc_impl(size_t size); extern "C" void* hb_calloc_impl(size_t nmemb, size_t size); extern "C" void* hb_realloc_impl(void *ptr, size_t size); @@ -233,12 +245,8 @@ extern "C" void hb_free_impl(void *ptr); #endif #if defined(__GNUC__) && (__GNUC__ >= 3) -#define HB_PURE_FUNC __attribute__((pure)) -#define HB_CONST_FUNC __attribute__((const)) #define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx))) #else -#define HB_PURE_FUNC -#define HB_CONST_FUNC #define HB_PRINTF_FUNC(format_idx, arg_idx) #endif #if defined(__GNUC__) && (__GNUC__ >= 4) || (__clang__) @@ -317,6 +325,18 @@ extern "C" void hb_free_impl(void *ptr); # define HB_FALLTHROUGH /* FALLTHROUGH */ #endif +/* A tag to enforce use of return value for a function */ +#if __cplusplus >= 201703L +# define HB_NODISCARD [[nodiscard]] +#elif defined(__GNUC__) || defined(__clang__) +# define HB_NODISCARD __attribute__((warn_unused_result)) +#elif defined(_MSC_VER) +# define HB_NODISCARD _Check_return_ +#else +# define HB_NODISCARD +#endif +#define hb_success_t HB_NODISCARD bool + /* https://github.com/harfbuzz/harfbuzz/issues/1852 */ #if defined(__clang__) && !(defined(_AIX) && (defined(__IBMCPP__) || defined(__ibmxl__))) /* Disable certain sanitizer errors. */ @@ -335,7 +355,7 @@ extern "C" void hb_free_impl(void *ptr); # undef _WIN32_WINNT # endif # ifndef _WIN32_WINNT -# if !defined(WINAPI_FAMILY) || !(WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) +# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) # define _WIN32_WINNT 0x0600 # endif # endif @@ -356,7 +376,7 @@ extern "C" void hb_free_impl(void *ptr); # define HB_NO_SETLOCALE # define HB_NO_ERRNO # endif -# elif defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) +# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) # ifndef HB_NO_GETENV # define HB_NO_GETENV # endif @@ -371,7 +391,7 @@ extern "C" void hb_free_impl(void *ptr); #endif #ifndef HB_NO_ERRNO -# include <errno.h> +# include <cerrno> #else static int HB_UNUSED _hb_errno = 0; # undef errno @@ -417,186 +437,12 @@ static int HB_UNUSED _hb_errno = 0; #define HB_STMT_START do #define HB_STMT_END while (0) -/* Static-assert as expression. */ -template <unsigned int cond> class hb_assert_constant_t; -template <> class hb_assert_constant_t<1> {}; -#define ASSERT_STATIC_EXPR_ZERO(_cond) (0 * (unsigned int) sizeof (hb_assert_constant_t<_cond>)) - /* Lets assert int types. Saves trouble down the road. */ -static_assert ((sizeof (int8_t) == 1), ""); -static_assert ((sizeof (uint8_t) == 1), ""); -static_assert ((sizeof (int16_t) == 2), ""); -static_assert ((sizeof (uint16_t) == 2), ""); -static_assert ((sizeof (int32_t) == 4), ""); -static_assert ((sizeof (uint32_t) == 4), ""); -static_assert ((sizeof (int64_t) == 8), ""); -static_assert ((sizeof (uint64_t) == 8), ""); static_assert ((sizeof (hb_codepoint_t) == 4), ""); static_assert ((sizeof (hb_position_t) == 4), ""); static_assert ((sizeof (hb_mask_t) == 4), ""); static_assert ((sizeof (hb_var_int_t) == 4), ""); -#define HB_DELETE_COPY_ASSIGN(TypeName) \ - TypeName(const TypeName&) = delete; \ - void operator=(const TypeName&) = delete -#define HB_DELETE_CREATE_COPY_ASSIGN(TypeName) \ - TypeName() = delete; \ - TypeName(const TypeName&) = delete; \ - void operator=(const TypeName&) = delete - - -/* Flags */ - -/* Enable bitwise ops on enums marked as flags_t */ -/* To my surprise, looks like the function resolver is happy to silently cast - * one enum to another... So this doesn't provide the type-checking that I - * originally had in mind... :(. - * - * For MSVC warnings, see: https://github.com/harfbuzz/harfbuzz/pull/163 - */ -#ifdef _MSC_VER -# pragma warning(disable:4200) -# pragma warning(disable:4800) -#endif -#define HB_MARK_AS_FLAG_T(T) \ - extern "C++" { \ - static inline T operator | (T l, T r) { return T ((unsigned) l | (unsigned) r); } \ - static inline T operator & (T l, T r) { return T ((unsigned) l & (unsigned) r); } \ - static inline T operator ^ (T l, T r) { return T ((unsigned) l ^ (unsigned) r); } \ - static inline T operator ~ (T r) { return T (~(unsigned int) r); } \ - static inline T& operator |= (T &l, T r) { l = l | r; return l; } \ - static inline T& operator &= (T& l, T r) { l = l & r; return l; } \ - static inline T& operator ^= (T& l, T r) { l = l ^ r; return l; } \ - } \ - static_assert (true, "") - -/* Useful for set-operations on small enums. - * For example, for testing "x ∈ {x1, x2, x3}" use: - * (FLAG_UNSAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3))) - */ -#define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned)(x) < 32) + (((uint32_t) 1U) << (unsigned)(x))) -#define FLAG_UNSAFE(x) ((unsigned)(x) < 32 ? (((uint32_t) 1U) << (unsigned)(x)) : 0) -#define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x)) -#define FLAG64(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned)(x) < 64) + (((uint64_t) 1ULL) << (unsigned)(x))) -#define FLAG64_UNSAFE(x) ((unsigned)(x) < 64 ? (((uint64_t) 1ULL) << (unsigned)(x)) : 0) - - -/* Size signifying variable-sized array */ -#ifndef HB_VAR_ARRAY -#define HB_VAR_ARRAY 1 -#endif - -static inline double -_hb_roundf (float x) -{ - return x >= 0 ? floor ((double) x + .5) : ceil ((double) x - .5); -} -#ifndef HAVE_ROUNDF -#define roundf(x) _hb_roundf(x) -#endif - -/* Endian swap, used in Windows related backends */ -static inline uint16_t hb_uint16_swap (const uint16_t v) -{ return (v >> 8) | (v << 8); } -static inline uint32_t hb_uint32_swap (const uint32_t v) -{ return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); } - -/* - * Big-endian integers. Here because fundamental. - */ - -template <typename Type, int Bytes> struct BEInt; - -template <typename Type> -struct BEInt<Type, 1> -{ - public: - BEInt<Type, 1>& operator = (Type V) - { - v = V; - return *this; - } - operator Type () const { return v; } - private: uint8_t v; -}; -template <typename Type> -struct BEInt<Type, 2> -{ - public: - BEInt<Type, 2>& operator = (Type V) - { - v[0] = (V >> 8) & 0xFF; - v[1] = (V ) & 0xFF; - return *this; - } - operator Type () const - { -#if ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \ - defined(__BYTE_ORDER) && \ - (__BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __BIG_ENDIAN) - /* Spoon-feed the compiler a big-endian integer with alignment 1. - * https://github.com/harfbuzz/harfbuzz/pull/1398 */ - struct __attribute__((packed)) packed_uint16_t { uint16_t v; }; -#if __BYTE_ORDER == __LITTLE_ENDIAN - return __builtin_bswap16 (((packed_uint16_t *) this)->v); -#else /* __BYTE_ORDER == __BIG_ENDIAN */ - return ((packed_uint16_t *) this)->v; -#endif -#endif - return (v[0] << 8) - + (v[1] ); - } - private: uint8_t v[2]; -}; -template <typename Type> -struct BEInt<Type, 3> -{ - public: - BEInt<Type, 3>& operator = (Type V) - { - v[0] = (V >> 16) & 0xFF; - v[1] = (V >> 8) & 0xFF; - v[2] = (V ) & 0xFF; - return *this; - } - operator Type () const - { - return (v[0] << 16) - + (v[1] << 8) - + (v[2] ); - } - private: uint8_t v[3]; -}; -template <typename Type> -struct BEInt<Type, 4> -{ - public: - BEInt<Type, 4>& operator = (Type V) - { - v[0] = (V >> 24) & 0xFF; - v[1] = (V >> 16) & 0xFF; - v[2] = (V >> 8) & 0xFF; - v[3] = (V ) & 0xFF; - return *this; - } - operator Type () const - { - return (v[0] << 24) - + (v[1] << 16) - + (v[2] << 8) - + (v[3] ); - } - private: uint8_t v[4]; -}; - - -/* - * For lack of a better place, put Zawgyi script hack here. - * https://github.com/harfbuzz/harfbuzz/issues/1162 - */ - -#define HB_SCRIPT_MYANMAR_ZAWGYI ((hb_script_t) HB_TAG ('Q','a','a','g')) - /* Headers we include for everyone. Keep topologically sorted by dependency. * They express dependency amongst themselves, but no other file should include diff --git a/src/3rdparty/harfbuzz-ng/src/main.cc b/src/3rdparty/harfbuzz-ng/src/main.cc index 983cb557db..e898e6e4b6 100644 --- a/src/3rdparty/harfbuzz-ng/src/main.cc +++ b/src/3rdparty/harfbuzz-ng/src/main.cc @@ -1,5 +1,7 @@ /* * Copyright © 2007,2008,2009 Red Hat, Inc. + * Copyright © 2018,2019,2020 Ebrahim Byagowi + * Copyright © 2018 Khaled Hosny * * This is part of HarfBuzz, a text shaping library. * @@ -24,48 +26,335 @@ * Red Hat Author(s): Behdad Esfahbod */ -#include "hb-static.cc" -#include "hb-open-file.hh" -#include "hb-ot-layout-gdef-table.hh" -#include "hb-ot-layout-gsubgpos.hh" - -#ifdef HAVE_GLIB -#include <glib.h> +#ifdef HAVE_CONFIG_H +#include "config.h" #endif -#include <stdlib.h> -#include <stdio.h> +#include "hb.h" +#include "hb-ot.h" -using namespace OT; +#include <stdlib.h> +#include <stdio.h> +#include <string.h> #ifdef HB_NO_OPEN #define hb_blob_create_from_file(x) hb_blob_get_empty () #endif -int -main (int argc, char **argv) +#if !defined(HB_NO_COLOR) && !defined(HB_NO_DRAW) && defined(HB_EXPERIMENTAL_API) +static void +svg_dump (hb_face_t *face, unsigned face_index) { - if (argc != 2) + unsigned glyph_count = hb_face_get_glyph_count (face); + + for (unsigned glyph_id = 0; glyph_id < glyph_count; ++glyph_id) { - fprintf (stderr, "usage: %s font-file.ttf\n", argv[0]); - exit (1); + hb_blob_t *blob = hb_ot_color_glyph_reference_svg (face, glyph_id); + + if (hb_blob_get_length (blob) == 0) continue; + + unsigned length; + const char *data = hb_blob_get_data (blob, &length); + + char output_path[255]; + sprintf (output_path, "out/svg-%u-%u.svg%s", + glyph_id, + face_index, + // append "z" if the content is gzipped, https://stackoverflow.com/a/6059405 + (length > 2 && (data[0] == '\x1F') && (data[1] == '\x8B')) ? "z" : ""); + + FILE *f = fopen (output_path, "wb"); + fwrite (data, 1, length, f); + fclose (f); + + hb_blob_destroy (blob); } +} - hb_blob_t *blob = hb_blob_create_from_file (argv[1]); - unsigned int len; - const char *font_data = hb_blob_get_data (blob, &len); - printf ("Opened font file %s: %d bytes long\n", argv[1], len); +/* _png API is so easy to use unlike the below code, don't get confused */ +static void +png_dump (hb_face_t *face, unsigned face_index) +{ + unsigned glyph_count = hb_face_get_glyph_count (face); + hb_font_t *font = hb_font_create (face); + + /* scans the font for strikes */ + unsigned sample_glyph_id; + /* we don't care about different strikes for different glyphs at this point */ + for (sample_glyph_id = 0; sample_glyph_id < glyph_count; ++sample_glyph_id) + { + hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, sample_glyph_id); + unsigned blob_length = hb_blob_get_length (blob); + hb_blob_destroy (blob); + if (blob_length != 0) + break; + } + + unsigned upem = hb_face_get_upem (face); + unsigned blob_length = 0; + unsigned strike = 0; + for (unsigned ppem = 1; ppem < upem; ++ppem) + { + hb_font_set_ppem (font, ppem, ppem); + hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, sample_glyph_id); + unsigned new_blob_length = hb_blob_get_length (blob); + hb_blob_destroy (blob); + if (new_blob_length != blob_length) + { + for (unsigned glyph_id = 0; glyph_id < glyph_count; ++glyph_id) + { + hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, glyph_id); + + if (hb_blob_get_length (blob) == 0) continue; + + unsigned length; + const char *data = hb_blob_get_data (blob, &length); + + char output_path[255]; + sprintf (output_path, "out/png-%u-%u-%u.png", glyph_id, strike, face_index); + + FILE *f = fopen (output_path, "wb"); + fwrite (data, 1, length, f); + fclose (f); + + hb_blob_destroy (blob); + } + + strike++; + blob_length = new_blob_length; + } + } + + hb_font_destroy (font); +} + +struct user_data_t +{ + FILE *f; + hb_position_t ascender; +}; + +static void +move_to (hb_position_t to_x, hb_position_t to_y, user_data_t &user_data) +{ + fprintf (user_data.f, "M%d,%d", to_x, user_data.ascender - to_y); +} + +static void +line_to (hb_position_t to_x, hb_position_t to_y, user_data_t &user_data) +{ + fprintf (user_data.f, "L%d,%d", to_x, user_data.ascender - to_y); +} + +static void +quadratic_to (hb_position_t control_x, hb_position_t control_y, + hb_position_t to_x, hb_position_t to_y, + user_data_t &user_data) +{ + fprintf (user_data.f, "Q%d,%d %d,%d", control_x, user_data.ascender - control_y, + to_x, user_data.ascender - to_y); +} + +static void +cubic_to (hb_position_t control1_x, hb_position_t control1_y, + hb_position_t control2_x, hb_position_t control2_y, + hb_position_t to_x, hb_position_t to_y, + user_data_t &user_data) +{ + fprintf (user_data.f, "C%d,%d %d,%d %d,%d", control1_x, user_data.ascender - control1_y, + control2_x, user_data.ascender - control2_y, + to_x, user_data.ascender - to_y); +} + +static void +close_path (user_data_t &user_data) +{ + fprintf (user_data.f, "Z"); +} + +static void +layered_glyph_dump (hb_font_t *font, hb_draw_funcs_t *funcs, unsigned face_index) +{ + hb_face_t *face = hb_font_get_face (font); + unsigned palette_count = hb_ot_color_palette_get_count (face); + for (unsigned palette = 0; palette < palette_count; ++palette) + { + unsigned num_colors = hb_ot_color_palette_get_colors (face, palette, 0, nullptr, nullptr); + if (!num_colors) continue; + + hb_color_t *colors = (hb_color_t*) calloc (num_colors, sizeof (hb_color_t)); + hb_ot_color_palette_get_colors (face, palette, 0, &num_colors, colors); + if (!num_colors) + { + free (colors); + continue; + } + + unsigned num_glyphs = hb_face_get_glyph_count (face); + for (hb_codepoint_t gid = 0; gid < num_glyphs; ++gid) + { + unsigned num_layers = hb_ot_color_glyph_get_layers (face, gid, 0, nullptr, nullptr); + if (!num_layers) continue; - hb_blob_t *font_blob = hb_sanitize_context_t().sanitize_blob<OpenTypeFontFile> (blob); + hb_ot_color_layer_t *layers = (hb_ot_color_layer_t*) malloc (num_layers * sizeof (hb_ot_color_layer_t)); + + hb_ot_color_glyph_get_layers (face, gid, 0, &num_layers, layers); + if (num_layers) + { + hb_font_extents_t font_extents; + hb_font_get_extents_for_direction (font, HB_DIRECTION_LTR, &font_extents); + hb_glyph_extents_t extents = {0}; + if (!hb_font_get_glyph_extents (font, gid, &extents)) + { + printf ("Skip gid: %d\n", gid); + continue; + } + + char output_path[255]; + sprintf (output_path, "out/colr-%u-%u-%u.svg", gid, palette, face_index); + FILE *f = fopen (output_path, "wb"); + fprintf (f, "<svg xmlns=\"http://www.w3.org/2000/svg\"" + " viewBox=\"%d %d %d %d\">\n", + extents.x_bearing, 0, + extents.x_bearing + extents.width, -extents.height); + user_data_t user_data; + user_data.ascender = extents.y_bearing; + user_data.f = f; + + for (unsigned layer = 0; layer < num_layers; ++layer) + { + hb_color_t color = 0x000000FF; + if (layers[layer].color_index != 0xFFFF) + color = colors[layers[layer].color_index]; + fprintf (f, "<path fill=\"#%02X%02X%02X\" ", + hb_color_get_red (color), hb_color_get_green (color), hb_color_get_green (color)); + if (hb_color_get_alpha (color) != 255) + fprintf (f, "fill-opacity=\"%.3f\"", (double) hb_color_get_alpha (color) / 255.); + fprintf (f, "d=\""); + if (!hb_font_draw_glyph (font, layers[layer].glyph, funcs, &user_data)) + printf ("Failed to decompose layer %d while %d\n", layers[layer].glyph, gid); + fprintf (f, "\"/>\n"); + } + + fprintf (f, "</svg>"); + fclose (f); + } + free (layers); + } + + free (colors); + } +} + +static void +dump_glyphs (hb_font_t *font, hb_draw_funcs_t *funcs, unsigned face_index) +{ + unsigned num_glyphs = hb_face_get_glyph_count (hb_font_get_face (font)); + for (unsigned gid = 0; gid < num_glyphs; ++gid) + { + hb_font_extents_t font_extents; + hb_font_get_extents_for_direction (font, HB_DIRECTION_LTR, &font_extents); + hb_glyph_extents_t extents = {0}; + if (!hb_font_get_glyph_extents (font, gid, &extents)) + { + printf ("Skip gid: %d\n", gid); + continue; + } + + char output_path[255]; + sprintf (output_path, "out/%u-%u.svg", face_index, gid); + FILE *f = fopen (output_path, "wb"); + fprintf (f, "<svg xmlns=\"http://www.w3.org/2000/svg\"" + " viewBox=\"%d %d %d %d\"><path d=\"", + extents.x_bearing, 0, + extents.x_bearing + extents.width, font_extents.ascender - font_extents.descender); + user_data_t user_data; + user_data.ascender = font_extents.ascender; + user_data.f = f; + if (!hb_font_draw_glyph (font, gid, funcs, &user_data)) + printf ("Failed to decompose gid: %d\n", gid); + fprintf (f, "\"/></svg>"); + fclose (f); + } +} + +static void +dump_glyphs (hb_blob_t *blob, const char *font_name) +{ + FILE *font_name_file = fopen ("out/.dumped_font_name", "r"); + if (font_name_file) + { + fprintf (stderr, "Purge or rename ./out folder if you like to run a glyph dump,\n" + "run it like `rm -rf out && mkdir out && src/main font-file.ttf`\n"); + return; + } + + font_name_file = fopen ("out/.dumped_font_name", "w"); + if (!font_name_file) + { + fprintf (stderr, "./out is not accessible as a folder, create it please\n"); + return; + } + fwrite (font_name, 1, strlen (font_name), font_name_file); + fclose (font_name_file); + + hb_draw_funcs_t *funcs = hb_draw_funcs_create (); + hb_draw_funcs_set_move_to_func (funcs, (hb_draw_move_to_func_t) move_to); + hb_draw_funcs_set_line_to_func (funcs, (hb_draw_line_to_func_t) line_to); + hb_draw_funcs_set_quadratic_to_func (funcs, (hb_draw_quadratic_to_func_t) quadratic_to); + hb_draw_funcs_set_cubic_to_func (funcs, (hb_draw_cubic_to_func_t) cubic_to); + hb_draw_funcs_set_close_path_func (funcs, (hb_draw_close_path_func_t) close_path); + + unsigned num_faces = hb_face_count (blob); + for (unsigned face_index = 0; face_index < num_faces; ++face_index) + { + hb_face_t *face = hb_face_create (blob, face_index); + hb_font_t *font = hb_font_create (face); + + if (hb_ot_color_has_png (face)) + printf ("Dumping png (CBDT/sbix)...\n"); + png_dump (face, face_index); + + if (hb_ot_color_has_svg (face)) + printf ("Dumping svg (SVG )...\n"); + svg_dump (face, face_index); + + if (hb_ot_color_has_layers (face) && hb_ot_color_has_palettes (face)) + printf ("Dumping layered color glyphs (COLR/CPAL)...\n"); + layered_glyph_dump (font, funcs, face_index); + + dump_glyphs (font, funcs, face_index); + + hb_font_destroy (font); + hb_face_destroy (face); + } + + hb_draw_funcs_destroy (funcs); +} +#endif + +#ifndef MAIN_CC_NO_PRIVATE_API +/* Only this part of this mini app uses private API */ +#include "hb-static.cc" +#include "hb-open-file.hh" +#include "hb-ot-layout-gdef-table.hh" +#include "hb-ot-layout-gsubgpos.hh" + +using namespace OT; + +static void +print_layout_info_using_private_api (hb_blob_t *blob) +{ + const char *font_data = hb_blob_get_data (blob, nullptr); + hb_blob_t *font_blob = hb_sanitize_context_t ().sanitize_blob<OpenTypeFontFile> (blob); const OpenTypeFontFile* sanitized = font_blob->as<OpenTypeFontFile> (); if (!font_blob->data) { printf ("Sanitization of the file wasn't successful. Exit"); - return 1; + exit (1); } const OpenTypeFontFile& ot = *sanitized; - switch (ot.get_tag ()) { case OpenTypeFontFile::TrueTypeTag: @@ -91,22 +380,22 @@ main (int argc, char **argv) break; } - int num_fonts = ot.get_face_count (); - printf ("%d font(s) found in file\n", num_fonts); - for (int n_font = 0; n_font < num_fonts; n_font++) + unsigned num_faces = hb_face_count (blob); + printf ("%d font(s) found in file\n", num_faces); + for (unsigned n_font = 0; n_font < num_faces; ++n_font) { const OpenTypeFontFace &font = ot.get_face (n_font); - printf ("Font %d of %d:\n", n_font, num_fonts); + printf ("Font %d of %d:\n", n_font, num_faces); - int num_tables = font.get_table_count (); + unsigned num_tables = font.get_table_count (); printf (" %d table(s) found in font\n", num_tables); - for (int n_table = 0; n_table < num_tables; n_table++) + for (unsigned n_table = 0; n_table < num_tables; ++n_table) { const OpenTypeTable &table = font.get_table (n_table); printf (" Table %2d of %2d: %.4s (0x%08x+0x%08x)\n", n_table, num_tables, (const char *) table.tag, - (unsigned int) table.offset, - (unsigned int) table.length); + (unsigned) table.offset, + (unsigned) table.length); switch (table.tag) { @@ -115,21 +404,22 @@ main (int argc, char **argv) case HB_OT_TAG_GPOS: { - const GSUBGPOS &g = *CastP<GSUBGPOS> (font_data + table.offset); + const GSUBGPOS &g = *reinterpret_cast<const GSUBGPOS *> (font_data + table.offset); - int num_scripts = g.get_script_count (); + unsigned num_scripts = g.get_script_count (); printf (" %d script(s) found in table\n", num_scripts); - for (int n_script = 0; n_script < num_scripts; n_script++) + for (unsigned n_script = 0; n_script < num_scripts; ++n_script) { const Script &script = g.get_script (n_script); printf (" Script %2d of %2d: %.4s\n", n_script, num_scripts, - (const char *)g.get_script_tag(n_script)); + (const char *) g.get_script_tag (n_script)); - if (!script.has_default_lang_sys()) + if (!script.has_default_lang_sys ()) printf (" No default language system\n"); int num_langsys = script.get_lang_sys_count (); printf (" %d language system(s) found in script\n", num_langsys); - for (int n_langsys = script.has_default_lang_sys() ? -1 : 0; n_langsys < num_langsys; n_langsys++) { + for (int n_langsys = script.has_default_lang_sys () ? -1 : 0; n_langsys < num_langsys; ++n_langsys) + { const LangSys &langsys = n_langsys == -1 ? script.get_default_lang_sys () : script.get_lang_sys (n_langsys); @@ -137,16 +427,16 @@ main (int argc, char **argv) printf (" Default Language System\n"); else printf (" Language System %2d of %2d: %.4s\n", n_langsys, num_langsys, - (const char *)script.get_lang_sys_tag (n_langsys)); + (const char *) script.get_lang_sys_tag (n_langsys)); if (!langsys.has_required_feature ()) printf (" No required feature\n"); else printf (" Required feature index: %d\n", langsys.get_required_feature_index ()); - int num_features = langsys.get_feature_count (); + unsigned num_features = langsys.get_feature_count (); printf (" %d feature(s) found in language system\n", num_features); - for (int n_feature = 0; n_feature < num_features; n_feature++) + for (unsigned n_feature = 0; n_feature < num_features; ++n_feature) { printf (" Feature index %2d of %2d: %d\n", n_feature, num_features, langsys.get_feature_index (n_feature)); @@ -154,29 +444,29 @@ main (int argc, char **argv) } } - int num_features = g.get_feature_count (); + unsigned num_features = g.get_feature_count (); printf (" %d feature(s) found in table\n", num_features); - for (int n_feature = 0; n_feature < num_features; n_feature++) + for (unsigned n_feature = 0; n_feature < num_features; ++n_feature) { const Feature &feature = g.get_feature (n_feature); - int num_lookups = feature.get_lookup_count (); + unsigned num_lookups = feature.get_lookup_count (); printf (" Feature %2d of %2d: %c%c%c%c\n", n_feature, num_features, - HB_UNTAG(g.get_feature_tag(n_feature))); + HB_UNTAG (g.get_feature_tag (n_feature))); printf (" %d lookup(s) found in feature\n", num_lookups); - for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) { + for (unsigned n_lookup = 0; n_lookup < num_lookups; ++n_lookup) { printf (" Lookup index %2d of %2d: %d\n", n_lookup, num_lookups, feature.get_lookup_index (n_lookup)); } } - int num_lookups = g.get_lookup_count (); + unsigned num_lookups = g.get_lookup_count (); printf (" %d lookup(s) found in table\n", num_lookups); - for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) + for (unsigned n_lookup = 0; n_lookup < num_lookups; ++n_lookup) { const Lookup &lookup = g.get_lookup (n_lookup); printf (" Lookup %2d of %2d: type %d, props 0x%04X\n", n_lookup, num_lookups, - lookup.get_type(), lookup.get_props()); + lookup.get_type (), lookup.get_props ()); } } @@ -185,7 +475,7 @@ main (int argc, char **argv) case GDEF::tableTag: { - const GDEF &gdef = *CastP<GDEF> (font_data + table.offset); + const GDEF &gdef = *reinterpret_cast<const GDEF *> (font_data + table.offset); printf (" Has %sglyph classes\n", gdef.has_glyph_classes () ? "" : "no "); @@ -202,6 +492,28 @@ main (int argc, char **argv) } } } +} +/* end of private API use */ +#endif + +int +main (int argc, char **argv) +{ + if (argc != 2) + { + fprintf (stderr, "usage: %s font-file.ttf\n", argv[0]); + exit (1); + } + + hb_blob_t *blob = hb_blob_create_from_file (argv[1]); + printf ("Opened font file %s: %d bytes long\n", argv[1], hb_blob_get_length (blob)); +#ifndef MAIN_CC_NO_PRIVATE_API + print_layout_info_using_private_api (blob); +#endif +#if !defined(HB_NO_COLOR) && !defined(HB_NO_DRAW) && defined(HB_EXPERIMENTAL_API) + dump_glyphs (blob, argv[1]); +#endif + hb_blob_destroy (blob); return 0; } diff --git a/src/3rdparty/harfbuzz-ng/src/test-array.cc b/src/3rdparty/harfbuzz-ng/src/test-array.cc new file mode 100644 index 0000000000..6c888138e7 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/test-array.cc @@ -0,0 +1,76 @@ +/* + * Copyright © 2020 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Garret Rieger + */ + +#include "hb.hh" +#include "hb-array.hh" + +static void +test_reverse () +{ + int values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + hb_array_t<int> a (values, 9); + a.reverse(); + + int expected_values[] = {9, 8, 7, 6, 5, 4, 3, 2, 1}; + hb_array_t<int> expected (expected_values, 9); + assert (a == expected); +} + +static void +test_reverse_range () +{ + int values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + hb_array_t<int> a (values, 9); + a.reverse(2, 6); + + int expected_values[] = {1, 2, 6, 5, 4, 3, 7, 8, 9}; + hb_array_t<int> expected (expected_values, 9); + assert (a == expected); +} + +static void +test_reverse_invalid () +{ + int values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + hb_array_t<int> a (values, 9); + + a.reverse(4, 3); + a.reverse(2, 3); + a.reverse(5, 5); + a.reverse(12, 15); + + int expected_values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + hb_array_t<int> expected (expected_values, 9); + assert (a == expected); +} + +int +main (int argc, char **argv) +{ + test_reverse (); + test_reverse_range (); + test_reverse_invalid (); +} diff --git a/src/3rdparty/harfbuzz-ng/src/test-buffer-serialize.cc b/src/3rdparty/harfbuzz-ng/src/test-buffer-serialize.cc index 6393f0b7f6..4a3d4bc107 100644 --- a/src/3rdparty/harfbuzz-ng/src/test-buffer-serialize.cc +++ b/src/3rdparty/harfbuzz-ng/src/test-buffer-serialize.cc @@ -32,8 +32,6 @@ #include "hb-ft.h" #endif -#include <stdio.h> - #ifdef HB_NO_OPEN #define hb_blob_create_from_file(x) hb_blob_get_empty () #endif @@ -68,7 +66,7 @@ main (int argc, char **argv) buf = hb_buffer_create (); char line[BUFSIZ], out[BUFSIZ]; - while (fgets (line, sizeof(line), stdin) != nullptr) + while (fgets (line, sizeof(line), stdin)) { hb_buffer_clear_contents (buf); diff --git a/src/3rdparty/harfbuzz-ng/src/test-gpos-size-params.cc b/src/3rdparty/harfbuzz-ng/src/test-gpos-size-params.cc index ad10ed40d4..549f5ae06a 100644 --- a/src/3rdparty/harfbuzz-ng/src/test-gpos-size-params.cc +++ b/src/3rdparty/harfbuzz-ng/src/test-gpos-size-params.cc @@ -29,8 +29,6 @@ #include "hb.h" #include "hb-ot.h" -#include <stdio.h> - #ifdef HB_NO_OPEN #define hb_blob_create_from_file(x) hb_blob_get_empty () #endif diff --git a/src/3rdparty/harfbuzz-ng/src/test-gsub-would-substitute.cc b/src/3rdparty/harfbuzz-ng/src/test-gsub-would-substitute.cc index 7ad9e084cb..508217dde9 100644 --- a/src/3rdparty/harfbuzz-ng/src/test-gsub-would-substitute.cc +++ b/src/3rdparty/harfbuzz-ng/src/test-gsub-would-substitute.cc @@ -29,8 +29,6 @@ #include "hb.h" #include "hb-ot.h" -#include <stdio.h> - #ifdef HAVE_FREETYPE #include "hb-ft.h" #endif diff --git a/src/3rdparty/harfbuzz-ng/src/test-iter.cc b/src/3rdparty/harfbuzz-ng/src/test-iter.cc index 9c83171889..fd201c85e8 100644 --- a/src/3rdparty/harfbuzz-ng/src/test-iter.cc +++ b/src/3rdparty/harfbuzz-ng/src/test-iter.cc @@ -105,7 +105,7 @@ test_iterator (Iter it) template <typename Iterable, hb_requires (hb_is_iterable (Iterable))> static void -test_iterable (const Iterable &lst = Null(Iterable)) +test_iterable (const Iterable &lst = Null (Iterable)) { for (auto _ : lst) (void) _; diff --git a/src/3rdparty/harfbuzz-ng/src/test-meta.cc b/src/3rdparty/harfbuzz-ng/src/test-meta.cc index 0b6e02c269..9436b9038e 100644 --- a/src/3rdparty/harfbuzz-ng/src/test-meta.cc +++ b/src/3rdparty/harfbuzz-ng/src/test-meta.cc @@ -29,6 +29,8 @@ #include <type_traits> +template <typename T> struct U { typedef T type; }; + int main (int argc, char **argv) { @@ -122,6 +124,9 @@ main (int argc, char **argv) static_assert (hb_is_trivial (X), ""); static_assert (hb_is_trivial (Y), ""); + static_assert (hb_is_signed (hb_unwrap_type (U<U<U<int>>>)), ""); + static_assert (hb_is_unsigned (hb_unwrap_type (U<U<U<U<unsigned>>>>)), ""); + /* TODO Add more meaningful tests. */ return 0; diff --git a/src/3rdparty/harfbuzz-ng/src/test-number.cc b/src/3rdparty/harfbuzz-ng/src/test-number.cc index 3591b13f27..57835288c4 100644 --- a/src/3rdparty/harfbuzz-ng/src/test-number.cc +++ b/src/3rdparty/harfbuzz-ng/src/test-number.cc @@ -25,7 +25,6 @@ #include "hb.hh" #include "hb-number.hh" -#include "hb-number-parser.hh" int @@ -146,11 +145,6 @@ main (int argc, char **argv) assert ((int) roundf (pv * 1000.) == 123); assert (pp - str == 4); assert (end - pp == 1); - - /* Test strtod_rl even if libc's strtod_l is used */ - char *pend; - assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123); - assert (pend - str == 4); } { @@ -163,10 +157,6 @@ main (int argc, char **argv) assert ((int) roundf (pv * 1000.) == 123); assert (pp - str == 5); assert (end - pp == 0); - - char *pend; - assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123); - assert (pend - str == 5); } { @@ -179,10 +169,6 @@ main (int argc, char **argv) assert ((int) roundf (pv * 1000.) == 123); assert (pp - str == 7); assert (end - pp == 0); - - char *pend; - assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123); - assert (pend - str == 7); } { @@ -195,10 +181,6 @@ main (int argc, char **argv) assert ((int) roundf (pv * 1000.) == 123); assert (pp - str == 6); assert (end - pp == 0); - - char *pend; - assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123); - assert (pend - str == 6); } { @@ -211,10 +193,6 @@ main (int argc, char **argv) assert ((int) roundf (pv * 1000.) == 123); assert (pp - str == 10); assert (end - pp == 0); - - char *pend; - assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123); - assert (pend - str == 10); } { @@ -228,9 +206,6 @@ main (int argc, char **argv) assert (pp - str == 13); assert (end - pp == 0); - char *pend; - assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == -123); - assert (pend - str == 13); } { @@ -243,10 +218,6 @@ main (int argc, char **argv) assert ((int) roundf (pv * 1000.) == -123); assert (pp - str == 8); assert (end - pp == 0); - - char *pend; - assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == -123); - assert (pend - str == 8); } return 0; diff --git a/src/3rdparty/harfbuzz-ng/src/test-ot-color.cc b/src/3rdparty/harfbuzz-ng/src/test-ot-color.cc deleted file mode 100644 index 88924b4473..0000000000 --- a/src/3rdparty/harfbuzz-ng/src/test-ot-color.cc +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright © 2018 Ebrahim Byagowi - * Copyright © 2018 Khaled Hosny - * - * 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.hh" - -#include <cairo.h> - -#ifdef HB_NO_OPEN -#define hb_blob_create_from_file(x) hb_blob_get_empty () -#endif - -#if !defined(HB_NO_COLOR) && defined(CAIRO_HAS_SVG_SURFACE) - -#include "hb-ot.h" - -#include "hb-ft.h" - -#include <ft2build.h> -#include FT_FREETYPE_H -#include FT_GLYPH_H - -#include <cairo-ft.h> -#include <cairo-svg.h> - -#include <stdlib.h> -#include <stdio.h> - -static void -svg_dump (hb_face_t *face, unsigned int face_index) -{ - unsigned glyph_count = hb_face_get_glyph_count (face); - - for (unsigned int glyph_id = 0; glyph_id < glyph_count; glyph_id++) - { - hb_blob_t *blob = hb_ot_color_glyph_reference_svg (face, glyph_id); - - if (hb_blob_get_length (blob) == 0) continue; - - unsigned int length; - const char *data = hb_blob_get_data (blob, &length); - - char output_path[255]; - sprintf (output_path, "out/svg-%u-%u.svg%s", - glyph_id, - face_index, - // append "z" if the content is gzipped, https://stackoverflow.com/a/6059405 - (length > 2 && (data[0] == '\x1F') && (data[1] == '\x8B')) ? "z" : ""); - - FILE *f = fopen (output_path, "wb"); - fwrite (data, 1, length, f); - fclose (f); - - hb_blob_destroy (blob); - } -} - -/* _png API is so easy to use unlike the below code, don't get confused */ -static void -png_dump (hb_face_t *face, unsigned int face_index) -{ - unsigned glyph_count = hb_face_get_glyph_count (face); - hb_font_t *font = hb_font_create (face); - - /* scans the font for strikes */ - unsigned int sample_glyph_id; - /* we don't care about different strikes for different glyphs at this point */ - for (sample_glyph_id = 0; sample_glyph_id < glyph_count; sample_glyph_id++) - { - hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, sample_glyph_id); - unsigned int blob_length = hb_blob_get_length (blob); - hb_blob_destroy (blob); - if (blob_length != 0) - break; - } - - unsigned int upem = hb_face_get_upem (face); - unsigned int blob_length = 0; - unsigned int strike = 0; - for (unsigned int ppem = 1; ppem < upem; ppem++) - { - hb_font_set_ppem (font, ppem, ppem); - hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, sample_glyph_id); - unsigned int new_blob_length = hb_blob_get_length (blob); - hb_blob_destroy (blob); - if (new_blob_length != blob_length) - { - for (unsigned int glyph_id = 0; glyph_id < glyph_count; glyph_id++) - { - hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, glyph_id); - - if (hb_blob_get_length (blob) == 0) continue; - - unsigned int length; - const char *data = hb_blob_get_data (blob, &length); - - char output_path[255]; - sprintf (output_path, "out/png-%u-%u-%u.png", glyph_id, strike, face_index); - - FILE *f = fopen (output_path, "wb"); - fwrite (data, 1, length, f); - fclose (f); - - hb_blob_destroy (blob); - } - - strike++; - blob_length = new_blob_length; - } - } - - hb_font_destroy (font); -} - -static void -layered_glyph_dump (hb_face_t *face, cairo_font_face_t *cairo_face, unsigned int face_index) -{ - unsigned int upem = hb_face_get_upem (face); - - unsigned glyph_count = hb_face_get_glyph_count (face); - for (hb_codepoint_t gid = 0; gid < glyph_count; ++gid) - { - unsigned int num_layers = hb_ot_color_glyph_get_layers (face, gid, 0, nullptr, nullptr); - if (!num_layers) - continue; - - hb_ot_color_layer_t *layers = (hb_ot_color_layer_t*) malloc (num_layers * sizeof (hb_ot_color_layer_t)); - - hb_ot_color_glyph_get_layers (face, gid, 0, &num_layers, layers); - if (num_layers) - { - // Measure - cairo_text_extents_t extents; - { - cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1); - cairo_t *cr = cairo_create (surface); - cairo_set_font_face (cr, cairo_face); - cairo_set_font_size (cr, upem); - - cairo_glyph_t *glyphs = (cairo_glyph_t *) calloc (num_layers, sizeof (cairo_glyph_t)); - for (unsigned int j = 0; j < num_layers; ++j) - glyphs[j].index = layers[j].glyph; - cairo_glyph_extents (cr, glyphs, num_layers, &extents); - free (glyphs); - cairo_surface_destroy (surface); - cairo_destroy (cr); - } - - // Add a slight margin - extents.width += extents.width / 10; - extents.height += extents.height / 10; - extents.x_bearing -= extents.width / 20; - extents.y_bearing -= extents.height / 20; - - // Render - unsigned int palette_count = hb_ot_color_palette_get_count (face); - for (unsigned int palette = 0; palette < palette_count; palette++) - { - unsigned int num_colors = hb_ot_color_palette_get_colors (face, palette, 0, nullptr, nullptr); - if (!num_colors) - continue; - - hb_color_t *colors = (hb_color_t*) calloc (num_colors, sizeof (hb_color_t)); - hb_ot_color_palette_get_colors (face, palette, 0, &num_colors, colors); - if (num_colors) - { - char output_path[255]; - sprintf (output_path, "out/colr-%u-%u-%u.svg", gid, palette, face_index); - - cairo_surface_t *surface = cairo_svg_surface_create (output_path, extents.width, extents.height); - cairo_t *cr = cairo_create (surface); - cairo_set_font_face (cr, cairo_face); - cairo_set_font_size (cr, upem); - - for (unsigned int layer = 0; layer < num_layers; ++layer) - { - hb_color_t color = 0x000000FF; - if (layers[layer].color_index != 0xFFFF) - color = colors[layers[layer].color_index]; - cairo_set_source_rgba (cr, - hb_color_get_red (color) / 255., - hb_color_get_green (color) / 255., - hb_color_get_blue (color) / 255., - hb_color_get_alpha (color) / 255.); - - cairo_glyph_t glyph; - glyph.index = layers[layer].glyph; - glyph.x = -extents.x_bearing; - glyph.y = -extents.y_bearing; - cairo_show_glyphs (cr, &glyph, 1); - } - - cairo_surface_destroy (surface); - cairo_destroy (cr); - } - free (colors); - } - } - - free (layers); - } -} - -static void -dump_glyphs (cairo_font_face_t *cairo_face, unsigned int upem, - unsigned int num_glyphs, unsigned int face_index) -{ - for (unsigned int i = 0; i < num_glyphs; ++i) - { - cairo_text_extents_t extents; - cairo_glyph_t glyph = {0}; - glyph.index = i; - - // Measure - { - cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1); - cairo_t *cr = cairo_create (surface); - cairo_set_font_face (cr, cairo_face); - cairo_set_font_size (cr, upem); - - cairo_glyph_extents (cr, &glyph, 1, &extents); - cairo_surface_destroy (surface); - cairo_destroy (cr); - } - - // Add a slight margin - extents.width += extents.width / 10; - extents.height += extents.height / 10; - extents.x_bearing -= extents.width / 20; - extents.y_bearing -= extents.height / 20; - - // Render - { - char output_path[255]; - sprintf (output_path, "out/%u-%u.svg", face_index, i); - cairo_surface_t *surface = cairo_svg_surface_create (output_path, extents.width, extents.height); - cairo_t *cr = cairo_create (surface); - cairo_set_font_face (cr, cairo_face); - cairo_set_font_size (cr, upem); - glyph.x = -extents.x_bearing; - glyph.y = -extents.y_bearing; - cairo_show_glyphs (cr, &glyph, 1); - cairo_surface_destroy (surface); - cairo_destroy (cr); - } - } -} - -int -main (int argc, char **argv) -{ - if (argc != 2) { - fprintf (stderr, "usage: %s font-file.ttf\n" - "run it like `rm -rf out && mkdir out && %s font-file.ttf`\n", - argv[0], argv[0]); - exit (1); - } - - - FILE *font_name_file = fopen ("out/.dumped_font_name", "r"); - if (font_name_file != nullptr) - { - fprintf (stderr, "Purge or move ./out folder in order to run a new dump\n"); - exit (1); - } - - font_name_file = fopen ("out/.dumped_font_name", "w"); - if (font_name_file == nullptr) - { - fprintf (stderr, "./out is not accessible as a folder, create it please\n"); - exit (1); - } - fwrite (argv[1], 1, strlen (argv[1]), font_name_file); - fclose (font_name_file); - - hb_blob_t *blob = hb_blob_create_from_file (argv[1]); - unsigned int num_faces = hb_face_count (blob); - if (num_faces == 0) - { - fprintf (stderr, "error: The file (%s) was corrupted, empty or not found", argv[1]); - exit (1); - } - - for (unsigned int face_index = 0; face_index < hb_face_count (blob); face_index++) - { - hb_face_t *face = hb_face_create (blob, face_index); - hb_font_t *font = hb_font_create (face); - - if (hb_ot_color_has_png (face)) printf ("Dumping png (cbdt/sbix)...\n"); - png_dump (face, face_index); - - if (hb_ot_color_has_svg (face)) printf ("Dumping svg...\n"); - svg_dump (face, face_index); - - cairo_font_face_t *cairo_face; - { - FT_Library library; - FT_Init_FreeType (&library); - FT_Face ft_face; - FT_New_Face (library, argv[1], 0, &ft_face); - cairo_face = cairo_ft_font_face_create_for_ft_face (ft_face, 0); - } - if (hb_ot_color_has_layers (face) && hb_ot_color_has_palettes (face)) - printf ("Dumping layered color glyphs...\n"); - layered_glyph_dump (face, cairo_face, face_index); - - unsigned int num_glyphs = hb_face_get_glyph_count (face); - unsigned int upem = hb_face_get_upem (face); - - // disabled when color font as cairo rendering of NotoColorEmoji is soooo slow - if (!hb_ot_color_has_layers (face) && - !hb_ot_color_has_png (face) && - !hb_ot_color_has_svg (face)) - dump_glyphs (cairo_face, upem, num_glyphs, face_index); - - hb_font_destroy (font); - hb_face_destroy (face); - } - - hb_blob_destroy (blob); - - return 0; -} - -#else -int main (int argc, char **argv) { return 0; } -#endif diff --git a/src/3rdparty/harfbuzz-ng/src/test-ot-glyphname.cc b/src/3rdparty/harfbuzz-ng/src/test-ot-glyphname.cc new file mode 100644 index 0000000000..b2d4b3bcf0 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/test-ot-glyphname.cc @@ -0,0 +1,88 @@ +/* + * Copyright © 2019 Adobe, 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. + * + * Adobe Author(s): Michiharu Ariza + */ + +#include "hb.hh" +#include "hb-ot.h" + +#ifdef HB_NO_OPEN +#define hb_blob_create_from_file(x) hb_blob_get_empty () +#endif + +int +main (int argc, char **argv) +{ + if (argc != 2) { + fprintf (stderr, "usage: %s font-file\n", argv[0]); + exit (1); + } + + hb_blob_t *blob = hb_blob_create_from_file (argv[1]); + hb_face_t *face = hb_face_create (blob, 0 /* first face */); + hb_font_t *font = hb_font_create (face); + hb_blob_destroy (blob); + blob = nullptr; + + + const unsigned int num_glyphs = hb_face_get_glyph_count (face); + int result = 1; + + for (hb_codepoint_t gid = 0; gid < num_glyphs; gid++) + { + char buf[64]; + unsigned int buf_size = sizeof (buf); + if (hb_font_get_glyph_name (font, gid, buf, buf_size)) + { + hb_codepoint_t gid_inv; + if (hb_font_get_glyph_from_name(font, buf, strlen (buf), &gid_inv)) + { + if (gid == gid_inv) + { + printf ("%u <-> %s\n", gid, buf); + } + else + { + printf ("%u -> %s -> %u\n", gid, buf, gid_inv); + result = 0; + } + } + else + { + printf ("%u -> %s -> ?\n", gid, buf); + result = 0; + } + } + else + { + printf ("%u -> ?\n", gid); + result = 0; + } + } + + hb_font_destroy (font); + hb_face_destroy (face); + + return result; +} diff --git a/src/3rdparty/harfbuzz-ng/src/test-ot-meta.cc b/src/3rdparty/harfbuzz-ng/src/test-ot-meta.cc index 1045007f7d..f7a755cd59 100644 --- a/src/3rdparty/harfbuzz-ng/src/test-ot-meta.cc +++ b/src/3rdparty/harfbuzz-ng/src/test-ot-meta.cc @@ -25,9 +25,6 @@ #include "hb.hh" #include "hb-ot.h" -#include <stdlib.h> -#include <stdio.h> - #ifdef HB_NO_OPEN #define hb_blob_create_from_file(x) hb_blob_get_empty () #endif diff --git a/src/3rdparty/harfbuzz-ng/src/test-ot-name.cc b/src/3rdparty/harfbuzz-ng/src/test-ot-name.cc index 4a484c6d66..f331161fa4 100644 --- a/src/3rdparty/harfbuzz-ng/src/test-ot-name.cc +++ b/src/3rdparty/harfbuzz-ng/src/test-ot-name.cc @@ -27,9 +27,6 @@ #include "hb.hh" #include "hb-ot.h" -#include <stdlib.h> -#include <stdio.h> - #ifdef HB_NO_OPEN #define hb_blob_create_from_file(x) hb_blob_get_empty () #endif diff --git a/src/3rdparty/harfbuzz-ng/src/test.cc b/src/3rdparty/harfbuzz-ng/src/test.cc index 65b469feb7..347b71d38b 100644 --- a/src/3rdparty/harfbuzz-ng/src/test.cc +++ b/src/3rdparty/harfbuzz-ng/src/test.cc @@ -26,10 +26,6 @@ #include "hb.hh" -#include "hb.h" - -#include <stdio.h> - #ifdef HAVE_FREETYPE #include "hb-ft.h" #endif |