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 Pick-to: 6.1 Change-Id: I23eae7b7bbbd5001df9873e4784a0c4213de5508 Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com> Reviewed-by: Lars Knoll <lars.knoll@qt.io>bb10
parent
29450dfa28
commit
70af64433f
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
====================================
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
[](https://travis-ci.org/harfbuzz/harfbuzz)
|
||||
[](https://ci.appveyor.com/project/harfbuzz/harfbuzz)
|
||||
[](https://github.com/harfbuzz/harfbuzz/workflows/linux-ci/badge.svg)
|
||||
[](https://circleci.com/gh/harfbuzz/harfbuzz/tree/master)
|
||||
[](https://oss-fuzz-build-logs.storage.googleapis.com/index.html)
|
||||
[](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>
|
||||
|
||||
[](https://repology.org/project/harfbuzz/versions)
|
||||
[](https://repology.org/project/harfbuzz/versions)
|
||||
|
||||
</details>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
* 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))
|
||||
;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
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 ();
|
||||
|
||||
|
|
|
|||
|
|
@ -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); }
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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). */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 *
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
@ -633,30 +805,91 @@ 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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*
|
||||
* Returns: A hb_blob_t pointer with the content of the file
|
||||
* Creates a new blob containing the data from the
|
||||
* specified binary font 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);
|
||||
|
|
|
|||
|
|
@ -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 *
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -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 */
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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 */
|
||||
|
|
@ -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)
|
||||
|
|
@ -196,19 +201,72 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
|
|||
return end - start;
|
||||
}
|
||||
|
||||
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,13 @@ 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:
|
||||
|
|
@ -379,6 +506,184 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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:
|
||||
return 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
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_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:
|
||||
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_json (buffer,
|
||||
buf, buf_len, end_ptr,
|
||||
font);
|
||||
|
||||
default:
|
||||
case HB_BUFFER_SERIALIZE_FORMAT_INVALID:
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -1425,14 +1382,33 @@ hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
|
|||
return (hb_glyph_position_t *) buffer->pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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));
|
||||
|
||||
buffer->assert_glyphs ();
|
||||
|
||||
bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
|
||||
|
||||
unsigned int count = buffer->len;
|
||||
if (unlikely (!count)) return;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
|
||||
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
|
||||
**/
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
if (unlikely (!make_room_for (num_in, num_out))) return false;
|
||||
|
||||
assert (idx + num_in <= len);
|
||||
|
||||
merge_clusters (idx, idx + num_in);
|
||||
|
||||
hb_glyph_info_t &orig_info = idx < len ? cur() : prev();
|
||||
|
||||
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++;
|
||||
}
|
||||
out_info[out_len].codepoint = glyph_index;
|
||||
|
||||
idx++;
|
||||
out_len++;
|
||||
idx += num_in;
|
||||
out_len += num_out;
|
||||
return true;
|
||||
}
|
||||
|
||||
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_glyph_info_t & output_glyph (hb_codepoint_t 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 Crap(hb_glyph_info_t);
|
||||
|
||||
if (unlikely (idx == len && !out_len))
|
||||
return Crap(hb_glyph_info_t);
|
||||
|
||||
out_info[out_len] = idx < len ? info[idx] : out_info[out_len - 1];
|
||||
out_info[out_len].codepoint = glyph_index;
|
||||
|
||||
out_len++;
|
||||
|
||||
return out_info[out_len - 1];
|
||||
}
|
||||
void 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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
* Return value: Alpha channel value of the given color
|
||||
* Fetches the alpha channel 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.
|
||||
*
|
||||
* Return value: Red channel value of the given color
|
||||
* Fetches the red channel 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.
|
||||
*
|
||||
* Return value: Blue channel value of the given color
|
||||
* Fetches the blue channel of the given @color.
|
||||
*
|
||||
* Return value: Blue channel value
|
||||
*
|
||||
* Since: 2.1.0
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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'),
|
||||
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*/
|
||||
|
||||
/*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'),
|
||||
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*/
|
||||
|
||||
/*2.0*/ HB_SCRIPT_TIBETAN = HB_TAG ('T','i','b','t'),
|
||||
HB_SCRIPT_TIBETAN = HB_TAG ('T','i','b','t'), /*2.0*/
|
||||
|
||||
/*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'),
|
||||
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*/
|
||||
|
||||
/*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'),
|
||||
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*/
|
||||
|
||||
/*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'),
|
||||
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*/
|
||||
|
||||
/*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'),
|
||||
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*/
|
||||
|
||||
/*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'),
|
||||
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*/
|
||||
|
||||
/*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'),
|
||||
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*/
|
||||
|
||||
/*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'),
|
||||
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*/
|
||||
|
||||
/*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'),
|
||||
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*/
|
||||
|
||||
/*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'),
|
||||
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*/
|
||||
|
||||
/*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_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'),
|
||||
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*/
|
||||
|
||||
/*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_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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
**/
|
||||
|
|
|
|||
|
|
@ -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 ***/
|
||||
|
|
@ -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 ***/
|
||||
|
|
@ -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.
|
||||
**/
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ())
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2011 Google, Inc.
|
||||
* Copyright (C) 2011 Google, Inc.
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
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;
|
||||
return *a != ab;
|
||||
}
|
||||
|
||||
return ret;
|
||||
else if (len == 2)
|
||||
{
|
||||
len = 0;
|
||||
U16_NEXT_UNSAFE (decomposed, len, *a);
|
||||
U16_NEXT_UNSAFE (decomposed, len, *b);
|
||||
}
|
||||
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 ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*
|
||||
* Return value: (transfer full):
|
||||
* Increases the reference count on a map.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Return value:
|
||||
* Attaches a user-data key/data pair to the specified map.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Return value: (transfer none):
|
||||
* Fetches the user data associated with the specified key,
|
||||
* attached to the specified map.
|
||||
*
|
||||
* 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
|
||||
**/
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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.;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
@ -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); });
|
||||
return _parse_number<unsigned> (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 ();
|
||||
}
|
||||
#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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {}
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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); }
|
||||
|
||||
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 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_offset4_op (hb_serialize_context_t *c, op_code_t op, int value)
|
||||
{ return serialize_uint4_op (c, op, value); }
|
||||
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_offset2_op (hb_serialize_context_t *c, op_code_t op, int value)
|
||||
{ return serialize_uint2_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_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);
|
||||
}
|
||||
dict->serialize (c, _.first, opszr, _.second);
|
||||
return c->head - (const char*)dict;
|
||||
})
|
||||
| hb_sink (sizes)
|
||||
;
|
||||
c->pop_pack (false);
|
||||
|
||||
/* 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);
|
||||
/* 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)
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
void init (hb_face_t *face)
|
||||
{
|
||||
SUPER::init (face);
|
||||
|
||||
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;
|
||||
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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue